From 335585b1d415136d261c98d49edc14fd54f920d6 Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 7 Mar 2026 10:18:35 +0100 Subject: [PATCH] add `const_param_ty_unchecked` gate --- compiler/rustc_feature/src/unstable.rs | 2 + .../rustc_hir_analysis/src/check/wfcheck.rs | 21 ++++--- .../src/coherence/builtin.rs | 4 ++ compiler/rustc_span/src/symbol.rs | 1 + .../rustc_trait_selection/src/traits/wf.rs | 5 ++ .../const_param_ty_unchecked-unsupported.rs | 19 +++++++ ...onst_param_ty_unchecked-unsupported.stderr | 34 +++++++++++ .../const_param_ty_unchecked.rs | 28 ++++++++++ .../const_param_ty_unchecked_fail.rs | 31 ++++++++++ .../const_param_ty_unchecked_fail.stderr | 56 +++++++++++++++++++ 10 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 859a1ad391cb9..309f26415aadf 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -229,6 +229,8 @@ declare_features! ( (internal, cfg_target_has_reliable_f16_f128, "1.88.0", None), /// Allows identifying the `compiler_builtins` crate. (internal, compiler_builtins, "1.13.0", None), + /// Allows skipping `ConstParamTy_` trait implementation checks + (internal, const_param_ty_unchecked, "CURRENT_RUSTC_VERSION", None), /// Allows writing custom MIR (internal, custom_mir, "1.65.0", None), /// Implementation details of externally implementable items diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 52cb061177c1f..928745095997c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -842,7 +842,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er let span = tcx.def_span(param.def_id); let def_id = param.def_id.expect_local(); - if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() { + if tcx.features().const_param_ty_unchecked() { + enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { + wfcx.register_wf_obligation(span, None, ty.into()); + Ok(()) + }) + } else if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() { enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { wfcx.register_bound( ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)), @@ -1313,12 +1318,14 @@ pub(super) fn check_type_const<'tcx>( let tcx = wfcx.tcx(); let span = tcx.def_span(def_id); - wfcx.register_bound( - ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), - wfcx.param_env, - item_ty, - tcx.require_lang_item(LangItem::ConstParamTy, span), - ); + if !tcx.features().const_param_ty_unchecked() { + wfcx.register_bound( + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), + wfcx.param_env, + item_ty, + tcx.require_lang_item(LangItem::ConstParamTy, span), + ); + } if has_value { let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61453e5328d5f..9100d0e952696 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -184,6 +184,10 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E return Ok(()); } + if tcx.features().const_param_ty_unchecked() { + return Ok(()); + } + if !tcx.features().adt_const_params() { match *self_type.kind() { ty::Adt(adt, _) if adt.is_struct() => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 71d67f9608bfa..528487edf7873 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -676,6 +676,7 @@ symbols! { const_panic, const_panic_fmt, const_param_ty, + const_param_ty_unchecked, const_precise_live_drops, const_ptr_cast, const_raw_ptr_deref, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index b8f5336115e12..17991fcd20ae0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -575,6 +575,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { if self.tcx().is_lang_item(def_id, LangItem::Sized) { return Default::default(); } + if self.tcx().is_lang_item(def_id, LangItem::ConstParamTy) + && self.tcx().features().const_param_ty_unchecked() + { + return Default::default(); + } let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs new file mode 100644 index 0000000000000..3d4d7d20615a8 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs @@ -0,0 +1,19 @@ +//! Ensure we don't allow Vec<[u8]> as const parameter even with +//! `const_param_ty_unchecked` feature. +#![allow(incomplete_features)] +#![feature(adt_const_params, const_param_ty_unchecked, const_param_ty_trait)] +use std::marker::ConstParamTy_; + +struct VectorOfBytes { + a: Vec<[u8]> + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] +} +impl ConstParamTy_ for VectorOfBytes {} + +fn bar() {} +fn foo>() {} + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + //~| ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr new file mode 100644 index 0000000000000..c24f676161441 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr @@ -0,0 +1,34 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:8:8 + | +LL | a: Vec<[u8]> + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs new file mode 100644 index 0000000000000..11da20102fe8e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs @@ -0,0 +1,28 @@ +//@run-pass +//! Ensure that const_param_ty_unchecked gate allow +//! bypassing `ConstParamTy_` implementation check + +#![allow(dead_code, incomplete_features)] +#![feature(const_param_ty_unchecked, const_param_ty_trait)] + +use std::marker::ConstParamTy_; + +struct Miow; + +struct Meoww(Miow); + +struct Float { + float: f32, +} + +impl ConstParamTy_ for Meoww {} +impl ConstParamTy_ for Float {} + +fn something2() {} +fn something(a: f64) -> f64 { + N + a +} + +fn main() { + assert_eq!(2.0, something::<{1.0}>(1.0)); +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs new file mode 100644 index 0000000000000..3f09a308cbe07 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs @@ -0,0 +1,31 @@ +// gate-test-const_param_ty_unchecked +//! Ensure this fails when const_param_ty_unchecked isn't used +#![allow(incomplete_features)] +#![feature(const_param_ty_trait)] + +use std::marker::ConstParamTy_; + +struct Miow; + +struct Meoww(Miow); + +struct Float { + float: f32, +} + +impl ConstParamTy_ for Meoww {} + //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204] +impl ConstParamTy_ for Float {} + //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204] + +fn something2() {} + //~^ ERROR: using raw pointers as const generic parameters is forbidden +fn something(a: f64) -> f64 { + //~^ ERROR: `f64` is forbidden as the type of a const generic parameter + N + a +} +fn foo>() {} + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + //~^^ ERROR: `Vec<[u8]>` is forbidden as the type of a const generic parameter + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr new file mode 100644 index 0000000000000..ae1ae61260f1a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr @@ -0,0 +1,56 @@ +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/const_param_ty_unchecked_fail.rs:16:24 + | +LL | struct Meoww(Miow); + | ---- this field does not implement `ConstParamTy_` +... +LL | impl ConstParamTy_ for Meoww {} + | ^^^^^ + +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/const_param_ty_unchecked_fail.rs:18:24 + | +LL | float: f32, + | ---------- this field does not implement `ConstParamTy_` +... +LL | impl ConstParamTy_ for Float {} + | ^^^^^ + +error: using raw pointers as const generic parameters is forbidden + --> $DIR/const_param_ty_unchecked_fail.rs:21:24 + | +LL | fn something2() {} + | ^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: `f64` is forbidden as the type of a const generic parameter + --> $DIR/const_param_ty_unchecked_fail.rs:23:23 + | +LL | fn something(a: f64) -> f64 { + | ^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked_fail.rs:27:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: `Vec<[u8]>` is forbidden as the type of a const generic parameter + --> $DIR/const_param_ty_unchecked_fail.rs:27:17 + | +LL | fn foo>() {} + | ^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0204, E0277. +For more information about an error, try `rustc --explain E0204`.