Skip to content

Commit 2fad396

Browse files
authored
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.
2 parents 1a54b61 + 6cd164f commit 2fad396

File tree

7 files changed

+86
-1
lines changed

7 files changed

+86
-1
lines changed

src/libcore/hint.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ use crate::intrinsics;
4545
/// ```
4646
#[inline]
4747
#[stable(feature = "unreachable", since = "1.27.0")]
48-
pub unsafe fn unreachable_unchecked() -> ! {
48+
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
49+
pub const unsafe fn unreachable_unchecked() -> ! {
4950
// SAFETY: the safety contract for `intrinsics::unreachable` must
5051
// be upheld by the caller.
5152
unsafe { intrinsics::unreachable() }

src/libcore/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,7 @@ extern "rust-intrinsic" {
932932
///
933933
/// The stabilized version of this intrinsic is
934934
/// [`std::hint::unreachable_unchecked`](../../std/hint/fn.unreachable_unchecked.html).
935+
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
935936
pub fn unreachable() -> !;
936937

937938
/// Informs the optimizer that a condition is always true.

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#![feature(const_slice_ptr_len)]
9393
#![feature(const_type_name)]
9494
#![feature(const_likely)]
95+
#![feature(const_unreachable_unchecked)]
9596
#![feature(custom_inner_attributes)]
9697
#![feature(decl_macro)]
9798
#![feature(doc_cfg)]

src/librustc_mir/interpret/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9595
let (dest, ret) = match ret {
9696
None => match intrinsic_name {
9797
sym::transmute => throw_ub_format!("transmuting to uninhabited type"),
98+
sym::unreachable => throw_ub!(Unreachable),
9899
sym::abort => M::abort(self)?,
99100
// Unsupported diverging intrinsic.
100101
_ => return Ok(false),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
3+
#![feature(const_fn)]
4+
#![feature(const_unreachable_unchecked)]
5+
6+
const unsafe fn foo(x: bool) -> bool {
7+
match x {
8+
true => true,
9+
false => std::hint::unreachable_unchecked(),
10+
}
11+
}
12+
13+
const BAR: bool = unsafe { foo(true) };
14+
15+
fn main() {
16+
assert_eq!(BAR, true);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// build-fail
2+
3+
#![feature(const_fn)]
4+
#![feature(const_unreachable_unchecked)]
5+
6+
const unsafe fn foo(x: bool) -> bool {
7+
match x {
8+
true => true,
9+
false => std::hint::unreachable_unchecked(),
10+
}
11+
}
12+
13+
#[warn(const_err)]
14+
const BAR: bool = unsafe { foo(false) };
15+
16+
fn main() {
17+
assert_eq!(BAR, true);
18+
//~^ ERROR E0080
19+
//~| ERROR erroneous constant
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
warning: any use of this value will cause an error
2+
--> $SRC_DIR/libcore/hint.rs:LL:COL
3+
|
4+
LL | unsafe { intrinsics::unreachable() }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| entering unreachable code
8+
| inside `std::hint::unreachable_unchecked` at $SRC_DIR/libcore/hint.rs:LL:COL
9+
| inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:9:18
10+
| inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:14:28
11+
|
12+
::: $DIR/const_unsafe_unreachable_ub.rs:14:1
13+
|
14+
LL | const BAR: bool = unsafe { foo(false) };
15+
| ----------------------------------------
16+
|
17+
note: the lint level is defined here
18+
--> $DIR/const_unsafe_unreachable_ub.rs:13:8
19+
|
20+
LL | #[warn(const_err)]
21+
| ^^^^^^^^^
22+
23+
error[E0080]: evaluation of constant expression failed
24+
--> $DIR/const_unsafe_unreachable_ub.rs:17:3
25+
|
26+
LL | assert_eq!(BAR, true);
27+
| ^^^^^^^^^^^---^^^^^^^^
28+
| |
29+
| referenced constant has errors
30+
|
31+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
32+
33+
error: erroneous constant used
34+
--> $DIR/const_unsafe_unreachable_ub.rs:17:3
35+
|
36+
LL | assert_eq!(BAR, true);
37+
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
38+
|
39+
= note: `#[deny(const_err)]` on by default
40+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
41+
42+
error: aborting due to 2 previous errors; 1 warning emitted
43+
44+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)