parent
3e70dfd655
commit
5fe8c59f12
6 changed files with 71 additions and 16 deletions
61
src/libcore/hint.rs
Normal file
61
src/libcore/hint.rs
Normal file
|
@ -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()
|
||||||
|
}
|
|
@ -638,6 +638,9 @@ extern "rust-intrinsic" {
|
||||||
/// NB: This is very different from the `unreachable!()` macro: Unlike the
|
/// NB: This is very different from the `unreachable!()` macro: Unlike the
|
||||||
/// macro, which panics when it is executed, it is *undefined behavior* to
|
/// macro, which panics when it is executed, it is *undefined behavior* to
|
||||||
/// reach code marked with this function.
|
/// 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() -> !;
|
pub fn unreachable() -> !;
|
||||||
|
|
||||||
/// Informs the optimizer that a condition is always true.
|
/// Informs the optimizer that a condition is always true.
|
||||||
|
|
|
@ -149,6 +149,7 @@ pub mod intrinsics;
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
pub mod nonzero;
|
pub mod nonzero;
|
||||||
pub mod ptr;
|
pub mod ptr;
|
||||||
|
pub mod hint;
|
||||||
|
|
||||||
/* Core language traits */
|
/* Core language traits */
|
||||||
|
|
||||||
|
|
|
@ -420,13 +420,13 @@ macro_rules! writeln {
|
||||||
/// * Iterators that dynamically terminate.
|
/// * Iterators that dynamically terminate.
|
||||||
///
|
///
|
||||||
/// If the determination that the code is unreachable proves incorrect, the
|
/// If the determination that the code is unreachable proves incorrect, the
|
||||||
/// program immediately terminates with a [`panic!`]. The function [`unreachable`],
|
/// program immediately terminates with a [`panic!`]. The function [`unreachable_unchecked`],
|
||||||
/// which belongs to the [`std::intrinsics`] module, informs the compilier to
|
/// which belongs to the [`std::hint`] module, informs the compilier to
|
||||||
/// optimize the code out of the release version entirely.
|
/// optimize the code out of the release version entirely.
|
||||||
///
|
///
|
||||||
/// [`panic!`]: ../std/macro.panic.html
|
/// [`panic!`]: ../std/macro.panic.html
|
||||||
/// [`unreachable`]: ../std/intrinsics/fn.unreachable.html
|
/// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
|
||||||
/// [`std::intrinsics`]: ../std/intrinsics/index.html
|
/// [`std::hint`]: ../std/hint/index.html
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
/// A pinned reference is a lot like a mutable reference, except that it is not
|
/// A pinned reference is a lot like a mutable reference, except that it is not
|
||||||
|
|
|
@ -457,6 +457,8 @@ pub use alloc_crate::vec;
|
||||||
pub use core::char;
|
pub use core::char;
|
||||||
#[stable(feature = "i128", since = "1.26.0")]
|
#[stable(feature = "i128", since = "1.26.0")]
|
||||||
pub use core::u128;
|
pub use core::u128;
|
||||||
|
#[stable(feature = "core_hint", since = "1.27.0")]
|
||||||
|
pub use core::hint;
|
||||||
|
|
||||||
pub mod f32;
|
pub mod f32;
|
||||||
pub mod f64;
|
pub mod f64;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue