about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs51
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs21
2 files changed, 48 insertions, 24 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index ecd2834dfd1..c1621b6ae4a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -922,7 +922,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
         } => {
             let ty = tcx.type_of(param.def_id).instantiate_identity();
 
-            if tcx.features().adt_const_params {
+            if tcx.features().unsized_const_params {
                 enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
                     wfcx.register_bound(
                         ObligationCause::new(
@@ -932,13 +932,21 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                         ),
                         wfcx.param_env,
                         ty,
-                        tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)),
+                        tcx.require_lang_item(LangItem::UnsizedConstParamTy, Some(hir_ty.span)),
                     );
+                    Ok(())
+                })
+            } else if tcx.features().adt_const_params {
+                enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
                     wfcx.register_bound(
-                        ObligationCause::new(hir_ty.span, param.def_id, ObligationCauseCode::Misc),
+                        ObligationCause::new(
+                            hir_ty.span,
+                            param.def_id,
+                            ObligationCauseCode::ConstParam(ty),
+                        ),
                         wfcx.param_env,
                         ty,
-                        tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
+                        tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)),
                     );
                     Ok(())
                 })
@@ -962,18 +970,29 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                 diag.note("the only supported types are integers, `bool` and `char`");
 
                 let cause = ObligationCause::misc(hir_ty.span, param.def_id);
+                let adt_const_params_feature_string =
+                    " more complex and user defined types".to_string();
                 let may_suggest_feature = match type_allowed_to_implement_const_param_ty(
                     tcx,
                     tcx.param_env(param.def_id),
                     ty,
+                    LangItem::ConstParamTy,
                     cause,
                 ) {
                     // Can never implement `ConstParamTy`, don't suggest anything.
                     Err(
                         ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed
-                        | ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(..)
-                        | ConstParamTyImplementationError::TypeNotSized,
-                    ) => false,
+                        | ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(..),
+                    ) => None,
+                    Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
+                        Some(vec![
+                            (adt_const_params_feature_string, sym::adt_const_params),
+                            (
+                                " references to implement the `ConstParamTy` trait".into(),
+                                sym::unsized_const_params,
+                            ),
+                        ])
+                    }
                     // May be able to implement `ConstParamTy`. Only emit the feature help
                     // if the type is local, since the user may be able to fix the local type.
                     Err(ConstParamTyImplementationError::InfrigingFields(..)) => {
@@ -993,20 +1012,16 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                             }
                         }
 
-                        ty_is_local(ty)
+                        ty_is_local(ty).then_some(vec![(
+                            adt_const_params_feature_string,
+                            sym::adt_const_params,
+                        )])
                     }
                     // Implments `ConstParamTy`, suggest adding the feature to enable.
-                    Ok(..) => true,
+                    Ok(..) => Some(vec![(adt_const_params_feature_string, sym::adt_const_params)]),
                 };
-                if may_suggest_feature {
-                    tcx.disabled_nightly_features(
-                        &mut diag,
-                        Some(param.hir_id),
-                        [(
-                            " more complex and user defined types".to_string(),
-                            sym::adt_const_params,
-                        )],
-                    );
+                if let Some(features) = may_suggest_feature {
+                    tcx.disabled_nightly_features(&mut diag, Some(param.hir_id), features);
                 }
 
                 Err(diag.emit())
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 16745668f8c..4fad40ff0e6 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -36,9 +36,13 @@ pub(super) fn check_trait<'tcx>(
     let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header };
     let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop);
     res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy));
-    res = res.and(
-        checker.check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty),
-    );
+    res = res.and(checker.check(lang_items.const_param_ty_trait(), |checker| {
+        visit_implementation_of_const_param_ty(checker, LangItem::ConstParamTy)
+    }));
+    res = res.and(checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
+        visit_implementation_of_const_param_ty(checker, LangItem::UnsizedConstParamTy)
+    }));
+
     res = res.and(
         checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized),
     );
@@ -122,7 +126,12 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
     }
 }
 
-fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
+fn visit_implementation_of_const_param_ty(
+    checker: &Checker<'_>,
+    kind: LangItem,
+) -> Result<(), ErrorGuaranteed> {
+    assert!(matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy));
+
     let tcx = checker.tcx;
     let header = checker.impl_header;
     let impl_did = checker.impl_def_id;
@@ -136,7 +145,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
     }
 
     let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
-    match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
+    match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) {
         Ok(()) => Ok(()),
         Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
             let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
@@ -162,7 +171,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
                 span,
             ))
         }
-        Err(ConstParamTyImplementationError::TypeNotSized) => {
+        Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
             let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
             Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span }))
         }