diff options
| author | tiif <pekyuan@gmail.com> | 2025-09-15 08:59:19 +0000 |
|---|---|---|
| committer | tiif <pekyuan@gmail.com> | 2025-09-15 08:59:19 +0000 |
| commit | 1a02cd531d6b5ff154078208daf7816b1657f389 (patch) | |
| tree | 26d2d9a85b6b36271d338acc21c247e51d9fb5fa | |
| parent | b919a5f5183afb876b5206b3b23b249183cb313c (diff) | |
| download | rust-1a02cd531d6b5ff154078208daf7816b1657f389.tar.gz rust-1a02cd531d6b5ff154078208daf7816b1657f389.zip | |
Add check to make sure ConstParamTy impls of certain types are gated with #[unstable_feature_bound(unsized_const_params)]
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/misc.rs | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 393f458bea2..4c25882daa9 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,15 +1,14 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. -use std::assert_matches::assert_matches; - use hir::LangItem; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_span::sym; use crate::regions::InferCtxtRegionExt; -use crate::traits::{self, FulfillmentError, ObligationCause}; +use crate::traits::{self, FulfillmentError, Obligation, ObligationCause}; pub enum CopyImplementationError<'tcx> { InfringingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>), @@ -98,10 +97,9 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, self_type: Ty<'tcx>, - lang_item: LangItem, parent_cause: ObligationCause<'tcx>, ) -> Result<(), ConstParamTyImplementationError<'tcx>> { - assert_matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy); + let mut need_unstable_feature_bound = false; let inner_tys: Vec<_> = match *self_type.kind() { // Trivially okay as these types are all: @@ -112,18 +110,14 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( // Handle types gated under `feature(unsized_const_params)` // FIXME(unsized_const_params): Make `const N: [u8]` work then forbid references - ty::Slice(inner_ty) | ty::Ref(_, inner_ty, Mutability::Not) - if lang_item == LangItem::UnsizedConstParamTy => - { + ty::Slice(inner_ty) | ty::Ref(_, inner_ty, Mutability::Not) => { + need_unstable_feature_bound = true; vec![inner_ty] } - ty::Str if lang_item == LangItem::UnsizedConstParamTy => { + ty::Str => { + need_unstable_feature_bound = true; vec![Ty::new_slice(tcx, tcx.types.u8)] } - ty::Str | ty::Slice(..) | ty::Ref(_, _, Mutability::Not) => { - return Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired); - } - ty::Array(inner_ty, _) => vec![inner_ty], // `str` morally acts like a newtype around `[u8]` @@ -137,7 +131,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( adt, args, parent_cause.clone(), - lang_item, + LangItem::ConstParamTy, ) .map_err(ConstParamTyImplementationError::InfrigingFields)?; @@ -153,11 +147,25 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); + // Make sure impls certain types are gated with #[unstable_feature_bound(unsized_const_params)] + if need_unstable_feature_bound { + ocx.register_obligation(Obligation::new( + tcx, + parent_cause.clone(), + param_env, + ty::ClauseKind::UnstableFeature(sym::unsized_const_params), + )); + + if !ocx.select_all_or_error().is_empty() { + return Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired); + } + } + ocx.register_bound( parent_cause.clone(), param_env, inner_ty, - tcx.require_lang_item(lang_item, parent_cause.span), + tcx.require_lang_item(LangItem::ConstParamTy, parent_cause.span), ); let errors = ocx.select_all_or_error(); |
