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
This commit is contained in:
commit
f98bd7eeca
@ -10,8 +10,8 @@
|
|||||||
)]
|
)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(box_patterns)]
|
#![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(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_fn_transmute)]
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
|
@ -283,6 +283,8 @@ macro_rules! declare_features {
|
|||||||
(accepted, non_ascii_idents, "1.53.0", Some(55467), None),
|
(accepted, non_ascii_idents, "1.53.0", Some(55467), None),
|
||||||
/// Allows arbitrary expressions in key-value attributes at parse time.
|
/// Allows arbitrary expressions in key-value attributes at parse time.
|
||||||
(accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
|
(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
|
// feature-group-end: accepted features
|
||||||
|
@ -644,9 +644,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
|||||||
/// Allows trait bounds in `const fn`.
|
/// Allows trait bounds in `const fn`.
|
||||||
(active, const_fn_trait_bound, "1.53.0", Some(57563), None),
|
(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.
|
/// Allows `async {}` expressions in const contexts.
|
||||||
(active, const_async_blocks, "1.53.0", Some(85368), None),
|
(active, const_async_blocks, "1.53.0", Some(85368), None),
|
||||||
|
|
||||||
|
@ -541,30 +541,6 @@ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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`.
|
// Types that cannot appear in the signature or locals of a `const fn`.
|
||||||
pub mod ty {
|
pub mod ty {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -10,9 +10,7 @@
|
|||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::cast::CastTy;
|
use rustc_middle::ty::cast::CastTy;
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
|
||||||
self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt, TypeAndMut,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
|
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||||
@ -636,17 +634,9 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
|||||||
_,
|
_,
|
||||||
) => self.check_op(ops::FnPtrCast),
|
) => self.check_op(ops::FnPtrCast),
|
||||||
|
|
||||||
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, cast_ty) => {
|
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
|
||||||
if let Some(TypeAndMut { ty, .. }) = cast_ty.builtin_deref(true) {
|
// Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
|
||||||
let unsized_ty = self.tcx.struct_tail_erasing_lifetimes(ty, self.param_env);
|
// in the type of any local, which also excludes casts).
|
||||||
|
|
||||||
// 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::Misc, ref operand, cast_ty) => {
|
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
|
||||||
|
@ -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
|
|
||||||
|
|
@ -1,16 +1,21 @@
|
|||||||
// gate-test-const_fn_unsize
|
// run-pass
|
||||||
|
#![feature(slice_ptr_len)]
|
||||||
// revisions: stock gated
|
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
|
||||||
#![cfg_attr(gated, feature(const_fn_unsize))]
|
|
||||||
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
const fn test() {
|
const fn test() {
|
||||||
let _x = NonNull::<[i32; 0]>::dangling() as NonNull<[i32]>;
|
let _x = NonNull::<[i32; 0]>::dangling() as NonNull<[i32]>;
|
||||||
//[stock]~^ unsizing cast
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_error]
|
// Regression test for #75118.
|
||||||
fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
|
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);
|
||||||
|
}
|
||||||
|
@ -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`.
|
|
@ -133,13 +133,13 @@ const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
|||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait bounds other than `Sized`
|
||||||
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait bounds other than `Sized`
|
||||||
//~| ERROR unsizing cast
|
|
||||||
//~| ERROR unsizing cast
|
|
||||||
|
|
||||||
const fn no_unsafe() { unsafe {} }
|
const fn no_unsafe() { unsafe {} }
|
||||||
|
|
||||||
const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
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()) {}
|
const fn no_fn_ptrs(_x: fn()) {}
|
||||||
//~^ ERROR function pointer
|
//~^ ERROR function pointer
|
||||||
|
@ -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
|
= 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
|
= 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.rs:134:63
|
--> $DIR/min_const_fn.rs:139:41
|
||||||
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
= 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[E0658]: unsizing casts to types besides slices are not allowed in const fn
|
|
||||||
--> $DIR/min_const_fn.rs:134:63
|
|
||||||
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
= 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[E0658]: unsizing casts to types besides slices are not allowed in const fn
|
|
||||||
--> $DIR/min_const_fn.rs:141:42
|
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
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
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
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 #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]: 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 #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
|
error[E0658]: function pointers cannot appear in constant functions
|
||||||
--> $DIR/min_const_fn.rs:144:21
|
--> $DIR/min_const_fn.rs:144:21
|
||||||
|
@ -10,6 +10,6 @@ const fn no_inner_dyn_trait2(x: Hide) {
|
|||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait bounds other than `Sized`
|
||||||
}
|
}
|
||||||
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||||
//~^ ERROR unsizing cast
|
//~^ ERROR trait bounds other than `Sized`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -7,14 +7,14 @@ LL | x.0.field;
|
|||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= 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
|
= 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
|
--> $DIR/min_const_fn_dyn.rs:12:66
|
||||||
|
|
|
|
||||||
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
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
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_unsize)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -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() {}
|
|
@ -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`.
|
|
Loading…
Reference in New Issue
Block a user