about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-04-12 21:47:38 +0800
committerkennytm <kennytm@gmail.com>2018-04-16 18:29:40 +0800
commit5fe8c59f1219705ea54f842f9868ad0017643a33 (patch)
tree7064fbd65a6788fc62b571646e227fee40580b43
parent3e70dfd65542a09db3a5ae31e6334a0f7cc20035 (diff)
downloadrust-5fe8c59f1219705ea54f842f9868ad0017643a33.tar.gz
rust-5fe8c59f1219705ea54f842f9868ad0017643a33.zip
Stabilize core::hint::unreachable_unchecked.
Closes #43751.
-rw-r--r--src/libcore/hint.rs61
-rw-r--r--src/libcore/intrinsics.rs3
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/macros.rs8
-rw-r--r--src/libcore/mem.rs12
-rw-r--r--src/libstd/lib.rs2
6 files changed, 71 insertions, 16 deletions
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
new file mode 100644
index 00000000000..f4e96e67b2c
--- /dev/null
+++ b/src/libcore/hint.rs
@@ -0,0 +1,61 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![stable(feature = "core_hint", since = "1.27.0")]
+
+//! Hints to compiler that affects how code should be emitted or optimized.
+
+use intrinsics;
+
+/// Informs the compiler that this point in the code is not reachable, enabling
+/// further optimizations.
+///
+/// # Safety
+///
+/// Reaching this function is completely *undefined behavior* (UB). In
+/// particular, the compiler assumes that all UB must never happen, and
+/// therefore will eliminate all branches that reach to a call to
+/// `unreachable_unchecked()`.
+///
+/// Like all instances of UB, if this assumption turns out to be wrong, i.e. the
+/// `unreachable_unchecked()` call is actually reachable among all possible
+/// control flow, the compiler will apply the wrong optimization strategy, and
+/// may sometimes even corrupt seemingly unrelated code, causing
+/// difficult-to-debug problems.
+///
+/// Use this function only when you can prove that the code will never call it.
+///
+/// The [`unreachable!()`] macro is the safe counterpart of this function, which
+/// will panic instead when executed.
+///
+/// [`unreachable!()`]: ../macro.unreachable.html
+///
+/// # Example
+///
+/// ```
+/// fn div_1(a: u32, b: u32) -> u32 {
+///     use std::hint::unreachable_unchecked;
+///
+///     // `b.saturating_add(1)` is always positive (not zero),
+///     // hence `checked_div` will never return None.
+///     // Therefore, the else branch is unreachable.
+///     a.checked_div(b.saturating_add(1))
+///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })
+/// }
+///
+/// assert_eq!(div_1(7, 0), 7);
+/// assert_eq!(div_1(9, 1), 4);
+/// assert_eq!(div_1(11, std::u32::MAX), 0);
+/// ```
+#[inline]
+#[stable(feature = "unreachable", since = "1.27.0")]
+pub unsafe fn unreachable_unchecked() -> ! {
+    intrinsics::unreachable()
+}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 83274682250..fb0d2d9c882 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -638,6 +638,9 @@ extern "rust-intrinsic" {
     /// NB: This is very different from the `unreachable!()` macro: Unlike the
     /// macro, which panics when it is executed, it is *undefined behavior* to
     /// reach code marked with this function.
+    ///
+    /// The stabilized version of this intrinsic is
+    /// [`std::hint::unreachable_unchecked`](../../std/hint/fn.unreachable_unchecked.html).
     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 5ebd9e4334c..1968c11d062 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -149,6 +149,7 @@ pub mod intrinsics;
 pub mod mem;
 pub mod nonzero;
 pub mod ptr;
+pub mod hint;
 
 /* Core language traits */
 
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 90a9cb3379b..1e2551e36f5 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -420,13 +420,13 @@ macro_rules! writeln {
 /// * Iterators that dynamically terminate.
 ///
 /// If the determination that the code is unreachable proves incorrect, the
-/// program immediately terminates with a [`panic!`].  The function [`unreachable`],
-/// which belongs to the [`std::intrinsics`] module, informs the compilier to
+/// program immediately terminates with a [`panic!`].  The function [`unreachable_unchecked`],
+/// which belongs to the [`std::hint`] module, informs the compilier to
 /// optimize the code out of the release version entirely.
 ///
 /// [`panic!`]:  ../std/macro.panic.html
-/// [`unreachable`]: ../std/intrinsics/fn.unreachable.html
-/// [`std::intrinsics`]: ../std/intrinsics/index.html
+/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
+/// [`std::hint`]: ../std/hint/index.html
 ///
 /// # Panics
 ///
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index e3f08926610..10efab82ddf 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -1094,18 +1094,6 @@ impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
     }
 }
 
-/// Tells LLVM that this point in the code is not reachable, enabling further
-/// optimizations.
-///
-/// NB: This is very different from the `unreachable!()` macro: Unlike the
-/// macro, which panics when it is executed, it is *undefined behavior* to
-/// reach code marked with this function.
-#[inline]
-#[unstable(feature = "unreachable", issue = "43751")]
-pub unsafe fn unreachable() -> ! {
-    intrinsics::unreachable()
-}
-
 /// A pinned reference.
 ///
 /// A pinned reference is a lot like a mutable reference, except that it is not
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index a34fcb5a7f9..d92a4526549 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -457,6 +457,8 @@ pub use alloc_crate::vec;
 pub use core::char;
 #[stable(feature = "i128", since = "1.26.0")]
 pub use core::u128;
+#[stable(feature = "core_hint", since = "1.27.0")]
+pub use core::hint;
 
 pub mod f32;
 pub mod f64;