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
|
|
|
//!
|
2015-07-17 17:50:42 -05:00
|
|
|
//! * Introducing mutability 'inside' of something immutable
|
2014-05-18 23:47:51 -05:00
|
|
|
//! * 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
|
|
|
//!
|
2015-07-17 17:50:42 -05:00
|
|
|
//! ## Introducing mutability 'inside' of something immutable
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2015-07-17 17:50:42 -05:00
|
|
|
//! Many shared smart pointer types, including `Rc<T>` and `Arc<T>`, provide containers that can be
|
2015-01-23 14:02:05 -06:00
|
|
|
//! cloned and shared between multiple parties. Because the contained values may be
|
2015-07-17 17:50:42 -05:00
|
|
|
//! multiply-aliased, they can only be borrowed with `&`, not `&mut`. Without cells it would be
|
|
|
|
//! impossible to mutate data inside of these smart pointers 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
|
2015-07-17 17:50:42 -05:00
|
|
|
//! scenarios. Consider using `RwLock<T>` or `Mutex<T>` if you need shared mutability in a
|
|
|
|
//! multi-threaded situation.
|
2015-01-21 11:43:34 -06:00
|
|
|
//!
|
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
|
|
|
//!
|
|
|
|
//! ```
|
2015-11-03 09:27:03 -06:00
|
|
|
//! # #![allow(dead_code)]
|
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
|
|
|
//!
|
|
|
|
//! ```
|
2016-08-22 02:37:08 -05:00
|
|
|
//! #![feature(core_intrinsics)]
|
|
|
|
//! #![feature(shared)]
|
2014-05-18 23:47:51 -05:00
|
|
|
//! use std::cell::Cell;
|
2016-08-22 02:37:08 -05:00
|
|
|
//! use std::ptr::Shared;
|
|
|
|
//! use std::intrinsics::abort;
|
|
|
|
//! use std::intrinsics::assume;
|
2014-05-18 23:47:51 -05:00
|
|
|
//!
|
2016-08-22 02:37:08 -05:00
|
|
|
//! struct Rc<T: ?Sized> {
|
|
|
|
//! ptr: Shared<RcBox<T>>
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//!
|
2016-08-22 02:37:08 -05:00
|
|
|
//! struct RcBox<T: ?Sized> {
|
|
|
|
//! strong: Cell<usize>,
|
|
|
|
//! refcount: Cell<usize>,
|
2014-05-18 23:47:51 -05:00
|
|
|
//! value: T,
|
|
|
|
//! }
|
|
|
|
//!
|
2016-08-22 02:37:08 -05:00
|
|
|
//! impl<T: ?Sized> Clone for Rc<T> {
|
2014-05-18 23:47:51 -05:00
|
|
|
//! fn clone(&self) -> Rc<T> {
|
2016-08-22 02:37:08 -05:00
|
|
|
//! self.inc_strong();
|
|
|
|
//! Rc { ptr: self.ptr }
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! trait RcBoxPtr<T: ?Sized> {
|
|
|
|
//!
|
|
|
|
//! fn inner(&self) -> &RcBox<T>;
|
|
|
|
//!
|
|
|
|
//! fn strong(&self) -> usize {
|
|
|
|
//! self.inner().strong.get()
|
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! fn inc_strong(&self) {
|
|
|
|
//! self.inner()
|
|
|
|
//! .strong
|
|
|
|
//! .set(self.strong()
|
|
|
|
//! .checked_add(1)
|
|
|
|
//! .unwrap_or_else(|| unsafe { abort() }));
|
2014-05-18 23:47:51 -05:00
|
|
|
//! }
|
|
|
|
//! }
|
2016-08-22 02:37:08 -05:00
|
|
|
//!
|
|
|
|
//! impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
|
|
|
|
//! fn inner(&self) -> &RcBox<T> {
|
|
|
|
//! unsafe {
|
|
|
|
//! assume(!(*(&self.ptr as *const _ as *const *const ())).is_null());
|
|
|
|
//! &(**self.ptr)
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! }
|
2014-05-18 23:47:51 -05:00
|
|
|
//! ```
|
|
|
|
//!
|
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
|
|
|
|
2016-08-22 05:02:28 -05:00
|
|
|
use cmp::Ordering;
|
2016-08-06 12:48:59 -05:00
|
|
|
use fmt::{self, Debug, Display};
|
2016-08-22 05:02:28 -05:00
|
|
|
use marker::{PhantomData, Unsize};
|
|
|
|
use ops::{Deref, DerefMut, CoerceUnsized};
|
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
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
2015-07-27 09:50:19 -05:00
|
|
|
/// #![feature(as_unsafe_cell)]
|
|
|
|
///
|
2015-01-23 14:02:05 -06:00
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
///
|
2016-03-28 08:29:15 -05:00
|
|
|
/// let uc = c.as_unsafe_cell();
|
2015-01-23 14:02:05 -06:00
|
|
|
/// ```
|
2014-10-21 14:59:21 -05:00
|
|
|
#[inline]
|
2015-08-12 19:23:48 -05:00
|
|
|
#[unstable(feature = "as_unsafe_cell", issue = "27708")]
|
2016-08-11 16:08:24 -05:00
|
|
|
#[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")]
|
2016-03-28 08:29:15 -05:00
|
|
|
pub fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
|
2014-10-21 14:59:21 -05:00
|
|
|
&self.value
|
|
|
|
}
|
2016-05-05 17:39:25 -05:00
|
|
|
|
2016-08-11 16:08:24 -05:00
|
|
|
/// Returns a raw pointer to the underlying data in this cell.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let c = Cell::new(5);
|
|
|
|
///
|
|
|
|
/// let ptr = c.as_ptr();
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
|
|
|
pub fn as_ptr(&self) -> *mut T {
|
|
|
|
self.value.get()
|
|
|
|
}
|
|
|
|
|
2016-05-05 17:39:25 -05:00
|
|
|
/// Returns a mutable reference to the underlying data.
|
|
|
|
///
|
|
|
|
/// This call borrows `Cell` mutably (at compile-time) which guarantees
|
|
|
|
/// that we possess the only reference.
|
2016-07-09 08:01:15 -05:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::Cell;
|
|
|
|
///
|
|
|
|
/// let mut c = Cell::new(5);
|
|
|
|
/// *c.get_mut() += 1;
|
|
|
|
///
|
|
|
|
/// assert_eq!(c.get(), 6);
|
|
|
|
/// ```
|
2016-05-05 17:39:25 -05:00
|
|
|
#[inline]
|
2016-06-28 10:56:56 -05:00
|
|
|
#[stable(feature = "cell_get_mut", since = "1.11.0")]
|
2016-05-05 17:39:25 -05:00
|
|
|
pub fn get_mut(&mut self) -> &mut T {
|
|
|
|
unsafe {
|
|
|
|
&mut *self.value.get()
|
|
|
|
}
|
|
|
|
}
|
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 {}
|
|
|
|
|
2016-02-29 21:03:23 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<T> !Sync for Cell<T> {}
|
|
|
|
|
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-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> {}
|
|
|
|
|
2016-05-01 03:26:39 -05:00
|
|
|
#[stable(feature = "cell_ord", since = "1.10.0")]
|
2016-05-01 03:07:47 -05:00
|
|
|
impl<T:PartialOrd + Copy> PartialOrd for Cell<T> {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &Cell<T>) -> Option<Ordering> {
|
|
|
|
self.get().partial_cmp(&other.get())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn lt(&self, other: &Cell<T>) -> bool {
|
|
|
|
self.get() < other.get()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn le(&self, other: &Cell<T>) -> bool {
|
|
|
|
self.get() <= other.get()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn gt(&self, other: &Cell<T>) -> bool {
|
|
|
|
self.get() > other.get()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ge(&self, other: &Cell<T>) -> bool {
|
|
|
|
self.get() >= other.get()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-01 03:26:39 -05:00
|
|
|
#[stable(feature = "cell_ord", since = "1.10.0")]
|
2016-05-01 03:07:47 -05:00
|
|
|
impl<T:Ord + Copy> Ord for Cell<T> {
|
|
|
|
#[inline]
|
|
|
|
fn cmp(&self, other: &Cell<T>) -> Ordering {
|
|
|
|
self.get().cmp(&other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 14:57:19 -05:00
|
|
|
#[stable(feature = "cell_from", since = "1.12.0")]
|
|
|
|
impl<T: Copy> From<T> for Cell<T> {
|
|
|
|
fn from(t: T) -> Cell<T> {
|
|
|
|
Cell::new(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-12 17:10:34 -05:00
|
|
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
|
|
|
impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> 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-08-12 19:23:48 -05:00
|
|
|
#[unstable(feature = "borrow_state", issue = "27733")]
|
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,
|
|
|
|
}
|
|
|
|
|
2016-08-06 12:48:59 -05:00
|
|
|
/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow).
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
pub struct BorrowError<'a, T: 'a + ?Sized> {
|
|
|
|
marker: PhantomData<&'a RefCell<T>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
impl<'a, T: ?Sized> Debug for BorrowError<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("BorrowError").finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
impl<'a, T: ?Sized> Display for BorrowError<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
Display::fmt("already mutably borrowed", f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut).
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
pub struct BorrowMutError<'a, T: 'a + ?Sized> {
|
|
|
|
marker: PhantomData<&'a RefCell<T>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
impl<'a, T: ?Sized> Debug for BorrowMutError<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("BorrowMutError").finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
impl<'a, T: ?Sized> Display for BorrowMutError<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
Display::fmt("already borrowed", f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
2016-07-09 08:01:15 -05:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(borrow_state)]
|
|
|
|
///
|
|
|
|
/// use std::cell::{BorrowState, RefCell};
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// match c.borrow_state() {
|
|
|
|
/// BorrowState::Writing => println!("Cannot be borrowed"),
|
|
|
|
/// BorrowState::Reading => println!("Cannot be borrowed mutably"),
|
|
|
|
/// BorrowState::Unused => println!("Can be borrowed (mutably as well)"),
|
|
|
|
/// }
|
|
|
|
/// ```
|
2015-08-12 19:23:48 -05:00
|
|
|
#[unstable(feature = "borrow_state", issue = "27733")]
|
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
|
|
|
///
|
2016-08-06 12:48:59 -05:00
|
|
|
/// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
|
|
|
|
/// [`try_borrow`](#method.try_borrow).
|
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]
|
2015-09-03 04:49:08 -05:00
|
|
|
pub fn borrow(&self) -> Ref<T> {
|
2016-08-06 12:48:59 -05:00
|
|
|
self.try_borrow().expect("already mutably borrowed")
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Immutably borrows the wrapped value, returning an error if the value is currently mutably
|
|
|
|
/// borrowed.
|
|
|
|
///
|
|
|
|
/// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
|
|
|
|
/// taken out at the same time.
|
|
|
|
///
|
|
|
|
/// This is the non-panicking variant of [`borrow`](#method.borrow).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(try_borrow)]
|
|
|
|
///
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// {
|
|
|
|
/// let m = c.borrow_mut();
|
|
|
|
/// assert!(c.try_borrow().is_err());
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// {
|
|
|
|
/// let m = c.borrow();
|
|
|
|
/// assert!(c.try_borrow().is_ok());
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
#[inline]
|
|
|
|
pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> {
|
2015-02-01 20:53:47 -06:00
|
|
|
match BorrowRef::new(&self.borrow) {
|
2016-08-06 12:48:59 -05:00
|
|
|
Some(b) => Ok(Ref {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: unsafe { &*self.value.get() },
|
|
|
|
borrow: b,
|
2016-08-06 12:48:59 -05:00
|
|
|
}),
|
|
|
|
None => Err(BorrowError { marker: PhantomData }),
|
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
|
|
|
///
|
2016-08-06 12:48:59 -05:00
|
|
|
/// Panics if the value is currently borrowed. For a non-panicking variant, use
|
|
|
|
/// [`try_borrow_mut`](#method.try_borrow_mut).
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
2016-01-25 16:07:55 -06:00
|
|
|
/// *c.borrow_mut() = 7;
|
|
|
|
///
|
|
|
|
/// assert_eq!(*c.borrow(), 7);
|
2015-01-23 14:02:05 -06:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// 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]
|
2015-09-03 04:49:08 -05:00
|
|
|
pub fn borrow_mut(&self) -> RefMut<T> {
|
2016-08-06 12:48:59 -05:00
|
|
|
self.try_borrow_mut().expect("already borrowed")
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
|
|
|
|
///
|
|
|
|
/// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed
|
|
|
|
/// while this borrow is active.
|
|
|
|
///
|
|
|
|
/// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(try_borrow)]
|
|
|
|
///
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// {
|
|
|
|
/// let m = c.borrow();
|
|
|
|
/// assert!(c.try_borrow_mut().is_err());
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// assert!(c.try_borrow_mut().is_ok());
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "try_borrow", issue = "35070")]
|
|
|
|
#[inline]
|
|
|
|
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> {
|
2015-02-01 20:53:47 -06:00
|
|
|
match BorrowRefMut::new(&self.borrow) {
|
2016-08-06 12:48:59 -05:00
|
|
|
Some(b) => Ok(RefMut {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: unsafe { &mut *self.value.get() },
|
|
|
|
borrow: b,
|
2016-08-06 12:48:59 -05:00
|
|
|
}),
|
|
|
|
None => Err(BorrowMutError { marker: PhantomData }),
|
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.
|
2016-07-09 08:01:15 -05:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(as_unsafe_cell)]
|
|
|
|
///
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
/// let c = unsafe { c.as_unsafe_cell() };
|
|
|
|
/// ```
|
2014-10-21 14:59:21 -05:00
|
|
|
#[inline]
|
2015-08-12 19:23:48 -05:00
|
|
|
#[unstable(feature = "as_unsafe_cell", issue = "27708")]
|
2016-08-11 16:08:24 -05:00
|
|
|
#[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")]
|
2015-09-03 04:49:08 -05:00
|
|
|
pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
|
2014-10-21 14:59:21 -05:00
|
|
|
&self.value
|
|
|
|
}
|
2016-05-05 17:39:25 -05:00
|
|
|
|
2016-08-11 16:08:24 -05:00
|
|
|
/// Returns a raw pointer to the underlying data in this cell.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let c = RefCell::new(5);
|
|
|
|
///
|
|
|
|
/// let ptr = c.as_ptr();
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
|
|
|
pub fn as_ptr(&self) -> *mut T {
|
|
|
|
self.value.get()
|
|
|
|
}
|
|
|
|
|
2016-05-05 17:39:25 -05:00
|
|
|
/// Returns a mutable reference to the underlying data.
|
|
|
|
///
|
|
|
|
/// This call borrows `RefCell` mutably (at compile-time) so there is no
|
|
|
|
/// need for dynamic checks.
|
2016-07-09 08:01:15 -05:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::cell::RefCell;
|
|
|
|
///
|
|
|
|
/// let mut c = RefCell::new(5);
|
|
|
|
/// *c.get_mut() += 1;
|
|
|
|
///
|
|
|
|
/// assert_eq!(c, RefCell::new(6));
|
|
|
|
/// ```
|
2016-05-05 17:39:25 -05:00
|
|
|
#[inline]
|
2016-06-28 10:56:56 -05:00
|
|
|
#[stable(feature = "cell_get_mut", since = "1.11.0")]
|
2016-05-05 17:39:25 -05:00
|
|
|
pub fn get_mut(&mut self) -> &mut T {
|
|
|
|
unsafe {
|
|
|
|
&mut *self.value.get()
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
2016-02-29 21:03:23 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<T: ?Sized> !Sync for RefCell<T> {}
|
|
|
|
|
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-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> {}
|
|
|
|
|
2016-05-01 03:26:39 -05:00
|
|
|
#[stable(feature = "cell_ord", since = "1.10.0")]
|
2016-05-01 03:07:47 -05:00
|
|
|
impl<T: ?Sized + PartialOrd> PartialOrd for RefCell<T> {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &RefCell<T>) -> Option<Ordering> {
|
|
|
|
self.borrow().partial_cmp(&*other.borrow())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn lt(&self, other: &RefCell<T>) -> bool {
|
|
|
|
*self.borrow() < *other.borrow()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn le(&self, other: &RefCell<T>) -> bool {
|
|
|
|
*self.borrow() <= *other.borrow()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn gt(&self, other: &RefCell<T>) -> bool {
|
|
|
|
*self.borrow() > *other.borrow()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ge(&self, other: &RefCell<T>) -> bool {
|
|
|
|
*self.borrow() >= *other.borrow()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-01 03:26:39 -05:00
|
|
|
#[stable(feature = "cell_ord", since = "1.10.0")]
|
2016-05-01 03:07:47 -05:00
|
|
|
impl<T: ?Sized + Ord> Ord for RefCell<T> {
|
|
|
|
#[inline]
|
|
|
|
fn cmp(&self, other: &RefCell<T>) -> Ordering {
|
|
|
|
self.borrow().cmp(&*other.borrow())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 14:57:19 -05:00
|
|
|
#[stable(feature = "cell_from", since = "1.12.0")]
|
|
|
|
impl<T> From<T> for RefCell<T> {
|
|
|
|
fn from(t: T) -> RefCell<T> {
|
|
|
|
RefCell::new(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-12 17:10:34 -05:00
|
|
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
|
|
|
impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
struct BorrowRef<'b> {
|
2016-04-05 04:02:49 -05:00
|
|
|
borrow: &'b Cell<BorrowFlag>,
|
2014-11-28 18:20:14 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2016-04-05 04:02:49 -05:00
|
|
|
Some(BorrowRef { borrow: borrow })
|
2014-11-28 18:20:14 -06:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
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) {
|
2016-04-05 04:02:49 -05:00
|
|
|
let borrow = self.borrow.get();
|
2014-04-26 20:25:20 -05:00
|
|
|
debug_assert!(borrow != WRITING && borrow != UNUSED);
|
2016-04-05 04:02:49 -05: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.
|
2016-04-05 04:02:49 -05:00
|
|
|
let borrow = self.borrow.get();
|
2016-05-30 02:53:09 -05:00
|
|
|
debug_assert!(borrow != UNUSED);
|
|
|
|
// Prevent the borrow counter from overflowing.
|
|
|
|
assert!(borrow != WRITING);
|
2016-04-05 04:02:49 -05:00
|
|
|
self.borrow.set(borrow + 1);
|
|
|
|
BorrowRef { borrow: self.borrow }
|
2014-11-28 18:20:14 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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> {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: &'b T,
|
|
|
|
borrow: BorrowRef<'b>,
|
2014-11-28 18:20:14 -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> 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]
|
2015-09-03 04:49:08 -05:00
|
|
|
fn deref(&self) -> &T {
|
2016-04-05 04:02:49 -05:00
|
|
|
self.value
|
2014-02-26 15:07:23 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-28 15:58:04 -05:00
|
|
|
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",
|
2015-08-12 19:23:48 -05:00
|
|
|
reason = "likely to be moved to a method, pending language changes",
|
|
|
|
issue = "27746")]
|
2015-05-28 15:58:04 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
|
|
|
Ref {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: orig.value,
|
|
|
|
borrow: orig.borrow.clone(),
|
2015-05-28 15:58:04 -05:00
|
|
|
}
|
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
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// 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)
|
|
|
|
/// ```
|
std: Stabilize APIs for the 1.8 release
This commit is the result of the FCPs ending for the 1.8 release cycle for both
the libs and the lang suteams. The full list of changes are:
Stabilized
* `braced_empty_structs`
* `augmented_assignments`
* `str::encode_utf16` - renamed from `utf16_units`
* `str::EncodeUtf16` - renamed from `Utf16Units`
* `Ref::map`
* `RefMut::map`
* `ptr::drop_in_place`
* `time::Instant`
* `time::SystemTime`
* `{Instant,SystemTime}::now`
* `{Instant,SystemTime}::duration_since` - renamed from `duration_from_earlier`
* `{Instant,SystemTime}::elapsed`
* Various `Add`/`Sub` impls for `Time` and `SystemTime`
* `SystemTimeError`
* `SystemTimeError::duration`
* Various impls for `SystemTimeError`
* `UNIX_EPOCH`
* `ops::{Add,Sub,Mul,Div,Rem,BitAnd,BitOr,BitXor,Shl,Shr}Assign`
Deprecated
* Scoped TLS (the `scoped_thread_local!` macro)
* `Ref::filter_map`
* `RefMut::filter_map`
* `RwLockReadGuard::map`
* `RwLockWriteGuard::map`
* `Condvar::wait_timeout_with`
Closes #27714
Closes #27715
Closes #27746
Closes #27748
Closes #27908
Closes #29866
2016-02-25 17:52:29 -06:00
|
|
|
#[stable(feature = "cell_map", since = "1.8.0")]
|
2015-05-28 16:00:52 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
|
|
|
|
where F: FnOnce(&T) -> &U
|
|
|
|
{
|
|
|
|
Ref {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: f(orig.value),
|
|
|
|
borrow: orig.borrow,
|
2015-05-28 16:00:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-31 09:11:59 -05:00
|
|
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
|
|
|
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
|
|
|
|
|
2015-05-28 16:00:52 -05:00
|
|
|
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
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// 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'));
|
|
|
|
/// ```
|
std: Stabilize APIs for the 1.8 release
This commit is the result of the FCPs ending for the 1.8 release cycle for both
the libs and the lang suteams. The full list of changes are:
Stabilized
* `braced_empty_structs`
* `augmented_assignments`
* `str::encode_utf16` - renamed from `utf16_units`
* `str::EncodeUtf16` - renamed from `Utf16Units`
* `Ref::map`
* `RefMut::map`
* `ptr::drop_in_place`
* `time::Instant`
* `time::SystemTime`
* `{Instant,SystemTime}::now`
* `{Instant,SystemTime}::duration_since` - renamed from `duration_from_earlier`
* `{Instant,SystemTime}::elapsed`
* Various `Add`/`Sub` impls for `Time` and `SystemTime`
* `SystemTimeError`
* `SystemTimeError::duration`
* Various impls for `SystemTimeError`
* `UNIX_EPOCH`
* `ops::{Add,Sub,Mul,Div,Rem,BitAnd,BitOr,BitXor,Shl,Shr}Assign`
Deprecated
* Scoped TLS (the `scoped_thread_local!` macro)
* `Ref::filter_map`
* `RefMut::filter_map`
* `RwLockReadGuard::map`
* `RwLockWriteGuard::map`
* `Condvar::wait_timeout_with`
Closes #27714
Closes #27715
Closes #27746
Closes #27748
Closes #27908
Closes #29866
2016-02-25 17:52:29 -06:00
|
|
|
#[stable(feature = "cell_map", since = "1.8.0")]
|
2015-05-28 16:00:52 -05:00
|
|
|
#[inline]
|
|
|
|
pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
|
|
|
|
where F: FnOnce(&mut T) -> &mut U
|
|
|
|
{
|
|
|
|
RefMut {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: f(orig.value),
|
|
|
|
borrow: orig.borrow,
|
2015-05-28 16:00:52 -05:00
|
|
|
}
|
|
|
|
}
|
2014-05-13 19:29:30 -05:00
|
|
|
}
|
|
|
|
|
2014-11-28 18:20:14 -06:00
|
|
|
struct BorrowRefMut<'b> {
|
2016-04-05 04:02:49 -05:00
|
|
|
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) {
|
2016-04-05 04:02:49 -05:00
|
|
|
let borrow = self.borrow.get();
|
2014-04-26 20:25:20 -05:00
|
|
|
debug_assert!(borrow == WRITING);
|
2016-04-05 04:02:49 -05: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);
|
2016-04-05 04:02:49 -05:00
|
|
|
Some(BorrowRefMut { borrow: borrow })
|
2014-11-28 18:20:14 -06:00
|
|
|
},
|
|
|
|
_ => 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> {
|
2016-04-05 04:02:49 -05:00
|
|
|
value: &'b mut T,
|
|
|
|
borrow: BorrowRefMut<'b>,
|
2014-11-28 18:20:14 -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> 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]
|
2015-09-03 04:49:08 -05:00
|
|
|
fn deref(&self) -> &T {
|
2016-04-05 04:02:49 -05: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]
|
2015-09-03 04:49:08 -05:00
|
|
|
fn deref_mut(&mut self) -> &mut T {
|
2016-04-05 04:02:49 -05: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
|
|
|
|
2016-03-31 09:11:59 -05:00
|
|
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
|
|
|
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, 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
|
|
|
/// 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
|
|
|
///
|
2016-06-28 01:23:37 -05:00
|
|
|
/// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or
|
|
|
|
/// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`,
|
|
|
|
/// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way
|
|
|
|
/// to do this. When `UnsafeCell<T>` is immutably aliased, it is still safe to obtain a mutable
|
|
|
|
/// reference to its interior and/or to mutate it. However, it is up to the abstraction designer
|
|
|
|
/// to ensure that no two mutable references obtained this way are active at the same time, and
|
|
|
|
/// that there are no active mutable references or mutations when an immutable reference is obtained
|
|
|
|
/// from the cell. This is often done via runtime checks.
|
|
|
|
///
|
|
|
|
/// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell<T>` is
|
|
|
|
/// okay (provided you enforce the invariants some other way); it is still undefined behavior
|
|
|
|
/// to have multiple `&mut UnsafeCell<T>` aliases.
|
|
|
|
///
|
|
|
|
///
|
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
|
|
|
///
|
2015-11-03 09:27:03 -06:00
|
|
|
/// # #[allow(dead_code)]
|
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-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> {
|
2015-08-11 19:27:05 -05:00
|
|
|
value: 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-11-16 10:54:28 -06:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
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-10-21 13:15:43 -05:00
|
|
|
/// All access to the inner value through methods is `unsafe`.
|
2015-01-23 14:02:05 -06:00
|
|
|
///
|
|
|
|
/// # 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> {
|
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.
|
|
|
|
///
|
2015-10-23 10:42:14 -05:00
|
|
|
/// # Safety
|
2015-04-23 05:53:54 -05:00
|
|
|
///
|
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 {
|
|
|
|
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
|
|
|
///
|
2016-06-28 01:23:37 -05:00
|
|
|
/// This can be cast to a pointer of any kind.
|
|
|
|
/// Ensure that the access is unique when casting to
|
|
|
|
/// `&mut T`, and ensure that there are no mutations or mutable
|
|
|
|
/// aliases going on when casting to `&T`
|
|
|
|
///
|
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 {
|
|
|
|
&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
|
|
|
}
|
2016-04-15 10:53:43 -05:00
|
|
|
|
|
|
|
#[stable(feature = "unsafe_cell_default", since = "1.9.0")]
|
|
|
|
impl<T: Default> Default for UnsafeCell<T> {
|
|
|
|
fn default() -> UnsafeCell<T> {
|
|
|
|
UnsafeCell::new(Default::default())
|
|
|
|
}
|
|
|
|
}
|
2016-08-05 14:57:19 -05:00
|
|
|
|
|
|
|
#[stable(feature = "cell_from", since = "1.12.0")]
|
|
|
|
impl<T> From<T> for UnsafeCell<T> {
|
|
|
|
fn from(t: T) -> UnsafeCell<T> {
|
|
|
|
UnsafeCell::new(t)
|
|
|
|
}
|
|
|
|
}
|
2016-08-12 17:10:34 -05:00
|
|
|
|
|
|
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
|
|
|
impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) {
|
|
|
|
let _: UnsafeCell<&Send> = a;
|
|
|
|
let _: Cell<&Send> = b;
|
|
|
|
let _: RefCell<&Send> = c;
|
|
|
|
}
|