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