about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-22 17:38:15 +0000
committerbors <bors@rust-lang.org>2021-05-22 17:38:15 +0000
commitf98bd7eeca7f01be426b8ffe73ae6717a9659a82 (patch)
tree3db235399455d1cf28eade2b5927b80da740e628
parented20e1e533f70644bc583b3c4e4f85426b98bb4d (diff)
parent5c6f41e349a08e792d7635dc88a6ca9fc51050d3 (diff)
Auto merge of #85078 - RalfJung:const_fn_unsize, r=oli-obk
stabilize const_fn_unsize

I will post a stabilization report and ask for FCP in https://github.com/rust-lang/rust/issues/64992.
This PR is for the implementation side of stabilization.

r? `@oli-obk`
Fixes https://github.com/rust-lang/rust/issues/64992
-rw-r--r--compiler/rustc_ast/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs24
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs18
-rw-r--r--src/test/ui/consts/const_fn_unsize.gated.stderr8
-rw-r--r--src/test/ui/consts/const_fn_unsize.rs23
-rw-r--r--src/test/ui/consts/const_fn_unsize.stock.stderr12
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs6
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr34
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr6
-rw-r--r--src/test/ui/consts/unsizing-cast-non-null.rs10
-rw-r--r--src/test/ui/consts/unsizing-cast-non-null.stderr12
14 files changed, 45 insertions, 117 deletions
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index ffec28a395f..8061e0b83c0 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -10,8 +10,8 @@
 )]
 #![feature(box_syntax)]
 #![feature(box_patterns)]
+// On bootstrap bump, this will likely have to become const_fn_unsize
 #![cfg_attr(bootstrap, feature(const_fn))] // For the `transmute` in `P::new`
-#![cfg_attr(not(bootstrap), feature(const_fn_unsize))] // For the `transmute` in `P::new`
 #![feature(const_fn_transmute)]
 #![feature(const_panic)]
 #![feature(crate_visibility_modifier)]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index eef71e096a5..945406aed4b 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -283,6 +283,8 @@ declare_features! (
     (accepted, non_ascii_idents, "1.53.0", Some(55467), None),
     /// Allows arbitrary expressions in key-value attributes at parse time.
     (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
+    /// Allows unsizing coercions in `const fn`.
+    (accepted, const_fn_unsize, "1.54.0", Some(64992), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 2cef46a844a..62d81304134 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -644,9 +644,6 @@ declare_features! (
     /// Allows trait bounds in `const fn`.
     (active, const_fn_trait_bound, "1.53.0", Some(57563), None),
 
-    /// Allows unsizing coercions in `const fn`.
-    (active, const_fn_unsize, "1.53.0", Some(64992), None),
-
     /// Allows `async {}` expressions in const contexts.
     (active, const_async_blocks, "1.53.0", Some(85368), None),
 
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 16f5f14f563..dcbc9c523dc 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -541,30 +541,6 @@ impl NonConstOp for UnionAccess {
     }
 }
 
-/// See [#64992].
-///
-/// [#64992]: https://github.com/rust-lang/rust/issues/64992
-#[derive(Debug)]
-pub struct UnsizingCast;
-impl NonConstOp for UnsizingCast {
-    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
-        if ccx.const_kind() != hir::ConstContext::ConstFn {
-            Status::Allowed
-        } else {
-            Status::Unstable(sym::const_fn_unsize)
-        }
-    }
-
-    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-        feature_err(
-            &ccx.tcx.sess.parse_sess,
-            sym::const_fn_unsize,
-            span,
-            "unsizing casts to types besides slices are not allowed in const fn",
-        )
-    }
-}
-
 // Types that cannot appear in the signature or locals of a `const fn`.
 pub mod ty {
     use super::*;
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 63fc66f2b9f..41d9d0d04b5 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -10,9 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC
 use rustc_middle::mir::*;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{
-    self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt, TypeAndMut,
-};
+use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
 use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
 use rustc_span::{sym, Span, Symbol};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
@@ -636,17 +634,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                 _,
             ) => self.check_op(ops::FnPtrCast),
 
-            Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, cast_ty) => {
-                if let Some(TypeAndMut { ty, .. }) = cast_ty.builtin_deref(true) {
-                    let unsized_ty = self.tcx.struct_tail_erasing_lifetimes(ty, self.param_env);
-
-                    // Casting/coercing things to slices is fine.
-                    if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
-                        return;
-                    }
-                }
-
-                self.check_op(ops::UnsizingCast);
+            Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
+                // Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
+                // in the type of any local, which also excludes casts).
             }
 
             Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
