]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/cell.rs
Added minor clarification to specification of realloc.
[rust.git] / src / libcore / cell.rs
index 03f32e726187b09ea86af46601df58465cd16c31..e7eecf7540ad74121d4a0c840536afff154a98e5 100644 (file)
 //! ```
 //!
 
-// 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.
@@ -243,7 +241,7 @@ unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
 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())
@@ -324,11 +322,10 @@ impl<T> Cell<T> {
     /// let c = Cell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[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.
@@ -369,6 +366,10 @@ pub fn swap(&self, other: &Self) {
         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());
         }
@@ -388,6 +389,8 @@ pub fn swap(&self, other: &Self) {
     /// ```
     #[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)
     }
 
@@ -409,7 +412,7 @@ pub fn into_inner(self) -> T {
     }
 }
 
-impl<T:Copy> Cell<T> {
+impl<T: Copy> Cell<T> {
     /// Returns a copy of the contained value.
     ///
     /// # Examples
@@ -424,7 +427,9 @@ impl<T:Copy> Cell<T> {
     #[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.
@@ -469,6 +474,7 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "cell_as_ptr", since = "1.12.0")]
+    #[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")]
     pub const fn as_ptr(&self) -> *mut T {
         self.value.get()
     }
@@ -491,9 +497,10 @@ 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 {
-        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`
@@ -512,9 +519,8 @@ 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> {
-        unsafe {
-            &*(t as *mut T as *const Cell<T>)
-        }
+        // SAFETY: `&mut` ensures unique access.
+        unsafe { &*(t as *mut T as *const Cell<T>) }
     }
 }
 
@@ -557,9 +563,8 @@ impl<T> 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>]) }
     }
 }
 
@@ -649,12 +654,10 @@ impl<T> RefCell<T> {
     /// let c = RefCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[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.
@@ -697,7 +700,7 @@ pub fn into_inner(self) -> T {
     /// 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)
     }
@@ -719,7 +722,7 @@ pub fn replace(&self, t: T) -> 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);
@@ -746,7 +749,7 @@ pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
     /// 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())
     }
@@ -824,10 +827,9 @@ pub fn borrow(&self) -> Ref<'_, T> {
     #[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: () }),
         }
     }
@@ -902,10 +904,8 @@ pub fn borrow_mut(&self) -> RefMut<'_, T> {
     #[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: () }),
         }
     }
@@ -954,9 +954,8 @@ 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 {
-        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
@@ -1186,10 +1185,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     #[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.
@@ -1213,12 +1209,10 @@ pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
     #[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
@@ -1244,7 +1238,8 @@ pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
     #[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();
@@ -1289,14 +1284,12 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
     #[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
@@ -1327,9 +1320,11 @@ pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
     #[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();
@@ -1361,7 +1356,7 @@ fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
             UNUSED => {
                 borrow.set(UNUSED - 1);
                 Some(BorrowRefMut { borrow })
-            },
+            }
             _ => None,
         }
     }
@@ -1501,6 +1496,7 @@ impl<T> UnsafeCell<T> {
     /// let uc = UnsafeCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_unsafe_cell_new", since = "1.32.0")]
     #[inline]
     pub const fn new(value: T) -> UnsafeCell<T> {
         UnsafeCell { value }
@@ -1543,6 +1539,7 @@ impl<T: ?Sized> UnsafeCell<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")]
     pub const fn get(&self) -> *mut T {
         // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
         // #[repr(transparent)]. This exploits libstd's special status, there is