Elaborate on SAFETY comments
This commit is contained in:
parent
e0140ffeb0
commit
ca2fae8edb
@ -366,7 +366,10 @@ pub fn swap(&self, other: &Self) {
|
||||
if ptr::eq(self, other) {
|
||||
return;
|
||||
}
|
||||
// SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe
|
||||
// SAFETY: This can be risky if called from separate threads, but `Cell`
|
||||
// is `!Sync` so this won't happen. This also won't invalidate any
|
||||
// pointers since `Cell` makes sure nothing else will be pointing into
|
||||
// either of these `Cell`s.
|
||||
unsafe {
|
||||
ptr::swap(self.value.get(), other.value.get());
|
||||
}
|
||||
@ -386,7 +389,8 @@ pub fn swap(&self, other: &Self) {
|
||||
/// ```
|
||||
#[stable(feature = "move_cell", since = "1.17.0")]
|
||||
pub fn replace(&self, val: T) -> T {
|
||||
// SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe
|
||||
// SAFETY: This can cause data races if called from a separate thread,
|
||||
// but `Cell` is `!Sync` so this won't happen.
|
||||
mem::replace(unsafe { &mut *self.value.get() }, val)
|
||||
}
|
||||
|
||||
@ -423,7 +427,8 @@ impl<T: Copy> Cell<T> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn get(&self) -> T {
|
||||
// SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe
|
||||
// SAFETY: This can cause data races if called from a separate thread,
|
||||
// but `Cell` is `!Sync` so this won't happen.
|
||||
unsafe { *self.value.get() }
|
||||
}
|
||||
|
||||
@ -492,7 +497,9 @@ pub const fn as_ptr(&self) -> *mut T {
|
||||
#[inline]
|
||||
#[stable(feature = "cell_get_mut", since = "1.11.0")]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
// SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe
|
||||
// SAFETY: This can cause data races if called from a separate thread,
|
||||
// but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees
|
||||
// unique access.
|
||||
unsafe { &mut *self.value.get() }
|
||||
}
|
||||
|
||||
@ -512,7 +519,7 @@ pub fn get_mut(&mut self) -> &mut T {
|
||||
#[inline]
|
||||
#[stable(feature = "as_cell", since = "1.37.0")]
|
||||
pub fn from_mut(t: &mut T) -> &Cell<T> {
|
||||
// SAFETY: `&mut` ensures unique access
|
||||
// SAFETY: `&mut` ensures unique access.
|
||||
unsafe { &*(t as *mut T as *const Cell<T>) }
|
||||
}
|
||||
}
|
||||
@ -556,7 +563,7 @@ impl<T> Cell<[T]> {
|
||||
/// ```
|
||||
#[stable(feature = "as_cell", since = "1.37.0")]
|
||||
pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
|
||||
// SAFETY: `Cell<T>` has the same memory layout as `T`
|
||||
// SAFETY: `Cell<T>` has the same memory layout as `T`.
|
||||
unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
|
||||
}
|
||||
}
|
||||
@ -821,7 +828,7 @@ pub fn borrow(&self) -> Ref<'_, T> {
|
||||
pub fn try_borrow(&self) -> Result<Ref<'_, T>, BorrowError> {
|
||||
match BorrowRef::new(&self.borrow) {
|
||||
// SAFETY: `BorrowRef` ensures that there is only immutable access
|
||||
// to the value while borrowed
|
||||
// to the value while borrowed.
|
||||
Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }),
|
||||
None => Err(BorrowError { _private: () }),
|
||||
}
|
||||
@ -897,7 +904,7 @@ pub fn borrow_mut(&self) -> RefMut<'_, T> {
|
||||
#[inline]
|
||||
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
|
||||
match BorrowRefMut::new(&self.borrow) {
|
||||
// SAFETY: `BorrowRef` guarantees unique access
|
||||
// SAFETY: `BorrowRef` guarantees unique access.
|
||||
Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }),
|
||||
None => Err(BorrowMutError { _private: () }),
|
||||
}
|
||||
@ -947,7 +954,7 @@ pub fn as_ptr(&self) -> *mut T {
|
||||
#[inline]
|
||||
#[stable(feature = "cell_get_mut", since = "1.11.0")]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
// SAFETY: `&mut` guarantees unique access
|
||||
// SAFETY: `&mut` guarantees unique access.
|
||||
unsafe { &mut *self.value.get() }
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ pub fn from_str(s: &str) -> &Utf8Lossy {
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
|
||||
// SAFETY: both use the same memory layout, and UTF-8 correctness isn't required
|
||||
// SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
|
||||
unsafe { mem::transmute(bytes) }
|
||||
}
|
||||
|
||||
@ -59,7 +59,8 @@ fn safe_get(xs: &[u8], i: usize) -> u8 {
|
||||
while i < self.source.len() {
|
||||
let i_ = i;
|
||||
|
||||
// SAFETY: 0 <= i < self.source.len()
|
||||
// SAFETY: `i` starts at `0`, is less than `self.source.len()`, and
|
||||
// only increases, so `0 <= i < self.source.len()`.
|
||||
let byte = unsafe { *self.source.get_unchecked(i) };
|
||||
i += 1;
|
||||
|
||||
@ -69,7 +70,7 @@ fn safe_get(xs: &[u8], i: usize) -> u8 {
|
||||
|
||||
macro_rules! error {
|
||||
() => {{
|
||||
// SAFETY: we have checked up to `i` that source is valid UTF-8
|
||||
// SAFETY: We have checked up to `i` that source is valid UTF-8.
|
||||
unsafe {
|
||||
let r = Utf8LossyChunk {
|
||||
valid: core_str::from_utf8_unchecked(&self.source[0..i_]),
|
||||
@ -131,7 +132,7 @@ macro_rules! error {
|
||||
}
|
||||
|
||||
let r = Utf8LossyChunk {
|
||||
// SAFETY: we have checked that the entire source is valid UTF-8
|
||||
// SAFETY: We have checked that the entire source is valid UTF-8.
|
||||
valid: unsafe { core_str::from_utf8_unchecked(self.source) },
|
||||
broken: &[],
|
||||
};
|
||||
|
@ -340,7 +340,7 @@ pub fn error_len(&self) -> Option<usize> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
||||
run_utf8_validation(v)?;
|
||||
// SAFETY: just ran validation
|
||||
// SAFETY: Just ran validation.
|
||||
Ok(unsafe { from_utf8_unchecked(v) })
|
||||
}
|
||||
|
||||
@ -379,7 +379,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
||||
#[stable(feature = "str_mut_extras", since = "1.20.0")]
|
||||
pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
run_utf8_validation(v)?;
|
||||
// SAFETY: just ran validation
|
||||
// SAFETY: Just ran validation.
|
||||
Ok(unsafe { from_utf8_unchecked_mut(v) })
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ impl<'a> Iterator for Chars<'a> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<char> {
|
||||
next_code_point(&mut self.iter).map(|ch| {
|
||||
// SAFETY: str invariant says `ch` is a valid Unicode Scalar Value
|
||||
// SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
|
||||
unsafe { char::from_u32_unchecked(ch) }
|
||||
})
|
||||
}
|
||||
@ -629,7 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<char> {
|
||||
next_code_point_reverse(&mut self.iter).map(|ch| {
|
||||
// SAFETY: str invariant says `ch` is a valid Unicode Scalar Value
|
||||
// SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
|
||||
unsafe { char::from_u32_unchecked(ch) }
|
||||
})
|
||||
}
|
||||
@ -659,7 +659,7 @@ impl<'a> Chars<'a> {
|
||||
#[stable(feature = "iter_to_slice", since = "1.4.0")]
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> &'a str {
|
||||
// SAFETY: `Chars` is only made from a str, which guarantees the iter is valid utf8
|
||||
// SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
|
||||
unsafe { from_utf8_unchecked(self.iter.as_slice()) }
|
||||
}
|
||||
}
|
||||
@ -1104,7 +1104,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
|
||||
fn get_end(&mut self) -> Option<&'a str> {
|
||||
if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
|
||||
self.finished = true;
|
||||
// SAFETY: `self.start` and `self.end` always lie on unicode boundaries
|
||||
// SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
|
||||
unsafe {
|
||||
let string = self.matcher.haystack().get_unchecked(self.start..self.end);
|
||||
Some(string)
|
||||
@ -1122,7 +1122,7 @@ fn next(&mut self) -> Option<&'a str> {
|
||||
|
||||
let haystack = self.matcher.haystack();
|
||||
match self.matcher.next_match() {
|
||||
// SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
|
||||
Some((a, b)) => unsafe {
|
||||
let elt = haystack.get_unchecked(self.start..a);
|
||||
self.start = b;
|
||||
@ -1155,13 +1155,13 @@ fn next_back(&mut self) -> Option<&'a str>
|
||||
|
||||
let haystack = self.matcher.haystack();
|
||||
match self.matcher.next_match_back() {
|
||||
// SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
|
||||
Some((a, b)) => unsafe {
|
||||
let elt = haystack.get_unchecked(b..self.end);
|
||||
self.end = a;
|
||||
Some(elt)
|
||||
},
|
||||
// SAFETY: `self.start` and `self.end` always lie on unicode boundaries
|
||||
// SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
|
||||
None => unsafe {
|
||||
self.finished = true;
|
||||
Some(haystack.get_unchecked(self.start..self.end))
|
||||
@ -1301,7 +1301,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<(usize, &'a str)> {
|
||||
// SAFETY: `Searcher` guaratees that `start` and `end` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
|
||||
self.0
|
||||
.next_match()
|
||||
.map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
|
||||
@ -1312,7 +1312,7 @@ fn next_back(&mut self) -> Option<(usize, &'a str)>
|
||||
where
|
||||
P::Searcher: ReverseSearcher<'a>,
|
||||
{
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
|
||||
self.0
|
||||
.next_match_back()
|
||||
.map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
|
||||
@ -1356,7 +1356,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
|
||||
self.0.next_match().map(|(a, b)| unsafe {
|
||||
// Indices are known to be on utf8 boundaries
|
||||
self.0.haystack().get_unchecked(a..b)
|
||||
@ -1368,7 +1368,7 @@ fn next_back(&mut self) -> Option<&'a str>
|
||||
where
|
||||
P::Searcher: ReverseSearcher<'a>,
|
||||
{
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries
|
||||
// SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
|
||||
self.0.next_match_back().map(|(a, b)| unsafe {
|
||||
// Indices are known to be on utf8 boundaries
|
||||
self.0.haystack().get_unchecked(a..b)
|
||||
@ -1589,9 +1589,10 @@ macro_rules! next {
|
||||
if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 {
|
||||
let ptr = v.as_ptr();
|
||||
while index < blocks_end {
|
||||
// SAFETY: since `align - index` and `ascii_block_size` are multiples of
|
||||
// `usize_bytes`, `ptr.add(index)` is always aligned with a `usize` so we
|
||||
// may cast directly to a `const` pointer.
|
||||
// SAFETY: since `align - index` and `ascii_block_size` are
|
||||
// multiples of `usize_bytes`, `block = ptr.add(index)` is
|
||||
// always aligned with a `usize` so it's safe to dereference
|
||||
// both `block` and `block.offset(1)`.
|
||||
unsafe {
|
||||
let block = ptr.add(index) as *const usize;
|
||||
// break if there is a nonascii byte
|
||||
@ -1817,7 +1818,7 @@ fn get(self, slice: &str) -> Option<&Self::Output> {
|
||||
&& slice.is_char_boundary(self.start)
|
||||
&& slice.is_char_boundary(self.end)
|
||||
{
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary.
|
||||
Some(unsafe { self.get_unchecked(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1829,7 +1830,7 @@ fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
|
||||
&& slice.is_char_boundary(self.start)
|
||||
&& slice.is_char_boundary(self.end)
|
||||
{
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary.
|
||||
Some(unsafe { self.get_unchecked_mut(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1860,7 +1861,7 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
&& slice.is_char_boundary(self.start)
|
||||
&& slice.is_char_boundary(self.end)
|
||||
{
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary
|
||||
// SAFETY: just checked that `start` and `end` are on a char boundary.
|
||||
unsafe { self.get_unchecked_mut(slice) }
|
||||
} else {
|
||||
super::slice_error_fail(slice, self.start, self.end)
|
||||
@ -1889,7 +1890,7 @@ impl SliceIndex<str> for ops::RangeTo<usize> {
|
||||
#[inline]
|
||||
fn get(self, slice: &str) -> Option<&Self::Output> {
|
||||
if slice.is_char_boundary(self.end) {
|
||||
// SAFETY: just checked that `end` is on a char boundary
|
||||
// SAFETY: just checked that `end` is on a char boundary.
|
||||
Some(unsafe { self.get_unchecked(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1898,7 +1899,7 @@ fn get(self, slice: &str) -> Option<&Self::Output> {
|
||||
#[inline]
|
||||
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
|
||||
if slice.is_char_boundary(self.end) {
|
||||
// SAFETY: just checked that `end` is on a char boundary
|
||||
// SAFETY: just checked that `end` is on a char boundary.
|
||||
Some(unsafe { self.get_unchecked_mut(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1922,7 +1923,7 @@ fn index(self, slice: &str) -> &Self::Output {
|
||||
#[inline]
|
||||
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
if slice.is_char_boundary(self.end) {
|
||||
// SAFETY: just checked that `end` is on a char boundary
|
||||
// SAFETY: just checked that `end` is on a char boundary.
|
||||
unsafe { self.get_unchecked_mut(slice) }
|
||||
} else {
|
||||
super::slice_error_fail(slice, 0, self.end)
|
||||
@ -1952,7 +1953,7 @@ impl SliceIndex<str> for ops::RangeFrom<usize> {
|
||||
#[inline]
|
||||
fn get(self, slice: &str) -> Option<&Self::Output> {
|
||||
if slice.is_char_boundary(self.start) {
|
||||
// SAFETY: just checked that `start` is on a char boundary
|
||||
// SAFETY: just checked that `start` is on a char boundary.
|
||||
Some(unsafe { self.get_unchecked(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1961,7 +1962,7 @@ fn get(self, slice: &str) -> Option<&Self::Output> {
|
||||
#[inline]
|
||||
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
|
||||
if slice.is_char_boundary(self.start) {
|
||||
// SAFETY: just checked that `start` is on a char boundary
|
||||
// SAFETY: just checked that `start` is on a char boundary.
|
||||
Some(unsafe { self.get_unchecked_mut(slice) })
|
||||
} else {
|
||||
None
|
||||
@ -1987,7 +1988,7 @@ fn index(self, slice: &str) -> &Self::Output {
|
||||
#[inline]
|
||||
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
if slice.is_char_boundary(self.start) {
|
||||
// SAFETY: just checked that `start` is on a char boundary
|
||||
// SAFETY: just checked that `start` is on a char boundary.
|
||||
unsafe { self.get_unchecked_mut(slice) }
|
||||
} else {
|
||||
super::slice_error_fail(slice, self.start, slice.len())
|
||||
@ -2593,7 +2594,7 @@ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut s
|
||||
pub fn split_at(&self, mid: usize) -> (&str, &str) {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(mid) {
|
||||
// SAFETY: just checked that `mid` is on a char boundary
|
||||
// SAFETY: just checked that `mid` is on a char boundary.
|
||||
unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) }
|
||||
} else {
|
||||
slice_error_fail(self, 0, mid)
|
||||
@ -2638,7 +2639,7 @@ pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
if self.is_char_boundary(mid) {
|
||||
let len = self.len();
|
||||
let ptr = self.as_mut_ptr();
|
||||
// SAFETY: just checked that `mid` is on a char boundary
|
||||
// SAFETY: just checked that `mid` is on a char boundary.
|
||||
unsafe {
|
||||
(
|
||||
from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)),
|
||||
@ -3827,7 +3828,7 @@ pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str
|
||||
if let Some((_, b)) = matcher.next_reject_back() {
|
||||
j = b;
|
||||
}
|
||||
// SAFETY: `Searcher` is known to return valid indices
|
||||
// SAFETY: `Searcher` is known to return valid indices.
|
||||
unsafe {
|
||||
self.get_unchecked(i..j)
|
||||
}
|
||||
@ -3866,7 +3867,7 @@ pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
|
||||
if let Some((a, _)) = matcher.next_reject() {
|
||||
i = a;
|
||||
}
|
||||
// SAFETY: `Searcher` is known to return valid indices
|
||||
// SAFETY: `Searcher` is known to return valid indices.
|
||||
unsafe {
|
||||
self.get_unchecked(i..self.len())
|
||||
}
|
||||
@ -3992,7 +3993,7 @@ pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str
|
||||
if let Some((_, b)) = matcher.next_reject_back() {
|
||||
j = b;
|
||||
}
|
||||
// SAFETY: `Searcher` is known to return valid indices
|
||||
// SAFETY: `Searcher` is known to return valid indices.
|
||||
unsafe {
|
||||
self.get_unchecked(0..j)
|
||||
}
|
||||
@ -4188,7 +4189,7 @@ pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
|
||||
/// ```
|
||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
pub fn make_ascii_uppercase(&mut self) {
|
||||
// SAFETY: safe because we transmute two types with the same layout
|
||||
// SAFETY: safe because we transmute two types with the same layout.
|
||||
let me = unsafe { self.as_bytes_mut() };
|
||||
me.make_ascii_uppercase()
|
||||
}
|
||||
@ -4214,7 +4215,7 @@ pub fn make_ascii_uppercase(&mut self) {
|
||||
/// ```
|
||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||
pub fn make_ascii_lowercase(&mut self) {
|
||||
// SAFETY: safe because we transmute two types with the same layout
|
||||
// SAFETY: safe because we transmute two types with the same layout.
|
||||
let me = unsafe { self.as_bytes_mut() };
|
||||
me.make_ascii_lowercase()
|
||||
}
|
||||
@ -4380,7 +4381,7 @@ fn default() -> Self {
|
||||
#[stable(feature = "default_mut_str", since = "1.28.0")]
|
||||
impl Default for &mut str {
|
||||
/// Creates an empty mutable str
|
||||
// SAFETY: `str` is guranteed to be UTF-8
|
||||
// SAFETY: `str` is guranteed to be UTF-8.
|
||||
fn default() -> Self {
|
||||
unsafe { from_utf8_unchecked_mut(&mut []) }
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ pub const fn new(v: bool) -> AtomicBool {
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_access", since = "1.15.0")]
|
||||
pub fn get_mut(&mut self) -> &mut bool {
|
||||
// SAFETY: the mutable reference guarantees unique ownership
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *(self.v.get() as *mut bool) }
|
||||
}
|
||||
|
||||
@ -399,7 +399,8 @@ pub fn into_inner(self) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn load(&self, order: Ordering) -> bool {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: any data races are prevented by atomic intrinsics and the raw
|
||||
// pointer passed in is valid because we got it from a reference.
|
||||
unsafe { atomic_load(self.v.get(), order) != 0 }
|
||||
}
|
||||
|
||||
@ -432,7 +433,8 @@ pub fn load(&self, order: Ordering) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn store(&self, val: bool, order: Ordering) {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: any data races are prevented by atomic intrinsics and the raw
|
||||
// pointer passed in is valid because we got it from a reference.
|
||||
unsafe {
|
||||
atomic_store(self.v.get(), val as u8, order);
|
||||
}
|
||||
@ -464,7 +466,7 @@ pub fn store(&self, val: bool, order: Ordering) {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
@ -560,7 +562,7 @@ pub fn compare_exchange(
|
||||
success: Ordering,
|
||||
failure: Ordering,
|
||||
) -> Result<bool, bool> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
match unsafe {
|
||||
atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
|
||||
} {
|
||||
@ -618,7 +620,7 @@ pub fn compare_exchange_weak(
|
||||
success: Ordering,
|
||||
failure: Ordering,
|
||||
) -> Result<bool, bool> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
match unsafe {
|
||||
atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
|
||||
} {
|
||||
@ -665,7 +667,7 @@ pub fn compare_exchange_weak(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
@ -761,7 +763,7 @@ pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
@ -803,7 +805,7 @@ pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
@ -879,7 +881,7 @@ pub const fn new(p: *mut T) -> AtomicPtr<T> {
|
||||
#[inline]
|
||||
#[stable(feature = "atomic_access", since = "1.15.0")]
|
||||
pub fn get_mut(&mut self) -> &mut *mut T {
|
||||
// SAFETY: the mutable reference guarantees unique ownership
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *self.p.get() }
|
||||
}
|
||||
|
||||
@ -931,7 +933,7 @@ pub fn into_inner(self) -> *mut T {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn load(&self, order: Ordering) -> *mut T {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
|
||||
}
|
||||
|
||||
@ -966,7 +968,7 @@ pub fn load(&self, order: Ordering) -> *mut T {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn store(&self, ptr: *mut T, order: Ordering) {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_store(self.p.get() as *mut usize, ptr as usize, order);
|
||||
}
|
||||
@ -1000,7 +1002,7 @@ pub fn store(&self, ptr: *mut T, order: Ordering) {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
|
||||
}
|
||||
|
||||
@ -1085,7 +1087,7 @@ pub fn compare_exchange(
|
||||
success: Ordering,
|
||||
failure: Ordering,
|
||||
) -> Result<*mut T, *mut T> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
let res = atomic_compare_exchange(
|
||||
self.p.get() as *mut usize,
|
||||
@ -1149,7 +1151,7 @@ pub fn compare_exchange_weak(
|
||||
success: Ordering,
|
||||
failure: Ordering,
|
||||
) -> Result<*mut T, *mut T> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
let res = atomic_compare_exchange_weak(
|
||||
self.p.get() as *mut usize,
|
||||
@ -1303,7 +1305,7 @@ pub const fn new(v: $int_type) -> Self {
|
||||
#[inline]
|
||||
#[$stable_access]
|
||||
pub fn get_mut(&mut self) -> &mut $int_type {
|
||||
// SAFETY: the mutable reference guarantees unique ownership
|
||||
// SAFETY: the mutable reference guarantees unique ownership.
|
||||
unsafe { &mut *self.v.get() }
|
||||
}
|
||||
}
|
||||
@ -1358,7 +1360,7 @@ pub fn into_inner(self) -> $int_type {
|
||||
#[inline]
|
||||
#[$stable]
|
||||
pub fn load(&self, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_load(self.v.get(), order) }
|
||||
}
|
||||
}
|
||||
@ -1393,7 +1395,7 @@ pub fn load(&self, order: Ordering) -> $int_type {
|
||||
#[inline]
|
||||
#[$stable]
|
||||
pub fn store(&self, val: $int_type, order: Ordering) {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
}
|
||||
}
|
||||
@ -1424,7 +1426,7 @@ pub fn store(&self, val: $int_type, order: Ordering) {
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1527,7 +1529,7 @@ pub fn compare_exchange(&self,
|
||||
new: $int_type,
|
||||
success: Ordering,
|
||||
failure: Ordering) -> Result<$int_type, $int_type> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
|
||||
}
|
||||
}
|
||||
@ -1580,7 +1582,7 @@ pub fn compare_exchange_weak(&self,
|
||||
new: $int_type,
|
||||
success: Ordering,
|
||||
failure: Ordering) -> Result<$int_type, $int_type> {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
|
||||
}
|
||||
@ -1615,7 +1617,7 @@ pub fn compare_exchange_weak(&self,
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1648,7 +1650,7 @@ pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1684,7 +1686,7 @@ pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1721,7 +1723,7 @@ pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
#[$stable_nand]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_nand(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1757,7 +1759,7 @@ pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1793,7 +1795,7 @@ pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
#[$stable]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1905,7 +1907,7 @@ pub fn fetch_update<F>(&self,
|
||||
issue = "48655")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { $max_fn(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -1958,7 +1960,7 @@ pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
issue = "48655")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
// SAFETY: data races are prevented by atomic intrinsics
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe { $min_fn(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
@ -2553,7 +2555,7 @@ pub fn fence(order: Ordering) {
|
||||
// https://github.com/WebAssembly/tool-conventions/issues/59. We should
|
||||
// follow that discussion and implement a solution when one comes about!
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
// SAFETY: using an atomic fence is safe
|
||||
// SAFETY: using an atomic fence is safe.
|
||||
unsafe {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_fence_acq(),
|
||||
@ -2641,7 +2643,7 @@ pub fn fence(order: Ordering) {
|
||||
#[inline]
|
||||
#[stable(feature = "compiler_fences", since = "1.21.0")]
|
||||
pub fn compiler_fence(order: Ordering) {
|
||||
// SAFETY: doesn't compile to machine code
|
||||
// SAFETY: using an atomic fence is safe.
|
||||
unsafe {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_singlethreadfence_acq(),
|
||||
|
Loading…
Reference in New Issue
Block a user