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