@@ -128,7 +128,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
128
128
129
129
if let Some ( generics) = node. generics ( ) {
130
130
for param in generics. params {
131
- check_param_wf ( tcx, param)
131
+ check_param_wf ( tcx, param, def_id . def_id )
132
132
}
133
133
}
134
134
}
@@ -846,140 +846,136 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
846
846
check_associated_item ( tcx, impl_item. owner_id . def_id , span, method_sig) ;
847
847
}
848
848
849
- fn check_param_wf ( tcx : TyCtxt < ' _ > , param : & hir:: GenericParam < ' _ > ) {
849
+ fn check_param_wf ( tcx : TyCtxt < ' _ > , param : & hir:: GenericParam < ' _ > , owner_id : LocalDefId ) {
850
850
match param. kind {
851
851
// We currently only check wf of const params here.
852
852
hir:: GenericParamKind :: Lifetime { .. } | hir:: GenericParamKind :: Type { .. } => ( ) ,
853
853
854
854
// Const parameters are well formed if their type is structural match.
855
855
hir:: GenericParamKind :: Const { ty : hir_ty, default : _ } => {
856
- let mut ty = tcx. type_of ( param. def_id ) ;
857
- while let ty:: Projection ( ty:: ProjectionTy { substs, item_def_id } ) = ty. kind ( ) {
858
- let binder_ty = tcx. bound_type_of ( * item_def_id) ;
859
- ty = binder_ty. subst ( tcx, substs) ;
860
- }
856
+ enter_wf_checking_ctxt ( tcx, param. span , owner_id, |wfcx| {
857
+ let ty = tcx. type_of ( param. def_id ) ;
858
+ let ty = wfcx. normalize ( hir_ty. span , None , ty) ;
859
+
860
+ if tcx. features ( ) . adt_const_params {
861
+ if let Some ( non_structural_match_ty) =
862
+ traits:: search_for_adt_const_param_violation ( param. span , tcx, ty)
863
+ {
864
+ // We use the same error code in both branches, because this is really the same
865
+ // issue: we just special-case the message for type parameters to make it
866
+ // clearer.
867
+ match non_structural_match_ty. kind ( ) {
868
+ ty:: Param ( _) => {
869
+ // Const parameters may not have type parameters as their types,
870
+ // because we cannot be sure that the type parameter derives `PartialEq`
871
+ // and `Eq` (just implementing them is not enough for `structural_match`).
872
+ struct_span_err ! (
873
+ tcx. sess,
874
+ hir_ty. span,
875
+ E0741 ,
876
+ "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
877
+ used as the type of a const parameter",
878
+ )
879
+ . span_label (
880
+ hir_ty. span ,
881
+ format ! ( "`{ty}` may not derive both `PartialEq` and `Eq`" ) ,
882
+ )
883
+ . note (
884
+ "it is not currently possible to use a type parameter as the type of a \
885
+ const parameter",
886
+ )
887
+ . emit ( ) ;
888
+ }
889
+ ty:: Float ( _) => {
890
+ struct_span_err ! (
891
+ tcx. sess,
892
+ hir_ty. span,
893
+ E0741 ,
894
+ "`{ty}` is forbidden as the type of a const generic parameter" ,
895
+ )
896
+ . note ( "floats do not derive `Eq` or `Ord`, which are required for const parameters" )
897
+ . emit ( ) ;
898
+ }
899
+ ty:: FnPtr ( _) => {
900
+ struct_span_err ! (
901
+ tcx. sess,
902
+ hir_ty. span,
903
+ E0741 ,
904
+ "using function pointers as const generic parameters is forbidden" ,
905
+ )
906
+ . emit ( ) ;
907
+ }
908
+ ty:: RawPtr ( _) => {
909
+ struct_span_err ! (
910
+ tcx. sess,
911
+ hir_ty. span,
912
+ E0741 ,
913
+ "using raw pointers as const generic parameters is forbidden" ,
914
+ )
915
+ . emit ( ) ;
916
+ }
917
+ _ => {
918
+ let mut diag = struct_span_err ! (
919
+ tcx. sess,
920
+ hir_ty. span,
921
+ E0741 ,
922
+ "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
923
+ the type of a const parameter",
924
+ non_structural_match_ty,
925
+ ) ;
861
926
862
- if tcx. features ( ) . adt_const_params {
863
- if let Some ( non_structural_match_ty) =
864
- traits:: search_for_adt_const_param_violation ( param. span , tcx, ty)
865
- {
866
- // We use the same error code in both branches, because this is really the same
867
- // issue: we just special-case the message for type parameters to make it
868
- // clearer.
869
- match non_structural_match_ty. kind ( ) {
870
- ty:: Param ( _) => {
871
- // Const parameters may not have type parameters as their types,
872
- // because we cannot be sure that the type parameter derives `PartialEq`
873
- // and `Eq` (just implementing them is not enough for `structural_match`).
874
- struct_span_err ! (
875
- tcx. sess,
876
- hir_ty. span,
877
- E0741 ,
878
- "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
879
- used as the type of a const parameter",
880
- )
881
- . span_label (
882
- hir_ty. span ,
883
- format ! ( "`{ty}` may not derive both `PartialEq` and `Eq`" ) ,
884
- )
885
- . note (
886
- "it is not currently possible to use a type parameter as the type of a \
887
- const parameter",
888
- )
889
- . emit ( ) ;
890
- }
891
- ty:: Float ( _) => {
892
- struct_span_err ! (
893
- tcx. sess,
894
- hir_ty. span,
895
- E0741 ,
896
- "`{ty}` is forbidden as the type of a const generic parameter" ,
897
- )
898
- . note ( "floats do not derive `Eq` or `Ord`, which are required for const parameters" )
899
- . emit ( ) ;
927
+ if ty == non_structural_match_ty {
928
+ diag. span_label (
929
+ hir_ty. span ,
930
+ format ! ( "`{ty}` doesn't derive both `PartialEq` and `Eq`" ) ,
931
+ ) ;
932
+ }
933
+
934
+ diag. emit ( ) ;
935
+ }
900
936
}
901
- ty:: FnPtr ( _) => {
902
- struct_span_err ! (
903
- tcx. sess,
904
- hir_ty. span,
905
- E0741 ,
906
- "using function pointers as const generic parameters is forbidden" ,
907
- )
908
- . emit ( ) ;
937
+ }
938
+ } else {
939
+ let err_ty_str;
940
+ let mut is_ptr = true ;
941
+
942
+ let err = match ty. kind ( ) {
943
+ ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) | ty:: Error ( _) => None ,
944
+ ty:: FnPtr ( _) => Some ( "function pointers" ) ,
945
+ ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
946
+ _ => {
947
+ is_ptr = false ;
948
+ err_ty_str = format ! ( "`{ty}`" ) ;
949
+ Some ( err_ty_str. as_str ( ) )
909
950
}
910
- ty:: RawPtr ( _) => {
911
- struct_span_err ! (
912
- tcx. sess,
951
+ } ;
952
+
953
+ if let Some ( unsupported_type) = err {
954
+ if is_ptr {
955
+ tcx. sess . span_err (
913
956
hir_ty. span ,
914
- E0741 ,
915
- "using raw pointers as const generic parameters is forbidden" ,
916
- )
917
- . emit ( ) ;
918
- }
919
- // Should have been normalized in
920
- // `traits::search_for_adt_const_param_violation`
921
- ty:: Projection ( _) => unreachable ! ( ) ,
922
- _ => {
923
- let mut diag = struct_span_err ! (
924
- tcx. sess,
957
+ & format ! (
958
+ "using {unsupported_type} as const generic parameters is forbidden" ,
959
+ ) ,
960
+ ) ;
961
+ } else {
962
+ let mut err = tcx. sess . struct_span_err (
925
963
hir_ty. span ,
926
- E0741 ,
927
- "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
928
- the type of a const parameter",
929
- non_structural_match_ty,
964
+ & format ! (
965
+ "{unsupported_type} is forbidden as the type of a const generic parameter" ,
966
+ ) ,
967
+ ) ;
968
+ err. note ( "the only supported types are integers, `bool` and `char`" ) ;
969
+ if tcx. sess . is_nightly_build ( ) {
970
+ err. help (
971
+ "more complex types are supported with `#![feature(adt_const_params)]`" ,
930
972
) ;
931
-
932
- if ty == non_structural_match_ty {
933
- diag. span_label (
934
- hir_ty. span ,
935
- format ! ( "`{ty}` doesn't derive both `PartialEq` and `Eq`" ) ,
936
- ) ;
937
973
}
938
-
939
- diag. emit ( ) ;
974
+ err. emit ( ) ;
940
975
}
941
976
}
942
977
}
943
- } else {
944
- let err_ty_str;
945
- let mut is_ptr = true ;
946
-
947
- let err = match ty. kind ( ) {
948
- ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) | ty:: Error ( _) => None ,
949
- ty:: FnPtr ( _) => Some ( "function pointers" ) ,
950
- ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
951
- _ => {
952
- is_ptr = false ;
953
- err_ty_str = format ! ( "`{ty}`" ) ;
954
- Some ( err_ty_str. as_str ( ) )
955
- }
956
- } ;
957
-
958
- if let Some ( unsupported_type) = err {
959
- if is_ptr {
960
- tcx. sess . span_err (
961
- hir_ty. span ,
962
- & format ! (
963
- "using {unsupported_type} as const generic parameters is forbidden" ,
964
- ) ,
965
- ) ;
966
- } else {
967
- let mut err = tcx. sess . struct_span_err (
968
- hir_ty. span ,
969
- & format ! (
970
- "{unsupported_type} is forbidden as the type of a const generic parameter" ,
971
- ) ,
972
- ) ;
973
- err. note ( "the only supported types are integers, `bool` and `char`" ) ;
974
- if tcx. sess . is_nightly_build ( ) {
975
- err. help (
976
- "more complex types are supported with `#![feature(adt_const_params)]`" ,
977
- ) ;
978
- }
979
- err. emit ( ) ;
980
- }
981
- }
982
- }
978
+ } ) ;
983
979
}
984
980
}
985
981
}
0 commit comments