@@ -846,6 +846,132 @@ 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
+
849
975
fn check_param_wf ( tcx : TyCtxt < ' _ > , param : & hir:: GenericParam < ' _ > ) {
850
976
match param. kind {
851
977
// We currently only check wf of const params here.
@@ -855,124 +981,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
855
981
hir:: GenericParamKind :: Const { ty : hir_ty, default : _ } => {
856
982
let ty = tcx. type_of ( param. def_id ) ;
857
983
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 ) ;
976
985
}
977
986
}
978
987
}
0 commit comments