Rollup merge of #73862 - oli-obk:const_array_to_slice, r=RalfJung
Stabilize casts and coercions to `&[T]` in const fn Part of #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
This commit is contained in:
commit
f4f969027c
@ -527,7 +527,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
|
||||
size: Size::ZERO,
|
||||
}),
|
||||
|
||||
// Potentially-fat pointers.
|
||||
// Potentially-wide pointers.
|
||||
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||
let mut data_ptr = scalar_unit(Pointer);
|
||||
if !ty.is_unsafe_ptr() {
|
||||
|
@ -191,8 +191,17 @@ fn check_rvalue(
|
||||
_,
|
||||
_,
|
||||
) => Err((span, "function pointer casts are not allowed in const fn".into())),
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
|
||||
Err((span, "unsizing casts are not allowed in const fn".into()))
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
|
||||
let pointee_ty = cast_ty.builtin_deref(true).unwrap().ty;
|
||||
let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
|
||||
if let ty::Slice(_) | ty::Str = unsized_ty.kind {
|
||||
check_operand(tcx, op, span, def_id, body)?;
|
||||
// Casting/coercing things to slices is fine.
|
||||
Ok(())
|
||||
} else {
|
||||
// We just can't allow trait objects until we have figured out trait method calls.
|
||||
Err((span, "unsizing casts are not allowed in const fn".into()))
|
||||
}
|
||||
}
|
||||
// binops are fine on integers
|
||||
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
|
||||
|
13
src/test/ui/consts/array-to-slice-cast.rs
Normal file
13
src/test/ui/consts/array-to-slice-cast.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
const fn foo() {
|
||||
let x = [1, 2, 3, 4, 5];
|
||||
let y: &[_] = &x;
|
||||
|
||||
struct Foo<T: ?Sized>(bool, T);
|
||||
|
||||
let x: Foo<[u8; 3]> = Foo(true, [1, 2, 3]);
|
||||
let y: &Foo<[u8]> = &x;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#![feature(const_extern_fn)]
|
||||
|
||||
const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
//~^ ERROR unsizing casts are not allowed in const fn
|
||||
const unsafe extern "C" fn closure() -> fn() { || {} }
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
const unsafe extern fn use_float() { 1.0 + 1.0; }
|
||||
|
@ -1,14 +1,5 @@
|
||||
error[E0723]: unsizing casts are not allowed in const fn
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:3:48
|
||||
|
|
||||
LL | const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: function pointers in const fn are unstable
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:5:41
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:4:41
|
||||
|
|
||||
LL | const unsafe extern "C" fn closure() -> fn() { || {} }
|
||||
| ^^^^
|
||||
@ -17,7 +8,7 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: only int, `bool` and `char` operations are stable in const fn
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:7:38
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:6:38
|
||||
|
|
||||
LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
|
||||
| ^^^^^^^^^
|
||||
@ -26,7 +17,7 @@ LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: casting pointers to ints is unstable in const fn
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:9:48
|
||||
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
|
||||
|
|
||||
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
|
||||
| ^^^^^^^^^^^^
|
||||
@ -34,6 +25,6 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0723`.
|
||||
|
@ -1,7 +1,6 @@
|
||||
fn main() {}
|
||||
|
||||
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
//~^ ERROR unsizing casts are not allowed in const fn
|
||||
const fn closure() -> fn() { || {} }
|
||||
//~^ ERROR function pointers in const fn are unstable
|
||||
const fn closure2() {
|
||||
|
@ -1,14 +1,5 @@
|
||||
error[E0723]: unsizing casts are not allowed in const fn
|
||||
--> $DIR/cast_errors.rs:3:41
|
||||
|
|
||||
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
|
||||
| ^
|
||||
|
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:5:23
|
||||
--> $DIR/cast_errors.rs:4:23
|
||||
|
|
||||
LL | const fn closure() -> fn() { || {} }
|
||||
| ^^^^
|
||||
@ -17,7 +8,7 @@ LL | const fn closure() -> fn() { || {} }
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:8:5
|
||||
--> $DIR/cast_errors.rs:7:5
|
||||
|
|
||||
LL | (|| {}) as fn();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
@ -26,7 +17,7 @@ LL | (|| {}) as fn();
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:11:28
|
||||
--> $DIR/cast_errors.rs:10:28
|
||||
|
|
||||
LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
| ^^^^^^^^^^^
|
||||
@ -35,7 +26,7 @@ LL | const fn reify(f: fn()) -> unsafe fn() { f }
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error[E0723]: function pointers in const fn are unstable
|
||||
--> $DIR/cast_errors.rs:13:21
|
||||
--> $DIR/cast_errors.rs:12:21
|
||||
|
|
||||
LL | const fn reify2() { main as unsafe fn(); }
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
@ -43,6 +34,6 @@ LL | const fn reify2() { main as unsafe fn(); }
|
||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0723`.
|
||||
|
Loading…
Reference in New Issue
Block a user