Skip to content
Open
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 @@ -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
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 @@ -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)),
Expand Down Expand Up @@ -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();
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 @@ -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,
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 @@ -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()];
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,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<const N: *mut u8>() {}
fn something<const N: f64>(a: f64) -> f64 {
N + a
}

fn main() {
assert_eq!(2.0, something::<{1.0}>(1.0));
}
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