@@ -846,142 +846,140 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
846846 check_associated_item ( tcx, impl_item. owner_id . def_id , span, method_sig) ;
847847}
848848
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-
975849fn check_param_wf ( tcx : TyCtxt < ' _ > , param : & hir:: GenericParam < ' _ > ) {
976850 match param. kind {
977851 // We currently only check wf of const params here.
978852 hir:: GenericParamKind :: Lifetime { .. } | hir:: GenericParamKind :: Type { .. } => ( ) ,
979853
980854 // Const parameters are well formed if their type is structural match.
981855 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+ }
983861
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+ }
985983 }
986984 }
987985}
0 commit comments