Skip to content

Commit

Permalink
Rollup merge of rust-lang#73862 - oli-obk:const_array_to_slice, r=Ral…
Browse files Browse the repository at this point in the history
…fJung

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
  • Loading branch information
Manishearth committed Jul 11, 2020
2 parents d82588b + 7e682d3 commit f4f9690
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/librustc_middle/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
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() {
Expand Down
13 changes: 11 additions & 2 deletions src/librustc_mir/transform/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/consts/array-to-slice-cast.rs
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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; }
Expand Down
Original file line number Diff line number Diff line change
@@ -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() { || {} }
| ^^^^
Expand All @@ -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; }
| ^^^^^^^^^
Expand All @@ -26,14 +17,14 @@ 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; }
| ^^^^^^^^^^^^
|
= 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 change: 0 additions & 1 deletion src/test/ui/consts/min_const_fn/cast_errors.rs
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
19 changes: 5 additions & 14 deletions src/test/ui/consts/min_const_fn/cast_errors.stderr
Original file line number Diff line number Diff line change
@@ -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() { || {} }
| ^^^^
Expand All @@ -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();
| ^^^^^^^^^^^^^^^
Expand All @@ -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 }
| ^^^^^^^^^^^
Expand All @@ -35,14 +26,14 @@ 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(); }
| ^^^^^^^^^^^^^^^^^^^
|
= 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`.

0 comments on commit f4f9690

Please sign in to comment.