Auto merge of #65388 - Centril:rollup-rhg0dvs, r=Centril
Rollup of 10 pull requests Successful merges: - #65214 (Split non-CAS atomic support off into target_has_atomic_load_store) - #65246 (vxWorks: implement get_path() and get_mode() for File fmt::Debug) - #65312 (improve performance of signed saturating_mul) - #65336 (Fix typo in task::Waker) - #65346 (nounwind tests and cleanup) - #65347 (Fix #[unwind(abort)] with Rust ABI) - #65366 (Implement Error::source on IntoStringError + Remove superfluous cause impls) - #65369 (Don't discard value names when using address or memory sanitizer) - #65370 (Add `dyn` to `Any` documentation) - #65373 (Fix typo in docs for `Rc`) Failed merges: r? @ghost
This commit is contained in:
commit
c27f7568bc
24 changed files with 269 additions and 199 deletions
|
@ -153,7 +153,7 @@ mod boxed {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
pub mod collections;
|
pub mod collections;
|
||||||
#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod rc;
|
pub mod rc;
|
||||||
pub mod raw_vec;
|
pub mod raw_vec;
|
||||||
|
|
|
@ -773,7 +773,7 @@ impl<T: Clone> Rc<T> {
|
||||||
/// referred to as clone-on-write.
|
/// referred to as clone-on-write.
|
||||||
///
|
///
|
||||||
/// If there are no other `Rc` pointers to this value, then [`Weak`]
|
/// If there are no other `Rc` pointers to this value, then [`Weak`]
|
||||||
/// pointers to this value will be dissassociated.
|
/// pointers to this value will be disassociated.
|
||||||
///
|
///
|
||||||
/// See also [`get_mut`], which will fail rather than cloning.
|
/// See also [`get_mut`], which will fail rather than cloning.
|
||||||
///
|
///
|
||||||
|
@ -799,7 +799,7 @@ impl<T: Clone> Rc<T> {
|
||||||
/// assert_eq!(*other_data, 12);
|
/// assert_eq!(*other_data, 12);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`Weak`] pointers will be dissassociated:
|
/// [`Weak`] pointers will be disassociated:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::rc::Rc;
|
/// use std::rc::Rc;
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
//! of any `'static` type through runtime reflection.
|
//! of any `'static` type through runtime reflection.
|
||||||
//!
|
//!
|
||||||
//! `Any` itself can be used to get a `TypeId`, and has more features when used
|
//! `Any` itself can be used to get a `TypeId`, and has more features when used
|
||||||
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
|
//! as a trait object. As `&dyn Any` (a borrowed trait object), it has the `is`
|
||||||
//! `downcast_ref` methods, to test if the contained value is of a given type,
|
//! and `downcast_ref` methods, to test if the contained value is of a given type,
|
||||||
//! and to get a reference to the inner value as a type. As `&mut Any`, there
|
//! and to get a reference to the inner value as a type. As `&mut dyn Any`, there
|
||||||
//! is also the `downcast_mut` method, for getting a mutable reference to the
|
//! is also the `downcast_mut` method, for getting a mutable reference to the
|
||||||
//! inner value. `Box<Any>` adds the `downcast` method, which attempts to
|
//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to
|
||||||
//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
|
//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
|
||||||
//!
|
//!
|
||||||
//! Note that &Any is limited to testing whether a value is of a specified
|
//! Note that `&dyn Any` is limited to testing whether a value is of a specified
|
||||||
//! concrete type, and cannot be used to test whether a type implements a trait.
|
//! concrete type, and cannot be used to test whether a type implements a trait.
|
||||||
//!
|
//!
|
||||||
//! [`Box`]: ../../std/boxed/struct.Box.html
|
//! [`Box`]: ../../std/boxed/struct.Box.html
|
||||||
|
|
|
@ -1058,7 +1058,7 @@ $EndFeature, "
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn saturating_mul(self, rhs: Self) -> Self {
|
pub fn saturating_mul(self, rhs: Self) -> Self {
|
||||||
self.checked_mul(rhs).unwrap_or_else(|| {
|
self.checked_mul(rhs).unwrap_or_else(|| {
|
||||||
if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) {
|
if (self < 0) == (rhs < 0) {
|
||||||
Self::max_value()
|
Self::max_value()
|
||||||
} else {
|
} else {
|
||||||
Self::min_value()
|
Self::min_value()
|
||||||
|
|
|
@ -113,8 +113,8 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![cfg_attr(not(target_has_atomic = "8"), allow(dead_code))]
|
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
|
||||||
#![cfg_attr(not(target_has_atomic = "8"), allow(unused_imports))]
|
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
|
||||||
|
|
||||||
use self::Ordering::*;
|
use self::Ordering::*;
|
||||||
|
|
||||||
|
@ -160,14 +160,14 @@ pub fn spin_loop_hint() {
|
||||||
/// This type has the same in-memory representation as a [`bool`].
|
/// This type has the same in-memory representation as a [`bool`].
|
||||||
///
|
///
|
||||||
/// [`bool`]: ../../../std/primitive.bool.html
|
/// [`bool`]: ../../../std/primitive.bool.html
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[repr(C, align(1))]
|
#[repr(C, align(1))]
|
||||||
pub struct AtomicBool {
|
pub struct AtomicBool {
|
||||||
v: UnsafeCell<u8>,
|
v: UnsafeCell<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl Default for AtomicBool {
|
impl Default for AtomicBool {
|
||||||
/// Creates an `AtomicBool` initialized to `false`.
|
/// Creates an `AtomicBool` initialized to `false`.
|
||||||
|
@ -177,14 +177,14 @@ impl Default for AtomicBool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send is implicitly implemented for AtomicBool.
|
// Send is implicitly implemented for AtomicBool.
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl Sync for AtomicBool {}
|
unsafe impl Sync for AtomicBool {}
|
||||||
|
|
||||||
/// A raw pointer type which can be safely shared between threads.
|
/// A raw pointer type which can be safely shared between threads.
|
||||||
///
|
///
|
||||||
/// This type has the same in-memory representation as a `*mut T`.
|
/// This type has the same in-memory representation as a `*mut T`.
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
|
#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
|
||||||
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
|
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
|
||||||
|
@ -193,7 +193,7 @@ pub struct AtomicPtr<T> {
|
||||||
p: UnsafeCell<*mut T>,
|
p: UnsafeCell<*mut T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Default for AtomicPtr<T> {
|
impl<T> Default for AtomicPtr<T> {
|
||||||
/// Creates a null `AtomicPtr<T>`.
|
/// Creates a null `AtomicPtr<T>`.
|
||||||
|
@ -202,10 +202,10 @@ impl<T> Default for AtomicPtr<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl<T> Send for AtomicPtr<T> {}
|
unsafe impl<T> Send for AtomicPtr<T> {}
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl<T> Sync for AtomicPtr<T> {}
|
unsafe impl<T> Sync for AtomicPtr<T> {}
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ pub enum Ordering {
|
||||||
/// An [`AtomicBool`] initialized to `false`.
|
/// An [`AtomicBool`] initialized to `false`.
|
||||||
///
|
///
|
||||||
/// [`AtomicBool`]: struct.AtomicBool.html
|
/// [`AtomicBool`]: struct.AtomicBool.html
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_deprecated(
|
#[rustc_deprecated(
|
||||||
since = "1.34.0",
|
since = "1.34.0",
|
||||||
|
@ -315,7 +315,7 @@ pub enum Ordering {
|
||||||
)]
|
)]
|
||||||
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
|
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
impl AtomicBool {
|
impl AtomicBool {
|
||||||
/// Creates a new `AtomicBool`.
|
/// Creates a new `AtomicBool`.
|
||||||
///
|
///
|
||||||
|
@ -464,7 +464,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
||||||
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
|
pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
|
||||||
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
|
@ -553,7 +553,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: bool,
|
current: bool,
|
||||||
new: bool,
|
new: bool,
|
||||||
|
@ -609,7 +609,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn compare_exchange_weak(&self,
|
pub fn compare_exchange_weak(&self,
|
||||||
current: bool,
|
current: bool,
|
||||||
new: bool,
|
new: bool,
|
||||||
|
@ -660,7 +660,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||||
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
||||||
}
|
}
|
||||||
|
@ -702,7 +702,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||||
// We can't use atomic_nand here because it can result in a bool with
|
// We can't use atomic_nand here because it can result in a bool with
|
||||||
// an invalid value. This happens because the atomic operation is done
|
// an invalid value. This happens because the atomic operation is done
|
||||||
|
@ -755,7 +755,7 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||||
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
||||||
}
|
}
|
||||||
|
@ -796,13 +796,13 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||||
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
impl<T> AtomicPtr<T> {
|
impl<T> AtomicPtr<T> {
|
||||||
/// Creates a new `AtomicPtr`.
|
/// Creates a new `AtomicPtr`.
|
||||||
///
|
///
|
||||||
|
@ -953,7 +953,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
||||||
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
|
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
|
||||||
}
|
}
|
||||||
|
@ -989,7 +989,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
|
pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
|
||||||
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
|
@ -1031,7 +1031,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: *mut T,
|
current: *mut T,
|
||||||
new: *mut T,
|
new: *mut T,
|
||||||
|
@ -1091,7 +1091,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
pub fn compare_exchange_weak(&self,
|
pub fn compare_exchange_weak(&self,
|
||||||
current: *mut T,
|
current: *mut T,
|
||||||
new: *mut T,
|
new: *mut T,
|
||||||
|
@ -1112,7 +1112,7 @@ impl<T> AtomicPtr<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
|
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
|
||||||
impl From<bool> for AtomicBool {
|
impl From<bool> for AtomicBool {
|
||||||
/// Converts a `bool` into an `AtomicBool`.
|
/// Converts a `bool` into an `AtomicBool`.
|
||||||
|
@ -1128,16 +1128,17 @@ impl From<bool> for AtomicBool {
|
||||||
fn from(b: bool) -> Self { Self::new(b) }
|
fn from(b: bool) -> Self { Self::new(b) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "atomic_from", since = "1.23.0")]
|
#[stable(feature = "atomic_from", since = "1.23.0")]
|
||||||
impl<T> From<*mut T> for AtomicPtr<T> {
|
impl<T> From<*mut T> for AtomicPtr<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(p: *mut T) -> Self { Self::new(p) }
|
fn from(p: *mut T) -> Self { Self::new(p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
macro_rules! atomic_int {
|
macro_rules! atomic_int {
|
||||||
($stable:meta,
|
($cfg_cas:meta,
|
||||||
|
$stable:meta,
|
||||||
$stable_cxchg:meta,
|
$stable_cxchg:meta,
|
||||||
$stable_debug:meta,
|
$stable_debug:meta,
|
||||||
$stable_access:meta,
|
$stable_access:meta,
|
||||||
|
@ -1358,7 +1359,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1398,7 +1399,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn compare_and_swap(&self,
|
pub fn compare_and_swap(&self,
|
||||||
current: $int_type,
|
current: $int_type,
|
||||||
new: $int_type,
|
new: $int_type,
|
||||||
|
@ -1456,7 +1457,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable_cxchg]
|
#[$stable_cxchg]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: $int_type,
|
current: $int_type,
|
||||||
new: $int_type,
|
new: $int_type,
|
||||||
|
@ -1508,7 +1509,7 @@ loop {
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable_cxchg]
|
#[$stable_cxchg]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn compare_exchange_weak(&self,
|
pub fn compare_exchange_weak(&self,
|
||||||
current: $int_type,
|
current: $int_type,
|
||||||
new: $int_type,
|
new: $int_type,
|
||||||
|
@ -1546,7 +1547,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_add(self.v.get(), val, order) }
|
unsafe { atomic_add(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1578,7 +1579,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1613,7 +1614,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_and(self.v.get(), val, order) }
|
unsafe { atomic_and(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1649,7 +1650,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable_nand]
|
#[$stable_nand]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_nand(self.v.get(), val, order) }
|
unsafe { atomic_nand(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1684,7 +1685,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_or(self.v.get(), val, order) }
|
unsafe { atomic_or(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1719,7 +1720,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
|
||||||
```"),
|
```"),
|
||||||
#[inline]
|
#[inline]
|
||||||
#[$stable]
|
#[$stable]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1769,7 +1770,7 @@ assert_eq!(x.load(Ordering::SeqCst), 9);
|
||||||
#[unstable(feature = "no_more_cas",
|
#[unstable(feature = "no_more_cas",
|
||||||
reason = "no more CAS loops in user code",
|
reason = "no more CAS loops in user code",
|
||||||
issue = "48655")]
|
issue = "48655")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_update<F>(&self,
|
pub fn fetch_update<F>(&self,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
fetch_order: Ordering,
|
fetch_order: Ordering,
|
||||||
|
@ -1830,7 +1831,7 @@ assert!(max_foo == 42);
|
||||||
#[unstable(feature = "atomic_min_max",
|
#[unstable(feature = "atomic_min_max",
|
||||||
reason = "easier and faster min/max than writing manual CAS loop",
|
reason = "easier and faster min/max than writing manual CAS loop",
|
||||||
issue = "48655")]
|
issue = "48655")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { $max_fn(self.v.get(), val, order) }
|
unsafe { $max_fn(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1882,7 +1883,7 @@ assert_eq!(min_foo, 12);
|
||||||
#[unstable(feature = "atomic_min_max",
|
#[unstable(feature = "atomic_min_max",
|
||||||
reason = "easier and faster min/max than writing manual CAS loop",
|
reason = "easier and faster min/max than writing manual CAS loop",
|
||||||
issue = "48655")]
|
issue = "48655")]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[$cfg_cas]
|
||||||
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
|
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||||
unsafe { $min_fn(self.v.get(), val, order) }
|
unsafe { $min_fn(self.v.get(), val, order) }
|
||||||
}
|
}
|
||||||
|
@ -1892,8 +1893,9 @@ assert_eq!(min_foo, 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "8"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1908,8 +1910,9 @@ atomic_int! {
|
||||||
"AtomicI8::new(0)",
|
"AtomicI8::new(0)",
|
||||||
i8 AtomicI8 ATOMIC_I8_INIT
|
i8 AtomicI8 ATOMIC_I8_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "8"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1924,8 +1927,9 @@ atomic_int! {
|
||||||
"AtomicU8::new(0)",
|
"AtomicU8::new(0)",
|
||||||
u8 AtomicU8 ATOMIC_U8_INIT
|
u8 AtomicU8 ATOMIC_U8_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "16"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1940,8 +1944,9 @@ atomic_int! {
|
||||||
"AtomicI16::new(0)",
|
"AtomicI16::new(0)",
|
||||||
i16 AtomicI16 ATOMIC_I16_INIT
|
i16 AtomicI16 ATOMIC_I16_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "16"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1956,8 +1961,9 @@ atomic_int! {
|
||||||
"AtomicU16::new(0)",
|
"AtomicU16::new(0)",
|
||||||
u16 AtomicU16 ATOMIC_U16_INIT
|
u16 AtomicU16 ATOMIC_U16_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "32"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1972,8 +1978,9 @@ atomic_int! {
|
||||||
"AtomicI32::new(0)",
|
"AtomicI32::new(0)",
|
||||||
i32 AtomicI32 ATOMIC_I32_INIT
|
i32 AtomicI32 ATOMIC_I32_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "32"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -1988,8 +1995,12 @@ atomic_int! {
|
||||||
"AtomicU32::new(0)",
|
"AtomicU32::new(0)",
|
||||||
u32 AtomicU32 ATOMIC_U32_INIT
|
u32 AtomicU32 ATOMIC_U32_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(any(
|
||||||
|
all(bootstrap, target_has_atomic = "64"),
|
||||||
|
target_has_atomic_load_store = "64"
|
||||||
|
))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "64"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -2004,8 +2015,12 @@ atomic_int! {
|
||||||
"AtomicI64::new(0)",
|
"AtomicI64::new(0)",
|
||||||
i64 AtomicI64 ATOMIC_I64_INIT
|
i64 AtomicI64 ATOMIC_I64_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(any(
|
||||||
|
all(bootstrap, target_has_atomic = "64"),
|
||||||
|
target_has_atomic_load_store = "64"
|
||||||
|
))]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "64"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||||
|
@ -2020,8 +2035,9 @@ atomic_int! {
|
||||||
"AtomicU64::new(0)",
|
"AtomicU64::new(0)",
|
||||||
u64 AtomicU64 ATOMIC_U64_INIT
|
u64 AtomicU64 ATOMIC_U64_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "128")]
|
#[cfg(target_has_atomic_load_store = "128")]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "128"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
|
@ -2036,8 +2052,9 @@ atomic_int! {
|
||||||
"AtomicI128::new(0)",
|
"AtomicI128::new(0)",
|
||||||
i128 AtomicI128 ATOMIC_I128_INIT
|
i128 AtomicI128 ATOMIC_I128_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "128")]
|
#[cfg(target_has_atomic_load_store = "128")]
|
||||||
atomic_int! {
|
atomic_int! {
|
||||||
|
cfg(target_has_atomic = "128"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
unstable(feature = "integer_atomics", issue = "32976"),
|
unstable(feature = "integer_atomics", issue = "32976"),
|
||||||
|
@ -2052,20 +2069,24 @@ atomic_int! {
|
||||||
"AtomicU128::new(0)",
|
"AtomicU128::new(0)",
|
||||||
u128 AtomicU128 ATOMIC_U128_INIT
|
u128 AtomicU128 ATOMIC_U128_INIT
|
||||||
}
|
}
|
||||||
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[cfg(target_pointer_width = "16")]
|
#[cfg(target_pointer_width = "16")]
|
||||||
macro_rules! ptr_width {
|
macro_rules! ptr_width {
|
||||||
() => { 2 }
|
() => { 2 }
|
||||||
}
|
}
|
||||||
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
macro_rules! ptr_width {
|
macro_rules! ptr_width {
|
||||||
() => { 4 }
|
() => { 4 }
|
||||||
}
|
}
|
||||||
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
macro_rules! ptr_width {
|
macro_rules! ptr_width {
|
||||||
() => { 8 }
|
() => { 8 }
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
atomic_int!{
|
atomic_int!{
|
||||||
|
cfg(target_has_atomic = "ptr"),
|
||||||
stable(feature = "rust1", since = "1.0.0"),
|
stable(feature = "rust1", since = "1.0.0"),
|
||||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||||
|
@ -2080,8 +2101,9 @@ atomic_int!{
|
||||||
"AtomicIsize::new(0)",
|
"AtomicIsize::new(0)",
|
||||||
isize AtomicIsize ATOMIC_ISIZE_INIT
|
isize AtomicIsize ATOMIC_ISIZE_INIT
|
||||||
}
|
}
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
atomic_int!{
|
atomic_int!{
|
||||||
|
cfg(target_has_atomic = "ptr"),
|
||||||
stable(feature = "rust1", since = "1.0.0"),
|
stable(feature = "rust1", since = "1.0.0"),
|
||||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||||
|
@ -2098,7 +2120,7 @@ atomic_int!{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
fn strongest_failure_ordering(order: Ordering) -> Ordering {
|
fn strongest_failure_ordering(order: Ordering) -> Ordering {
|
||||||
match order {
|
match order {
|
||||||
Release => Relaxed,
|
Release => Relaxed,
|
||||||
|
@ -2132,7 +2154,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_xchg_acq(dst, val),
|
Acquire => intrinsics::atomic_xchg_acq(dst, val),
|
||||||
|
@ -2145,7 +2167,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// Returns the previous value (like __sync_fetch_and_add).
|
/// Returns the previous value (like __sync_fetch_and_add).
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_xadd_acq(dst, val),
|
Acquire => intrinsics::atomic_xadd_acq(dst, val),
|
||||||
|
@ -2158,7 +2180,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// Returns the previous value (like __sync_fetch_and_sub).
|
/// Returns the previous value (like __sync_fetch_and_sub).
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_xsub_acq(dst, val),
|
Acquire => intrinsics::atomic_xsub_acq(dst, val),
|
||||||
|
@ -2170,7 +2192,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
||||||
old: T,
|
old: T,
|
||||||
new: T,
|
new: T,
|
||||||
|
@ -2195,7 +2217,7 @@ unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
||||||
old: T,
|
old: T,
|
||||||
new: T,
|
new: T,
|
||||||
|
@ -2220,7 +2242,7 @@ unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_and_acq(dst, val),
|
Acquire => intrinsics::atomic_and_acq(dst, val),
|
||||||
|
@ -2232,7 +2254,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_nand_acq(dst, val),
|
Acquire => intrinsics::atomic_nand_acq(dst, val),
|
||||||
|
@ -2244,7 +2266,7 @@ unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_or_acq(dst, val),
|
Acquire => intrinsics::atomic_or_acq(dst, val),
|
||||||
|
@ -2256,7 +2278,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_xor_acq(dst, val),
|
Acquire => intrinsics::atomic_xor_acq(dst, val),
|
||||||
|
@ -2269,7 +2291,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// returns the max value (signed comparison)
|
/// returns the max value (signed comparison)
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_max_acq(dst, val),
|
Acquire => intrinsics::atomic_max_acq(dst, val),
|
||||||
|
@ -2282,7 +2304,7 @@ unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// returns the min value (signed comparison)
|
/// returns the min value (signed comparison)
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_min_acq(dst, val),
|
Acquire => intrinsics::atomic_min_acq(dst, val),
|
||||||
|
@ -2295,7 +2317,7 @@ unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// returns the max value (signed comparison)
|
/// returns the max value (signed comparison)
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_umax_acq(dst, val),
|
Acquire => intrinsics::atomic_umax_acq(dst, val),
|
||||||
|
@ -2308,7 +2330,7 @@ unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
|
|
||||||
/// returns the min value (signed comparison)
|
/// returns the min value (signed comparison)
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_has_atomic = "cas")]
|
#[cfg(target_has_atomic = "8")]
|
||||||
unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||||
match order {
|
match order {
|
||||||
Acquire => intrinsics::atomic_umin_acq(dst, val),
|
Acquire => intrinsics::atomic_umin_acq(dst, val),
|
||||||
|
@ -2506,7 +2528,7 @@ pub fn compiler_fence(order: Ordering) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||||
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
||||||
impl fmt::Debug for AtomicBool {
|
impl fmt::Debug for AtomicBool {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -2514,7 +2536,7 @@ impl fmt::Debug for AtomicBool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
||||||
impl<T> fmt::Debug for AtomicPtr<T> {
|
impl<T> fmt::Debug for AtomicPtr<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -2522,7 +2544,7 @@ impl<T> fmt::Debug for AtomicPtr<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||||
#[stable(feature = "atomic_pointer", since = "1.24.0")]
|
#[stable(feature = "atomic_pointer", since = "1.24.0")]
|
||||||
impl<T> fmt::Pointer for AtomicPtr<T> {
|
impl<T> fmt::Pointer for AtomicPtr<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
|
@ -217,7 +217,7 @@ impl fmt::Debug for Context<'_> {
|
||||||
/// This handle encapsulates a [`RawWaker`] instance, which defines the
|
/// This handle encapsulates a [`RawWaker`] instance, which defines the
|
||||||
/// executor-specific wakeup behavior.
|
/// executor-specific wakeup behavior.
|
||||||
///
|
///
|
||||||
/// Implements [`Clone`], [`trait@Send`], and [`trait@Sync`].
|
/// Implements [`Clone`], [`Send`], and [`Sync`].
|
||||||
///
|
///
|
||||||
/// [`RawWaker`]: struct.RawWaker.html
|
/// [`RawWaker`]: struct.RawWaker.html
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
|
@ -1513,22 +1513,25 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
||||||
}
|
}
|
||||||
for &i in &[8, 16, 32, 64, 128] {
|
for &i in &[8, 16, 32, 64, 128] {
|
||||||
if i >= min_atomic_width && i <= max_atomic_width {
|
if i >= min_atomic_width && i <= max_atomic_width {
|
||||||
let s = i.to_string();
|
let mut insert_atomic = |s| {
|
||||||
ret.insert((
|
|
||||||
sym::target_has_atomic,
|
|
||||||
Some(Symbol::intern(&s)),
|
|
||||||
));
|
|
||||||
if &s == wordsz {
|
|
||||||
ret.insert((
|
ret.insert((
|
||||||
sym::target_has_atomic,
|
sym::target_has_atomic_load_store,
|
||||||
Some(Symbol::intern("ptr")),
|
Some(Symbol::intern(s)),
|
||||||
));
|
));
|
||||||
|
if atomic_cas {
|
||||||
|
ret.insert((
|
||||||
|
sym::target_has_atomic,
|
||||||
|
Some(Symbol::intern(s))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let s = i.to_string();
|
||||||
|
insert_atomic(&s);
|
||||||
|
if &s == wordsz {
|
||||||
|
insert_atomic("ptr");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if atomic_cas {
|
|
||||||
ret.insert((sym::target_has_atomic, Some(Symbol::intern("cas"))));
|
|
||||||
}
|
|
||||||
if sess.opts.debug_assertions {
|
if sess.opts.debug_assertions {
|
||||||
ret.insert((Symbol::intern("debug_assertions"), None));
|
ret.insert((Symbol::intern("debug_assertions"), None));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
|
|
||||||
use crate::lint;
|
use crate::lint;
|
||||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||||
use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath};
|
use crate::session::config::{OutputType, PrintRequest, Sanitizer, SwitchWithOptPath};
|
||||||
use crate::session::search_paths::{PathKind, SearchPath};
|
use crate::session::search_paths::{PathKind, SearchPath};
|
||||||
use crate::util::nodemap::{FxHashMap, FxHashSet};
|
use crate::util::nodemap::{FxHashMap, FxHashSet};
|
||||||
use crate::util::common::{duration_to_secs_str, ErrorReported};
|
use crate::util::common::{duration_to_secs_str, ErrorReported};
|
||||||
|
@ -626,6 +626,14 @@ impl Session {
|
||||||
.output_types
|
.output_types
|
||||||
.contains_key(&OutputType::LlvmAssembly)
|
.contains_key(&OutputType::LlvmAssembly)
|
||||||
|| self.opts.output_types.contains_key(&OutputType::Bitcode);
|
|| self.opts.output_types.contains_key(&OutputType::Bitcode);
|
||||||
|
|
||||||
|
// Address sanitizer and memory sanitizer use alloca name when reporting an issue.
|
||||||
|
let more_names = match self.opts.debugging_opts.sanitizer {
|
||||||
|
Some(Sanitizer::Address) => true,
|
||||||
|
Some(Sanitizer::Memory) => true,
|
||||||
|
_ => more_names,
|
||||||
|
};
|
||||||
|
|
||||||
self.opts.debugging_opts.fewer_names || !more_names
|
self.opts.debugging_opts.fewer_names || !more_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,23 +270,12 @@ pub fn from_fn_attrs(
|
||||||
// optimize based on this!
|
// optimize based on this!
|
||||||
false
|
false
|
||||||
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
|
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
|
||||||
// If a specific #[unwind] attribute is present, use that
|
// If a specific #[unwind] attribute is present, use that.
|
||||||
true
|
true
|
||||||
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
|
} else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
|
||||||
// Special attribute for allocator functions, which can't unwind
|
// Special attribute for allocator functions, which can't unwind.
|
||||||
false
|
false
|
||||||
} else if let Some(_) = id {
|
} else {
|
||||||
// rust-lang/rust#64655, rust-lang/rust#63909: to minimize
|
|
||||||
// risk associated with changing cases where nounwind
|
|
||||||
// attribute is attached, this code is deliberately mimicking
|
|
||||||
// old control flow based on whether `id` is `Some` or `None`.
|
|
||||||
//
|
|
||||||
// However, in the long term we should either:
|
|
||||||
// - fold this into final else (i.e. stop inspecting `id`)
|
|
||||||
// - or, adopt Rust PR #63909.
|
|
||||||
//
|
|
||||||
// see also Rust RFC 2753.
|
|
||||||
|
|
||||||
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
||||||
if sig.abi == Abi::Rust || sig.abi == Abi::RustCall {
|
if sig.abi == Abi::Rust || sig.abi == Abi::RustCall {
|
||||||
// Any Rust method (or `extern "Rust" fn` or `extern
|
// Any Rust method (or `extern "Rust" fn` or `extern
|
||||||
|
@ -312,15 +301,6 @@ pub fn from_fn_attrs(
|
||||||
// In either case, we mark item as explicitly nounwind.
|
// In either case, we mark item as explicitly nounwind.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// assume this can possibly unwind, avoiding the application of a
|
|
||||||
// `nounwind` attribute below.
|
|
||||||
//
|
|
||||||
// (But: See comments in previous branch. Specifically, it is
|
|
||||||
// unclear whether there is real value in the assumption this
|
|
||||||
// can unwind. The conservatism here may just be papering over
|
|
||||||
// a real problem by making some UB a bit harder to hit.)
|
|
||||||
true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Always annotate functions with the target-cpu they are compiled for.
|
// Always annotate functions with the target-cpu they are compiled for.
|
||||||
|
|
|
@ -502,24 +502,21 @@ macro_rules! unpack {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
|
fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, _abi: Abi) -> bool {
|
||||||
// Not callable from C, so we can safely unwind through these
|
// Validate `#[unwind]` syntax regardless of platform-specific panic strategy.
|
||||||
if abi == Abi::Rust || abi == Abi::RustCall { return false; }
|
|
||||||
|
|
||||||
// Validate `#[unwind]` syntax regardless of platform-specific panic strategy
|
|
||||||
let attrs = &tcx.get_attrs(fn_def_id);
|
let attrs = &tcx.get_attrs(fn_def_id);
|
||||||
let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs);
|
let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs);
|
||||||
|
|
||||||
// We never unwind, so it's not relevant to stop an unwind
|
// We never unwind, so it's not relevant to stop an unwind.
|
||||||
if tcx.sess.panic_strategy() != PanicStrategy::Unwind { return false; }
|
if tcx.sess.panic_strategy() != PanicStrategy::Unwind { return false; }
|
||||||
|
|
||||||
// We cannot add landing pads, so don't add one
|
// We cannot add landing pads, so don't add one.
|
||||||
if tcx.sess.no_landing_pads() { return false; }
|
if tcx.sess.no_landing_pads() { return false; }
|
||||||
|
|
||||||
// This is a special case: some functions have a C abi but are meant to
|
// This is a special case: some functions have a C abi but are meant to
|
||||||
// unwind anyway. Don't stop them.
|
// unwind anyway. Don't stop them.
|
||||||
match unwind_attr {
|
match unwind_attr {
|
||||||
None => false, // FIXME(#58794)
|
None => false, // FIXME(#58794); should be `!(abi == Abi::Rust || abi == Abi::RustCall)`
|
||||||
Some(UnwindAttr::Allowed) => false,
|
Some(UnwindAttr::Allowed) => false,
|
||||||
Some(UnwindAttr::Aborts) => true,
|
Some(UnwindAttr::Aborts) => true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,8 +269,8 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
|
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
|
||||||
/// Converts a type of [`Error`] + [`trait@Send`] + [`trait@Sync`] into a box of
|
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
|
||||||
/// dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
|
/// dyn [`Error`] + [`Send`] + [`Sync`].
|
||||||
///
|
///
|
||||||
/// [`Error`]: ../error/trait.Error.html
|
/// [`Error`]: ../error/trait.Error.html
|
||||||
///
|
///
|
||||||
|
@ -313,7 +313,7 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl From<String> for Box<dyn Error + Send + Sync> {
|
impl From<String> for Box<dyn Error + Send + Sync> {
|
||||||
/// Converts a [`String`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
|
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
|
||||||
///
|
///
|
||||||
/// [`Error`]: ../error/trait.Error.html
|
/// [`Error`]: ../error/trait.Error.html
|
||||||
///
|
///
|
||||||
|
@ -377,7 +377,7 @@ impl From<String> for Box<dyn Error> {
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
|
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
|
||||||
/// Converts a [`str`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
|
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
|
||||||
///
|
///
|
||||||
/// [`Error`]: ../error/trait.Error.html
|
/// [`Error`]: ../error/trait.Error.html
|
||||||
///
|
///
|
||||||
|
@ -420,7 +420,7 @@ impl From<&str> for Box<dyn Error> {
|
||||||
|
|
||||||
#[stable(feature = "cow_box_error", since = "1.22.0")]
|
#[stable(feature = "cow_box_error", since = "1.22.0")]
|
||||||
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
|
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
|
||||||
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
|
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
|
||||||
///
|
///
|
||||||
/// [`Cow`]: ../borrow/enum.Cow.html
|
/// [`Cow`]: ../borrow/enum.Cow.html
|
||||||
/// [`Error`]: ../error/trait.Error.html
|
/// [`Error`]: ../error/trait.Error.html
|
||||||
|
|
|
@ -919,7 +919,7 @@ impl Error for IntoStringError {
|
||||||
"C string contained non-utf8 bytes"
|
"C string contained non-utf8 bytes"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn Error> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
Some(&self.error)
|
Some(&self.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@ use crate::ops::{Deref, DerefMut};
|
||||||
use crate::panicking;
|
use crate::panicking;
|
||||||
use crate::ptr::{Unique, NonNull};
|
use crate::ptr::{Unique, NonNull};
|
||||||
use crate::rc::Rc;
|
use crate::rc::Rc;
|
||||||
use crate::sync::{Arc, Mutex, RwLock, atomic};
|
use crate::sync::{Arc, Mutex, RwLock};
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
use crate::sync::atomic;
|
||||||
use crate::task::{Context, Poll};
|
use crate::task::{Context, Poll};
|
||||||
use crate::thread::Result;
|
use crate::thread::Result;
|
||||||
|
|
||||||
|
@ -240,49 +242,49 @@ impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
|
||||||
#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
|
#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
|
||||||
impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
|
impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||||
impl RefUnwindSafe for atomic::AtomicIsize {}
|
impl RefUnwindSafe for atomic::AtomicIsize {}
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(target_has_atomic_load_store = "8")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicI8 {}
|
impl RefUnwindSafe for atomic::AtomicI8 {}
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(target_has_atomic_load_store = "16")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicI16 {}
|
impl RefUnwindSafe for atomic::AtomicI16 {}
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(target_has_atomic_load_store = "32")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicI32 {}
|
impl RefUnwindSafe for atomic::AtomicI32 {}
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(target_has_atomic_load_store = "64")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicI64 {}
|
impl RefUnwindSafe for atomic::AtomicI64 {}
|
||||||
#[cfg(target_has_atomic = "128")]
|
#[cfg(target_has_atomic_load_store = "128")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicI128 {}
|
impl RefUnwindSafe for atomic::AtomicI128 {}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||||
impl RefUnwindSafe for atomic::AtomicUsize {}
|
impl RefUnwindSafe for atomic::AtomicUsize {}
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(target_hastarget_has_atomic_load_store_atomic = "8")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicU8 {}
|
impl RefUnwindSafe for atomic::AtomicU8 {}
|
||||||
#[cfg(target_has_atomic = "16")]
|
#[cfg(target_has_atomic_load_store = "16")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicU16 {}
|
impl RefUnwindSafe for atomic::AtomicU16 {}
|
||||||
#[cfg(target_has_atomic = "32")]
|
#[cfg(target_has_atomic_load_store = "32")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicU32 {}
|
impl RefUnwindSafe for atomic::AtomicU32 {}
|
||||||
#[cfg(target_has_atomic = "64")]
|
#[cfg(target_has_atomic_load_store = "64")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicU64 {}
|
impl RefUnwindSafe for atomic::AtomicU64 {}
|
||||||
#[cfg(target_has_atomic = "128")]
|
#[cfg(target_has_atomic_load_store = "128")]
|
||||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||||
impl RefUnwindSafe for atomic::AtomicU128 {}
|
impl RefUnwindSafe for atomic::AtomicU128 {}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "8")]
|
#[cfg(target_has_atomic_load_store = "8")]
|
||||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||||
impl RefUnwindSafe for atomic::AtomicBool {}
|
impl RefUnwindSafe for atomic::AtomicBool {}
|
||||||
|
|
||||||
#[cfg(target_has_atomic = "ptr")]
|
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||||
impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
|
impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
|
||||||
|
|
||||||
|
|
|
@ -1581,10 +1581,6 @@ impl<T: Send> error::Error for SendError<T> {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
"sending on a closed channel"
|
"sending on a closed channel"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -1624,10 +1620,6 @@ impl<T: Send> error::Error for TrySendError<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
||||||
|
@ -1652,10 +1644,6 @@ impl error::Error for RecvError {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
"receiving on a closed channel"
|
"receiving on a closed channel"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -1685,10 +1673,6 @@ impl error::Error for TryRecvError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
||||||
|
@ -1726,10 +1710,6 @@ impl error::Error for RecvTimeoutError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
#[stable(feature = "mpsc_error_conversions", since = "1.24.0")]
|
||||||
|
|
|
@ -400,13 +400,27 @@ impl FromInner<c_int> for File {
|
||||||
|
|
||||||
impl fmt::Debug for File {
|
impl fmt::Debug for File {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fn get_path(_fd: c_int) -> Option<PathBuf> {
|
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||||
// FIXME(#:(): implement this for VxWorks
|
let mut buf = vec![0;libc::PATH_MAX as usize];
|
||||||
None
|
let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) };
|
||||||
|
if n == -1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let l = buf.iter().position(|&c| c == 0).unwrap();
|
||||||
|
buf.truncate(l as usize);
|
||||||
|
Some(PathBuf::from(OsString::from_vec(buf)))
|
||||||
}
|
}
|
||||||
fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
|
fn get_mode(fd: c_int) -> Option<(bool, bool)> {
|
||||||
// FIXME(#:(): implement this for VxWorks
|
let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) };
|
||||||
None
|
if mode == -1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
match mode & libc::O_ACCMODE {
|
||||||
|
libc::O_RDONLY => Some((true, false)),
|
||||||
|
libc::O_RDWR => Some((true, true)),
|
||||||
|
libc::O_WRONLY => Some((false, true)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fd = self.0.raw();
|
let fd = self.0.raw();
|
||||||
|
|
|
@ -29,6 +29,7 @@ const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[
|
||||||
// (name in cfg, feature, function to check if the feature is enabled)
|
// (name in cfg, feature, function to check if the feature is enabled)
|
||||||
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
||||||
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||||
|
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||||
(sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
|
(sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
|
||||||
(sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
|
(sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
|
||||||
];
|
];
|
||||||
|
|
|
@ -658,6 +658,7 @@ symbols! {
|
||||||
suggestion,
|
suggestion,
|
||||||
target_feature,
|
target_feature,
|
||||||
target_has_atomic,
|
target_has_atomic,
|
||||||
|
target_has_atomic_load_store,
|
||||||
target_thread_local,
|
target_thread_local,
|
||||||
task,
|
task,
|
||||||
tbm_target_feature,
|
tbm_target_feature,
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// compile-flags: -C no-prepopulate-passes
|
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![feature(unwind_attributes)]
|
|
||||||
|
|
||||||
extern {
|
|
||||||
// CHECK: Function Attrs: nounwind
|
|
||||||
// CHECK-NEXT: declare void @extern_fn
|
|
||||||
fn extern_fn();
|
|
||||||
// CHECK-NOT: Function Attrs: nounwind
|
|
||||||
// CHECK: declare void @unwinding_extern_fn
|
|
||||||
#[unwind(allowed)]
|
|
||||||
fn unwinding_extern_fn();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn force_declare() {
|
|
||||||
extern_fn();
|
|
||||||
unwinding_extern_fn();
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
// compile-flags: -O
|
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
|
|
||||||
// CHECK: Function Attrs: norecurse nounwind
|
|
||||||
pub extern fn foo() {}
|
|
19
src/test/codegen/unwind-extern-exports.rs
Normal file
19
src/test/codegen/unwind-extern-exports.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// compile-flags: -C opt-level=0
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(unwind_attributes)]
|
||||||
|
|
||||||
|
// Make sure these all do *not* get the attribute.
|
||||||
|
// We disable optimizations to prevent LLVM from infering the attribute.
|
||||||
|
// CHECK-NOT: nounwind
|
||||||
|
|
||||||
|
// "C" ABI
|
||||||
|
// pub extern fn foo() {} // FIXME right now we don't abort-on-panic but add `nounwind` nevertheless
|
||||||
|
#[unwind(allowed)]
|
||||||
|
pub extern fn foo_allowed() {}
|
||||||
|
|
||||||
|
// "Rust"
|
||||||
|
// (`extern "Rust"` could be removed as all `fn` get it implicitly; we leave it in for clarity.)
|
||||||
|
pub extern "Rust" fn bar() {}
|
||||||
|
#[unwind(allowed)]
|
||||||
|
pub extern "Rust" fn bar_allowed() {}
|
41
src/test/codegen/unwind-extern-imports.rs
Normal file
41
src/test/codegen/unwind-extern-imports.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// compile-flags: -C no-prepopulate-passes
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(unwind_attributes)]
|
||||||
|
|
||||||
|
extern {
|
||||||
|
// CHECK: Function Attrs:{{.*}}nounwind
|
||||||
|
// CHECK-NEXT: declare void @extern_fn
|
||||||
|
fn extern_fn();
|
||||||
|
// CHECK-NOT: Function Attrs:{{.*}}nounwind
|
||||||
|
// CHECK: declare void @unwinding_extern_fn
|
||||||
|
#[unwind(allowed)]
|
||||||
|
fn unwinding_extern_fn();
|
||||||
|
// CHECK-NOT: nounwind
|
||||||
|
// CHECK: declare void @aborting_extern_fn
|
||||||
|
#[unwind(aborts)]
|
||||||
|
fn aborting_extern_fn(); // FIXME: we want to have the attribute here
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
// CHECK-NOT: nounwind
|
||||||
|
// CHECK: declare void @rust_extern_fn
|
||||||
|
fn rust_extern_fn();
|
||||||
|
// CHECK-NOT: nounwind
|
||||||
|
// CHECK: declare void @rust_unwinding_extern_fn
|
||||||
|
#[unwind(allowed)]
|
||||||
|
fn rust_unwinding_extern_fn();
|
||||||
|
// CHECK-NOT: nounwind
|
||||||
|
// CHECK: declare void @rust_aborting_extern_fn
|
||||||
|
#[unwind(aborts)]
|
||||||
|
fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn force_declare() {
|
||||||
|
extern_fn();
|
||||||
|
unwinding_extern_fn();
|
||||||
|
aborting_extern_fn();
|
||||||
|
rust_extern_fn();
|
||||||
|
rust_unwinding_extern_fn();
|
||||||
|
rust_aborting_extern_fn();
|
||||||
|
}
|
|
@ -24,4 +24,7 @@ endif
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan
|
$(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan
|
||||||
|
# Verify that stack buffer overflow is detected:
|
||||||
$(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow
|
$(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow
|
||||||
|
# Verify that variable name is included in address sanitizer report:
|
||||||
|
$(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
# The target used below doesn't support atomic CAS operations. Verify that's the case
|
# The target used below doesn't support atomic CAS operations. Verify that's the case
|
||||||
all:
|
all:
|
||||||
$(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="cas"'
|
$(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="ptr"'
|
||||||
|
|
|
@ -14,11 +14,16 @@ use std::io::prelude::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
#[unwind(aborts)] // FIXME(#58794)
|
#[unwind(aborts)] // FIXME(#58794) should work even without the attribute
|
||||||
extern "C" fn panic_in_ffi() {
|
extern "C" fn panic_in_ffi() {
|
||||||
panic!("Test");
|
panic!("Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unwind(aborts)]
|
||||||
|
extern "Rust" fn panic_in_rust_abi() {
|
||||||
|
panic!("TestRust");
|
||||||
|
}
|
||||||
|
|
||||||
fn test() {
|
fn test() {
|
||||||
let _ = panic::catch_unwind(|| { panic_in_ffi(); });
|
let _ = panic::catch_unwind(|| { panic_in_ffi(); });
|
||||||
// The process should have aborted by now.
|
// The process should have aborted by now.
|
||||||
|
@ -26,15 +31,34 @@ fn test() {
|
||||||
let _ = io::stdout().flush();
|
let _ = io::stdout().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testrust() {
|
||||||
|
let _ = panic::catch_unwind(|| { panic_in_rust_abi(); });
|
||||||
|
// The process should have aborted by now.
|
||||||
|
io::stdout().write(b"This should never be printed.\n");
|
||||||
|
let _ = io::stdout().flush();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() > 1 && args[1] == "test" {
|
if args.len() > 1 {
|
||||||
return test();
|
// This is inside the self-executed command.
|
||||||
|
match &*args[1] {
|
||||||
|
"test" => return test(),
|
||||||
|
"testrust" => return testrust(),
|
||||||
|
_ => panic!("bad test"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These end up calling the self-execution branches above.
|
||||||
let mut p = Command::new(&args[0])
|
let mut p = Command::new(&args[0])
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.arg("test").spawn().unwrap();
|
.arg("test").spawn().unwrap();
|
||||||
assert!(!p.wait().unwrap().success());
|
assert!(!p.wait().unwrap().success());
|
||||||
|
|
||||||
|
let mut p = Command::new(&args[0])
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.arg("testrust").spawn().unwrap();
|
||||||
|
assert!(!p.wait().unwrap().success());
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue