//! ```
//!
-// ignore-tidy-undocumented-unsafe
-
#![stable(feature = "rust1", since = "1.0.0")]
use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::Unsize;
use crate::mem;
-use crate::ops::{Deref, DerefMut, CoerceUnsized};
+use crate::ops::{CoerceUnsized, Deref, DerefMut};
use crate::ptr;
/// A mutable memory location.
impl<T: ?Sized> !Sync for Cell<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T:Copy> Clone for Cell<T> {
+impl<T: Copy> Clone for Cell<T> {
#[inline]
fn clone(&self) -> Cell<T> {
Cell::new(self.get())
#[rustc_const_stable(feature = "const_cell_new", since = "1.32.0")]
#[inline]
pub const fn new(value: T) -> Cell<T> {
- Cell {
- value: UnsafeCell::new(value),
- }
+ Cell { value: UnsafeCell::new(value) }
}
/// Sets the contained value.
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());
}
/// ```
#[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)
}
}
}
-impl<T:Copy> Cell<T> {
+impl<T: Copy> Cell<T> {
/// Returns a copy of the contained value.
///
/// # Examples
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> T {
- unsafe{ *self.value.get() }
+ // 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() }
}
/// Updates the contained value using a function and returns the new value.
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
- unsafe {
- &mut *self.value.get()
- }
+ // 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() }
}
/// Returns a `&Cell<T>` from a `&mut T`
#[inline]
#[stable(feature = "as_cell", since = "1.37.0")]
pub fn from_mut(t: &mut T) -> &Cell<T> {
- unsafe {
- &*(t as *mut T as *const Cell<T>)
- }
+ // SAFETY: `&mut` ensures unique access.
+ unsafe { &*(t as *mut T as *const Cell<T>) }
}
}
/// ```
#[stable(feature = "as_cell", since = "1.37.0")]
pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
- unsafe {
- &*(self as *const Cell<[T]> as *const [Cell<T>])
- }
+ // SAFETY: `Cell<T>` has the same memory layout as `T`.
+ unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
}
}
#[rustc_const_stable(feature = "const_refcell_new", since = "1.32.0")]
#[inline]
pub const fn new(value: T) -> RefCell<T> {
- RefCell {
- value: UnsafeCell::new(value),
- borrow: Cell::new(UNUSED),
- }
+ RefCell { value: UnsafeCell::new(value), borrow: Cell::new(UNUSED) }
}
/// Consumes the `RefCell`, returning the wrapped value.
/// assert_eq!(cell, RefCell::new(6));
/// ```
#[inline]
- #[stable(feature = "refcell_replace", since="1.24.0")]
+ #[stable(feature = "refcell_replace", since = "1.24.0")]
pub fn replace(&self, t: T) -> T {
mem::replace(&mut *self.borrow_mut(), t)
}
/// assert_eq!(cell, RefCell::new(6));
/// ```
#[inline]
- #[stable(feature = "refcell_replace_swap", since="1.35.0")]
+ #[stable(feature = "refcell_replace_swap", since = "1.35.0")]
pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
let mut_borrow = &mut *self.borrow_mut();
let replacement = f(mut_borrow);
/// assert_eq!(d, RefCell::new(5));
/// ```
#[inline]
- #[stable(feature = "refcell_swap", since="1.24.0")]
+ #[stable(feature = "refcell_swap", since = "1.24.0")]
pub fn swap(&self, other: &Self) {
mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
}
#[inline]
pub fn try_borrow(&self) -> Result<Ref<'_, T>, BorrowError> {
match BorrowRef::new(&self.borrow) {
- Some(b) => Ok(Ref {
- value: unsafe { &*self.value.get() },
- borrow: b,
- }),
+ // 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: () }),
}
}
#[inline]
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
match BorrowRefMut::new(&self.borrow) {
- Some(b) => Ok(RefMut {
- value: unsafe { &mut *self.value.get() },
- borrow: b,
- }),
+ // SAFETY: `BorrowRef` guarantees unique access.
+ Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }),
None => Err(BorrowMutError { _private: () }),
}
}
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
- unsafe {
- &mut *self.value.get()
- }
+ // SAFETY: `&mut` guarantees unique access.
+ unsafe { &mut *self.value.get() }
}
/// Immutably borrows the wrapped value, returning an error if the value is
#[stable(feature = "cell_extras", since = "1.15.0")]
#[inline]
pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
- Ref {
- value: orig.value,
- borrow: orig.borrow.clone(),
- }
+ Ref { value: orig.value, borrow: orig.borrow.clone() }
}
/// Makes a new `Ref` for a component of the borrowed data.
#[stable(feature = "cell_map", since = "1.8.0")]
#[inline]
pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
- where F: FnOnce(&T) -> &U
+ where
+ F: FnOnce(&T) -> &U,
{
- Ref {
- value: f(orig.value),
- borrow: orig.borrow,
- }
+ Ref { value: f(orig.value), borrow: orig.borrow }
}
/// Splits a `Ref` into multiple `Ref`s for different components of the
#[stable(feature = "refcell_map_split", since = "1.35.0")]
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
- where F: FnOnce(&T) -> (&U, &V)
+ where
+ F: FnOnce(&T) -> (&U, &V),
{
let (a, b) = f(orig.value);
let borrow = orig.borrow.clone();
#[stable(feature = "cell_map", since = "1.8.0")]
#[inline]
pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
- where F: FnOnce(&mut T) -> &mut U
+ where
+ F: FnOnce(&mut T) -> &mut U,
{
// FIXME(nll-rfc#40): fix borrow-check
let RefMut { value, borrow } = orig;
- RefMut {
- value: f(value),
- borrow,
- }
+ RefMut { value: f(value), borrow }
}
/// Splits a `RefMut` into multiple `RefMut`s for different components of the
#[stable(feature = "refcell_map_split", since = "1.35.0")]
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
- orig: RefMut<'b, T>, f: F
+ orig: RefMut<'b, T>,
+ f: F,
) -> (RefMut<'b, U>, RefMut<'b, V>)
- where F: FnOnce(&mut T) -> (&mut U, &mut V)
+ where
+ F: FnOnce(&mut T) -> (&mut U, &mut V),
{
let (a, b) = f(orig.value);
let borrow = orig.borrow.clone();
UNUSED => {
borrow.set(UNUSED - 1);
Some(BorrowRefMut { borrow })
- },
+ }
_ => None,
}
}