Skip to content

Commit 335585b

Browse files
committed
add const_param_ty_unchecked gate
1 parent 0312a55 commit 335585b

10 files changed

Lines changed: 194 additions & 7 deletions

File tree

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ declare_features! (
229229
(internal, cfg_target_has_reliable_f16_f128, "1.88.0", None),
230230
/// Allows identifying the `compiler_builtins` crate.
231231
(internal, compiler_builtins, "1.13.0", None),
232+
/// Allows skipping `ConstParamTy_` trait implementation checks
233+
(internal, const_param_ty_unchecked, "CURRENT_RUSTC_VERSION", None),
232234
/// Allows writing custom MIR
233235
(internal, custom_mir, "1.65.0", None),
234236
/// Implementation details of externally implementable items

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
842842
let span = tcx.def_span(param.def_id);
843843
let def_id = param.def_id.expect_local();
844844

845-
if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() {
845+
if tcx.features().const_param_ty_unchecked() {
846+
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
847+
wfcx.register_wf_obligation(span, None, ty.into());
848+
Ok(())
849+
})
850+
} else if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() {
846851
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
847852
wfcx.register_bound(
848853
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)),
@@ -1313,12 +1318,14 @@ pub(super) fn check_type_const<'tcx>(
13131318
let tcx = wfcx.tcx();
13141319
let span = tcx.def_span(def_id);
13151320

1316-
wfcx.register_bound(
1317-
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
1318-
wfcx.param_env,
1319-
item_ty,
1320-
tcx.require_lang_item(LangItem::ConstParamTy, span),
1321-
);
1321+
if !tcx.features().const_param_ty_unchecked() {
1322+
wfcx.register_bound(
1323+
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
1324+
wfcx.param_env,
1325+
item_ty,
1326+
tcx.require_lang_item(LangItem::ConstParamTy, span),
1327+
);
1328+
}
13221329

13231330
if has_value {
13241331
let raw_ct = tcx.const_of_item(def_id).instantiate_identity();

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
184184
return Ok(());
185185
}
186186

