@@ -816,16 +816,69 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
816816 hir:: GenericParamKind :: Const { ty : hir_ty, default : _ } => {
817817 let ty = tcx. type_of ( tcx. hir ( ) . local_def_id ( param. hir_id ) ) ;
818818
819- let err_ty_str;
820- let mut is_ptr = true ;
821- let err = if tcx. features ( ) . adt_const_params {
822- match ty. peel_refs ( ) . kind ( ) {
819+ if tcx. features ( ) . adt_const_params {
820+ let err = match ty. peel_refs ( ) . kind ( ) {
823821 ty:: FnPtr ( _) => Some ( "function pointers" ) ,
824822 ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
825823 _ => None ,
824+ } ;
825+
826+ if let Some ( unsupported_type) = err {
827+ tcx. sess . span_err (
828+ hir_ty. span ,
829+ & format ! (
830+ "using {} as const generic parameters is forbidden" ,
831+ unsupported_type
832+ ) ,
833+ ) ;
834+ }
835+
836+ if traits:: search_for_structural_match_violation ( param. span , tcx, ty) . is_some ( ) {
837+ // We use the same error code in both branches, because this is really the same
838+ // issue: we just special-case the message for type parameters to make it
839+ // clearer.
840+ if let ty:: Param ( _) = ty. peel_refs ( ) . kind ( ) {
841+ // Const parameters may not have type parameters as their types,
842+ // because we cannot be sure that the type parameter derives `PartialEq`
843+ // and `Eq` (just implementing them is not enough for `structural_match`).
844+ struct_span_err ! (
845+ tcx. sess,
846+ hir_ty. span,
847+ E0741 ,
848+ "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
849+ used as the type of a const parameter",
850+ ty,
851+ )
852+ . span_label (
853+ hir_ty. span ,
854+ format ! ( "`{}` may not derive both `PartialEq` and `Eq`" , ty) ,
855+ )
856+ . note (
857+ "it is not currently possible to use a type parameter as the type of a \
858+ const parameter",
859+ )
860+ . emit ( ) ;
861+ } else {
862+ struct_span_err ! (
863+ tcx. sess,
864+ hir_ty. span,
865+ E0741 ,
866+ "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
867+ the type of a const parameter",
868+ ty,
869+ )
870+ . span_label (
871+ hir_ty. span ,
872+ format ! ( "`{}` doesn't derive both `PartialEq` and `Eq`" , ty) ,
873+ )
874+ . emit ( ) ;
875+ }
826876 }
827877 } else {
828- match ty. kind ( ) {
878+ let err_ty_str;
879+ let mut is_ptr = true ;
880+
881+ let err = match ty. kind ( ) {
829882 ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) | ty:: Error ( _) => None ,
830883 ty:: FnPtr ( _) => Some ( "function pointers" ) ,
831884 ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
@@ -834,74 +887,33 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
834887 err_ty_str = format ! ( "`{}`" , ty) ;
835888 Some ( err_ty_str. as_str ( ) )
836889 }
837- }
838- } ;
839- if let Some ( unsupported_type) = err {
840- if is_ptr {
841- tcx. sess . span_err (
842- hir_ty. span ,
843- & format ! (
844- "using {} as const generic parameters is forbidden" ,
845- unsupported_type
846- ) ,
847- ) ;
848- } else {
849- let mut err = tcx. sess . struct_span_err (
850- hir_ty. span ,
851- & format ! (
852- "{} is forbidden as the type of a const generic parameter" ,
853- unsupported_type
854- ) ,
855- ) ;
856- err. note ( "the only supported types are integers, `bool` and `char`" ) ;
857- if tcx. sess . is_nightly_build ( ) {
858- err. help (
890+ } ;
891+
892+ if let Some ( unsupported_type) = err {
893+ if is_ptr {
894+ tcx. sess . span_err (
895+ hir_ty. span ,
896+ & format ! (
897+ "using {} as const generic parameters is forbidden" ,
898+ unsupported_type
899+ ) ,
900+ ) ;
901+ } else {
902+ let mut err = tcx. sess . struct_span_err (
903+ hir_ty. span ,
904+ & format ! (
905+ "{} is forbidden as the type of a const generic parameter" ,
906+ unsupported_type
907+ ) ,
908+ ) ;
909+ err. note ( "the only supported types are integers, `bool` and `char`" ) ;
910+ if tcx. sess . is_nightly_build ( ) {
911+ err. help (
859912 "more complex types are supported with `#![feature(adt_const_params)]`" ,
860913 ) ;
914+ }
915+ err. emit ( ) ;
861916 }
862- err. emit ( ) ;
863- }
864- } ;
865-
866- if traits:: search_for_structural_match_violation ( param. span , tcx, ty) . is_some ( ) {
867- // We use the same error code in both branches, because this is really the same
868- // issue: we just special-case the message for type parameters to make it
869- // clearer.
870- if let ty:: Param ( _) = ty. peel_refs ( ) . kind ( ) {
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- "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
879- used as the type of a const parameter",
880- ty,
881- )
882- . span_label (
883- hir_ty. span ,
884- format ! ( "`{}` may not derive both `PartialEq` and `Eq`" , ty) ,
885- )
886- . note (
887- "it is not currently possible to use a type parameter as the type of a \
888- const parameter",
889- )
890- . emit ( ) ;
891- } else {
892- struct_span_err ! (
893- tcx. sess,
894- hir_ty. span,
895- E0741 ,
896- "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
897- the type of a const parameter",
898- ty,
899- )
900- . span_label (
901- hir_ty. span ,
902- format ! ( "`{}` doesn't derive both `PartialEq` and `Eq`" , ty) ,
903- )
904- . emit ( ) ;
905917 }
906918 }
907919 }
0 commit comments