Skip to content

Commit

Permalink
Rollup merge of #74459 - canova:const-unreachable-unchecked, r=oli-obk
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Manishearth committed Jul 18, 2020
2 parents 1a54b61 + 6cd164f commit 2fad396
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/libcore/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
Expand Down
1 change: 1 addition & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/consts/const_unsafe_unreachable.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions src/test/ui/consts/const_unsafe_unreachable_ub.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 44 additions & 0 deletions src/test/ui/consts/const_unsafe_unreachable_ub.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 2fad396

Please sign in to comment.