187+
if tcx.features().const_param_ty_unchecked() {
188+
return Ok(());
189+
}
190+
187191
if !tcx.features().adt_const_params() {
188192
match *self_type.kind() {
189193
ty::Adt(adt, _) if adt.is_struct() => {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ symbols! {
676676
const_panic,
677677
const_panic_fmt,
678678
const_param_ty,
679+
const_param_ty_unchecked,
679680
const_precise_live_drops,
680681
const_ptr_cast,
681682
const_raw_ptr_deref,

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
575575
if self.tcx().is_lang_item(def_id, LangItem::Sized) {
576576
return Default::default();
577577
}
578+
if self.tcx().is_lang_item(def_id, LangItem::ConstParamTy)
579+
&& self.tcx().features().const_param_ty_unchecked()
580+
{
581+
return Default::default();
582+
}
578583

579584
let predicates = self.tcx().predicates_of(def_id);
580585
let mut origins = vec![def_id; predicates.predicates.len()];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//! Ensure we don't allow Vec<[u8]> as const parameter even with
2+
//! `const_param_ty_unchecked` feature.
3+
#![allow(incomplete_features)]
4+
#![feature(adt_const_params, const_param_ty_unchecked, const_param_ty_trait)]
5+
use std::marker::ConstParamTy_;
6+
7+
struct VectorOfBytes {
8+
a: Vec<[u8]>
9+
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
10+
}
11+
impl ConstParamTy_ for VectorOfBytes {}
12+
13+
fn bar<const N: VectorOfBytes>() {}
14+
fn foo<const N: Vec<[u8]>>() {}
15+
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
16+
//~| ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
17+
18+
19+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> $DIR/const_param_ty_unchecked-unsupported.rs:8:8
3+
|
4+
LL | a: Vec<[u8]>
5+
| ^^^^^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u8]`
8+
note: required by an implicit `Sized` bound in `Vec`
9+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
10+
11+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
12+
--> $DIR/const_param_ty_unchecked-unsupported.rs:14:8
13+
|
14+
LL | fn foo<const N: Vec<[u8]>>() {}
15+
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
16+
|
17+
= help: the trait `Sized` is not implemented for `[u8]`
18+
note: required by an implicit `Sized` bound in `Vec`
19+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
20+
21+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
22+
--> $DIR/const_param_ty_unchecked-unsupported.rs:14:8
23+
|
24+
LL | fn foo<const N: Vec<[u8]>>() {}
25+
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
26+
|
27+
= help: the trait `Sized` is not implemented for `[u8]`
28+
note: required by an implicit `Sized` bound in `Vec`
29+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
30+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
31+
32+
error: aborting due to 3 previous errors
33+
34+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@run-pass
2+
//! Ensure that const_param_ty_unchecked gate allow
3+
//! bypassing `ConstParamTy_` implementation check
4+
5+
#![allow(dead_code, incomplete_features)]
6+
#![feature(const_param_ty_unchecked, const_param_ty_trait)]
7+
8+
use std::marker::ConstParamTy_;
9+
10+
struct Miow;
11+
12+
struct Meoww(Miow);
13+
14+
struct Float {
15+
float: f32,
16+
}
17+
18+
impl ConstParamTy_ for Meoww {}
19+
impl ConstParamTy_ for Float {}
20+
21+
fn something2<const N: *mut u8>() {}
22+
fn something<const N: f64>(a: f64) -> f64 {
23+
N + a
24+
}
25+
26+
fn main() {
27+
assert_eq!(2.0, something::<{1.0}>(1.0));
28+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// gate-test-const_param_ty_unchecked
2+
//! Ensure this fails when const_param_ty_unchecked isn't used
3+
#![allow(incomplete_features)]
4+
#![feature(const_param_ty_trait)]
5+
6+
use std::marker::ConstParamTy_;
7+
8+
struct Miow;
9+
10+
struct Meoww(Miow);
11+
12+
struct Float {
13+
float: f32,
14+
}
15+
16+
impl ConstParamTy_ for Meoww {}
17+
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204]
18+
impl ConstParamTy_ for Float {}
19+
//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204]
20+
21+
fn something2<const N: *mut u8>() {}
22+
//~^ ERROR: using raw pointers as const generic parameters is forbidden
23+
fn something<const N: f64>(a: f64) -> f64 {
24+
//~^ ERROR: `f64` is forbidden as the type of a const generic parameter
25+
N + a
26+
}
27+
fn foo<const N: Vec<[u8]>>() {}
28+
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
29+
//~^^ ERROR: `Vec<[u8]>` is forbidden as the type of a const generic parameter
30+
31+
fn main() {}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
2+
--> $DIR/const_param_ty_unchecked_fail.rs:16:24
3+
|
4+
LL | struct Meoww(Miow);
5+
| ---- this field does not implement `ConstParamTy_`
6+
...
7+
LL | impl ConstParamTy_ for Meoww {}
8+
| ^^^^^
9+
10+
error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
11+
--> $DIR/const_param_ty_unchecked_fail.rs:18:24
12+
|
13+
LL | float: f32,
14+
| ---------- this field does not implement `ConstParamTy_`
15+
...
16+
LL | impl ConstParamTy_ for Float {}
17+
| ^^^^^
18+
19+
error: using raw pointers as const generic parameters is forbidden
20+
--> $DIR/const_param_ty_unchecked_fail.rs:21:24
21+
|
22+
LL | fn something2<const N: *mut u8>() {}
23+
| ^^^^^^^
24+
|
25+
= note: the only supported types are integers, `bool`, and `char`
26+
27+
error: `f64` is forbidden as the type of a const generic parameter
28+
--> $DIR/const_param_ty_unchecked_fail.rs:23:23
29+
|
30+
LL | fn something<const N: f64>(a: f64) -> f64 {
31+
| ^^^
32+
|
33+
= note: the only supported types are integers, `bool`, and `char`
34+
35+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
36+
--> $DIR/const_param_ty_unchecked_fail.rs:27:8
37+
|
38+
LL | fn foo<const N: Vec<[u8]>>() {}
39+
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
40+
|
41+
= help: the trait `Sized` is not implemented for `[u8]`
42+
note: required by an implicit `Sized` bound in `Vec`
43+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
44+
45+
error: `Vec<[u8]>` is forbidden as the type of a const generic parameter
46+
--> $DIR/const_param_ty_unchecked_fail.rs:27:17
47+
|
48+
LL | fn foo<const N: Vec<[u8]>>() {}
49+
| ^^^^^^^^^
50+
|
51+
= note: the only supported types are integers, `bool`, and `char`
52+
53+
error: aborting due to 6 previous errors
54+
55+
Some errors have detailed explanations: E0204, E0277.
56+
For more information about an error, try `rustc --explain E0204`.

0 commit comments

Comments
 (0)