diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 51 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/builtin.rs | 21 |
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 })) } |
