rust/src/liballoc/rc.rs

2091 lines
65 KiB
Rust
Raw Normal View History

//! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference
//! Counted'.
2014-08-04 10:48:39 +00:00
//!
2016-12-06 02:33:03 +00:00
//! The type [`Rc<T>`][`Rc`] provides shared ownership of a value of type `T`,
//! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new
2019-10-17 17:37:05 +00:00
//! pointer to the same allocation in the heap. When the last [`Rc`] pointer to a
2019-10-17 17:51:42 +00:00
//! given allocation is destroyed, the value stored in that allocation (often
//! referred to as "inner value") is also dropped.
2014-08-04 10:48:39 +00:00
//!
//! Shared references in Rust disallow mutation by default, and [`Rc`]
//! is no exception: you cannot generally obtain a mutable reference to
//! something inside an [`Rc`]. If you need mutability, put a [`Cell`]
//! or [`RefCell`] inside the [`Rc`]; see [an example of mutability
//! inside an Rc][mutability].
2014-08-04 10:48:39 +00:00
//!
2016-12-06 02:33:03 +00:00
//! [`Rc`] uses non-atomic reference counting. This means that overhead is very
//! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`]
2016-09-17 18:22:04 +00:00
//! does not implement [`Send`][send]. As a result, the Rust compiler
2016-12-06 02:33:03 +00:00
//! will check *at compile time* that you are not sending [`Rc`]s between
2016-09-17 18:22:04 +00:00
//! threads. If you need multi-threaded, atomic reference counting, use
//! [`sync::Arc`][arc].
//!
//! The [`downgrade`][downgrade] method can be used to create a non-owning
2016-12-06 02:33:03 +00:00
//! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d
2019-10-17 17:51:42 +00:00
//! to an [`Rc`], but this will return [`None`] if the value stored in the allocation has
//! already been dropped. In other words, `Weak` pointers do not keep the value
//! inside the allocation alive; however, they *do* keep the allocation
2019-10-19 11:47:32 +00:00
//! (the backing store for the inner value) alive.
2016-09-17 18:22:04 +00:00
//!
2016-12-06 02:33:03 +00:00
//! A cycle between [`Rc`] pointers will never be deallocated. For this reason,
//! [`Weak`] is used to break cycles. For example, a tree could have strong
//! [`Rc`] pointers from parent nodes to children, and [`Weak`] pointers from
2016-09-17 18:22:04 +00:00
//! children back to their parents.
//!
2016-12-06 02:33:03 +00:00
//! `Rc<T>` automatically dereferences to `T` (via the [`Deref`] trait),
//! so you can call `T`'s methods on a value of type [`Rc<T>`][`Rc`]. To avoid name
2018-11-21 00:49:47 +00:00
//! clashes with `T`'s methods, the methods of [`Rc<T>`][`Rc`] itself are associated
//! functions, called using function-like syntax:
2016-09-17 18:22:04 +00:00
//!
//! ```
2016-09-27 19:45:29 +00:00
//! use std::rc::Rc;
//! let my_rc = Rc::new(());
//!
2016-09-17 18:22:04 +00:00
//! Rc::downgrade(&my_rc);
//! ```
//!
2019-10-19 11:47:32 +00:00
//! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the inner value may have
//! already been dropped.
2016-09-17 18:22:04 +00:00
//!
//! # Cloning references
//!
2019-10-17 17:51:42 +00:00
//! Creating a new reference to the same allocation as an existing reference counted pointer
//! is done using the `Clone` trait implemented for [`Rc<T>`][`Rc`] and [`Weak<T>`][`Weak`].
//!
//! ```
//! use std::rc::Rc;
//! let foo = Rc::new(vec![1.0, 2.0, 3.0]);
//! // The two syntaxes below are equivalent.
//! let a = foo.clone();
//! let b = Rc::clone(&foo);
//! // a and b both point to the same memory location as foo.
//! ```
//!
//! The `Rc::clone(&from)` syntax is the most idiomatic because it conveys more explicitly
//! the meaning of the code. In the example above, this syntax makes it easier to see that
//! this code is creating a new reference rather than copying the whole content of foo.
//!
2014-08-04 10:48:39 +00:00
//! # Examples
//!
std: Stabilize the std::hash module This commit aims to prepare the `std::hash` module for alpha by formalizing its current interface whileholding off on adding `#[stable]` to the new APIs. The current usage with the `HashMap` and `HashSet` types is also reconciled by separating out composable parts of the design. The primary goal of this slight redesign is to separate the concepts of a hasher's state from a hashing algorithm itself. The primary change of this commit is to separate the `Hasher` trait into a `Hasher` and a `HashState` trait. Conceptually the old `Hasher` trait was actually just a factory for various states, but hashing had very little control over how these states were used. Additionally the old `Hasher` trait was actually fairly unrelated to hashing. This commit redesigns the existing `Hasher` trait to match what the notion of a `Hasher` normally implies with the following definition: trait Hasher { type Output; fn reset(&mut self); fn finish(&self) -> Output; } This `Hasher` trait emphasizes that hashing algorithms may produce outputs other than a `u64`, so the output type is made generic. Other than that, however, very little is assumed about a particular hasher. It is left up to implementors to provide specific methods or trait implementations to feed data into a hasher. The corresponding `Hash` trait becomes: trait Hash<H: Hasher> { fn hash(&self, &mut H); } The old default of `SipState` was removed from this trait as it's not something that we're willing to stabilize until the end of time, but the type parameter is always required to implement `Hasher`. Note that the type parameter `H` remains on the trait to enable multidispatch for specialization of hashing for particular hashers. Note that `Writer` is not mentioned in either of `Hash` or `Hasher`, it is simply used as part `derive` and the implementations for all primitive types. With these definitions, the old `Hasher` trait is realized as a new `HashState` trait in the `collections::hash_state` module as an unstable addition for now. The current definition looks like: trait HashState { type Hasher: Hasher; fn hasher(&self) -> Hasher; } The purpose of this trait is to emphasize that the one piece of functionality for implementors is that new instances of `Hasher` can be created. This conceptually represents the two keys from which more instances of a `SipHasher` can be created, and a `HashState` is what's stored in a `HashMap`, not a `Hasher`. Implementors of custom hash algorithms should implement the `Hasher` trait, and only hash algorithms intended for use in hash maps need to implement or worry about the `HashState` trait. The entire module and `HashState` infrastructure remains `#[unstable]` due to it being recently redesigned, but some other stability decision made for the `std::hash` module are: * The `Writer` trait remains `#[experimental]` as it's intended to be replaced with an `io::Writer` (more details soon). * The top-level `hash` function is `#[unstable]` as it is intended to be generic over the hashing algorithm instead of hardwired to `SipHasher` * The inner `sip` module is now private as its one export, `SipHasher` is reexported in the `hash` module. And finally, a few changes were made to the default parameters on `HashMap`. * The `RandomSipHasher` default type parameter was renamed to `RandomState`. This renaming emphasizes that it is not a hasher, but rather just state to generate hashers. It also moves away from the name "sip" as it may not always be implemented as `SipHasher`. This type lives in the `std::collections::hash_map` module as `#[unstable]` * The associated `Hasher` type of `RandomState` is creatively called... `Hasher`! This concrete structure lives next to `RandomState` as an implemenation of the "default hashing algorithm" used for a `HashMap`. Under the hood this is currently implemented as `SipHasher`, but it draws an explicit interface for now and allows us to modify the implementation over time if necessary. There are many breaking changes outlined above, and as a result this commit is a: [breaking-change]
2014-12-09 20:37:23 +00:00
//! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`.
//! We want to have our `Gadget`s point to their `Owner`. We can't do this with
//! unique ownership, because more than one gadget may belong to the same
2016-12-06 02:33:03 +00:00
//! `Owner`. [`Rc`] allows us to share an `Owner` between multiple `Gadget`s,
std: Stabilize the std::hash module This commit aims to prepare the `std::hash` module for alpha by formalizing its current interface whileholding off on adding `#[stable]` to the new APIs. The current usage with the `HashMap` and `HashSet` types is also reconciled by separating out composable parts of the design. The primary goal of this slight redesign is to separate the concepts of a hasher's state from a hashing algorithm itself. The primary change of this commit is to separate the `Hasher` trait into a `Hasher` and a `HashState` trait. Conceptually the old `Hasher` trait was actually just a factory for various states, but hashing had very little control over how these states were used. Additionally the old `Hasher` trait was actually fairly unrelated to hashing. This commit redesigns the existing `Hasher` trait to match what the notion of a `Hasher` normally implies with the following definition: trait Hasher { type Output; fn reset(&mut self); fn finish(&self) -> Output; } This `Hasher` trait emphasizes that hashing algorithms may produce outputs other than a `u64`, so the output type is made generic. Other than that, however, very little is assumed about a particular hasher. It is left up to implementors to provide specific methods or trait implementations to feed data into a hasher. The corresponding `Hash` trait becomes: trait Hash<H: Hasher> { fn hash(&self, &mut H); } The old default of `SipState` was removed from this trait as it's not something that we're willing to stabilize until the end of time, but the type parameter is always required to implement `Hasher`. Note that the type parameter `H` remains on the trait to enable multidispatch for specialization of hashing for particular hashers. Note that `Writer` is not mentioned in either of `Hash` or `Hasher`, it is simply used as part `derive` and the implementations for all primitive types. With these definitions, the old `Hasher` trait is realized as a new `HashState` trait in the `collections::hash_state` module as an unstable addition for now. The current definition looks like: trait HashState { type Hasher: Hasher; fn hasher(&self) -> Hasher; } The purpose of this trait is to emphasize that the one piece of functionality for implementors is that new instances of `Hasher` can be created. This conceptually represents the two keys from which more instances of a `SipHasher` can be created, and a `HashState` is what's stored in a `HashMap`, not a `Hasher`. Implementors of custom hash algorithms should implement the `Hasher` trait, and only hash algorithms intended for use in hash maps need to implement or worry about the `HashState` trait. The entire module and `HashState` infrastructure remains `#[unstable]` due to it being recently redesigned, but some other stability decision made for the `std::hash` module are: * The `Writer` trait remains `#[experimental]` as it's intended to be replaced with an `io::Writer` (more details soon). * The top-level `hash` function is `#[unstable]` as it is intended to be generic over the hashing algorithm instead of hardwired to `SipHasher` * The inner `sip` module is now private as its one export, `SipHasher` is reexported in the `hash` module. And finally, a few changes were made to the default parameters on `HashMap`. * The `RandomSipHasher` default type parameter was renamed to `RandomState`. This renaming emphasizes that it is not a hasher, but rather just state to generate hashers. It also moves away from the name "sip" as it may not always be implemented as `SipHasher`. This type lives in the `std::collections::hash_map` module as `#[unstable]` * The associated `Hasher` type of `RandomState` is creatively called... `Hasher`! This concrete structure lives next to `RandomState` as an implemenation of the "default hashing algorithm" used for a `HashMap`. Under the hood this is currently implemented as `SipHasher`, but it draws an explicit interface for now and allows us to modify the implementation over time if necessary. There are many breaking changes outlined above, and as a result this commit is a: [breaking-change]
2014-12-09 20:37:23 +00:00
//! and have the `Owner` remain allocated as long as any `Gadget` points at it.
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! ```
2014-08-04 10:48:39 +00:00
//! use std::rc::Rc;
//!
//! struct Owner {
2016-09-17 18:22:04 +00:00
//! name: String,
2014-08-04 10:48:39 +00:00
//! // ...other fields
//! }
//!
//! struct Gadget {
//! id: i32,
2016-09-17 18:22:04 +00:00
//! owner: Rc<Owner>,
2014-08-04 10:48:39 +00:00
//! // ...other fields
//! }
//!
//! fn main() {
2016-09-17 18:22:04 +00:00
//! // Create a reference-counted `Owner`.
//! let gadget_owner: Rc<Owner> = Rc::new(
//! Owner {
//! name: "Gadget Man".to_string(),
//! }
2014-08-04 10:48:39 +00:00
//! );
//!
2016-09-17 18:22:04 +00:00
//! // Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>`
2019-10-17 17:37:05 +00:00
//! // gives us a new pointer to the same `Owner` allocation, incrementing
2016-09-17 18:22:04 +00:00
//! // the reference count in the process.
//! let gadget1 = Gadget {
//! id: 1,
//! owner: Rc::clone(&gadget_owner),
2016-09-17 18:22:04 +00:00
//! };
//! let gadget2 = Gadget {
//! id: 2,
//! owner: Rc::clone(&gadget_owner),
2016-09-17 18:22:04 +00:00
//! };
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! // Dispose of our local variable `gadget_owner`.
2014-08-04 10:48:39 +00:00
//! drop(gadget_owner);
//!
2016-09-17 18:22:04 +00:00
//! // Despite dropping `gadget_owner`, we're still able to print out the name
//! // of the `Owner` of the `Gadget`s. This is because we've only dropped a
//! // single `Rc<Owner>`, not the `Owner` it points to. As long as there are
2019-10-17 17:51:42 +00:00
//! // other `Rc<Owner>` pointing at the same `Owner` allocation, it will remain
//! // live. The field projection `gadget1.owner.name` works because
2016-09-17 18:22:04 +00:00
//! // `Rc<Owner>` automatically dereferences to `Owner`.
2014-08-04 10:48:39 +00:00
//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
//! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
//!
2016-09-17 18:22:04 +00:00
//! // At the end of the function, `gadget1` and `gadget2` are destroyed, and
//! // with them the last counted references to our `Owner`. Gadget Man now
//! // gets destroyed as well.
2014-08-04 10:48:39 +00:00
//! }
//! ```
//!
//! If our requirements change, and we also need to be able to traverse from
2016-12-06 02:33:03 +00:00
//! `Owner` to `Gadget`, we will run into problems. An [`Rc`] pointer from `Owner`
2019-10-17 17:37:05 +00:00
//! to `Gadget` introduces a cycle. This means that their
//! reference counts can never reach 0, and the allocation will never be destroyed:
//! a memory leak. In order to get around this, we can use [`Weak`]
2016-09-17 18:22:04 +00:00
//! pointers.
2014-08-04 10:48:39 +00:00
//!
//! Rust actually makes it somewhat difficult to produce this loop in the first
2016-09-17 18:22:04 +00:00
//! place. In order to end up with two values that point at each other, one of
2016-12-06 02:33:03 +00:00
//! them needs to be mutable. This is difficult because [`Rc`] enforces
2016-09-17 18:22:04 +00:00
//! memory safety by only giving out shared references to the value it wraps,
//! and these don't allow direct mutation. We need to wrap the part of the
2016-12-06 02:33:03 +00:00
//! value we wish to mutate in a [`RefCell`], which provides *interior
//! mutability*: a method to achieve mutability through a shared reference.
2016-12-06 02:33:03 +00:00
//! [`RefCell`] enforces Rust's borrowing rules at runtime.
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! ```
2014-08-04 10:48:39 +00:00
//! use std::rc::Rc;
//! use std::rc::Weak;
//! use std::cell::RefCell;
//!
//! struct Owner {
//! name: String,
//! gadgets: RefCell<Vec<Weak<Gadget>>>,
2014-08-04 10:48:39 +00:00
//! // ...other fields
//! }
//!
//! struct Gadget {
//! id: i32,
//! owner: Rc<Owner>,
2014-08-04 10:48:39 +00:00
//! // ...other fields
//! }
//!
//! fn main() {
2016-09-17 18:22:04 +00:00
//! // Create a reference-counted `Owner`. Note that we've put the `Owner`'s
//! // vector of `Gadget`s inside a `RefCell` so that we can mutate it through
//! // a shared reference.
//! let gadget_owner: Rc<Owner> = Rc::new(
//! Owner {
//! name: "Gadget Man".to_string(),
2016-09-17 18:22:04 +00:00
//! gadgets: RefCell::new(vec![]),
//! }
2014-08-04 10:48:39 +00:00
//! );
//!
2016-09-17 18:22:04 +00:00
//! // Create `Gadget`s belonging to `gadget_owner`, as before.
//! let gadget1 = Rc::new(
//! Gadget {
//! id: 1,
//! owner: Rc::clone(&gadget_owner),
2016-09-17 18:22:04 +00:00
//! }
//! );
//! let gadget2 = Rc::new(
//! Gadget {
//! id: 2,
//! owner: Rc::clone(&gadget_owner),
2016-09-17 18:22:04 +00:00
//! }
//! );
//!
//! // Add the `Gadget`s to their `Owner`.
//! {
//! let mut gadgets = gadget_owner.gadgets.borrow_mut();
//! gadgets.push(Rc::downgrade(&gadget1));
//! gadgets.push(Rc::downgrade(&gadget2));
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! // `RefCell` dynamic borrow ends here.
//! }
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! // Iterate over our `Gadget`s, printing their details out.
//! for gadget_weak in gadget_owner.gadgets.borrow().iter() {
2014-08-04 10:48:39 +00:00
//!
2016-09-17 18:22:04 +00:00
//! // `gadget_weak` is a `Weak<Gadget>`. Since `Weak` pointers can't
2019-10-17 17:37:05 +00:00
//! // guarantee the allocation still exists, we need to call
2016-09-17 18:22:04 +00:00
//! // `upgrade`, which returns an `Option<Rc<Gadget>>`.
//! //
2019-10-17 17:37:05 +00:00
//! // In this case we know the allocation still exists, so we simply
2016-09-17 18:22:04 +00:00
//! // `unwrap` the `Option`. In a more complicated program, you might
//! // need graceful error handling for a `None` result.
//!
//! let gadget = gadget_weak.upgrade().unwrap();
2014-08-04 10:48:39 +00:00
//! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name);
//! }
//!
2016-09-17 18:22:04 +00:00
//! // At the end of the function, `gadget_owner`, `gadget1`, and `gadget2`
//! // are destroyed. There are now no strong (`Rc`) pointers to the
//! // gadgets, so they are destroyed. This zeroes the reference count on
//! // Gadget Man, so he gets destroyed as well.
2014-08-04 10:48:39 +00:00
//! }
//! ```
2016-12-06 02:33:03 +00:00
//!
//! [`Rc`]: struct.Rc.html
//! [`Weak`]: struct.Weak.html
//! [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
//! [`Cell`]: ../../std/cell/struct.Cell.html
//! [`RefCell`]: ../../std/cell/struct.RefCell.html
//! [send]: ../../std/marker/trait.Send.html
//! [arc]: ../../std/sync/struct.Arc.html
//! [`Deref`]: ../../std/ops/trait.Deref.html
//! [downgrade]: struct.Rc.html#method.downgrade
//! [upgrade]: struct.Weak.html#method.upgrade
//! [`None`]: ../../std/option/enum.Option.html#variant.None
//! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable
2015-01-24 05:48:20 +00:00
#![stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(test))]
2019-02-02 07:36:45 +00:00
use crate::boxed::Box;
#[cfg(test)]
use std::boxed::Box;
use core::any::Any;
use core::array::LengthAtMost32;
use core::borrow;
use core::cell::Cell;
use core::cmp::Ordering;
2019-12-22 22:42:04 +00:00
use core::convert::{From, TryFrom};
use core::fmt;
use core::hash::{Hash, Hasher};
use core::intrinsics::abort;
use core::iter;
2019-12-22 22:42:04 +00:00
use core::marker::{self, PhantomData, Unpin, Unsize};
use core::mem::{self, align_of, align_of_val, forget, size_of_val};
2019-12-22 22:42:04 +00:00
use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver};
use core::pin::Pin;
use core::ptr::{self, NonNull};
use core::slice::{self, from_raw_parts_mut};
use core::usize;
2019-12-22 22:42:04 +00:00
use crate::alloc::{box_free, handle_alloc_error, Alloc, Global, Layout};
use crate::string::String;
use crate::vec::Vec;
#[cfg(test)]
mod tests;
2015-04-16 02:36:47 +00:00
struct RcBox<T: ?Sized> {
strong: Cell<usize>,
weak: Cell<usize>,
value: T,
}
/// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference
/// Counted'.
///
2016-09-17 18:22:04 +00:00
/// See the [module-level documentation](./index.html) for more details.
///
2016-09-17 18:22:04 +00:00
/// The inherent methods of `Rc` are all associated functions, which means
/// that you have to call them as e.g., [`Rc::get_mut(&mut value)`][get_mut] instead of
2016-12-06 02:33:03 +00:00
/// `value.get_mut()`. This avoids conflicts with methods of the inner
2016-09-17 18:22:04 +00:00
/// type `T`.
2016-12-06 02:33:03 +00:00
///
/// [get_mut]: #method.get_mut
#[cfg_attr(not(test), lang = "rc")]
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> {
ptr: NonNull<RcBox<T>>,
phantom: PhantomData<RcBox<T>>,
2015-04-16 02:36:47 +00:00
}
2015-11-16 16:54:28 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> !marker::Send for Rc<T> {}
2015-11-16 16:54:28 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> !marker::Sync for Rc<T> {}
2015-11-16 16:54:28 +00:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
2015-04-16 02:36:47 +00:00
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {}
2019-06-19 02:46:19 +00:00
impl<T: ?Sized> Rc<T> {
fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
2019-12-22 22:42:04 +00:00
Self { ptr, phantom: PhantomData }
2019-06-19 02:46:19 +00:00
}
unsafe fn from_ptr(ptr: *mut RcBox<T>) -> Self {
Self::from_inner(NonNull::new_unchecked(ptr))
}
}
impl<T> Rc<T> {
2015-01-11 10:09:53 +00:00
/// Constructs a new `Rc<T>`.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
2015-01-11 10:09:53 +00:00
/// ```
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-11 10:09:53 +00:00
pub fn new(value: T) -> Rc<T> {
2019-06-19 02:46:19 +00:00
// There is an implicit weak pointer owned by all the strong
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
Self::from_inner(Box::into_raw_non_null(box RcBox {
strong: Cell::new(1),
weak: Cell::new(1),
value,
}))
2015-01-11 10:09:53 +00:00
}
/// Constructs a new `Rc` with uninitialized contents.
///
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let mut five = Rc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
///
/// five.assume_init()
/// };
///
/// assert_eq!(*five, 5)
/// ```
2019-08-05 15:45:30 +00:00
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
unsafe {
2019-12-22 22:42:04 +00:00
Rc::from_ptr(Rc::allocate_for_layout(Layout::new::<T>(), |mem| {
mem as *mut RcBox<mem::MaybeUninit<T>>
}))
}
}
/// Constructs a new `Rc` with uninitialized contents, with the memory
/// being filled with `0` bytes.
///
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
/// incorrect usage of this method.
///
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
///
/// use std::rc::Rc;
///
/// let zero = Rc::<u32>::new_zeroed();
/// let zero = unsafe { zero.assume_init() };
///
/// assert_eq!(*zero, 0)
/// ```
///
/// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
unsafe {
let mut uninit = Self::new_uninit();
ptr::write_bytes::<T>(Rc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
uninit
}
}
2018-12-18 18:25:02 +00:00
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
/// `value` will be pinned in memory and unable to be moved.
2018-12-18 02:14:07 +00:00
#[stable(feature = "pin", since = "1.33.0")]
2018-12-18 18:25:02 +00:00
pub fn pin(value: T) -> Pin<Rc<T>> {
2018-09-01 04:12:10 +00:00
unsafe { Pin::new_unchecked(Rc::new(value)) }
}
2019-10-17 17:51:42 +00:00
/// Returns the inner value, if the `Rc` has exactly one strong reference.
///
2016-09-27 19:45:29 +00:00
/// Otherwise, an [`Err`][result] is returned with the same `Rc` that was
/// passed in.
///
/// This will succeed even if there are outstanding weak references.
///
2016-09-27 19:45:29 +00:00
/// [result]: ../../std/result/enum.Result.html
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let x = Rc::new(3);
/// assert_eq!(Rc::try_unwrap(x), Ok(3));
///
/// let x = Rc::new(4);
/// let _y = Rc::clone(&x);
2016-09-17 18:22:04 +00:00
/// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
/// ```
#[inline]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_unique", since = "1.4.0")]
pub fn try_unwrap(this: Self) -> Result<T, Self> {
2016-12-14 21:02:00 +00:00
if Rc::strong_count(&this) == 1 {
unsafe {
let val = ptr::read(&*this); // copy the contained object
2017-11-21 14:33:45 +00:00
// Indicate to Weaks that they can't be promoted by decrementing
// the strong count, and then remove the implicit "strong weak"
// pointer while also handling drop logic by just crafting a
// fake Weak.
this.dec_strong();
let _weak = Weak { ptr: this.ptr };
forget(this);
Ok(val)
}
} else {
Err(this)
}
}
}
impl<T> Rc<[T]> {
/// Constructs a new reference-counted slice with uninitialized contents.
///
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let mut values = Rc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
///
/// values.assume_init()
/// };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
2019-08-05 15:45:30 +00:00
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
2019-12-22 22:42:04 +00:00
unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) }
}
}
impl<T> Rc<mem::MaybeUninit<T>> {
/// Converts to `Rc<T>`.
///
/// # Safety
///
/// As with [`MaybeUninit::assume_init`],
2019-10-19 11:47:32 +00:00
/// it is up to the caller to guarantee that the inner value
/// really is in an initialized state.
/// Calling this when the content is not yet fully initialized
/// causes immediate undefined behavior.
///
2019-07-06 21:30:32 +00:00
/// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
///
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let mut five = Rc::<u32>::new_uninit();
///
/// let five = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
///
/// five.assume_init()
/// };
///
/// assert_eq!(*five, 5)
/// ```
2019-08-05 15:45:30 +00:00
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub unsafe fn assume_init(self) -> Rc<T> {
2019-08-16 15:44:24 +00:00
Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
}
}
impl<T> Rc<[mem::MaybeUninit<T>]> {
/// Converts to `Rc<[T]>`.
///
/// # Safety
///
/// As with [`MaybeUninit::assume_init`],
2019-10-19 11:47:32 +00:00
/// it is up to the caller to guarantee that the inner value
/// really is in an initialized state.
/// Calling this when the content is not yet fully initialized
/// causes immediate undefined behavior.
///
2019-07-06 21:30:32 +00:00
/// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
///
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let mut values = Rc::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
/// // Deferred initialization:
/// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
/// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
/// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
///
/// values.assume_init()
/// };
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
2019-08-05 15:45:30 +00:00
#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub unsafe fn assume_init(self) -> Rc<[T]> {
2019-08-16 15:44:24 +00:00
Rc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
}
}
impl<T: ?Sized> Rc<T> {
2016-10-15 15:32:14 +00:00
/// Consumes the `Rc`, returning the wrapped pointer.
///
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
/// [`Rc::from_raw`][from_raw].
///
/// [from_raw]: struct.Rc.html#method.from_raw
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let x = Rc::new("hello".to_owned());
2016-10-15 15:32:14 +00:00
/// let x_ptr = Rc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello");
2016-10-15 15:32:14 +00:00
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
let ptr: *const T = &*this;
2016-10-15 15:32:14 +00:00
mem::forget(this);
ptr
}
/// Constructs an `Rc` from a raw pointer.
///
/// The raw pointer must have been previously returned by a call to a
/// [`Rc::into_raw`][into_raw].
///
/// This function is unsafe because improper use may lead to memory problems. For example, a
/// double-free may occur if the function is called twice on the same raw pointer.
///
/// [into_raw]: struct.Rc.html#method.into_raw
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let x = Rc::new("hello".to_owned());
2016-10-15 15:32:14 +00:00
/// let x_ptr = Rc::into_raw(x);
///
/// unsafe {
/// // Convert back to an `Rc` to prevent leak.
/// let x = Rc::from_raw(x_ptr);
/// assert_eq!(&*x, "hello");
2016-10-15 15:32:14 +00:00
///
/// // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.
2016-10-15 15:32:14 +00:00
/// }
///
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub unsafe fn from_raw(ptr: *const T) -> Self {
let offset = data_offset(ptr);
// Reverse the offset to find the original RcBox.
let fake_ptr = ptr as *mut RcBox<T>;
let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
2019-06-19 02:46:19 +00:00
Self::from_ptr(rc_ptr)
2016-10-15 15:32:14 +00:00
}
2015-01-11 10:09:53 +00:00
/// Consumes the `Rc`, returning the wrapped pointer as `NonNull<T>`.
///
/// # Examples
///
/// ```
/// #![feature(rc_into_raw_non_null)]
///
/// use std::rc::Rc;
///
/// let x = Rc::new("hello".to_owned());
/// let ptr = Rc::into_raw_non_null(x);
/// let deref = unsafe { ptr.as_ref() };
/// assert_eq!(deref, "hello");
/// ```
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
#[inline]
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
// safe because Rc guarantees its pointer is non-null
unsafe { NonNull::new_unchecked(Rc::into_raw(this) as *mut _) }
}
2019-10-17 17:37:05 +00:00
/// Creates a new [`Weak`][weak] pointer to this allocation.
2016-09-17 18:22:04 +00:00
///
/// [weak]: struct.Weak.html
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// let weak_five = Rc::downgrade(&five);
2015-04-16 02:36:47 +00:00
/// ```
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn downgrade(this: &Self) -> Weak<T> {
this.inc_weak();
// Make sure we do not create a dangling Weak
debug_assert!(!is_dangling(this.ptr));
Weak { ptr: this.ptr }
2015-04-16 02:36:47 +00:00
}
2019-10-17 17:37:05 +00:00
/// Gets the number of [`Weak`][weak] pointers to this allocation.
2016-09-17 18:22:04 +00:00
///
/// [weak]: struct.Weak.html
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// let _weak_five = Rc::downgrade(&five);
///
/// assert_eq!(1, Rc::weak_count(&five));
/// ```
#[inline]
#[stable(feature = "rc_counts", since = "1.15.0")]
2015-09-23 22:00:54 +00:00
pub fn weak_count(this: &Self) -> usize {
this.weak() - 1
}
2019-10-17 17:37:05 +00:00
/// Gets the number of strong (`Rc`) pointers to this allocation.
2016-09-17 18:22:04 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// let _also_five = Rc::clone(&five);
2016-09-17 18:22:04 +00:00
///
/// assert_eq!(2, Rc::strong_count(&five));
/// ```
#[inline]
#[stable(feature = "rc_counts", since = "1.15.0")]
2015-09-23 22:00:54 +00:00
pub fn strong_count(this: &Self) -> usize {
this.strong()
}
2019-02-09 22:16:58 +00:00
/// Returns `true` if there are no other `Rc` or [`Weak`][weak] pointers to
2019-10-17 17:37:05 +00:00
/// this allocation.
2016-09-17 18:22:04 +00:00
///
/// [weak]: struct.Weak.html
#[inline]
fn is_unique(this: &Self) -> bool {
Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1
}
2019-10-17 17:37:05 +00:00
/// Returns a mutable reference into the given `Rc`, if there are
/// no other `Rc` or [`Weak`][weak] pointers to the same allocation.
2016-09-17 18:22:04 +00:00
///
2016-12-06 02:33:03 +00:00
/// Returns [`None`] otherwise, because it is not safe to
2016-09-17 18:22:04 +00:00
/// mutate a shared value.
///
2016-09-17 18:22:04 +00:00
/// See also [`make_mut`][make_mut], which will [`clone`][clone]
2019-10-17 17:51:42 +00:00
/// the inner value when there are other pointers.
2016-09-17 18:22:04 +00:00
///
/// [weak]: struct.Weak.html
2016-12-06 02:33:03 +00:00
/// [`None`]: ../../std/option/enum.Option.html#variant.None
2016-09-17 18:22:04 +00:00
/// [make_mut]: struct.Rc.html#method.make_mut
/// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let mut x = Rc::new(3);
/// *Rc::get_mut(&mut x).unwrap() = 4;
/// assert_eq!(*x, 4);
///
/// let _y = Rc::clone(&x);
/// assert!(Rc::get_mut(&mut x).is_none());
/// ```
#[inline]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_unique", since = "1.4.0")]
pub fn get_mut(this: &mut Self) -> Option<&mut T> {
2019-12-22 22:42:04 +00:00
if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None }
}
2019-10-17 17:37:05 +00:00
/// Returns a mutable reference into the given `Rc`,
/// without any check.
///
/// See also [`get_mut`], which is safe and does appropriate checks.
///
/// [`get_mut`]: struct.Rc.html#method.get_mut
///
/// # Safety
///
2019-10-17 17:37:05 +00:00
/// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
/// for the duration of the returned borrow.
/// This is trivially the case if no such pointers exist,
/// for example immediately after `Rc::new`.
///
/// # Examples
///
/// ```
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let mut x = Rc::new(String::new());
/// unsafe {
/// Rc::get_mut_unchecked(&mut x).push_str("foo")
/// }
/// assert_eq!(*x, "foo");
/// ```
#[inline]
2019-08-05 15:45:30 +00:00
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
&mut this.ptr.as_mut().value
}
#[inline]
#[stable(feature = "ptr_eq", since = "1.17.0")]
2019-10-17 17:37:05 +00:00
/// Returns `true` if the two `Rc`s point to the same allocation
/// (in a vein similar to [`ptr::eq`]).
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// let same_five = Rc::clone(&five);
/// let other_five = Rc::new(5);
///
/// assert!(Rc::ptr_eq(&five, &same_five));
/// assert!(!Rc::ptr_eq(&five, &other_five));
/// ```
2019-10-17 17:37:05 +00:00
///
/// [`ptr::eq`]: ../../std/ptr/fn.eq.html
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
this.ptr.as_ptr() == other.ptr.as_ptr()
}
2015-04-16 02:36:47 +00:00
}
impl<T: Clone> Rc<T> {
2016-09-17 18:22:04 +00:00
/// Makes a mutable reference into the given `Rc`.
///
2019-10-17 17:37:05 +00:00
/// If there are other `Rc` pointers to the same allocation, then `make_mut` will
/// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also
/// referred to as clone-on-write.
///
2019-10-17 17:37:05 +00:00
/// If there are no other `Rc` pointers to this allocation, then [`Weak`]
/// pointers to this allocation will be disassociated.
2016-09-17 18:22:04 +00:00
///
/// See also [`get_mut`], which will fail rather than cloning.
///
/// [`Weak`]: struct.Weak.html
/// [`clone`]: ../../std/clone/trait.Clone.html#tymethod.clone
/// [`get_mut`]: struct.Rc.html#method.get_mut
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let mut data = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// *Rc::make_mut(&mut data) += 1; // Won't clone anything
/// let mut other_data = Rc::clone(&data); // Won't clone inner data
2016-09-17 18:22:04 +00:00
/// *Rc::make_mut(&mut data) += 1; // Clones inner data
/// *Rc::make_mut(&mut data) += 1; // Won't clone anything
/// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything
///
2019-10-17 17:37:05 +00:00
/// // Now `data` and `other_data` point to different allocations.
/// assert_eq!(*data, 8);
/// assert_eq!(*other_data, 12);
/// ```
///
2019-10-13 12:46:28 +00:00
/// [`Weak`] pointers will be disassociated:
///
/// ```
2019-05-25 02:10:17 +00:00
/// use std::rc::Rc;
///
/// let mut data = Rc::new(75);
/// let weak = Rc::downgrade(&data);
///
/// assert!(75 == *data);
/// assert!(75 == *weak.upgrade().unwrap());
///
/// *Rc::make_mut(&mut data) += 1;
///
/// assert!(76 == *data);
/// assert!(weak.upgrade().is_none());
/// ```
#[inline]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_unique", since = "1.4.0")]
pub fn make_mut(this: &mut Self) -> &mut T {
if Rc::strong_count(this) != 1 {
// Gotta clone the data, there are other Rcs
*this = Rc::new((**this).clone())
} else if Rc::weak_count(this) != 0 {
// Can just steal the data, all that's left is Weaks
unsafe {
let mut swap = Rc::new(ptr::read(&this.ptr.as_ref().value));
mem::swap(this, &mut swap);
swap.dec_strong();
// Remove implicit strong-weak ref (no need to craft a fake
// Weak here -- we know other Weaks can clean up for us)
swap.dec_weak();
forget(swap);
}
}
// This unsafety is ok because we're guaranteed that the pointer
// returned is the *only* pointer that will ever be returned to T. Our
// reference count is guaranteed to be 1 at this point, and we required
// the `Rc<T>` itself to be `mut`, so we're returning the only possible
2019-10-17 17:37:05 +00:00
// reference to the allocation.
2019-12-22 22:42:04 +00:00
unsafe { &mut this.ptr.as_mut().value }
}
}
2018-07-11 08:19:54 +00:00
impl Rc<dyn Any> {
#[inline]
2018-07-06 07:00:40 +00:00
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
/// use std::rc::Rc;
///
/// fn print_if_string(value: Rc<dyn Any>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// let my_string = "Hello World".to_string();
/// print_if_string(Rc::new(my_string));
/// print_if_string(Rc::new(0i8));
/// ```
2018-07-11 08:19:54 +00:00
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
if (*self).is::<T>() {
let ptr = self.ptr.cast::<RcBox<T>>();
forget(self);
2019-06-19 02:46:19 +00:00
Ok(Rc::from_inner(ptr))
} else {
Err(self)
}
}
}
impl<T: ?Sized> Rc<T> {
/// Allocates an `RcBox<T>` with sufficient space for
2019-10-19 11:47:32 +00:00
/// a possibly-unsized inner value where the value has the layout provided.
///
/// The function `mem_to_rcbox` is called with the data pointer
/// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
unsafe fn allocate_for_layout(
value_layout: Layout,
2019-12-22 22:42:04 +00:00
mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>,
) -> *mut RcBox<T> {
// Calculate layout using the given value layout.
// Previously, layout was calculated on the expression
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
// reference (see #54908).
2019-12-22 22:42:04 +00:00
let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
// Allocate for the layout.
2019-12-22 22:42:04 +00:00
let mem = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
// Initialize the RcBox
let inner = mem_to_rcbox(mem.as_ptr());
debug_assert_eq!(Layout::for_value(&*inner), layout);
ptr::write(&mut (*inner).strong, Cell::new(1));
ptr::write(&mut (*inner).weak, Cell::new(1));
inner
}
2019-10-19 11:47:32 +00:00
/// Allocates an `RcBox<T>` with sufficient space for an unsized inner value
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
// Allocate for the `RcBox<T>` using the given value.
2019-12-22 22:42:04 +00:00
Self::allocate_for_layout(Layout::for_value(&*ptr), |mem| {
set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>
})
}
fn from_box(v: Box<T>) -> Rc<T> {
unsafe {
let box_unique = Box::into_unique(v);
let bptr = box_unique.as_ptr();
let value_size = size_of_val(&*bptr);
let ptr = Self::allocate_for_ptr(bptr);
// Copy value as bytes
ptr::copy_nonoverlapping(
bptr as *const T as *const u8,
&mut (*ptr).value as *mut _ as *mut u8,
2019-12-22 22:42:04 +00:00
value_size,
);
// Free the allocation without dropping its contents
box_free(box_unique);
2019-06-19 02:46:19 +00:00
Self::from_ptr(ptr)
}
}
}
impl<T> Rc<[T]> {
/// Allocates an `RcBox<[T]>` with the given length.
unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> {
2019-12-22 22:42:04 +00:00
Self::allocate_for_layout(Layout::array::<T>(len).unwrap(), |mem| {
ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>
})
}
}
/// Sets the data pointer of a `?Sized` raw pointer.
///
/// For a slice/trait object, this sets the `data` field and leaves the rest
/// unchanged. For a sized raw pointer, this simply sets the pointer.
unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
ptr
}
impl<T> Rc<[T]> {
/// Copy elements from slice into newly allocated Rc<[T]>
///
/// Unsafe because the caller must either take ownership or bind `T: Copy`
unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
let ptr = Self::allocate_for_slice(v.len());
2019-12-22 22:42:04 +00:00
ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).value as *mut [T] as *mut T, v.len());
2019-06-19 02:46:19 +00:00
Self::from_ptr(ptr)
}
/// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
///
/// Behavior is undefined should the size be wrong.
unsafe fn from_iter_exact(iter: impl iter::Iterator<Item = T>, len: usize) -> Rc<[T]> {
// Panic guard while cloning T elements.
// In the event of a panic, elements that have been written
// into the new RcBox will be dropped, then the memory freed.
struct Guard<T> {
mem: NonNull<u8>,
elems: *mut T,
layout: Layout,
n_elems: usize,
}
impl<T> Drop for Guard<T> {
fn drop(&mut self) {
unsafe {
let slice = from_raw_parts_mut(self.elems, self.n_elems);
ptr::drop_in_place(slice);
2019-07-18 12:16:04 +00:00
Global.dealloc(self.mem, self.layout);
}
}
}
let ptr = Self::allocate_for_slice(len);
let mem = ptr as *mut _ as *mut u8;
let layout = Layout::for_value(&*ptr);
// Pointer to first element
let elems = &mut (*ptr).value as *mut [T] as *mut T;
2019-12-22 22:42:04 +00:00
let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 };
for (i, item) in iter.enumerate() {
ptr::write(elems.add(i), item);
guard.n_elems += 1;
}
// All clear. Forget the guard so it doesn't free the new RcBox.
forget(guard);
Self::from_ptr(ptr)
}
}
/// Specialization trait used for `From<&[T]>`.
trait RcFromSlice<T> {
fn from_slice(slice: &[T]) -> Self;
}
impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
#[inline]
default fn from_slice(v: &[T]) -> Self {
2019-12-22 22:42:04 +00:00
unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) }
}
}
impl<T: Copy> RcFromSlice<T> for Rc<[T]> {
#[inline]
fn from_slice(v: &[T]) -> Self {
unsafe { Rc::copy_from_slice(v) }
}
}
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for Rc<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.inner().value
}
}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized> Receiver for Rc<T> {}
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
2016-09-17 18:22:04 +00:00
/// Drops the `Rc`.
2015-04-16 02:36:47 +00:00
///
/// This will decrement the strong reference count. If the strong reference
2016-09-27 19:45:29 +00:00
/// count reaches zero then the only other references (if any) are
2018-07-01 16:51:39 +00:00
/// [`Weak`], so we `drop` the inner value.
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2016-09-17 18:22:04 +00:00
/// struct Foo;
2015-04-16 02:36:47 +00:00
///
2016-09-17 18:22:04 +00:00
/// impl Drop for Foo {
/// fn drop(&mut self) {
/// println!("dropped!");
/// }
2015-04-16 02:36:47 +00:00
/// }
///
2016-09-17 18:22:04 +00:00
/// let foo = Rc::new(Foo);
/// let foo2 = Rc::clone(&foo);
2015-04-16 02:36:47 +00:00
///
2016-09-17 18:22:04 +00:00
/// drop(foo); // Doesn't print anything
/// drop(foo2); // Prints "dropped!"
2015-04-16 02:36:47 +00:00
/// ```
///
/// [`Weak`]: ../../std/rc/struct.Weak.html
2015-04-16 02:36:47 +00:00
fn drop(&mut self) {
unsafe {
self.dec_strong();
if self.strong() == 0 {
// destroy the contained object
ptr::drop_in_place(self.ptr.as_mut());
2015-04-16 02:36:47 +00:00
// remove the implicit "strong weak" pointer now that we've
// destroyed the contents.
self.dec_weak();
2015-04-16 02:36:47 +00:00
if self.weak() == 0 {
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
2015-04-16 02:36:47 +00:00
}
}
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for Rc<T> {
2016-09-17 18:22:04 +00:00
/// Makes a clone of the `Rc` pointer.
2015-04-16 02:36:47 +00:00
///
2019-10-17 17:37:05 +00:00
/// This creates another pointer to the same allocation, increasing the
2016-09-17 18:22:04 +00:00
/// strong reference count.
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// let _ = Rc::clone(&five);
2015-04-16 02:36:47 +00:00
/// ```
#[inline]
fn clone(&self) -> Rc<T> {
self.inc_strong();
2019-06-19 02:46:19 +00:00
Self::from_inner(self.ptr)
2015-04-16 02:36:47 +00:00
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-06-23 23:09:19 +00:00
impl<T: Default> Default for Rc<T> {
/// Creates a new `Rc<T>`, with the `Default` value for `T`.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let x: Rc<i32> = Default::default();
2016-09-17 18:22:04 +00:00
/// assert_eq!(*x, 0);
/// ```
2014-06-23 23:09:19 +00:00
#[inline]
fn default() -> Rc<T> {
Rc::new(Default::default())
}
}
#[stable(feature = "rust1", since = "1.0.0")]
trait RcEqIdent<T: ?Sized + PartialEq> {
fn eq(&self, other: &Rc<T>) -> bool;
fn ne(&self, other: &Rc<T>) -> bool;
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> {
#[inline]
default fn eq(&self, other: &Rc<T>) -> bool {
**self == **other
}
#[inline]
default fn ne(&self, other: &Rc<T>) -> bool {
**self != **other
}
}
/// We're doing this specialization here, and not as a more general optimization on `&T`, because it
/// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to
/// store large values, that are slow to clone, but also heavy to check for equality, causing this
/// cost to pay off more easily. It's also more likely to have two `Rc` clones, that point to
/// the same value, than two `&T`s.
2019-10-19 11:47:32 +00:00
///
/// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Eq> RcEqIdent<T> for Rc<T> {
#[inline]
fn eq(&self, other: &Rc<T>) -> bool {
Rc::ptr_eq(self, other) || **self == **other
}
#[inline]
fn ne(&self, other: &Rc<T>) -> bool {
!Rc::ptr_eq(self, other) && **self != **other
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
2016-09-17 18:22:04 +00:00
/// Equality for two `Rc`s.
///
2019-10-17 17:37:05 +00:00
/// Two `Rc`s are equal if their inner values are equal, even if they are
/// stored in different allocation.
///
2019-10-17 17:37:05 +00:00
/// If `T` also implements `Eq` (implying reflexivity of equality),
/// two `Rc`s that point to the same allocation are
/// always equal.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five == Rc::new(5));
/// ```
#[inline]
fn eq(&self, other: &Rc<T>) -> bool {
RcEqIdent::eq(self, other)
2015-09-23 22:00:54 +00:00
}
2016-09-17 18:22:04 +00:00
/// Inequality for two `Rc`s.
///
2016-09-17 18:22:04 +00:00
/// Two `Rc`s are unequal if their inner values are unequal.
///
2019-10-17 17:37:05 +00:00
/// If `T` also implements `Eq` (implying reflexivity of equality),
/// two `Rc`s that point to the same allocation are
/// never unequal.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five != Rc::new(6));
/// ```
#[inline]
fn ne(&self, other: &Rc<T>) -> bool {
RcEqIdent::ne(self, other)
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Eq> Eq for Rc<T> {}
2014-03-22 20:30:45 +00:00
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> {
2016-09-17 18:22:04 +00:00
/// Partial comparison for two `Rc`s.
///
/// The two are compared by calling `partial_cmp()` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
2016-09-17 18:22:04 +00:00
/// use std::cmp::Ordering;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Rc::new(6)));
/// ```
#[inline(always)]
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other)
}
2016-09-17 18:22:04 +00:00
/// Less-than comparison for two `Rc`s.
///
/// The two are compared by calling `<` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five < Rc::new(6));
/// ```
#[inline(always)]
2015-09-23 22:00:54 +00:00
fn lt(&self, other: &Rc<T>) -> bool {
**self < **other
}
2016-09-17 18:22:04 +00:00
/// 'Less than or equal to' comparison for two `Rc`s.
///
/// The two are compared by calling `<=` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five <= Rc::new(5));
/// ```
#[inline(always)]
2015-09-23 22:00:54 +00:00
fn le(&self, other: &Rc<T>) -> bool {
**self <= **other
}
2016-09-17 18:22:04 +00:00
/// Greater-than comparison for two `Rc`s.
///
/// The two are compared by calling `>` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five > Rc::new(4));
/// ```
#[inline(always)]
2015-09-23 22:00:54 +00:00
fn gt(&self, other: &Rc<T>) -> bool {
**self > **other
}
2016-09-17 18:22:04 +00:00
/// 'Greater than or equal to' comparison for two `Rc`s.
///
/// The two are compared by calling `>=` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert!(five >= Rc::new(5));
/// ```
#[inline(always)]
2015-09-23 22:00:54 +00:00
fn ge(&self, other: &Rc<T>) -> bool {
**self >= **other
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord> Ord for Rc<T> {
2016-09-17 18:22:04 +00:00
/// Comparison for two `Rc`s.
///
/// The two are compared by calling `cmp()` on their inner values.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
2016-09-17 18:22:04 +00:00
/// use std::cmp::Ordering;
///
2015-01-25 21:05:03 +00:00
/// let five = Rc::new(5);
///
2016-09-17 18:22:04 +00:00
/// assert_eq!(Ordering::Less, five.cmp(&Rc::new(6)));
/// ```
2014-03-22 20:30:45 +00:00
#[inline]
2015-09-23 22:00:54 +00:00
fn cmp(&self, other: &Rc<T>) -> Ordering {
(**self).cmp(&**other)
}
2014-03-22 20:30:45 +00:00
}
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Hash> Hash for Rc<T> {
2015-04-16 02:36:47 +00:00
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + fmt::Display> fmt::Display for Rc<T> {
2019-02-02 11:48:12 +00:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2015-04-16 02:36:47 +00:00
fmt::Display::fmt(&**self, f)
}
}
2014-06-02 06:35:15 +00:00
2015-04-16 02:36:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for Rc<T> {
2019-02-02 11:48:12 +00:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2015-04-16 02:36:47 +00:00
fmt::Debug::fmt(&**self, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> fmt::Pointer for Rc<T> {
2019-02-02 11:48:12 +00:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&(&**self as *const T), f)
}
}
2015-11-16 08:04:17 +00:00
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
impl<T> From<T> for Rc<T> {
fn from(t: T) -> Self {
Rc::new(t)
}
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: Clone> From<&[T]> for Rc<[T]> {
#[inline]
fn from(v: &[T]) -> Rc<[T]> {
<Self as RcFromSlice<T>>::from_slice(v)
}
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<&str> for Rc<str> {
#[inline]
fn from(v: &str) -> Rc<str> {
let rc = Rc::<[u8]>::from(v.as_bytes());
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) }
}
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<String> for Rc<str> {
#[inline]
fn from(v: String) -> Rc<str> {
Rc::from(&v[..])
}
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: ?Sized> From<Box<T>> for Rc<T> {
#[inline]
fn from(v: Box<T>) -> Rc<T> {
Rc::from_box(v)
}
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T> From<Vec<T>> for Rc<[T]> {
#[inline]
fn from(mut v: Vec<T>) -> Rc<[T]> {
unsafe {
let rc = Rc::copy_from_slice(&v);
// Allow the Vec to free its memory, but not destroy its contents
v.set_len(0);
rc
}
}
}
#[unstable(feature = "boxed_slice_try_from", issue = "none")]
impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]>
where
[T; N]: LengthAtMost32,
{
type Error = Rc<[T]>;
fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
if boxed_slice.len() == N {
Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
} else {
Err(boxed_slice)
}
}
}
2019-06-18 23:39:51 +00:00
#[stable(feature = "shared_from_iter", since = "1.37.0")]
impl<T> iter::FromIterator<T> for Rc<[T]> {
/// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`.
///
/// # Performance characteristics
///
/// ## The general case
///
/// In the general case, collecting into `Rc<[T]>` is done by first
/// collecting into a `Vec<T>`. That is, when writing the following:
///
/// ```rust
/// # use std::rc::Rc;
/// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
/// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
/// ```
///
/// this behaves as if we wrote:
///
/// ```rust
/// # use std::rc::Rc;
/// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
/// .collect::<Vec<_>>() // The first set of allocations happens here.
/// .into(); // A second allocation for `Rc<[T]>` happens here.
/// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
/// ```
///
/// This will allocate as many times as needed for constructing the `Vec<T>`
/// and then it will allocate once for turning the `Vec<T>` into the `Rc<[T]>`.
///
/// ## Iterators of known length
///
/// When your `Iterator` implements `TrustedLen` and is of an exact size,
/// a single allocation will be made for the `Rc<[T]>`. For example:
///
/// ```rust
/// # use std::rc::Rc;
/// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
/// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
/// ```
fn from_iter<I: iter::IntoIterator<Item = T>>(iter: I) -> Self {
RcFromIter::from_iter(iter.into_iter())
}
}
/// Specialization trait used for collecting into `Rc<[T]>`.
trait RcFromIter<T, I> {
fn from_iter(iter: I) -> Self;
}
impl<T, I: Iterator<Item = T>> RcFromIter<T, I> for Rc<[T]> {
default fn from_iter(iter: I) -> Self {
iter.collect::<Vec<T>>().into()
}
}
2019-12-22 22:42:04 +00:00
impl<T, I: iter::TrustedLen<Item = T>> RcFromIter<T, I> for Rc<[T]> {
default fn from_iter(iter: I) -> Self {
// This is the case for a `TrustedLen` iterator.
let (low, high) = iter.size_hint();
if let Some(high) = high {
debug_assert_eq!(
2019-12-22 22:42:04 +00:00
low,
high,
"TrustedLen iterator's size hint is not exact: {:?}",
(low, high)
);
unsafe {
// SAFETY: We need to ensure that the iterator has an exact length and we have.
Rc::from_iter_exact(iter, low)
}
} else {
// Fall back to normal implementation.
iter.collect::<Vec<T>>().into()
}
}
}
impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> {
fn from_iter(iter: slice::Iter<'a, T>) -> Self {
// Delegate to `impl<T: Clone> From<&[T]> for Rc<[T]>`.
//
// In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping`
// which is even more performant.
//
// In the fall-back case we have `T: Clone`. This is still better
// than the `TrustedLen` implementation as slices have a known length
// and so we get to avoid calling `size_hint` and avoid the branching.
iter.as_slice().into()
2019-06-18 23:39:51 +00:00
}
}
2017-04-13 01:33:49 +00:00
/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
2019-10-17 17:37:05 +00:00
/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
2017-04-13 01:33:49 +00:00
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
2016-09-17 18:22:04 +00:00
///
2017-04-13 01:33:49 +00:00
/// Since a `Weak` reference does not count towards ownership, it will not
2019-10-17 17:37:05 +00:00
/// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no
2019-10-17 17:51:42 +00:00
/// guarantees about the value still being present. Thus it may return [`None`]
/// when [`upgrade`]d. Note however that a `Weak` reference *does* prevent the allocation
/// itself (the backing store) from being deallocated.
2016-09-17 18:22:04 +00:00
///
2019-10-17 17:37:05 +00:00
/// A `Weak` pointer is useful for keeping a temporary reference to the allocation
2019-10-17 17:51:42 +00:00
/// managed by [`Rc`] without preventing its inner value from being dropped. It is also used to
/// prevent circular references between [`Rc`] pointers, since mutual owning references
/// would never allow either [`Rc`] to be dropped. For example, a tree could
2017-04-13 01:33:49 +00:00
/// have strong [`Rc`] pointers from parent nodes to children, and `Weak`
/// pointers from children back to their parents.
2015-01-11 10:09:53 +00:00
///
2017-04-13 01:33:49 +00:00
/// The typical way to obtain a `Weak` pointer is to call [`Rc::downgrade`].
2015-01-11 10:09:53 +00:00
///
2017-04-13 01:33:49 +00:00
/// [`Rc`]: struct.Rc.html
/// [`Rc::downgrade`]: struct.Rc.html#method.downgrade
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// [`Option`]: ../../std/option/enum.Option.html
/// [`None`]: ../../std/option/enum.Option.html#variant.None
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
pub struct Weak<T: ?Sized> {
// This is a `NonNull` to allow optimizing the size of this type in enums,
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to `usize::MAX` so that it doesnt need
2018-07-23 10:53:37 +00:00
// to allocate space on the heap. That's not a value a real pointer
// will ever have because RcBox has alignment at least 2.
ptr: NonNull<RcBox<T>>,
2015-04-16 02:36:47 +00:00
}
2015-01-11 10:09:53 +00:00
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> !marker::Send for Weak<T> {}
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> !marker::Sync for Weak<T> {}
2015-01-11 10:09:53 +00:00
2015-11-16 16:54:28 +00:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
impl<T> Weak<T> {
/// Constructs a new `Weak<T>`, without allocating any memory.
2018-11-23 11:26:13 +00:00
/// Calling [`upgrade`] on the return value always gives [`None`].
2016-09-17 18:22:04 +00:00
///
2018-11-23 11:26:13 +00:00
/// [`upgrade`]: #method.upgrade
2017-04-13 01:33:49 +00:00
/// [`None`]: ../../std/option/enum.Option.html
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Weak;
///
/// let empty: Weak<i64> = Weak::new();
2016-09-17 18:22:04 +00:00
/// assert!(empty.upgrade().is_none());
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> {
2019-12-22 22:42:04 +00:00
Weak { ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0") }
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
}
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
/// The pointer is valid only if there are some strong references. The pointer may be dangling
/// or even [`null`] otherwise.
///
/// # Examples
///
/// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::Rc;
/// use std::ptr;
///
/// let strong = Rc::new("hello".to_owned());
/// let weak = Rc::downgrade(&strong);
/// // Both point to the same object
/// assert!(ptr::eq(&*strong, weak.as_raw()));
/// // The strong here keeps it alive, so we can still access the object.
/// assert_eq!("hello", unsafe { &*weak.as_raw() });
///
/// drop(strong);
/// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to
/// // undefined behaviour.
/// // assert_eq!("hello", unsafe { &*weak.as_raw() });
/// ```
///
/// [`null`]: ../../std/ptr/fn.null.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn as_raw(&self) -> *const T {
match self.inner() {
None => ptr::null(),
Some(inner) => {
let offset = data_offset_sized::<T>();
let ptr = inner as *const RcBox<T>;
// Note: while the pointer we create may already point to dropped value, the
// allocation still lives (it must hold the weak point as long as we are alive).
// Therefore, the offset is OK to do, it won't get out of the allocation.
let ptr = unsafe { (ptr as *const u8).offset(offset) };
ptr as *const T
}
}
}
/// Consumes the `Weak<T>` and turns it into a raw pointer.
///
/// This converts the weak pointer into a raw pointer, preserving the original weak count. It
/// can be turned back into the `Weak<T>` with [`from_raw`].
///
/// The same restrictions of accessing the target of the pointer as with
/// [`as_raw`] apply.
///
/// # Examples
///
/// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::{Rc, Weak};
///
/// let strong = Rc::new("hello".to_owned());
/// let weak = Rc::downgrade(&strong);
/// let raw = weak.into_raw();
///
/// assert_eq!(1, Rc::weak_count(&strong));
/// assert_eq!("hello", unsafe { &*raw });
///
/// drop(unsafe { Weak::from_raw(raw) });
/// assert_eq!(0, Rc::weak_count(&strong));
/// ```
///
/// [`from_raw`]: struct.Weak.html#method.from_raw
/// [`as_raw`]: struct.Weak.html#method.as_raw
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn into_raw(self) -> *const T {
let result = self.as_raw();
mem::forget(self);
result
}
/// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`.
///
/// This can be used to safely get a strong reference (by calling [`upgrade`]
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
///
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
/// as these don't have any corresponding weak count).
///
/// # Safety
///
/// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
/// count.
///
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
/// by [`new`]).
///
/// # Examples
///
/// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::{Rc, Weak};
///
/// let strong = Rc::new("hello".to_owned());
///
/// let raw_1 = Rc::downgrade(&strong).into_raw();
/// let raw_2 = Rc::downgrade(&strong).into_raw();
///
/// assert_eq!(2, Rc::weak_count(&strong));
///
/// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());
/// assert_eq!(1, Rc::weak_count(&strong));
///
/// drop(strong);
///
/// // Decrement the last weak count.
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
/// ```
///
/// [`into_raw`]: struct.Weak.html#method.into_raw
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// [`Rc`]: struct.Rc.html
/// [`Weak`]: struct.Weak.html
/// [`as_raw`]: struct.Weak.html#method.as_raw
/// [`new`]: struct.Weak.html#method.new
/// [`forget`]: ../../std/mem/fn.forget.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub unsafe fn from_raw(ptr: *const T) -> Self {
if ptr.is_null() {
Self::new()
} else {
// See Rc::from_raw for details
let offset = data_offset(ptr);
let fake_ptr = ptr as *mut RcBox<T>;
let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
2019-12-22 22:42:04 +00:00
Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") }
}
}
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
}
pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
let address = ptr.as_ptr() as *mut () as usize;
address == usize::MAX
}
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> Weak<T> {
2019-10-19 11:47:32 +00:00
/// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying
/// dropping of the inner value if successful.
2015-04-16 02:36:47 +00:00
///
2019-10-19 11:47:32 +00:00
/// Returns [`None`] if the inner value has since been dropped.
2015-04-16 02:36:47 +00:00
///
2017-04-13 01:33:49 +00:00
/// [`Rc`]: struct.Rc.html
/// [`None`]: ../../std/option/enum.Option.html
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// let weak_five = Rc::downgrade(&five);
2015-04-16 02:36:47 +00:00
///
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
2016-09-17 18:22:04 +00:00
/// assert!(strong_five.is_some());
///
/// // Destroy all strong pointers.
/// drop(strong_five);
/// drop(five);
///
/// assert!(weak_five.upgrade().is_none());
2015-04-16 02:36:47 +00:00
/// ```
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
pub fn upgrade(&self) -> Option<Rc<T>> {
let inner = self.inner()?;
if inner.strong() == 0 {
2015-04-16 02:36:47 +00:00
None
} else {
inner.inc_strong();
2019-06-19 02:46:19 +00:00
Some(Rc::from_inner(self.ptr))
2015-04-16 02:36:47 +00:00
}
}
2019-10-17 17:37:05 +00:00
/// Gets the number of strong (`Rc`) pointers pointing to this allocation.
///
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
2019-12-22 22:42:04 +00:00
if let Some(inner) = self.inner() { inner.strong() } else { 0 }
}
2019-10-17 17:37:05 +00:00
/// Gets the number of `Weak` pointers pointing to this allocation.
///
/// If no strong pointers remain, this will return zero.
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn weak_count(&self) -> usize {
2019-12-22 22:42:04 +00:00
self.inner()
.map(|inner| {
if inner.strong() > 0 {
inner.weak() - 1 // subtract the implicit weak ptr
} else {
0
}
})
.unwrap_or(0)
}
2019-02-09 22:16:58 +00:00
/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
/// (i.e., when this `Weak` was created by `Weak::new`).
#[inline]
fn inner(&self) -> Option<&RcBox<T>> {
2019-12-22 22:42:04 +00:00
if is_dangling(self.ptr) { None } else { Some(unsafe { self.ptr.as_ref() }) }
}
2018-11-15 15:41:06 +00:00
2019-10-17 17:37:05 +00:00
/// Returns `true` if the two `Weak`s point to the same allocation (similar to
/// [`ptr::eq`]), or if both don't point to any allocation
/// (because they were created with `Weak::new()`).
2018-11-15 15:41:06 +00:00
///
/// # Notes
///
/// Since this compares pointers it means that `Weak::new()` will equal each
2019-10-17 17:37:05 +00:00
/// other, even though they don't point to any allocation.
2018-11-15 15:41:06 +00:00
///
/// # Examples
///
/// ```
2019-06-16 11:57:07 +00:00
/// use std::rc::Rc;
2018-11-15 15:41:06 +00:00
///
/// let first_rc = Rc::new(5);
/// let first = Rc::downgrade(&first_rc);
/// let second = Rc::downgrade(&first_rc);
///
2019-06-16 11:57:07 +00:00
/// assert!(first.ptr_eq(&second));
2018-11-15 15:41:06 +00:00
///
/// let third_rc = Rc::new(5);
/// let third = Rc::downgrade(&third_rc);
///
2019-06-16 11:57:07 +00:00
/// assert!(!first.ptr_eq(&third));
2018-11-15 15:41:06 +00:00
/// ```
///
/// Comparing `Weak::new`.
///
/// ```
/// use std::rc::{Rc, Weak};
///
/// let first = Weak::new();
/// let second = Weak::new();
2019-06-16 11:57:07 +00:00
/// assert!(first.ptr_eq(&second));
2018-11-15 15:41:06 +00:00
///
/// let third_rc = Rc::new(());
/// let third = Rc::downgrade(&third_rc);
2019-06-16 11:57:07 +00:00
/// assert!(!first.ptr_eq(&third));
2018-11-15 15:41:06 +00:00
/// ```
2019-10-17 17:37:05 +00:00
///
/// [`ptr::eq`]: ../../std/ptr/fn.eq.html
2018-11-15 15:41:06 +00:00
#[inline]
2019-08-25 11:06:49 +00:00
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
2019-06-16 11:57:07 +00:00
pub fn ptr_eq(&self, other: &Self) -> bool {
self.ptr.as_ptr() == other.ptr.as_ptr()
2018-11-15 15:41:06 +00:00
}
2015-04-16 02:36:47 +00:00
}
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> Drop for Weak<T> {
2016-09-17 18:22:04 +00:00
/// Drops the `Weak` pointer.
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::{Rc, Weak};
2015-04-16 02:36:47 +00:00
///
2016-09-17 18:22:04 +00:00
/// struct Foo;
2015-04-16 02:36:47 +00:00
///
2016-09-17 18:22:04 +00:00
/// impl Drop for Foo {
/// fn drop(&mut self) {
/// println!("dropped!");
/// }
2015-04-16 02:36:47 +00:00
/// }
///
2016-09-17 18:22:04 +00:00
/// let foo = Rc::new(Foo);
/// let weak_foo = Rc::downgrade(&foo);
/// let other_weak_foo = Weak::clone(&weak_foo);
2015-04-16 02:36:47 +00:00
///
2016-09-17 18:22:04 +00:00
/// drop(weak_foo); // Doesn't print anything
/// drop(foo); // Prints "dropped!"
///
/// assert!(other_weak_foo.upgrade().is_none());
2015-04-16 02:36:47 +00:00
/// ```
fn drop(&mut self) {
if let Some(inner) = self.inner() {
inner.dec_weak();
// the weak count starts at 1, and will only go to zero if all
// the strong pointers have disappeared.
if inner.weak() == 0 {
unsafe {
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
}
2015-04-16 02:36:47 +00:00
}
}
}
}
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 20:26:44 +00:00
#[stable(feature = "rc_weak", since = "1.4.0")]
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> Clone for Weak<T> {
2019-10-17 17:37:05 +00:00
/// Makes a clone of the `Weak` pointer that points to the same allocation.
2015-04-16 02:36:47 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::{Rc, Weak};
2015-04-16 02:36:47 +00:00
///
/// let weak_five = Rc::downgrade(&Rc::new(5));
2015-04-16 02:36:47 +00:00
///
/// let _ = Weak::clone(&weak_five);
2015-04-16 02:36:47 +00:00
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
if let Some(inner) = self.inner() {
inner.inc_weak()
}
Weak { ptr: self.ptr }
2015-04-16 02:36:47 +00:00
}
}
#[stable(feature = "rc_weak", since = "1.4.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
2019-02-02 11:48:12 +00:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2015-04-16 02:36:47 +00:00
write!(f, "(Weak)")
}
}
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
#[stable(feature = "downgraded_weak", since = "1.10.0")]
impl<T> Default for Weak<T> {
2017-04-13 01:33:49 +00:00
/// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
/// it. Calling [`upgrade`] on the return value always gives [`None`].
2016-09-17 18:22:04 +00:00
///
2017-04-13 01:33:49 +00:00
/// [`None`]: ../../std/option/enum.Option.html
/// [`upgrade`]: ../../std/rc/struct.Weak.html#method.upgrade
2016-09-17 18:22:04 +00:00
///
/// # Examples
///
/// ```
/// use std::rc::Weak;
///
/// let empty: Weak<i64> = Default::default();
/// assert!(empty.upgrade().is_none());
/// ```
std: Stabilize APIs for the 1.10 release This commit applies the FCP decisions made by the libs team for the 1.10 cycle, including both new stabilizations and deprecations. Specifically, the list of APIs is: Stabilized: * `os::windows::fs::OpenOptionsExt::access_mode` * `os::windows::fs::OpenOptionsExt::share_mode` * `os::windows::fs::OpenOptionsExt::custom_flags` * `os::windows::fs::OpenOptionsExt::attributes` * `os::windows::fs::OpenOptionsExt::security_qos_flags` * `os::unix::fs::OpenOptionsExt::custom_flags` * `sync::Weak::new` * `Default for sync::Weak` * `panic::set_hook` * `panic::take_hook` * `panic::PanicInfo` * `panic::PanicInfo::payload` * `panic::PanicInfo::location` * `panic::Location` * `panic::Location::file` * `panic::Location::line` * `ffi::CStr::from_bytes_with_nul` * `ffi::CStr::from_bytes_with_nul_unchecked` * `ffi::FromBytesWithNulError` * `fs::Metadata::modified` * `fs::Metadata::accessed` * `fs::Metadata::created` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange` * `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak` * `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key` * `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}` * `SocketAddr::is_unnamed` * `SocketAddr::as_pathname` * `UnixStream::connect` * `UnixStream::pair` * `UnixStream::try_clone` * `UnixStream::local_addr` * `UnixStream::peer_addr` * `UnixStream::set_read_timeout` * `UnixStream::set_write_timeout` * `UnixStream::read_timeout` * `UnixStream::write_Timeout` * `UnixStream::set_nonblocking` * `UnixStream::take_error` * `UnixStream::shutdown` * Read/Write/RawFd impls for `UnixStream` * `UnixListener::bind` * `UnixListener::accept` * `UnixListener::try_clone` * `UnixListener::local_addr` * `UnixListener::set_nonblocking` * `UnixListener::take_error` * `UnixListener::incoming` * RawFd impls for `UnixListener` * `UnixDatagram::bind` * `UnixDatagram::unbound` * `UnixDatagram::pair` * `UnixDatagram::connect` * `UnixDatagram::try_clone` * `UnixDatagram::local_addr` * `UnixDatagram::peer_addr` * `UnixDatagram::recv_from` * `UnixDatagram::recv` * `UnixDatagram::send_to` * `UnixDatagram::send` * `UnixDatagram::set_read_timeout` * `UnixDatagram::set_write_timeout` * `UnixDatagram::read_timeout` * `UnixDatagram::write_timeout` * `UnixDatagram::set_nonblocking` * `UnixDatagram::take_error` * `UnixDatagram::shutdown` * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` * `<[_]>::binary_search_by_key` Deprecated: * `StaticCondvar` - this, and all other static synchronization primitives below, are usable today through the lazy-static crate on stable Rust today. Additionally, we'd like the non-static versions to be directly usable in a static context one day, so they're unlikely to be the final forms of the APIs in any case. * `CONDVAR_INIT` * `StaticMutex` * `MUTEX_INIT` * `StaticRwLock` * `RWLOCK_INIT` * `iter::Peekable::is_empty` Closes #27717 Closes #27720 cc #27784 (but encode methods still exist) Closes #30014 Closes #30425 Closes #30449 Closes #31190 Closes #31399 Closes #31767 Closes #32111 Closes #32281 Closes #32312 Closes #32551 Closes #33018
2016-05-17 18:57:07 +00:00
fn default() -> Weak<T> {
Weak::new()
}
}
// NOTE: We checked_add here to deal with mem::forget safely. In particular
2015-07-20 23:57:29 +00:00
// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
// you can free the allocation while outstanding Rcs (or Weaks) exist.
// We abort because this is such a degenerate scenario that we don't care about
// what happens -- no real program should ever experience this.
//
// This should have negligible overhead since you don't actually need to
// clone these much in Rust thanks to ownership and move-semantics.
2015-04-16 02:36:47 +00:00
#[doc(hidden)]
trait RcBoxPtr<T: ?Sized> {
fn inner(&self) -> &RcBox<T>;
#[inline]
2015-09-23 22:00:54 +00:00
fn strong(&self) -> usize {
self.inner().strong.get()
}
2015-04-16 02:36:47 +00:00
#[inline]
2015-07-20 23:57:29 +00:00
fn inc_strong(&self) {
2019-06-19 02:56:58 +00:00
let strong = self.strong();
// We want to abort on overflow instead of dropping the value.
// The reference count will never be zero when this is called;
// nevertheless, we insert an abort here to hint LLVM at
2018-08-05 06:41:14 +00:00
// an otherwise missed optimization.
2019-06-19 02:56:58 +00:00
if strong == 0 || strong == usize::max_value() {
2019-12-22 22:42:04 +00:00
unsafe {
abort();
}
}
2019-06-19 02:56:58 +00:00
self.inner().strong.set(strong + 1);
2015-07-20 23:57:29 +00:00
}
2015-04-16 02:36:47 +00:00
#[inline]
2015-09-23 22:00:54 +00:00
fn dec_strong(&self) {
self.inner().strong.set(self.strong() - 1);
}
2015-04-16 02:36:47 +00:00
#[inline]
2015-09-23 22:00:54 +00:00
fn weak(&self) -> usize {
self.inner().weak.get()
}
2015-04-16 02:36:47 +00:00
#[inline]
2015-07-20 23:57:29 +00:00
fn inc_weak(&self) {
2019-06-19 02:56:58 +00:00
let weak = self.weak();
// We want to abort on overflow instead of dropping the value.
// The reference count will never be zero when this is called;
// nevertheless, we insert an abort here to hint LLVM at
2018-08-05 06:41:14 +00:00
// an otherwise missed optimization.
2019-06-19 02:56:58 +00:00
if weak == 0 || weak == usize::max_value() {
2019-12-22 22:42:04 +00:00
unsafe {
abort();
}
}
2019-06-19 02:56:58 +00:00
self.inner().weak.set(weak + 1);
2015-07-20 23:57:29 +00:00
}
2015-04-16 02:36:47 +00:00
#[inline]
2015-09-23 22:00:54 +00:00
fn dec_weak(&self) {
self.inner().weak.set(self.weak() - 1);
}
2015-04-16 02:36:47 +00:00
}
2015-04-16 02:36:47 +00:00
impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
2019-12-22 22:42:04 +00:00
unsafe { self.ptr.as_ref() }
}
}
impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
2015-04-16 02:36:47 +00:00
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
self
}
}
2015-11-16 16:54:28 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
2015-09-23 22:00:54 +00:00
fn borrow(&self) -> &T {
&**self
}
}
#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized> AsRef<T> for Rc<T> {
2015-10-12 05:11:59 +00:00
fn as_ref(&self) -> &T {
&**self
}
}
2018-08-31 23:54:59 +00:00
2018-12-18 02:14:07 +00:00
#[stable(feature = "pin", since = "1.33.0")]
2019-12-22 22:42:04 +00:00
impl<T: ?Sized> Unpin for Rc<T> {}
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
2019-06-19 02:48:46 +00:00
// Align the unsized value to the end of the `RcBox`.
// Because it is ?Sized, it will always be the last field in memory.
// Note: This is a detail of the current implementation of the compiler,
// and is not a guaranteed language detail. Do not rely on it outside of std.
2019-06-19 02:48:46 +00:00
data_offset_align(align_of_val(&*ptr))
}
2019-06-19 02:48:46 +00:00
/// Computes the offset of the data field within `RcBox`.
///
/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`.
fn data_offset_sized<T>() -> isize {
2019-06-19 02:48:46 +00:00
data_offset_align(align_of::<T>())
}
#[inline]
2019-06-19 02:48:46 +00:00
fn data_offset_align(align: usize) -> isize {
let layout = Layout::new::<RcBox<()>>();
(layout.size() + layout.padding_needed_for(align)) as isize
}