Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,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
Expand Down
21 changes: 14 additions & 7 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,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,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,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()];
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,8 +1050,9 @@ impl char {
/// ```
#[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.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ffi/va_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: VaArgSafe>(&mut self) -> T {
// SAFETY: the caller must uphold the safety contract for `va_arg`.
unsafe { va_arg(self) }
Expand Down
4 changes: 1 addition & 3 deletions src/tools/miri/tests/fail/c-variadic.rs
Original file line number Diff line number Diff line change
@@ -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::<i32>();
ap.next_arg::<i32>(); //~ERROR: more C-variadic arguments read than were passed
}

unsafe { variadic() };
Expand Down
14 changes: 6 additions & 8 deletions src/tools/miri/tests/fail/c-variadic.stderr
Original file line number Diff line number Diff line change
@@ -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::<i32>();
| ^^^^^^^^^^^^^^^^^^^^ 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Loading