about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-18 16:50:59 -0700
committerGitHub <noreply@github.com>2020-07-18 16:50:59 -0700
commit2fad396368dfbe404f0bd6ce6307a0314794537c (patch)
treeda077af6b53e4264b80f5f71f092d3304025dcdb /src
parent1a54b61e39b2c5d383da622d3d390bcda32f6b3c (diff)
parent6cd164f49e6f9c2b914fa5d55755d78e3fabbc27 (diff)
downloadrust-2fad396368dfbe404f0bd6ce6307a0314794537c.tar.gz
rust-2fad396368dfbe404f0bd6ce6307a0314794537c.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/hint.rs3
-rw-r--r--src/libcore/intrinsics.rs1
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs1
-rw-r--r--src/test/ui/consts/const_unsafe_unreachable.rs17
-rw-r--r--src/test/ui/consts/const_unsafe_unreachable_ub.rs20
-rw-r--r--src/test/ui/consts/const_unsafe_unreachable_ub.stderr44
7 files changed, 86 insertions, 1 deletions
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 9ebcde79b63..3116815f5d6 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -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() }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 080760aa81f..8f0cf4361e7 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -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.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 1621cf79751..2e443064706 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -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)]
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 85186264022..5836fc9c95a 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -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),
diff --git a/src/test/ui/consts/const_unsafe_unreachable.rs b/src/test/ui/consts/const_unsafe_unreachable.rs
new file mode 100644
index 00000000000..cfed6e5deb9
--- /dev/null
+++ b/src/test/ui/consts/const_unsafe_unreachable.rs
@@ -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);
+}
diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.rs b/src/test/ui/consts/const_unsafe_unreachable_ub.rs
new file mode 100644
index 00000000000..11920d852e0
--- /dev/null
+++ b/src/test/ui/consts/const_unsafe_unreachable_ub.rs
@@ -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
+}
diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr
new file mode 100644
index 00000000000..3ef8043a54d
--- /dev/null
+++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr
@@ -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`.