diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
commit | 5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch) | |
tree | 35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /library/core/src/intrinsics.rs | |
parent | Adding debian version 1.66.0+dfsg1-1. (diff) | |
download | rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/intrinsics.rs')
-rw-r--r-- | library/core/src/intrinsics.rs | 146 |
1 files changed, 108 insertions, 38 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 1dc79afe8..7ed7d767f 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -55,8 +55,13 @@ #![allow(missing_docs)] use crate::marker::DiscriminantKind; +#[cfg(not(bootstrap))] +use crate::marker::Tuple; use crate::mem; +#[cfg(not(bootstrap))] +pub mod mir; + // These imports are used for simplifying intra-doc links #[allow(unused_imports)] #[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))] @@ -788,7 +793,7 @@ extern "rust-intrinsic" { /// uninitialized at that point in the control flow. /// /// This intrinsic should not be used outside of the compiler. - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn rustc_peek<T>(_: T) -> T; /// Aborts the execution of the process. @@ -806,7 +811,7 @@ extern "rust-intrinsic" { /// On Unix, the /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn abort() -> !; /// Informs the optimizer that this point in the code is not reachable, @@ -845,7 +850,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn likely(b: bool) -> bool; /// Hints to the compiler that branch condition is likely to be false. @@ -860,7 +865,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn unlikely(b: bool) -> bool; /// Executes a breakpoint trap, for inspection by a debugger. @@ -880,7 +885,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn size_of<T>() -> usize; /// The minimum alignment of a type. @@ -892,7 +897,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn min_align_of<T>() -> usize; /// The preferred alignment of a type. /// @@ -921,7 +926,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::type_name`]. #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn type_name<T: ?Sized>() -> &'static str; /// Gets an identifier which is globally unique to the specified type. This @@ -935,7 +940,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn type_id<T: ?Sized + 'static>() -> u64; /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: @@ -943,7 +948,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn assert_inhabited<T>(); /// A guard for unsafe functions that cannot ever be executed if `T` does not permit @@ -951,7 +956,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn assert_zero_valid<T>(); /// A guard for unsafe functions that cannot ever be executed if `T` has invalid @@ -959,7 +964,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn assert_uninit_valid<T>(); /// Gets a reference to a static `Location` indicating where it was called. @@ -971,7 +976,7 @@ extern "rust-intrinsic" { /// /// Consider using [`core::panic::Location::caller`] instead. #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn caller_location() -> &'static crate::panic::Location<'static>; /// Moves a value out of scope without running drop glue. @@ -984,7 +989,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn forget<T: ?Sized>(_: T); /// Reinterprets the bits of a value of one type as another type. @@ -1264,7 +1269,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn needs_drop<T: ?Sized>() -> bool; /// Calculates the offset from a pointer. @@ -1309,7 +1314,7 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// Consider using [`pointer::mask`] instead. - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T; /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with @@ -1501,7 +1506,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::min`] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. /// @@ -1512,7 +1517,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::min`] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn minnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f32` values. /// @@ -1523,7 +1528,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::max`] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. /// @@ -1534,7 +1539,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::max`] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn maxnumf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f32` values. @@ -1655,7 +1660,7 @@ extern "rust-intrinsic" { /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn ctpop<T: Copy>(x: T) -> T; /// Returns the number of leading unset bits (zeroes) in an integer type `T`. @@ -1693,7 +1698,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_leading, 16); /// ``` #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn ctlz<T: Copy>(x: T) -> T; /// Like `ctlz`, but extra-unsafe as it returns `undef` when @@ -1750,7 +1755,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_trailing, 16); /// ``` #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn cttz<T: Copy>(x: T) -> T; /// Like `cttz`, but extra-unsafe as it returns `undef` when @@ -1783,7 +1788,7 @@ extern "rust-intrinsic" { /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn bswap<T: Copy>(x: T) -> T; /// Reverses the bits in an integer type `T`. @@ -1797,7 +1802,7 @@ extern "rust-intrinsic" { /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn bitreverse<T: Copy>(x: T) -> T; /// Performs checked integer addition. @@ -1811,7 +1816,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs checked integer subtraction @@ -1825,7 +1830,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs checked integer multiplication @@ -1839,13 +1844,14 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs an exact division, resulting in undefined behavior where /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1` /// /// This intrinsic does not have a stable counterpart. + #[rustc_const_unstable(feature = "const_exact_div", issue = "none")] pub fn exact_div<T: Copy>(x: T, y: T) -> T; /// Performs an unchecked division, resulting in undefined behavior @@ -1914,7 +1920,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn rotate_left<T: Copy>(x: T, y: T) -> T; /// Performs rotate right. @@ -1928,7 +1934,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn rotate_right<T: Copy>(x: T, y: T) -> T; /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits. @@ -1942,7 +1948,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn wrapping_add<T: Copy>(a: T, b: T) -> T; /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits. /// @@ -1955,7 +1961,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T; /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits. /// @@ -1968,7 +1974,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T; /// Computes `a + b`, saturating at numeric bounds. @@ -1982,7 +1988,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn saturating_add<T: Copy>(a: T, b: T) -> T; /// Computes `a - b`, saturating at numeric bounds. /// @@ -1995,7 +2001,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn saturating_sub<T: Copy>(a: T, b: T) -> T; /// Returns the value of the discriminant for the variant in 'v'; @@ -2008,7 +2014,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant; /// Returns the number of variants of the type `T` cast to a `usize`; @@ -2021,7 +2027,7 @@ extern "rust-intrinsic" { /// /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`]. #[rustc_const_unstable(feature = "variant_count", issue = "73662")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn variant_count<T>() -> usize; /// Rust's "try catch" construct which invokes the function pointer `try_fn` @@ -2055,7 +2061,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8; /// Allocates a block of memory at compile time. @@ -2106,7 +2112,7 @@ extern "rust-intrinsic" { /// /// [`std::hint::black_box`]: crate::hint::black_box #[rustc_const_unstable(feature = "const_black_box", issue = "none")] - #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] + #[rustc_safe_intrinsic] pub fn black_box<T>(dummy: T) -> T; /// `ptr` must point to a vtable. @@ -2169,11 +2175,75 @@ extern "rust-intrinsic" { /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, /// which violates the principle that a `const fn` must behave the same at /// compile-time and at run-time. The unsafe code in crate B is fine. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] pub fn const_eval_select<ARG, F, G, RET>(arg: ARG, called_in_const: F, called_at_rt: G) -> RET where G: FnOnce<ARG, Output = RET>, F: FnOnce<ARG, Output = RET>; + + /// Selects which function to call depending on the context. + /// + /// If this function is evaluated at compile-time, then a call to this + /// intrinsic will be replaced with a call to `called_in_const`. It gets + /// replaced with a call to `called_at_rt` otherwise. + /// + /// # Type Requirements + /// + /// The two functions must be both function items. They cannot be function + /// pointers or closures. The first function must be a `const fn`. + /// + /// `arg` will be the tupled arguments that will be passed to either one of + /// the two functions, therefore, both functions must accept the same type of + /// arguments. Both functions must return RET. + /// + /// # Safety + /// + /// The two functions must behave observably equivalent. Safe code in other + /// crates may assume that calling a `const fn` at compile-time and at run-time + /// produces the same result. A function that produces a different result when + /// evaluated at run-time, or has any other observable side-effects, is + /// *unsound*. + /// + /// Here is an example of how this could cause a problem: + /// ```no_run + /// #![feature(const_eval_select)] + /// #![feature(core_intrinsics)] + /// use std::hint::unreachable_unchecked; + /// use std::intrinsics::const_eval_select; + /// + /// // Crate A + /// pub const fn inconsistent() -> i32 { + /// fn runtime() -> i32 { 1 } + /// const fn compiletime() -> i32 { 2 } + /// + /// unsafe { + // // ⚠ This code violates the required equivalence of `compiletime` + /// // and `runtime`. + /// const_eval_select((), compiletime, runtime) + /// } + /// } + /// + /// // Crate B + /// const X: i32 = inconsistent(); + /// let x = inconsistent(); + /// if x != X { unsafe { unreachable_unchecked(); }} + /// ``` + /// + /// This code causes Undefined Behavior when being run, since the + /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, + /// which violates the principle that a `const fn` must behave the same at + /// compile-time and at run-time. The unsafe code in crate B is fine. + #[cfg(not(bootstrap))] + #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] + pub fn const_eval_select<ARG: Tuple, F, G, RET>( + arg: ARG, + called_in_const: F, + called_at_rt: G, + ) -> RET + where + G: FnOnce<ARG, Output = RET>, + F: FnOnce<ARG, Output = RET>; } // Some functions are defined here because they accidentally got made |