@@ -816,16 +816,69 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
816
816
hir:: GenericParamKind :: Const { ty : hir_ty, default : _ } => {
817
817
let ty = tcx. type_of ( tcx. hir ( ) . local_def_id ( param. hir_id ) ) ;
818
818
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 ( ) {
823
821
ty:: FnPtr ( _) => Some ( "function pointers" ) ,
824
822
ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
825
823
_ => 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
+ }
826
876
}
827
877
} else {
828
- match ty. kind ( ) {
878
+ let err_ty_str;
879
+ let mut is_ptr = true ;
880
+
881
+ let err = match ty. kind ( ) {
829
882
ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) | ty:: Error ( _) => None ,
830
883
ty:: FnPtr ( _) => Some ( "function pointers" ) ,
831
884
ty:: RawPtr ( _) => Some ( "raw pointers" ) ,
@@ -834,74 +887,33 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
834
887
err_ty_str = format ! ( "`{}`" , ty) ;
835
888
Some ( err_ty_str. as_str ( ) )
836
889
}
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 (
859
912
"more complex types are supported with `#![feature(adt_const_params)]`" ,
860
913
) ;
914
+ }
915
+ err. emit ( ) ;
861
916
}
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 ( ) ;
905
917
}
906
918
}
907
919
}
0 commit comments