Rollup merge of #74459 - canova:const-unreachable-unchecked, r=oli-obk
Make unreachable_unchecked a const fn This PR makes `std::hint::unreachable_unchecked` a const fn so we can use it inside a const function. r? @RalfJung Fixes #53188.
This commit is contained in:
commit
2fad396368
7 changed files with 86 additions and 1 deletions
|
@ -45,7 +45,8 @@ use crate::intrinsics;
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "unreachable", since = "1.27.0")]
|
||||
pub unsafe fn unreachable_unchecked() -> ! {
|
||||
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
|
||||
pub const unsafe fn unreachable_unchecked() -> ! {
|
||||
// SAFETY: the safety contract for `intrinsics::unreachable` must
|
||||
// be upheld by the caller.
|
||||
unsafe { intrinsics::unreachable() }
|
||||
|
|
|
@ -932,6 +932,7 @@ extern "rust-intrinsic" {
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`std::hint::unreachable_unchecked`](../../std/hint/fn.unreachable_unchecked.html).
|
||||
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
|
||||
pub fn unreachable() -> !;
|
||||
|
||||
/// Informs the optimizer that a condition is always true.
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
#![feature(const_slice_ptr_len)]
|
||||
#![feature(const_type_name)]
|
||||
#![feature(const_likely)]
|
||||
#![feature(const_unreachable_unchecked)]
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(doc_cfg)]
|
||||
|
|
|
@ -95,6 +95,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let (dest, ret) = match ret {
|
||||
None => match intrinsic_name {
|
||||
sym::transmute => throw_ub_format!("transmuting to uninhabited type"),
|
||||
sym::unreachable => throw_ub!(Unreachable),
|
||||
sym::abort => M::abort(self)?,
|
||||
// Unsupported diverging intrinsic.
|
||||
_ => return Ok(false),
|
||||
|
|
17
src/test/ui/consts/const_unsafe_unreachable.rs
Normal file
17
src/test/ui/consts/const_unsafe_unreachable.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_unreachable_unchecked)]
|
||||
|
||||
const unsafe fn foo(x: bool) -> bool {
|
||||
match x {
|
||||
true => true,
|
||||
false => std::hint::unreachable_unchecked(),
|
||||
}
|
||||
}
|
||||
|
||||
const BAR: bool = unsafe { foo(true) };
|
||||
|
||||
fn main() {
|
||||
assert_eq!(BAR, true);
|
||||
}
|
20
src/test/ui/consts/const_unsafe_unreachable_ub.rs
Normal file
20
src/test/ui/consts/const_unsafe_unreachable_ub.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// build-fail
|
||||
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_unreachable_unchecked)]
|
||||
|
||||
const unsafe fn foo(x: bool) -> bool {
|
||||
match x {
|
||||
true => true,
|
||||
false => std::hint::unreachable_unchecked(),
|
||||
}
|
||||
}
|
||||
|
||||
#[warn(const_err)]
|
||||
const BAR: bool = unsafe { foo(false) };
|
||||
|
||||
fn main() {
|
||||
assert_eq!(BAR, true);
|
||||
//~^ ERROR E0080
|
||||
//~| ERROR erroneous constant
|
||||
}
|
44
src/test/ui/consts/const_unsafe_unreachable_ub.stderr
Normal file
44
src/test/ui/consts/const_unsafe_unreachable_ub.stderr
Normal file
|
@ -0,0 +1,44 @@
|
|||
warning: any use of this value will cause an error
|
||||
--> $SRC_DIR/libcore/hint.rs:LL:COL
|
||||
|
|
||||
LL | unsafe { intrinsics::unreachable() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| entering unreachable code
|
||||
| inside `std::hint::unreachable_unchecked` at $SRC_DIR/libcore/hint.rs:LL:COL
|
||||
| inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:9:18
|
||||
| inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:14:28
|
||||
|
|
||||
::: $DIR/const_unsafe_unreachable_ub.rs:14:1
|
||||
|
|
||||
LL | const BAR: bool = unsafe { foo(false) };
|
||||
| ----------------------------------------
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/const_unsafe_unreachable_ub.rs:13:8
|
||||
|
|
||||
LL | #[warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0080]: evaluation of constant expression failed
|
||||
--> $DIR/const_unsafe_unreachable_ub.rs:17:3
|
||||
|
|
||||
LL | assert_eq!(BAR, true);
|
||||
| ^^^^^^^^^^^---^^^^^^^^
|
||||
| |
|
||||
| referenced constant has errors
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: erroneous constant used
|
||||
--> $DIR/const_unsafe_unreachable_ub.rs:17:3
|
||||
|
|
||||
LL | assert_eq!(BAR, true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
Loading…
Add table
Reference in a new issue