2015-02-09 05:56:24 -06:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-05-22 07:50:31 -05:00
|
|
|
//! Shareable mutable containers.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! Values of the `Cell<T>` and `RefCell<T>` 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<T>` and `RefCell<T>` provide 'interior mutability', in contrast
|
|
|
|
//! with typical Rust types that exhibit 'inherited mutability'.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` provides `get` and `set`
|
|
|
|
//! methods that change the interior value with a single method call. `Cell<T>` though is only
|
|
|
|
//! compatible with types that implement `Copy`. For other types, one must use the `RefCell<T>`
|
|
|
|
//! type, acquiring a write lock before mutating.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! `RefCell<T>` 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<T>`s are
|
|
|
|
//! tracked 'at runtime', unlike Rust's native reference types which are entirely tracked
|
|
|
|
//! statically, at compile time. Because `RefCell<T>` borrows are dynamic it is possible to attempt
|
2015-05-08 10:56:50 -05:00
|
|
|
//! to borrow a value that is already mutably borrowed; when this happens it results in thread
|
|
|
|
//! panic.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! # When to choose interior mutability
|
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! 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.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! * Introducing inherited mutability roots to shared types.
|
|
|
|
//! * Implementation details of logically-immutable methods.
|
2015-06-04 18:45:43 -05:00
|
|
|
//! * Mutating implementations of `Clone`.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! ## Introducing inherited mutability roots to shared types
|
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! Shared smart pointer types, including `Rc<T>` and `Arc<T>`, 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!
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! It's very common then to put a `RefCell<T>` inside shared pointer types to reintroduce
|
|
|
|
//! mutability:
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! ```
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
//! use std::collections::HashMap;
|
2014-05-18 23:47:51 -05:00
|
|
|
//! use std::cell::RefCell;
|
|
|
|
//! use std::rc::Rc;
|
|
|
|
//!
|
|
|
|
//! fn main() {
|
|
|
|
//! let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
|
2015-01-22 08:08:56 -06:00
|
|
|
//! shared_map.borrow_mut().insert("africa", 92388);
|
|
|
|
//! shared_map.borrow_mut().insert("kyoto", 11837);
|
|
|
|
//! shared_map.borrow_mut().insert("piccadilly", 11826);
|
|
|
|
//! shared_map.borrow_mut().insert("marbles", 38);
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
2015-01-21 11:43:34 -06:00
|
|
|
//! Note that this example uses `Rc<T>` and not `Arc<T>`. `RefCell<T>`s are for single-threaded
|
|
|
|
//! scenarios. Consider using `Mutex<T>` if you need shared mutability in a multi-threaded
|
|
|
|
//! situation.
|
|
|
|
//!
|
2014-05-18 23:47:51 -05:00
|
|
|
//! ## Implementation details of logically-immutable methods
|
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! 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`.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! use std::cell::RefCell;
|
|
|
|
//!
|
|
|
|
//! struct Graph {
|
2015-02-16 07:41:33 -06:00
|
|
|
//! edges: Vec<(i32, i32)>,
|
|
|
|
//! span_tree_cache: RefCell<Option<Vec<(i32, i32)>>>
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! impl Graph {
|
2015-02-16 07:41:33 -06:00
|
|
|
//! fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> {
|
2014-05-18 23:47:51 -05:00
|
|
|
//! // 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() {
|
2014-08-18 19:52:38 -05:00
|
|
|
//! return cache.as_ref().unwrap().clone();
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! 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
|
2015-05-08 10:12:29 -05:00
|
|
|
//! // recursive borrow would cause a dynamic thread panic.
|
2014-05-18 23:47:51 -05:00
|
|
|
//! // This is the major hazard of using `RefCell`.
|
|
|
|
//! self.minimum_spanning_tree()
|
|
|
|
//! }
|
2015-02-16 07:41:33 -06:00
|
|
|
//! # fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] }
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
2015-06-04 18:45:43 -05:00
|
|
|
//! ## Mutating implementations of `Clone`
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-01-23 14:02:05 -06:00
|
|
|
//! 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<T>` maintains its reference counts within a
|
|
|
|
//! `Cell<T>`.
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! use std::cell::Cell;
|
|
|
|
//!
|
|
|
|
//! struct Rc<T> {
|
|
|
|
//! ptr: *mut RcBox<T>
|
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! struct RcBox<T> {
|
|
|
|
//! value: T,
|
2015-02-16 07:41:33 -06:00
|
|
|
//! refcount: Cell<usize>
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! impl<T> Clone for Rc<T> {
|
|
|
|
//! fn clone(&self) -> Rc<T> {
|
|
|
|
//! unsafe {
|
|
|
|
//! (*self.ptr).refcount.set((*self.ptr).refcount.get() + 1);
|
|
|
|
//! Rc { ptr: self.ptr }
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
2013-03-24 20:59:04 -05:00
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 17:03:01 -06:00
|
|
|
|
2014-03-05 00:19:14 -06:00
|
|
|
use clone::Clone;
|
2015-05-24 03:38:59 -05:00
|
|
|
use cmp::{PartialEq, Eq};
|
2014-11-14 13:22:42 -06:00
|
|
|
use default::Default;
|
2015-04-23 05:53:54 -05:00
|
|
|
use marker::{Copy, Send, Sync, Sized};
|
2015-05-28 16:00:52 -05:00
|
|
|
use ops::{Deref, DerefMut, Drop, FnOnce};
|
2014-11-28 10:57:41 -06:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::{None, Some};
|
2013-11-21 23:30:34 -06:00
|
|
|
|
2014-03-26 18:01:11 -05:00
|
|
|
/// A mutable memory location that admits only `Copy` data.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
2015-02-09 05:56:24 -06:00
|
|
|
/// See the [module-level documentation](index.html) for more.
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2013-12-11 16:54:27 -06:00
|
|
|
pub struct Cell<T> {
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
value: UnsafeCell<T>,
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
|
2014-03-26 18:01:11 -05:00
|
|
|
impl<T:Copy> Cell<T> {
|
2013-12-11 16:54:27 -06:00
|
|
|
/// Creates a new `Cell` containing the given value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2015-05-27 03:18:36 -05:00
|
|
|
pub const fn new(value: T) -> Cell<T> {
|
2013-12-11 16:54:27 -06:00
|
|
|
Cell {
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
value: UnsafeCell::new(value),
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a copy of the contained value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
///
|
|
|
|
/// let five = c.get();
|
|
|
|
/// ```
|
2013-12-11 16:54:27 -06:00
|
|
|
#[inline]
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2013-12-11 16:54:27 -06:00
|
|
|
pub fn get(&self) -> T {
|
2014-03-10 16:55:37 -05:00
|
|
|
unsafe{ *self.value.get() }
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets the contained value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
///
|
|
|
|
/// c.set(10);
|
|
|
|
/// ```
|
2013-12-11 16:54:27 -06:00
|
|
|
#[inline]
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2013-12-11 16:54:27 -06:00
|
|
|
pub fn set(&self, value: T) {
|
|
|
|
unsafe {
|
2014-03-10 16:55:37 -05:00
|
|
|
*self.value.get() = value;
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-21 14:59:21 -05:00
|
|
|
|
2015-05-22 19:32:02 -05:00
|
|
|
/// Returns a reference to the underlying `UnsafeCell`.
|
2014-10-21 14:59:21 -05:00
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// # Unsafety
|
2014-10-21 14:59:21 -05:00
|
|
|
///
|
|
|
|
/// This function is `unsafe` because `UnsafeCell`'s field is public.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
2015-06-10 15:33:52 -05:00
|
|
|
/// # #![feature(as_unsafe_cell)]
|
2015-01-23 14:02:05 -06:00
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
///
|
|
|
|
/// let uc = unsafe { c.as_unsafe_cell() };
|
|
|
|
/// ```
|
2014-10-21 14:59:21 -05:00
|
|
|
#[inline]
|
2015-06-09 13:18:03 -05:00
|
|
|
#[unstable(feature = "as_unsafe_cell")]
|
2014-10-21 14:59:21 -05:00
|
|
|
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
|
|
|
|
&self.value
|
|
|
|
}
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 12:58:22 -06:00
|
|
|
unsafe impl<T> Send for Cell<T> where T: Send {}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-03-26 18:01:11 -05:00
|
|
|
impl<T:Copy> Clone for Cell<T> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-01-22 13:03:02 -06:00
|
|
|
fn clone(&self) -> Cell<T> {
|
|
|
|
Cell::new(self.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 13:22:42 -06:00
|
|
|
impl<T:Default + Copy> Default for Cell<T> {
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-14 13:22:42 -06:00
|
|
|
fn default() -> Cell<T> {
|
|
|
|
Cell::new(Default::default())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-05-29 19:45:07 -05:00
|
|
|
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-02-24 19:38:40 -06:00
|
|
|
fn eq(&self, other: &Cell<T>) -> bool {
|
|
|
|
self.get() == other.get()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-24 03:38:59 -05:00
|
|
|
#[stable(feature = "cell_eq", since = "1.2.0")]
|
|
|
|
impl<T:Eq + Copy> Eq for Cell<T> {}
|
|
|
|
|
2013-11-21 23:30:34 -06:00
|
|
|
/// A mutable memory location with dynamically checked borrow rules
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
2015-02-09 05:56:24 -06:00
|
|
|
/// See the [module-level documentation](index.html) for more.
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
pub struct RefCell<T: ?Sized> {
|
2014-04-09 00:54:06 -05:00
|
|
|
borrow: Cell<BorrowFlag>,
|
2015-04-23 05:53:54 -05:00
|
|
|
value: UnsafeCell<T>,
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
|
2015-02-01 20:53:47 -06:00
|
|
|
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
|
2015-05-24 03:38:59 -05:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
2015-06-09 13:18:03 -05:00
|
|
|
#[unstable(feature = "borrow_state")]
|
2015-02-01 20:53:47 -06:00
|
|
|
pub enum BorrowState {
|
|
|
|
/// The cell is currently being read, there is at least one active `borrow`.
|
|
|
|
Reading,
|
|
|
|
/// The cell is currently being written to, there is an active `borrow_mut`.
|
|
|
|
Writing,
|
|
|
|
/// There are no outstanding borrows on this cell.
|
|
|
|
Unused,
|
|
|
|
}
|
|
|
|
|
2013-11-21 23:30:34 -06:00
|
|
|
// Values [1, MAX-1] represent the number of `Ref` active
|
2015-02-16 07:41:33 -06:00
|
|
|
// (will not outgrow its range since `usize` is the size of the address space)
|
|
|
|
type BorrowFlag = usize;
|
2014-10-06 18:14:00 -05:00
|
|
|
const UNUSED: BorrowFlag = 0;
|
2015-04-01 05:36:37 -05:00
|
|
|
const WRITING: BorrowFlag = !0;
|
2013-11-21 23:30:34 -06:00
|
|
|
|
|
|
|
impl<T> RefCell<T> {
|
2015-01-23 14:02:05 -06:00
|
|
|
/// Creates a new `RefCell` containing `value`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2015-05-27 03:18:36 -05:00
|
|
|
pub const fn new(value: T) -> RefCell<T> {
|
2013-11-21 23:30:34 -06:00
|
|
|
RefCell {
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
value: UnsafeCell::new(value),
|
2014-04-09 00:54:06 -05:00
|
|
|
borrow: Cell::new(UNUSED),
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Consumes the `RefCell`, returning the wrapped value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// let five = c.into_inner();
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-20 11:23:43 -06:00
|
|
|
pub fn into_inner(self) -> T {
|
2014-11-20 04:20:10 -06:00
|
|
|
// 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!`.
|
2014-04-26 20:25:20 -05:00
|
|
|
debug_assert!(self.borrow.get() == UNUSED);
|
2014-11-20 11:23:43 -06:00
|
|
|
unsafe { self.value.into_inner() }
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
2015-04-23 05:53:54 -05:00
|
|
|
}
|
2013-11-21 23:30:34 -06:00
|
|
|
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<T: ?Sized> RefCell<T> {
|
2015-02-01 20:53:47 -06:00
|
|
|
/// Query the current state of this `RefCell`
|
|
|
|
///
|
|
|
|
/// The returned value can be dispatched on to determine if a call to
|
|
|
|
/// `borrow` or `borrow_mut` would succeed.
|
2015-06-09 13:18:03 -05:00
|
|
|
#[unstable(feature = "borrow_state")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2015-02-01 20:53:47 -06:00
|
|
|
pub fn borrow_state(&self) -> BorrowState {
|
|
|
|
match self.borrow.get() {
|
|
|
|
WRITING => BorrowState::Writing,
|
|
|
|
UNUSED => BorrowState::Unused,
|
|
|
|
_ => BorrowState::Reading,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-21 23:30:34 -06:00
|
|
|
/// Immutably borrows the wrapped value.
|
|
|
|
///
|
2015-02-01 20:53:47 -06:00
|
|
|
/// The borrow lasts until the returned `Ref` exits scope. Multiple
|
|
|
|
/// immutable borrows can be taken out at the same time.
|
2013-11-21 23:30:34 -06:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2013-11-21 23:30:34 -06:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if the value is currently mutably borrowed.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// let borrowed_five = c.borrow();
|
|
|
|
/// let borrowed_five2 = c.borrow();
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// An example of panic:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
2015-02-17 17:10:25 -06:00
|
|
|
/// use std::thread;
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
2015-02-17 17:10:25 -06:00
|
|
|
/// let result = thread::spawn(move || {
|
2015-01-23 14:02:05 -06:00
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
/// let m = c.borrow_mut();
|
|
|
|
///
|
|
|
|
/// let b = c.borrow(); // this causes a panic
|
|
|
|
/// }).join();
|
|
|
|
///
|
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
|
2015-02-01 20:53:47 -06:00
|
|
|
match BorrowRef::new(&self.borrow) {
|
|
|
|
Some(b) => Ref {
|
|
|
|
_value: unsafe { &*self.value.get() },
|
|
|
|
_borrow: b,
|
|
|
|
},
|
|
|
|
None => panic!("RefCell<T> already mutably borrowed"),
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Mutably borrows the wrapped value.
|
|
|
|
///
|
2015-02-01 20:53:47 -06:00
|
|
|
/// The borrow lasts until the returned `RefMut` exits scope. The value
|
|
|
|
/// cannot be borrowed while this borrow is active.
|
2013-11-21 23:30:34 -06:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2013-11-21 23:30:34 -06:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if the value is currently borrowed.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// let borrowed_five = c.borrow_mut();
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// An example of panic:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
2015-02-17 17:10:25 -06:00
|
|
|
/// use std::thread;
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
2015-02-17 17:10:25 -06:00
|
|
|
/// let result = thread::spawn(move || {
|
2015-01-23 14:02:05 -06:00
|
|
|
/// let c = RefCell::new(5);
|
2015-04-26 16:16:49 -05:00
|
|
|
/// let m = c.borrow();
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// let b = c.borrow_mut(); // this causes a panic
|
|
|
|
/// }).join();
|
|
|
|
///
|
|
|
|
/// assert!(result.is_err());
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
|
2015-02-01 20:53:47 -06:00
|
|
|
match BorrowRefMut::new(&self.borrow) {
|
|
|
|
Some(b) => RefMut {
|
|
|
|
_value: unsafe { &mut *self.value.get() },
|
|
|
|
_borrow: b,
|
|
|
|
},
|
|
|
|
None => panic!("RefCell<T> already borrowed"),
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-21 14:59:21 -05:00
|
|
|
|
2015-05-22 19:32:02 -05:00
|
|
|
/// Returns a reference to the underlying `UnsafeCell`.
|
2014-10-21 14:59:21 -05:00
|
|
|
///
|
|
|
|
/// This can be used to circumvent `RefCell`'s safety checks.
|
|
|
|
///
|
|
|
|
/// This function is `unsafe` because `UnsafeCell`'s field is public.
|
|
|
|
#[inline]
|
2015-06-09 13:18:03 -05:00
|
|
|
#[unstable(feature = "as_unsafe_cell")]
|
2014-10-21 14:59:21 -05:00
|
|
|
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
|
|
|
|
&self.value
|
|
|
|
}
|
2013-12-11 16:54:27 -06:00
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
|
2014-12-29 12:58:22 -06:00
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2013-11-21 23:30:34 -06:00
|
|
|
impl<T: Clone> Clone for RefCell<T> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
fn clone(&self) -> RefCell<T> {
|
2014-03-28 12:29:55 -05:00
|
|
|
RefCell::new(self.borrow().clone())
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 13:22:42 -06:00
|
|
|
impl<T:Default> Default for RefCell<T> {
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-14 13:22:42 -06:00
|
|
|
fn default() -> RefCell<T> {
|
|
|
|
RefCell::new(Default::default())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
fn eq(&self, other: &RefCell<T>) -> bool {
|
2014-03-20 17:04:55 -05:00
|
|
|
*self.borrow() == *other.borrow()
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-24 03:38:59 -05:00
|
|
|
#[stable(feature = "cell_eq", since = "1.2.0")]
|
|
|
|
impl<T: ?Sized + Eq> Eq for RefCell<T> {}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
struct BorrowRef<'b> {
|
|
|
|
_borrow: &'b Cell<BorrowFlag>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'b> BorrowRef<'b> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-28 18:20:14 -06:00
|
|
|
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
|
|
|
|
match borrow.get() {
|
|
|
|
WRITING => None,
|
|
|
|
b => {
|
|
|
|
borrow.set(b + 1);
|
|
|
|
Some(BorrowRef { _borrow: borrow })
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2014-08-27 20:46:52 -05:00
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
impl<'b> Drop for BorrowRef<'b> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
fn drop(&mut self) {
|
2014-11-28 18:20:14 -06:00
|
|
|
let borrow = self._borrow.get();
|
2014-04-26 20:25:20 -05:00
|
|
|
debug_assert!(borrow != WRITING && borrow != UNUSED);
|
2014-11-28 18:20:14 -06:00
|
|
|
self._borrow.set(borrow - 1);
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
impl<'b> Clone for BorrowRef<'b> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-28 18:20:14 -06:00
|
|
|
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.
|
2015-01-23 14:02:05 -06:00
|
|
|
/// A wrapper type for an immutably borrowed value from a `RefCell<T>`.
|
|
|
|
///
|
2015-02-09 05:56:24 -06:00
|
|
|
/// See the [module-level documentation](index.html) for more.
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
pub struct Ref<'b, T: ?Sized + 'b> {
|
2014-11-28 18:20:14 -06:00
|
|
|
// FIXME #12808: strange name to try to avoid interfering with
|
|
|
|
// field accesses of the contained type via Deref
|
|
|
|
_value: &'b T,
|
|
|
|
_borrow: BorrowRef<'b>,
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<'b, T: ?Sized> Deref for Ref<'b, T> {
|
2015-01-01 13:53:20 -06:00
|
|
|
type Target = T;
|
|
|
|
|
2014-02-26 15:07:23 -06:00
|
|
|
#[inline]
|
|
|
|
fn deref<'a>(&'a self) -> &'a T {
|
2014-11-28 18:20:14 -06:00
|
|
|
self._value
|
2014-02-26 15:07:23 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-13 09:21:32 -05:00
|
|
|
/// Copies a `Ref`.
|
2014-05-13 19:29:30 -05:00
|
|
|
///
|
|
|
|
/// 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`.
|
2015-05-28 15:58:04 -05:00
|
|
|
#[deprecated(since = "1.2.0", reason = "moved to a `Ref::clone` associated function")]
|
2015-01-22 20:22:03 -06:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 20:40:19 -06:00
|
|
|
reason = "likely to be moved to a method, pending language changes")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-28 18:20:14 -06:00
|
|
|
pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
2015-05-28 15:58:04 -05:00
|
|
|
Ref::clone(orig)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'b, T: ?Sized> Ref<'b, T> {
|
|
|
|
/// Copies a `Ref`.
|
|
|
|
///
|
|
|
|
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
|
|
|
///
|
2015-06-09 13:18:03 -05:00
|
|
|
/// This is an associated function that needs to be used as
|
|
|
|
/// `Ref::clone(...)`. A `Clone` implementation or a method would interfere
|
|
|
|
/// with the widespread use of `r.borrow().clone()` to clone the contents of
|
|
|
|
/// a `RefCell`.
|
2015-05-28 15:58:04 -05:00
|
|
|
#[unstable(feature = "cell_extras",
|
|
|
|
reason = "likely to be moved to a method, pending language changes")]
|
|
|
|
#[inline]
|
|
|
|
pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
|
|
|
Ref {
|
|
|
|
_value: orig._value,
|
|
|
|
_borrow: orig._borrow.clone(),
|
|
|
|
}
|
2014-05-13 19:29:30 -05:00
|
|
|
}
|
2015-05-28 16:00:52 -05:00
|
|
|
|
|
|
|
/// Make a new `Ref` for a component of the borrowed data.
|
|
|
|
///
|
|
|
|
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
|
|
|
///
|
|
|
|
/// This is an associated function that needs to be used as `Ref::map(...)`.
|
2015-06-09 13:18:03 -05:00
|
|
|
/// A method would interfere with methods of the same name on the contents
|
|
|
|
/// of a `RefCell` used through `Deref`.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #![feature(cell_extras)]
|
|
|
|
/// use std::cell::{RefCell, Ref};
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new((5, 'b'));
|
|
|
|
/// let b1: Ref<(u32, char)> = c.borrow();
|
|
|
|
/// let b2: Ref<u32> = Ref::map(b1, |t| &t.0);
|
|
|
|
/// assert_eq!(*b2, 5)
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cell_extras", reason = "recently added")]
|
|
|
|
#[inline]
|
|
|
|
pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
|
|
|
|
where F: FnOnce(&T) -> &U
|
|
|
|
{
|
|
|
|
Ref {
|
|
|
|
_value: f(orig._value),
|
|
|
|
_borrow: orig._borrow,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-09 13:18:03 -05:00
|
|
|
/// Make a new `Ref` for a optional component of the borrowed data, e.g. an
|
|
|
|
/// enum variant.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
|
|
|
///
|
2015-06-09 13:18:03 -05:00
|
|
|
/// This is an associated function that needs to be used as
|
|
|
|
/// `Ref::filter_map(...)`. A method would interfere with methods of the
|
|
|
|
/// same name on the contents of a `RefCell` used through `Deref`.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #![feature(cell_extras)]
|
|
|
|
/// use std::cell::{RefCell, Ref};
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(Ok(5));
|
|
|
|
/// let b1: Ref<Result<u32, ()>> = c.borrow();
|
|
|
|
/// let b2: Ref<u32> = Ref::filter_map(b1, |o| o.as_ref().ok()).unwrap();
|
|
|
|
/// assert_eq!(*b2, 5)
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cell_extras", reason = "recently added")]
|
|
|
|
#[inline]
|
|
|
|
pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Option<Ref<'b, U>>
|
|
|
|
where F: FnOnce(&T) -> Option<&U>
|
|
|
|
{
|
|
|
|
f(orig._value).map(move |new| Ref {
|
|
|
|
_value: new,
|
|
|
|
_borrow: orig._borrow,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'b, T: ?Sized> RefMut<'b, T> {
|
2015-06-09 13:18:03 -05:00
|
|
|
/// Make a new `RefMut` for a component of the borrowed data, e.g. an enum
|
|
|
|
/// variant.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// The `RefCell` is already mutably borrowed, so this cannot fail.
|
|
|
|
///
|
2015-06-09 13:18:03 -05:00
|
|
|
/// This is an associated function that needs to be used as
|
|
|
|
/// `RefMut::map(...)`. A method would interfere with methods of the same
|
|
|
|
/// name on the contents of a `RefCell` used through `Deref`.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #![feature(cell_extras)]
|
|
|
|
/// use std::cell::{RefCell, RefMut};
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new((5, 'b'));
|
|
|
|
/// {
|
|
|
|
/// let b1: RefMut<(u32, char)> = c.borrow_mut();
|
|
|
|
/// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0);
|
|
|
|
/// assert_eq!(*b2, 5);
|
|
|
|
/// *b2 = 42;
|
|
|
|
/// }
|
|
|
|
/// assert_eq!(*c.borrow(), (42, 'b'));
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cell_extras", reason = "recently added")]
|
|
|
|
#[inline]
|
|
|
|
pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
|
|
|
|
where F: FnOnce(&mut T) -> &mut U
|
|
|
|
{
|
|
|
|
RefMut {
|
|
|
|
_value: f(orig._value),
|
|
|
|
_borrow: orig._borrow,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-09 13:18:03 -05:00
|
|
|
/// Make a new `RefMut` for a optional component of the borrowed data, e.g.
|
|
|
|
/// an enum variant.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// The `RefCell` is already mutably borrowed, so this cannot fail.
|
|
|
|
///
|
2015-06-09 13:18:03 -05:00
|
|
|
/// This is an associated function that needs to be used as
|
|
|
|
/// `RefMut::filter_map(...)`. A method would interfere with methods of the
|
|
|
|
/// same name on the contents of a `RefCell` used through `Deref`.
|
2015-05-28 16:00:52 -05:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #![feature(cell_extras)]
|
|
|
|
/// use std::cell::{RefCell, RefMut};
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(Ok(5));
|
|
|
|
/// {
|
|
|
|
/// let b1: RefMut<Result<u32, ()>> = c.borrow_mut();
|
2015-06-09 13:18:03 -05:00
|
|
|
/// let mut b2: RefMut<u32> = RefMut::filter_map(b1, |o| {
|
|
|
|
/// o.as_mut().ok()
|
|
|
|
/// }).unwrap();
|
2015-05-28 16:00:52 -05:00
|
|
|
/// assert_eq!(*b2, 5);
|
|
|
|
/// *b2 = 42;
|
|
|
|
/// }
|
|
|
|
/// assert_eq!(*c.borrow(), Ok(42));
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cell_extras", reason = "recently added")]
|
|
|
|
#[inline]
|
|
|
|
pub fn filter_map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> Option<RefMut<'b, U>>
|
|
|
|
where F: FnOnce(&mut T) -> Option<&mut U>
|
|
|
|
{
|
|
|
|
let RefMut { _value, _borrow } = orig;
|
|
|
|
f(_value).map(move |new| RefMut {
|
|
|
|
_value: new,
|
|
|
|
_borrow: _borrow,
|
|
|
|
})
|
2014-05-13 19:29:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
struct BorrowRefMut<'b> {
|
|
|
|
_borrow: &'b Cell<BorrowFlag>,
|
2014-08-27 20:46:52 -05:00
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
impl<'b> Drop for BorrowRefMut<'b> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2013-11-21 23:30:34 -06:00
|
|
|
fn drop(&mut self) {
|
2014-11-28 18:20:14 -06:00
|
|
|
let borrow = self._borrow.get();
|
2014-04-26 20:25:20 -05:00
|
|
|
debug_assert!(borrow == WRITING);
|
2014-11-28 18:20:14 -06:00
|
|
|
self._borrow.set(UNUSED);
|
2013-11-21 23:30:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
impl<'b> BorrowRefMut<'b> {
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2014-11-28 18:20:14 -06:00
|
|
|
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
|
|
|
|
match borrow.get() {
|
|
|
|
UNUSED => {
|
|
|
|
borrow.set(WRITING);
|
|
|
|
Some(BorrowRefMut { _borrow: borrow })
|
|
|
|
},
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 14:02:05 -06:00
|
|
|
/// A wrapper type for a mutably borrowed value from a `RefCell<T>`.
|
|
|
|
///
|
2015-02-09 05:56:24 -06:00
|
|
|
/// See the [module-level documentation](index.html) for more.
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
pub struct RefMut<'b, T: ?Sized + 'b> {
|
2014-11-28 18:20:14 -06:00
|
|
|
// 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>,
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
|
2015-01-01 13:53:20 -06:00
|
|
|
type Target = T;
|
|
|
|
|
2014-02-26 15:07:23 -06:00
|
|
|
#[inline]
|
|
|
|
fn deref<'a>(&'a self) -> &'a T {
|
2014-11-28 18:20:14 -06:00
|
|
|
self._value
|
2014-02-26 15:07:23 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
|
2014-02-26 15:07:23 -06:00
|
|
|
#[inline]
|
|
|
|
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
|
2014-11-28 18:20:14 -06:00
|
|
|
self._value
|
2014-02-26 15:07:23 -06:00
|
|
|
}
|
|
|
|
}
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
|
|
|
|
/// The core primitive for interior mutability in Rust.
|
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the
|
|
|
|
/// wrapped type. Types with an `UnsafeCell<T>` field are considered to have an 'unsafe interior'.
|
|
|
|
/// The `UnsafeCell<T>` 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.
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data.
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// # Examples
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// ```
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
/// use std::cell::UnsafeCell;
|
2015-01-16 01:18:39 -06:00
|
|
|
/// use std::marker::Sync;
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
///
|
|
|
|
/// struct NotThreadSafe<T> {
|
|
|
|
/// value: UnsafeCell<T>,
|
|
|
|
/// }
|
2015-01-16 01:18:39 -06:00
|
|
|
///
|
|
|
|
/// unsafe impl<T> Sync for NotThreadSafe<T> {}
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
/// ```
|
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// **NOTE:** `UnsafeCell<T>`'s fields are public to allow static initializers. It is not
|
|
|
|
/// recommended to access its fields directly, `get` should be used instead.
|
2015-05-09 14:50:28 -05:00
|
|
|
#[lang = "unsafe_cell"]
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
pub struct UnsafeCell<T: ?Sized> {
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
/// Wrapped value
|
|
|
|
///
|
|
|
|
/// This field should not be accessed directly, it is made public for static
|
|
|
|
/// initializers.
|
2015-05-30 04:15:19 -05:00
|
|
|
#[deprecated(since = "1.2.0", reason = "use `get` to access the wrapped \
|
|
|
|
value or `new` to initialize `UnsafeCell` in statics")]
|
2015-01-22 20:22:03 -06:00
|
|
|
#[unstable(feature = "core")]
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
pub value: T,
|
|
|
|
}
|
|
|
|
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
|
2015-01-26 16:10:24 -06:00
|
|
|
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
impl<T> UnsafeCell<T> {
|
2015-04-13 09:21:32 -05:00
|
|
|
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
/// value.
|
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// All access to the inner value through methods is `unsafe`, and it is highly discouraged to
|
|
|
|
/// access the fields directly.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::UnsafeCell;
|
|
|
|
///
|
|
|
|
/// let uc = UnsafeCell::new(5);
|
|
|
|
/// ```
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-03-18 18:44:37 -05:00
|
|
|
#[inline]
|
2015-05-27 03:18:36 -05:00
|
|
|
pub const fn new(value: T) -> UnsafeCell<T> {
|
2015-05-30 04:15:19 -05:00
|
|
|
#![allow(deprecated)]
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
UnsafeCell { value: value }
|
|
|
|
}
|
|
|
|
|
2015-04-23 05:53:54 -05:00
|
|
|
/// Unwraps the value.
|
|
|
|
///
|
|
|
|
/// # Unsafety
|
|
|
|
///
|
2015-05-22 19:32:02 -05:00
|
|
|
/// This function is unsafe because this thread or another thread may currently be
|
|
|
|
/// inspecting the inner value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::UnsafeCell;
|
|
|
|
///
|
|
|
|
/// let uc = UnsafeCell::new(5);
|
|
|
|
///
|
2015-04-23 05:53:54 -05:00
|
|
|
/// let five = unsafe { uc.into_inner() };
|
2015-01-23 14:02:05 -06:00
|
|
|
/// ```
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
#[inline]
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-05-30 04:15:19 -05:00
|
|
|
pub unsafe fn into_inner(self) -> T {
|
|
|
|
#![allow(deprecated)]
|
|
|
|
self.value
|
|
|
|
}
|
2015-04-23 05:53:54 -05:00
|
|
|
}
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
|
2015-04-23 05:53:54 -05:00
|
|
|
impl<T: ?Sized> UnsafeCell<T> {
|
|
|
|
/// Gets a mutable pointer to the wrapped value.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::UnsafeCell;
|
|
|
|
///
|
|
|
|
/// let uc = UnsafeCell::new(5);
|
|
|
|
///
|
2015-04-23 05:53:54 -05:00
|
|
|
/// let five = uc.get();
|
2015-01-23 14:02:05 -06:00
|
|
|
/// ```
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
#[inline]
|
2015-01-23 23:48:20 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-04-23 05:53:54 -05:00
|
|
|
pub fn get(&self) -> *mut T {
|
|
|
|
// FIXME(#23542) Replace with type ascription.
|
|
|
|
#![allow(trivial_casts)]
|
2015-05-30 04:15:19 -05:00
|
|
|
#![allow(deprecated)]
|
2015-04-23 05:53:54 -05:00
|
|
|
&self.value as *const T as *mut T
|
|
|
|
}
|
std: Stabilize unit, bool, ty, tuple, arc, any
This commit applies stability attributes to the contents of these modules,
summarized here:
* The `unit` and `bool` modules have become #[unstable] as they are purely meant
for documentation purposes and are candidates for removal.
* The `ty` module has been deprecated, and the inner `Unsafe` type has been
renamed to `UnsafeCell` and moved to the `cell` module. The `marker1` field
has been removed as the compiler now always infers `UnsafeCell` to be
invariant. The `new` method i stable, but the `value` field, `get` and
`unwrap` methods are all unstable.
* The `tuple` module has its name as stable, the naming of the `TupleN` traits
as stable while the methods are all #[unstable]. The other impls in the module
have appropriate stability for the corresponding trait.
* The `arc` module has received the exact same treatment as the `rc` module
previously did.
* The `any` module has its name as stable. The `Any` trait is also stable, with
a new private supertrait which now contains the `get_type_id` method. This is
to make the method a private implementation detail rather than a public-facing
detail.
The two extension traits in the module are marked #[unstable] as they will not
be necessary with DST. The `is` method is #[stable], the as_{mut,ref} methods
have been renamed to downcast_{mut,ref} and are #[unstable].
The extension trait `BoxAny` has been clarified as to why it is unstable as it
will not be necessary with DST.
This is a breaking change because the `marker1` field was removed from the
`UnsafeCell` type. To deal with this change, you can simply delete the field and
only specify the value of the `data` field in static initializers.
[breaking-change]
2014-07-23 21:10:12 -05:00
|
|
|
}
|