add const_param_ty_unchecked gate

This commit is contained in:
zedddie
2026-03-07 10:18:35 +01:00
parent 57cb10ae1e
commit 35bc5436d3
10 changed files with 192 additions and 7 deletions
+2
View File
@@ -229,6 +229,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
(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
@@ -844,7 +844,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)),
@@ -1348,12 +1353,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();
@@ -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() => {
+1
View File
@@ -679,6 +679,7 @@
const_panic,
const_panic_fmt,
const_param_ty,
const_param_ty_unchecked,
const_precise_live_drops,
const_ptr_cast,
const_raw_ptr_deref,
@@ -574,6 +574,11 @@ fn nominal_obligations(
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()];
@@ -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<const N: VectorOfBytes>() {}
fn foo<const N: Vec<[u8]>>() {}
//~^ 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() {}
@@ -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<const N: 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<const N: 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
= 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`.
@@ -0,0 +1,26 @@
//@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<const N: *mut u8>() {}
fn something<const N: f64>(a: f64) -> f64 {
N + a
}
fn main() {}
@@ -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<const N: *mut u8>() {}
//~^ ERROR: using raw pointers as const generic parameters is forbidden
fn something<const N: f64>(a: f64) -> f64 {
//~^ ERROR: `f64` is forbidden as the type of a const generic parameter
N + a
}
fn foo<const N: Vec<[u8]>>() {}
//~^ 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() {}
@@ -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<const N: *mut u8>() {}
| ^^^^^^^
|
= 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<const N: f64>(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<const N: 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: `Vec<[u8]>` is forbidden as the type of a const generic parameter
--> $DIR/const_param_ty_unchecked_fail.rs:27:17
|
LL | fn foo<const N: Vec<[u8]>>() {}
| ^^^^^^^^^
|
= 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`.