Skip to content

Commit

Permalink
Rollup merge of rust-lang#66564 - foeb:66219-document-unsafe-sync-cel…
Browse files Browse the repository at this point in the history
…l-str, r=Amanieu

Document unsafe blocks in core::{cell, str, sync}

Split from rust-lang#66506 (issue rust-lang#66219). Hopefully doing a chunk at a time is more manageable!

r? @RalfJung
  • Loading branch information
Dylan-DPC authored Jan 17, 2020
2 parents 2480c9e + 022a7de commit 00c7c34
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 35 deletions.
19 changes: 17 additions & 2 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,6 @@
//! ```
//!
// ignore-tidy-undocumented-unsafe

#![stable(feature = "rust1", since = "1.0.0")]

use crate::cmp::Ordering;
Expand Down Expand Up @@ -368,6 +366,10 @@ impl<T> Cell<T> {
if ptr::eq(self, other) {
return;
}
// 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());
}
Expand All @@ -387,6 +389,8 @@ impl<T> Cell<T> {
/// ```
#[stable(feature = "move_cell", since = "1.17.0")]
pub fn replace(&self, val: T) -> T {
// 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)
}

Expand Down Expand Up @@ -423,6 +427,8 @@ impl<T: Copy> Cell<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> T {
// 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() }
}

Expand Down Expand Up @@ -491,6 +497,9 @@ impl<T: ?Sized> Cell<T> {
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
// 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() }
}

Expand All @@ -510,6 +519,7 @@ impl<T: ?Sized> Cell<T> {
#[inline]
#[stable(feature = "as_cell", since = "1.37.0")]
pub fn from_mut(t: &mut T) -> &Cell<T> {
// SAFETY: `&mut` ensures unique access.
unsafe { &*(t as *mut T as *const Cell<T>) }
}
}
Expand Down Expand Up @@ -553,6 +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`.
unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
}
}
Expand Down Expand Up @@ -816,6 +827,8 @@ impl<T: ?Sized> RefCell<T> {
#[inline]
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.
Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }),
None => Err(BorrowError { _private: () }),
}
Expand Down Expand Up @@ -891,6 +904,7 @@ impl<T: ?Sized> RefCell<T> {
#[inline]
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
match BorrowRefMut::new(&self.borrow) {
// SAFETY: `BorrowRef` guarantees unique access.
Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }),
None => Err(BorrowMutError { _private: () }),
}
Expand Down Expand Up @@ -940,6 +954,7 @@ impl<T: ?Sized> RefCell<T> {
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
// SAFETY: `&mut` guarantees unique access.
unsafe { &mut *self.value.get() }
}

Expand Down
7 changes: 5 additions & 2 deletions src/libcore/str/lossy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ use crate::fmt::{self, Write};
use crate::mem;
use crate::str as core_str;

// ignore-tidy-undocumented-unsafe

/// Lossy UTF-8 string.
#[unstable(feature = "str_internals", issue = "none")]
pub struct Utf8Lossy {
Expand All @@ -17,6 +15,7 @@ impl Utf8Lossy {
}

pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
// SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
unsafe { mem::transmute(bytes) }
}

Expand Down Expand Up @@ -60,6 +59,8 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
while i < self.source.len() {
let i_ = i;

// 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;

Expand All @@ -69,6 +70,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {

macro_rules! error {
() => {{
// 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_]),
Expand Down Expand Up @@ -130,6 +132,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
}

let r = Utf8LossyChunk {
// SAFETY: We have checked that the entire source is valid UTF-8.
valid: unsafe { core_str::from_utf8_unchecked(self.source) },
broken: &[],
};
Expand Down
Loading

0 comments on commit 00c7c34

Please sign in to comment.