Skip to content

Commit 5856b5c

Browse files
authored
Rollup merge of rust-lang#73862 - oli-obk:const_array_to_slice, r=RalfJung
Stabilize casts and coercions to `&[T]` in const fn Part of rust-lang#64992 There was never a reason to not stabilize this, we just accidentally prevented them when we implemented the `min_const_fn` feature that gave us `const fn` on stable. This PR stabilizes these casts (which are already stable in `const` outside `const fn`), while keeping all other unsizing casts (so `T` -> `dyn Trait`) unstable within const fn. These casts have no forward compatibility concerns with any future features for const eval and users were able to use them under the `const_fn` feature gate already since at least the miri merger, possibly longer. r? @rust-lang/lang
2 parents 81bcee6 + 7e682d3 commit 5856b5c

File tree

7 files changed

+34
-32
lines changed

7 files changed

+34
-32
lines changed

src/librustc_middle/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
527527
size: Size::ZERO,
528528
}),
529529

530-
// Potentially-fat pointers.
530+
// Potentially-wide pointers.
531531
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
532532
let mut data_ptr = scalar_unit(Pointer);
533533
if !ty.is_unsafe_ptr() {

src/librustc_mir/transform/qualify_min_const_fn.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,17 @@ fn check_rvalue(
191191
_,
192192
_,
193193
) => Err((span, "function pointer casts are not allowed in const fn".into())),
194-
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
195-
Err((span, "unsizing casts are not allowed in const fn".into()))
194+
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
195+
let pointee_ty = cast_ty.builtin_deref(true).unwrap().ty;
196+
let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
197+
if let ty::Slice(_) | ty::Str = unsized_ty.kind {
198+
check_operand(tcx, op, span, def_id, body)?;
199+
// Casting/coercing things to slices is fine.
200+
Ok(())
201+
} else {
202+
// We just can't allow trait objects until we have figured out trait method calls.
203+
Err((span, "unsizing casts are not allowed in const fn".into()))
204+
}
196205
}
197206
// binops are fine on integers
198207
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// check-pass
2+
3+
fn main() {}
4+
5+
const fn foo() {
6+
let x = [1, 2, 3, 4, 5];
7+
let y: &[_] = &x;
8+
9+
struct Foo<T: ?Sized>(bool, T);
10+
11+
let x: Foo<[u8; 3]> = Foo(true, [1, 2, 3]);
12+
let y: &Foo<[u8]> = &x;
13+
}

src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![feature(const_extern_fn)]
22

33
const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
4-
//~^ ERROR unsizing casts are not allowed in const fn
54
const unsafe extern "C" fn closure() -> fn() { || {} }
65
//~^ ERROR function pointers in const fn are unstable
76
const unsafe extern fn use_float() { 1.0 + 1.0; }
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
1-
error[E0723]: unsizing casts are not allowed in const fn
2-
--> $DIR/const-extern-fn-min-const-fn.rs:3:48
3-
|
4-
LL | const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
5-
| ^
6-
|
7-
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
8-
= help: add `#![feature(const_fn)]` to the crate attributes to enable
9-
101
error[E0723]: function pointers in const fn are unstable
11-
--> $DIR/const-extern-fn-min-const-fn.rs:5:41
2+
--> $DIR/const-extern-fn-min-const-fn.rs:4:41
123
|
134
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
145
| ^^^^
@@ -17,7 +8,7 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
178
= help: add `#![feature(const_fn)]` to the crate attributes to enable
189

1910
error[E0723]: only int, `bool` and `char` operations are stable in const fn
20-
--> $DIR/const-extern-fn-min-const-fn.rs:7:38
11+
--> $DIR/const-extern-fn-min-const-fn.rs:6:38
2112
|
2213
LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
2314
| ^^^^^^^^^
@@ -26,14 +17,14 @@ LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
2617
= help: add `#![feature(const_fn)]` to the crate attributes to enable
2718

2819
error[E0723]: casting pointers to ints is unstable in const fn
29-
--> $DIR/const-extern-fn-min-const-fn.rs:9:48
20+
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
3021
|
3122
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
3223
| ^^^^^^^^^^^^
3324
|
3425
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
3526
= help: add `#![feature(const_fn)]` to the crate attributes to enable
3627

37-
error: aborting due to 4 previous errors
28+
error: aborting due to 3 previous errors
3829

3930
For more information about this error, try `rustc --explain E0723`.

src/test/ui/consts/min_const_fn/cast_errors.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
fn main() {}
22

33
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
4-
//~^ ERROR unsizing casts are not allowed in const fn
54
const fn closure() -> fn() { || {} }
65
//~^ ERROR function pointers in const fn are unstable
76
const fn closure2() {
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
1-
error[E0723]: unsizing casts are not allowed in const fn
2-
--> $DIR/cast_errors.rs:3:41
3-
|
4-
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
5-
| ^
6-
|
7-
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
8-
= help: add `#![feature(const_fn)]` to the crate attributes to enable
9-
101
error[E0723]: function pointers in const fn are unstable
11-
--> $DIR/cast_errors.rs:5:23
2+
--> $DIR/cast_errors.rs:4:23
123
|
134
LL | const fn closure() -> fn() { || {} }
145
| ^^^^
@@ -17,7 +8,7 @@ LL | const fn closure() -> fn() { || {} }
178
= help: add `#![feature(const_fn)]` to the crate attributes to enable
189

1910
error[E0723]: function pointers in const fn are unstable
20-
--> $DIR/cast_errors.rs:8:5
11+
--> $DIR/cast_errors.rs:7:5
2112
|
2213
LL | (|| {}) as fn();
2314
| ^^^^^^^^^^^^^^^
@@ -26,7 +17,7 @@ LL | (|| {}) as fn();
2617
= help: add `#![feature(const_fn)]` to the crate attributes to enable
2718

2819
error[E0723]: function pointers in const fn are unstable
29-
--> $DIR/cast_errors.rs:11:28
20+
--> $DIR/cast_errors.rs:10:28
3021
|
3122
LL | const fn reify(f: fn()) -> unsafe fn() { f }
3223
| ^^^^^^^^^^^
@@ -35,14 +26,14 @@ LL | const fn reify(f: fn()) -> unsafe fn() { f }
3526
= help: add `#![feature(const_fn)]` to the crate attributes to enable
3627

3728
error[E0723]: function pointers in const fn are unstable
38-
--> $DIR/cast_errors.rs:13:21
29+
--> $DIR/cast_errors.rs:12:21
3930
|
4031
LL | const fn reify2() { main as unsafe fn(); }
4132
| ^^^^^^^^^^^^^^^^^^^
4233
|
4334
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
4435
= help: add `#![feature(const_fn)]` to the crate attributes to enable
4536

46-
error: aborting due to 5 previous errors
37+
error: aborting due to 4 previous errors
4738

4839
For more information about this error, try `rustc --explain E0723`.

0 commit comments

Comments
 (0)