about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-06-29 17:01:44 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-06-30 11:15:28 +0200
commit7e682d3f6f5761471e05fefc21e5de6ce4a52444 (patch)
tree6efa90a5c3e1e6c81e513fda4580098ee9588f2f
parentc86039b33343de264d8b3b1a9e3591b10d5615e8 (diff)
downloadrust-7e682d3f6f5761471e05fefc21e5de6ce4a52444.tar.gz
rust-7e682d3f6f5761471e05fefc21e5de6ce4a52444.zip
Stabilize casts and coercions to `&[T]` in const fn
-rw-r--r--src/librustc_middle/ty/layout.rs2
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs13
-rw-r--r--src/test/ui/consts/array-to-slice-cast.rs13
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs1
-rw-r--r--src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr17
-rw-r--r--src/test/ui/consts/min_const_fn/cast_errors.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/cast_errors.stderr19
7 files changed, 34 insertions, 32 deletions
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index e4cc96dd83b..f6788e317ae 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -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() {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 5a3663384fb..28d9a3ad63c 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -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) => {
diff --git a/src/test/ui/consts/array-to-slice-cast.rs b/src/test/ui/consts/array-to-slice-cast.rs
new file mode 100644
index 00000000000..796f9d1b71f
--- /dev/null
+++ b/src/test/ui/consts/array-to-slice-cast.rs
@@ -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;
+}
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
index 56198117688..2854c086657 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
@@ -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; }
diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
index f520bd35847..146d119fc8f 100644
--- a/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
@@ -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`.
diff --git a/src/test/ui/consts/min_const_fn/cast_errors.rs b/src/test/ui/consts/min_const_fn/cast_errors.rs
index 8648cd35387..8d730df16b0 100644
--- a/src/test/ui/consts/min_const_fn/cast_errors.rs
+++ b/src/test/ui/consts/min_const_fn/cast_errors.rs
@@ -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() {
diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr
index a6a05b522a5..583cb4e9720 100644
--- a/src/test/ui/consts/min_const_fn/cast_errors.stderr
+++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr
@@ -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`.