// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Shareable mutable containers. //! //! Values of the `Cell` and `RefCell` types may be mutated through //! shared references (i.e. the common `&T` type), whereas most Rust //! types can only be mutated through unique (`&mut T`) references. We //! say that `Cell` and `RefCell` provide *interior mutability*, in //! contrast with typical Rust types that exhibit *inherited //! mutability*. //! //! Cell types come in two flavors: `Cell` and `RefCell`. `Cell` //! provides `get` and `set` methods that change the //! interior value with a single method call. `Cell` though is only //! compatible with types that implement `Copy`. For other types, //! one must use the `RefCell` type, acquiring a write lock before //! mutating. //! //! `RefCell` uses Rust's lifetimes to implement *dynamic borrowing*, //! a process whereby one can claim temporary, exclusive, mutable //! access to the inner value. Borrows for `RefCell`s are tracked *at //! runtime*, unlike Rust's native reference types which are entirely //! tracked statically, at compile time. Because `RefCell` borrows are //! dynamic it is possible to attempt to borrow a value that is //! already mutably borrowed; when this happens it results in task //! panic. //! //! # When to choose interior mutability //! //! The more common inherited mutability, where one must have unique //! access to mutate a value, is one of the key language elements that //! enables Rust to reason strongly about pointer aliasing, statically //! preventing crash bugs. Because of that, inherited mutability is //! preferred, and interior mutability is something of a last //! resort. Since cell types enable mutation where it would otherwise //! be disallowed though, there are occasions when interior //! mutability might be appropriate, or even *must* be used, e.g. //! //! * Introducing inherited mutability roots to shared types. //! * Implementation details of logically-immutable methods. //! * Mutating implementations of `clone`. //! //! ## Introducing inherited mutability roots to shared types //! //! Shared smart pointer types, including `Rc` and `Arc`, provide //! containers that can be cloned and shared between multiple parties. //! Because the contained values may be multiply-aliased, they can //! only be borrowed as shared references, not mutable references. //! Without cells it would be impossible to mutate data inside of //! shared boxes at all! //! //! It's very common then to put a `RefCell` inside shared pointer //! types to reintroduce mutability: //! //! ``` //! use std::collections::HashMap; //! use std::cell::RefCell; //! use std::rc::Rc; //! //! fn main() { //! let shared_map: Rc> = Rc::new(RefCell::new(HashMap::new())); //! shared_map.borrow_mut().insert("africa", 92388i); //! shared_map.borrow_mut().insert("kyoto", 11837i); //! shared_map.borrow_mut().insert("piccadilly", 11826i); //! shared_map.borrow_mut().insert("marbles", 38i); //! } //! ``` //! //! ## Implementation details of logically-immutable methods //! //! Occasionally it may be desirable not to expose in an API that //! there is mutation happening "under the hood". This may be because //! logically the operation is immutable, but e.g. caching forces the //! implementation to perform mutation; or because you must employ //! mutation to implement a trait method that was originally defined //! to take `&self`. //! //! ``` //! use std::cell::RefCell; //! //! struct Graph { //! edges: Vec<(uint, uint)>, //! span_tree_cache: RefCell>> //! } //! //! impl Graph { //! fn minimum_spanning_tree(&self) -> Vec<(uint, uint)> { //! // Create a new scope to contain the lifetime of the //! // dynamic borrow //! { //! // Take a reference to the inside of cache cell //! let mut cache = self.span_tree_cache.borrow_mut(); //! if cache.is_some() { //! return cache.as_ref().unwrap().clone(); //! } //! //! let span_tree = self.calc_span_tree(); //! *cache = Some(span_tree); //! } //! //! // Recursive call to return the just-cached value. //! // Note that if we had not let the previous borrow //! // of the cache fall out of scope then the subsequent //! // recursive borrow would cause a dynamic task panic. //! // This is the major hazard of using `RefCell`. //! self.minimum_spanning_tree() //! } //! # fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] } //! } //! # fn main() { } //! ``` //! //! ## Mutating implementations of `clone` //! //! This is simply a special - but common - case of the previous: //! hiding mutability for operations that appear to be immutable. //! The `clone` method is expected to not change the source value, and //! is declared to take `&self`, not `&mut self`. Therefore any //! mutation that happens in the `clone` method must use cell //! types. For example, `Rc` maintains its reference counts within a //! `Cell`. //! //! ``` //! use std::cell::Cell; //! //! struct Rc { //! ptr: *mut RcBox //! } //! //! struct RcBox { //! value: T, //! refcount: Cell //! } //! //! impl Clone for Rc { //! fn clone(&self) -> Rc { //! unsafe { //! (*self.ptr).refcount.set((*self.ptr).refcount.get() + 1); //! Rc { ptr: self.ptr } //! } //! } //! } //! ``` //! // FIXME: Explain difference between Cell and RefCell // FIXME: Downsides to interior mutability // FIXME: Can't be shared between threads. Dynamic borrows // FIXME: Relationship to Atomic types and RWLock use clone::Clone; use cmp::PartialEq; use default::Default; use kinds::{marker, Copy}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{None, Some}; /// A mutable memory location that admits only `Copy` data. #[stable] pub struct Cell { value: UnsafeCell, noshare: marker::NoSync, } impl Cell { /// Creates a new `Cell` containing the given value. #[stable] pub fn new(value: T) -> Cell { Cell { value: UnsafeCell::new(value), noshare: marker::NoSync, } } /// Returns a copy of the contained value. #[inline] #[stable] pub fn get(&self) -> T { unsafe{ *self.value.get() } } /// Sets the contained value. #[inline] #[stable] pub fn set(&self, value: T) { unsafe { *self.value.get() = value; } } /// Get a reference to the underlying `UnsafeCell`. /// /// This can be used to circumvent `Cell`'s safety checks. /// /// This function is `unsafe` because `UnsafeCell`'s field is public. #[inline] #[experimental] pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell { &self.value } } #[stable] impl Clone for Cell { fn clone(&self) -> Cell { Cell::new(self.get()) } } #[stable] impl Default for Cell { #[stable] fn default() -> Cell { Cell::new(Default::default()) } } #[unstable = "waiting for `PartialEq` trait to become stable"] impl PartialEq for Cell { fn eq(&self, other: &Cell) -> bool { self.get() == other.get() } } /// A mutable memory location with dynamically checked borrow rules #[stable] pub struct RefCell { value: UnsafeCell, borrow: Cell, noshare: marker::NoSync, } // Values [1, MAX-1] represent the number of `Ref` active // (will not outgrow its range since `uint` is the size of the address space) type BorrowFlag = uint; const UNUSED: BorrowFlag = 0; const WRITING: BorrowFlag = -1; impl RefCell { /// Create a new `RefCell` containing `value` #[stable] pub fn new(value: T) -> RefCell { RefCell { value: UnsafeCell::new(value), borrow: Cell::new(UNUSED), noshare: marker::NoSync, } } /// Consumes the `RefCell`, returning the wrapped value. #[stable] pub fn into_inner(self) -> T { // Since this function takes `self` (the `RefCell`) by value, the // compiler statically verifies that it is not currently borrowed. // Therefore the following assertion is just a `debug_assert!`. debug_assert!(self.borrow.get() == UNUSED); unsafe { self.value.into_inner() } } /// Deprecated, use into_inner() instead #[deprecated = "renamed to into_inner()"] pub fn unwrap(self) -> T { self.into_inner() } /// Attempts to immutably borrow the wrapped value. /// /// The borrow lasts until the returned `Ref` exits scope. Multiple /// immutable borrows can be taken out at the same time. /// /// Returns `None` if the value is currently mutably borrowed. #[unstable = "may be renamed or removed"] pub fn try_borrow<'a>(&'a self) -> Option> { match BorrowRef::new(&self.borrow) { Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }), None => None, } } /// Immutably borrows the wrapped value. /// /// The borrow lasts until the returned `Ref` exits scope. Multiple /// immutable borrows can be taken out at the same time. /// /// # Panics /// /// Panics if the value is currently mutably borrowed. #[stable] pub fn borrow<'a>(&'a self) -> Ref<'a, T> { match self.try_borrow() { Some(ptr) => ptr, None => panic!("RefCell already mutably borrowed") } } /// Mutably borrows the wrapped value. /// /// The borrow lasts until the returned `RefMut` exits scope. The value /// cannot be borrowed while this borrow is active. /// /// Returns `None` if the value is currently borrowed. #[unstable = "may be renamed or removed"] pub fn try_borrow_mut<'a>(&'a self) -> Option> { match BorrowRefMut::new(&self.borrow) { Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }), None => None, } } /// Mutably borrows the wrapped value. /// /// The borrow lasts until the returned `RefMut` exits scope. The value /// cannot be borrowed while this borrow is active. /// /// # Panics /// /// Panics if the value is currently borrowed. #[stable] pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> { match self.try_borrow_mut() { Some(ptr) => ptr, None => panic!("RefCell already borrowed") } } /// Get a reference to the underlying `UnsafeCell`. /// /// This can be used to circumvent `RefCell`'s safety checks. /// /// This function is `unsafe` because `UnsafeCell`'s field is public. #[inline] #[experimental] pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell { &self.value } } #[stable] impl Clone for RefCell { fn clone(&self) -> RefCell { RefCell::new(self.borrow().clone()) } } #[stable] impl Default for RefCell { #[stable] fn default() -> RefCell { RefCell::new(Default::default()) } } #[unstable = "waiting for `PartialEq` to become stable"] impl PartialEq for RefCell { fn eq(&self, other: &RefCell) -> bool { *self.borrow() == *other.borrow() } } struct BorrowRef<'b> { _borrow: &'b Cell, } impl<'b> BorrowRef<'b> { fn new(borrow: &'b Cell) -> Option> { match borrow.get() { WRITING => None, b => { borrow.set(b + 1); Some(BorrowRef { _borrow: borrow }) }, } } } #[unsafe_destructor] impl<'b> Drop for BorrowRef<'b> { fn drop(&mut self) { let borrow = self._borrow.get(); debug_assert!(borrow != WRITING && borrow != UNUSED); self._borrow.set(borrow - 1); } } impl<'b> Clone for BorrowRef<'b> { fn clone(&self) -> BorrowRef<'b> { // Since this Ref exists, we know the borrow flag // is not set to WRITING. let borrow = self._borrow.get(); debug_assert!(borrow != WRITING && borrow != UNUSED); self._borrow.set(borrow + 1); BorrowRef { _borrow: self._borrow } } } /// Wraps a borrowed reference to a value in a `RefCell` box. #[stable] pub struct Ref<'b, T:'b> { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref _value: &'b T, _borrow: BorrowRef<'b>, } #[unstable = "waiting for `Deref` to become stable"] impl<'b, T> Deref for Ref<'b, T> { #[inline] fn deref<'a>(&'a self) -> &'a T { self._value } } /// Copy a `Ref`. /// /// The `RefCell` is already immutably borrowed, so this cannot fail. /// /// A `Clone` implementation would interfere with the widespread /// use of `r.borrow().clone()` to clone the contents of a `RefCell`. #[experimental = "likely to be moved to a method, pending language changes"] pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> { Ref { _value: orig._value, _borrow: orig._borrow.clone(), } } struct BorrowRefMut<'b> { _borrow: &'b Cell, } #[unsafe_destructor] impl<'b> Drop for BorrowRefMut<'b> { fn drop(&mut self) { let borrow = self._borrow.get(); debug_assert!(borrow == WRITING); self._borrow.set(UNUSED); } } impl<'b> BorrowRefMut<'b> { fn new(borrow: &'b Cell) -> Option> { match borrow.get() { UNUSED => { borrow.set(WRITING); Some(BorrowRefMut { _borrow: borrow }) }, _ => None, } } } /// Wraps a mutable borrowed reference to a value in a `RefCell` box. #[stable] pub struct RefMut<'b, T:'b> { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref _value: &'b mut T, _borrow: BorrowRefMut<'b>, } #[unstable = "waiting for `Deref` to become stable"] impl<'b, T> Deref for RefMut<'b, T> { #[inline] fn deref<'a>(&'a self) -> &'a T { self._value } } #[unstable = "waiting for `DerefMut` to become stable"] impl<'b, T> DerefMut for RefMut<'b, T> { #[inline] fn deref_mut<'a>(&'a mut self) -> &'a mut T { self._value } } /// The core primitive for interior mutability in Rust. /// /// `UnsafeCell` type that wraps a type T and indicates unsafe interior /// operations on the wrapped type. Types with an `UnsafeCell` field are /// considered to have an *unsafe interior*. The `UnsafeCell` type is the only /// legal way to obtain aliasable data that is considered mutable. In general, /// transmuting an &T type into an &mut T is considered undefined behavior. /// /// Although it is possible to put an `UnsafeCell` into static item, it is /// not permitted to take the address of the static item if the item is not /// declared as mutable. This rule exists because immutable static items are /// stored in read-only memory, and thus any attempt to mutate their interior /// can cause segfaults. Immutable static items containing `UnsafeCell` /// instances are still useful as read-only initializers, however, so we do not /// forbid them altogether. /// /// Types like `Cell` and `RefCell` use this type to wrap their internal data. /// /// `UnsafeCell` doesn't opt-out from any kind, instead, types with an /// `UnsafeCell` interior are expected to opt-out from kinds themselves. /// /// # Example: /// /// ```rust /// use std::cell::UnsafeCell; /// use std::kinds::marker; /// /// struct NotThreadSafe { /// value: UnsafeCell, /// marker: marker::NoSync /// } /// ``` /// /// **NOTE:** `UnsafeCell` fields are public to allow static initializers. It /// is not recommended to access its fields directly, `get` should be used /// instead. #[lang="unsafe"] #[stable] pub struct UnsafeCell { /// Wrapped value /// /// This field should not be accessed directly, it is made public for static /// initializers. #[unstable] pub value: T, } impl UnsafeCell { /// Construct a new instance of `UnsafeCell` which will wrap the specified /// value. /// /// All access to the inner value through methods is `unsafe`, and it is /// highly discouraged to access the fields directly. #[stable] pub fn new(value: T) -> UnsafeCell { UnsafeCell { value: value } } /// Gets a mutable pointer to the wrapped value. #[inline] #[stable] pub fn get(&self) -> *mut T { &self.value as *const T as *mut T } /// Unwraps the value /// /// This function is unsafe because there is no guarantee that this or other /// tasks are currently inspecting the inner value. #[inline] #[stable] pub unsafe fn into_inner(self) -> T { self.value } /// Deprecated, use into_inner() instead #[deprecated = "renamed to into_inner()"] pub unsafe fn unwrap(self) -> T { self.into_inner() } }