diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index ffec28a395fdb..8061e0b83c0dc 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 eef71e096a52e..945406aed4bb0 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 2cef46a844a72..62d813041343f 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 16f5f14f563a3..dcbc9c523dc19 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 63fc66f2b9f16..41d9d0d04b50c 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 8a65c274ca933..0000000000000 --- 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 0cab3b0a031b1..01da57320c280 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() -> 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 cc746d4f175ca..0000000000000 --- 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 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 e46127c36bf6a..b7904e6841b5d 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 e6ce7e12520f5..d31d412193698 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 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 for more information - = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable + = note: see issue #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 for more information - = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable + = note: see issue #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 for more information - = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable + = note: see issue #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 4a22ef2dffddb..6ca1e59b3af10 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 cf635d656996e..ce844a2f07164 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 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 for more information - = help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable + = note: see issue #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 af6bc2d85fdd6..0000000000000 --- 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() -> 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 79691cddfb403..0000000000000 --- 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 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`.