Skip to content

Commit

Permalink
Auto merge of #85078 - RalfJung:const_fn_unsize, r=oli-obk
Browse files Browse the repository at this point in the history
stabilize const_fn_unsize

I will post a stabilization report and ask for FCP in #64992.
This PR is for the implementation side of stabilization.

r? `@oli-obk`
Fixes #64992
  • Loading branch information
bors committed May 22, 2021
2 parents ed20e1e + 5c6f41e commit f98bd7e
Show file tree
Hide file tree
Showing 14 changed files with 45 additions and 117 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down
24 changes: 0 additions & 24 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
18 changes: 4 additions & 14 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) => {
Expand Down
8 changes: 0 additions & 8 deletions src/test/ui/consts/const_fn_unsize.gated.stderr

This file was deleted.

23 changes: 14 additions & 9 deletions src/test/ui/consts/const_fn_unsize.rs
Original file line number Diff line number Diff line change
@@ -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);
}
12 changes: 0 additions & 12 deletions src/test/ui/consts/const_fn_unsize.stock.stderr

This file was deleted.

6 changes: 3 additions & 3 deletions src/test/ui/consts/min_const_fn/min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 17 additions & 17 deletions src/test/ui/consts/min_const_fn/min_const_fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
6 changes: 3 additions & 3 deletions src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 0 additions & 10 deletions src/test/ui/consts/unsizing-cast-non-null.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/consts/unsizing-cast-non-null.stderr

This file was deleted.

0 comments on commit f98bd7e

Please sign in to comment.