diff --git a/src/test/ui/consts/const_fn_unsize.gated.stderr b/src/test/ui/consts/const_fn_unsize.gated.stderr
deleted file mode 100644
index 8a65c274ca9..00000000000
--- a/src/test/ui/consts/const_fn_unsize.gated.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/const_fn_unsize.rs:16:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/consts/const_fn_unsize.rs b/src/test/ui/consts/const_fn_unsize.rs
index 0cab3b0a031..01da57320c2 100644
--- a/src/test/ui/consts/const_fn_unsize.rs
+++ b/src/test/ui/consts/const_fn_unsize.rs
@@ -1,16 +1,21 @@
-// gate-test-const_fn_unsize
-
-// revisions: stock gated
-
-#![feature(rustc_attrs)]
-#![cfg_attr(gated, feature(const_fn_unsize))]
+// run-pass
+#![feature(slice_ptr_len)]
 
 use std::ptr::NonNull;
 
+#[allow(unused)]
 const fn test() {
     let _x = NonNull::<[i32; 0]>::dangling() as NonNull<[i32]>;
-    //[stock]~^ unsizing cast
 }
 
-#[rustc_error]
-fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
+// Regression test for #75118.
+pub const fn dangling_slice<T>() -> NonNull<[T]> {
+    NonNull::<[T; 1]>::dangling()
+}
+
+const C: NonNull<[i32]> = dangling_slice();
+
+fn main() {
+    assert_eq!(C.as_ptr(), NonNull::<[i32; 1]>::dangling().as_ptr() as *mut _);
+    assert_eq!(C.as_ptr().len(), 1);
+}
diff --git a/src/test/ui/consts/const_fn_unsize.stock.stderr b/src/test/ui/consts/const_fn_unsize.stock.stderr
deleted file mode 100644
index cc746d4f175..00000000000
--- a/src/test/ui/consts/const_fn_unsize.stock.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
-  --> $DIR/const_fn_unsize.rs:11:14
-   |
-LL |     let _x = NonNull::<[i32; 0]>::dangling() as NonNull<[i32]>;
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index e46127c36bf..b7904e6841b 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -133,13 +133,13 @@ const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
 //~^ ERROR trait bounds other than `Sized`
 const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
 //~^ ERROR trait bounds other than `Sized`
-//~| ERROR unsizing cast
-//~| ERROR unsizing cast
 
 const fn no_unsafe() { unsafe {} }
 
 const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-//~^ ERROR unsizing cast
+//~^ ERROR trait bounds other than `Sized`
+//~| ERROR trait bounds other than `Sized`
+//~| ERROR trait bounds other than `Sized`
 
 const fn no_fn_ptrs(_x: fn()) {}
 //~^ ERROR function pointer
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index e6ce7e12520..d31d4121936 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -288,32 +288,32 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
-  --> $DIR/min_const_fn.rs:134:63
+error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+  --> $DIR/min_const_fn.rs:139:41
    |
-LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
-   |                                                               ^^^
+LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
-  --> $DIR/min_const_fn.rs:134:63
+error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+  --> $DIR/min_const_fn.rs:139:42
    |
-LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
-   |                                                               ^^^
+LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
-  --> $DIR/min_const_fn.rs:141:42
+error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+  --> $DIR/min_const_fn.rs:139:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-   |                                          ^^^
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error[E0658]: function pointers cannot appear in constant functions
   --> $DIR/min_const_fn.rs:144:21
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
index 4a22ef2dffd..6ca1e59b3af 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
@@ -10,6 +10,6 @@ const fn no_inner_dyn_trait2(x: Hide) {
 //~^ ERROR trait bounds other than `Sized`
 }
 const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
-//~^ ERROR unsizing cast
+//~^ ERROR trait bounds other than `Sized`
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index cf635d65699..ce844a2f071 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -7,14 +7,14 @@ LL |     x.0.field;
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
+error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
   --> $DIR/min_const_fn_dyn.rs:12:66
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
    |                                                                  ^^
    |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/unsizing-cast-non-null.rs b/src/test/ui/consts/unsizing-cast-non-null.rs
deleted file mode 100644
index af6bc2d85fd..00000000000
--- a/src/test/ui/consts/unsizing-cast-non-null.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Regression test for #75118.
-
-use std::ptr::NonNull;
-
-pub const fn dangling_slice<T>() -> NonNull<[T]> {
-    NonNull::<[T; 0]>::dangling()
-    //~^ ERROR: unsizing casts to types besides slices
-}
-
-fn main() {}
diff --git a/src/test/ui/consts/unsizing-cast-non-null.stderr b/src/test/ui/consts/unsizing-cast-non-null.stderr
deleted file mode 100644
index 79691cddfb4..00000000000
--- a/src/test/ui/consts/unsizing-cast-non-null.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: unsizing casts to types besides slices are not allowed in const fn
-  --> $DIR/unsizing-cast-non-null.rs:6:5
-   |
-LL |     NonNull::<[T; 0]>::dangling()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64992 <https://github.com/rust-lang/rust/issues/64992> for more information
-   = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.