diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1e58e6159ccb..65bb487c7b8e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -256,6 +256,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 diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c9b1bcf52f57..63753aee383a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -856,7 +856,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)), @@ -1363,12 +1368,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 c983a03f613b..ba22ee6d1aa8 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 430232bab9b4..695103a249b4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -680,6 +680,7 @@ 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 57b14e93e277..51173500f471 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -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()]; diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index cdf3deb0d83c..13c20908c7d6 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1050,8 +1050,9 @@ pub fn is_alphanumeric(self) -> bool { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_is_control", since = "CURRENT_RUSTC_VERSION")] #[inline] - pub fn is_control(self) -> bool { + pub const fn is_control(self) -> bool { // According to // https://www.unicode.org/policies/stability_policy.html#Property_Value, // the set of codepoints in `Cc` will never change. diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index a27f9e2deec9..871943a91e6c 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -422,6 +422,7 @@ impl<'f> VaList<'f> { /// [`c_void`]: core::ffi::c_void #[inline] // Avoid codegen when not used to help backends that don't support VaList. #[rustc_const_unstable(feature = "const_c_variadic", issue = "151787")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn next_arg(&mut self) -> T { // SAFETY: the caller must uphold the safety contract for `va_arg`. unsafe { va_arg(self) } diff --git a/src/tools/miri/tests/fail/c-variadic.rs b/src/tools/miri/tests/fail/c-variadic.rs index d36dccec8d8d..e0cbf2dc8446 100644 --- a/src/tools/miri/tests/fail/c-variadic.rs +++ b/src/tools/miri/tests/fail/c-variadic.rs @@ -1,10 +1,8 @@ #![feature(c_variadic)] -//@error-in-other-file: Undefined Behavior: more C-variadic arguments read than were passed - fn read_too_many() { unsafe extern "C" fn variadic(mut ap: ...) { - ap.next_arg::(); + ap.next_arg::(); //~ERROR: more C-variadic arguments read than were passed } unsafe { variadic() }; diff --git a/src/tools/miri/tests/fail/c-variadic.stderr b/src/tools/miri/tests/fail/c-variadic.stderr index af145b0ed1e7..bc474c34e706 100644 --- a/src/tools/miri/tests/fail/c-variadic.stderr +++ b/src/tools/miri/tests/fail/c-variadic.stderr @@ -1,19 +1,17 @@ error: Undefined Behavior: more C-variadic arguments read than were passed - --> RUSTLIB/core/src/ffi/va_list.rs:LL:CC + --> tests/fail/c-variadic.rs:LL:CC | -LL | unsafe { va_arg(self) } - | ^^^^^^^^^^^^ Undefined Behavior occurred here +LL | ap.next_arg::(); + | ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: stack backtrace: - 0: std::ffi::VaList::<'_>::next_arg - at RUSTLIB/core/src/ffi/va_list.rs:LL:CC - 1: read_too_many::variadic + 0: read_too_many::variadic at tests/fail/c-variadic.rs:LL:CC - 2: read_too_many + 1: read_too_many at tests/fail/c-variadic.rs:LL:CC - 3: main + 2: main at tests/fail/c-variadic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 000000000000..3d4d7d20615a --- /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 000000000000..c24f67616144 --- /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 000000000000..b3f69fce0360 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs @@ -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() {} +fn something(a: f64) -> f64 { + N + a +} + +fn main() {} 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 000000000000..3f09a308cbe0 --- /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 000000000000..ae1ae61260f1 --- /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`.