diff options
| author | bors <bors@rust-lang.org> | 2015-06-18 19:14:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-06-18 19:14:52 +0000 |
| commit | 9cc0b2247509d61d6a246a5c5ad67f84b9a2d8b6 (patch) | |
| tree | c9c5e9d32ccf0c44d331dc9fe139b8d82d912b15 /src/liballoc | |
| parent | f4518127636e6bffab0599ab4dad785a873c5bd8 (diff) | |
| parent | ec333380e03eb1fb94c4938db888d5bed40b8fd6 (diff) | |
| download | rust-9cc0b2247509d61d6a246a5c5ad67f84b9a2d8b6.tar.gz rust-9cc0b2247509d61d6a246a5c5ad67f84b9a2d8b6.zip | |
Auto merge of #26192 - alexcrichton:features-clean, r=aturon
This commit shards the all-encompassing `core`, `std_misc`, `collections`, and `alloc` features into finer-grained components that are much more easily opted into and tracked. This reflects the effort to push forward current unstable APIs to either stabilization or removal. Keeping track of unstable features on a much more fine-grained basis will enable the library subteam to quickly analyze a feature and help prioritize internally about what APIs should be stabilized. A few assorted APIs were deprecated along the way, but otherwise this change is just changing the feature name associated with each API. Soon we will have a dashboard for keeping track of all the unstable APIs in the standard library, and I'll also start making issues for each unstable API after performing a first-pass for stabilization.
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/arc.rs | 56 | ||||
| -rw-r--r-- | src/liballoc/boxed.rs | 63 | ||||
| -rw-r--r-- | src/liballoc/heap.rs | 7 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 34 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 197 |
5 files changed, 244 insertions, 113 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 616071f0df7..7bfeaec36d7 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -134,7 +134,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {} /// Weak pointers will not keep the data inside of the `Arc` alive, and can be /// used to break cycles between `Arc` pointers. #[unsafe_no_drop_flag] -#[unstable(feature = "alloc", +#[unstable(feature = "arc_weak", reason = "Weak pointers may not belong in this module.")] pub struct Weak<T: ?Sized> { // FIXME #12808: strange name to try to avoid interfering with @@ -191,23 +191,35 @@ impl<T: ?Sized> Arc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(arc_weak)] /// use std::sync::Arc; /// /// let five = Arc::new(5); /// /// let weak_five = five.downgrade(); /// ``` - #[unstable(feature = "alloc", + #[unstable(feature = "arc_weak", reason = "Weak pointers may not belong in this module.")] pub fn downgrade(&self) -> Weak<T> { // See the clone() impl for why this is relaxed self.inner().weak.fetch_add(1, Relaxed); Weak { _ptr: self._ptr } } -} -impl<T: ?Sized> Arc<T> { + /// Get the number of weak references to this value. + #[inline] + #[unstable(feature = "arc_counts")] + pub fn weak_count(this: &Arc<T>) -> usize { + this.inner().weak.load(SeqCst) - 1 + } + + /// Get the number of strong references to this value. + #[inline] + #[unstable(feature = "arc_counts")] + pub fn strong_count(this: &Arc<T>) -> usize { + this.inner().strong.load(SeqCst) + } + #[inline] fn inner(&self) -> &ArcInner<T> { // This unsafety is ok because while this arc is alive we're guaranteed @@ -236,13 +248,15 @@ impl<T: ?Sized> Arc<T> { /// Get the number of weak references to this value. #[inline] -#[unstable(feature = "alloc")] -pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) - 1 } +#[unstable(feature = "arc_counts")] +#[deprecated(since = "1.2.0", reason = "renamed to Arc::weak_count")] +pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::weak_count(this) } /// Get the number of strong references to this value. #[inline] -#[unstable(feature = "alloc")] -pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst) } +#[unstable(feature = "arc_counts")] +#[deprecated(since = "1.2.0", reason = "renamed to Arc::strong_count")] +pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::strong_count(this) } /// Returns a mutable reference to the contained value if the `Arc<T>` is unique. @@ -255,7 +269,7 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa /// # Examples /// /// ``` -/// # #![feature(alloc)] +/// # #![feature(arc_unique, alloc)] /// extern crate alloc; /// # fn main() { /// use alloc::arc::{Arc, get_mut}; @@ -271,10 +285,12 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa /// # } /// ``` #[inline] -#[unstable(feature = "alloc")] +#[unstable(feature = "arc_unique")] +#[deprecated(since = "1.2.0", + reason = "this function is unsafe with weak pointers")] pub unsafe fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> { // FIXME(#24880) potential race with upgraded weak pointers here - if strong_count(this) == 1 && weak_count(this) == 0 { + if Arc::strong_count(this) == 1 && Arc::weak_count(this) == 0 { // 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 @@ -342,7 +358,7 @@ impl<T: Clone> Arc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(arc_unique)] /// use std::sync::Arc; /// /// # unsafe { @@ -352,7 +368,9 @@ impl<T: Clone> Arc<T> { /// # } /// ``` #[inline] - #[unstable(feature = "alloc")] + #[unstable(feature = "arc_unique")] + #[deprecated(since = "1.2.0", + reason = "this function is unsafe with weak pointers")] pub unsafe fn make_unique(&mut self) -> &mut T { // FIXME(#24880) potential race with upgraded weak pointers here // @@ -438,7 +456,7 @@ impl<T: ?Sized> Drop for Arc<T> { } } -#[unstable(feature = "alloc", +#[unstable(feature = "arc_weak", reason = "Weak pointers may not belong in this module.")] impl<T: ?Sized> Weak<T> { /// Upgrades a weak reference to a strong reference. @@ -451,7 +469,7 @@ impl<T: ?Sized> Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(arc_weak)] /// use std::sync::Arc; /// /// let five = Arc::new(5); @@ -479,7 +497,7 @@ impl<T: ?Sized> Weak<T> { } } -#[unstable(feature = "alloc", +#[unstable(feature = "arc_weak", reason = "Weak pointers may not belong in this module.")] impl<T: ?Sized> Clone for Weak<T> { /// Makes a clone of the `Weak<T>`. @@ -489,7 +507,7 @@ impl<T: ?Sized> Clone for Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(arc_weak)] /// use std::sync::Arc; /// /// let weak_five = Arc::new(5).downgrade(); @@ -513,7 +531,7 @@ impl<T: ?Sized> Drop for Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(arc_weak)] /// use std::sync::Arc; /// /// { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 4ee500faa22..1039756363e 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -10,9 +10,9 @@ //! A pointer type for heap allocation. //! -//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in -//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of -//! scope. +//! `Box<T>`, casually referred to as a 'box', provides the simplest form of +//! heap allocation in Rust. Boxes provide ownership for this allocation, and +//! drop their contents when they go out of scope. //! //! # Examples //! @@ -39,15 +39,17 @@ //! //! This will print `Cons(1, Cons(2, Nil))`. //! -//! Recursive structures must be boxed, because if the definition of `Cons` looked like this: +//! Recursive structures must be boxed, because if the definition of `Cons` +//! looked like this: //! //! ```rust,ignore //! Cons(T, List<T>), //! ``` //! -//! It wouldn't work. This is because the size of a `List` depends on how many elements are in the -//! list, and so we don't know how much memory to allocate for a `Cons`. By introducing a `Box`, -//! which has a defined size, we know how big `Cons` needs to be. +//! It wouldn't work. This is because the size of a `List` depends on how many +//! elements are in the list, and so we don't know how much memory to allocate +//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how +//! big `Cons` needs to be. #![stable(feature = "rust1", since = "1.0.0")] @@ -69,7 +71,7 @@ use core::raw::{TraitObject}; /// The following two examples are equivalent: /// /// ``` -/// # #![feature(alloc)] +/// # #![feature(box_heap)] /// #![feature(box_syntax)] /// use std::boxed::HEAP; /// @@ -79,7 +81,7 @@ use core::raw::{TraitObject}; /// } /// ``` #[lang = "exchange_heap"] -#[unstable(feature = "alloc", +#[unstable(feature = "box_heap", reason = "may be renamed; uncertain about custom allocator design")] pub const HEAP: () = (); @@ -119,12 +121,37 @@ impl<T : ?Sized> Box<T> { /// Function is unsafe, because improper use of this function may /// lead to memory problems like double-free, for example if the /// function is called twice on the same raw pointer. - #[unstable(feature = "alloc", + #[unstable(feature = "box_raw", reason = "may be renamed or moved out of Box scope")] #[inline] + // NB: may want to be called from_ptr, see comments on CStr::from_ptr pub unsafe fn from_raw(raw: *mut T) -> Self { mem::transmute(raw) } + + /// Consumes the `Box`, returning the wrapped raw pointer. + /// + /// After call to this function, caller is responsible for the memory + /// previously managed by `Box`, in particular caller should properly + /// destroy `T` and release memory. The proper way to do it is to + /// convert pointer back to `Box` with `Box::from_raw` function, because + /// `Box` does not specify, how memory is allocated. + /// + /// # Examples + /// ``` + /// # #![feature(box_raw)] + /// use std::boxed; + /// + /// let seventeen = Box::new(17u32); + /// let raw = boxed::into_raw(seventeen); + /// let boxed_again = unsafe { Box::from_raw(raw) }; + /// ``` + #[unstable(feature = "box_raw", reason = "may be renamed")] + #[inline] + // NB: may want to be called into_ptr, see comments on CStr::from_ptr + pub fn into_raw(b: Box<T>) -> *mut T { + unsafe { mem::transmute(b) } + } } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -137,18 +164,18 @@ impl<T : ?Sized> Box<T> { /// /// # Examples /// ``` -/// # #![feature(alloc)] +/// # #![feature(box_raw)] /// use std::boxed; /// /// let seventeen = Box::new(17u32); /// let raw = boxed::into_raw(seventeen); /// let boxed_again = unsafe { Box::from_raw(raw) }; /// ``` -#[unstable(feature = "alloc", - reason = "may be renamed")] +#[unstable(feature = "box_raw", reason = "may be renamed")] +#[deprecated(since = "1.2.0", reason = "renamed to Box::into_raw")] #[inline] pub fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T { - unsafe { mem::transmute(b) } + Box::into_raw(b) } #[stable(feature = "rust1", since = "1.0.0")] @@ -181,7 +208,7 @@ impl<T: Clone> Clone for Box<T> { /// # Examples /// /// ``` - /// # #![feature(alloc, core)] + /// # #![feature(box_raw)] /// let x = Box::new(5); /// let mut y = Box::new(10); /// @@ -242,7 +269,7 @@ impl Box<Any> { if self.is::<T>() { unsafe { // Get the raw representation of the trait object - let raw = into_raw(self); + let raw = Box::into_raw(self); let to: TraitObject = mem::transmute::<*mut Any, TraitObject>(raw); @@ -334,7 +361,7 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {} /// -> i32>`. /// /// ``` -/// #![feature(core)] +/// #![feature(fnbox)] /// /// use std::boxed::FnBox; /// use std::collections::HashMap; @@ -355,7 +382,7 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {} /// } /// ``` #[rustc_paren_sugar] -#[unstable(feature = "core", reason = "Newly introduced")] +#[unstable(feature = "fnbox", reason = "Newly introduced")] pub trait FnBox<A> { type Output; diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 1cc63588fdd..14797d7f4b5 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -8,6 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![unstable(feature = "heap_api", + reason = "the precise API and guarantees it provides may be tweaked \ + slightly, especially to possibly take into account the \ + types being stored to make room for a future \ + tracing garbage collector")] + use core::{isize, usize}; #[inline(always)] @@ -94,7 +100,6 @@ pub fn usable_size(size: usize, align: usize) -> usize { /// /// These statistics may be inconsistent if other threads use the allocator /// during the call. -#[unstable(feature = "alloc")] pub fn stats_print() { imp::stats_print(); } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5541a5f34c4..7dcf7a76da0 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -59,32 +59,40 @@ // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) #![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "alloc"] -#![unstable(feature = "alloc")] -#![feature(staged_api)] -#![staged_api] #![crate_type = "rlib"] +#![staged_api] +#![unstable(feature = "alloc", + reason = "this library is unlikely to be stabilized in its current \ + form or name")] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/nightly/")] -#![doc(test(no_crate_inject))] - -#![feature(no_std)] + html_root_url = "http://doc.rust-lang.org/nightly/", + test(no_crate_inject))] #![no_std] + #![feature(allocator)] +#![feature(box_syntax)] +#![feature(coerce_unsized)] +#![feature(core)] +#![feature(core_intrinsics)] +#![feature(core_prelude)] #![feature(custom_attribute)] #![feature(fundamental)] #![feature(lang_items)] -#![feature(box_syntax)] +#![feature(no_std)] +#![feature(nonzero)] #![feature(optin_builtin_traits)] +#![feature(raw)] +#![feature(staged_api)] #![feature(unboxed_closures)] -#![feature(unsafe_no_drop_flag, filling_drop)] -#![feature(core)] #![feature(unique)] -#![cfg_attr(test, feature(test, alloc, rustc_private))] +#![feature(unsafe_no_drop_flag, filling_drop)] +#![feature(unsize)] + +#![cfg_attr(test, feature(test, alloc, rustc_private, box_raw))] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] - #[macro_use] extern crate core; @@ -118,6 +126,7 @@ pub mod rc; /// Common out-of-memory routine #[cold] #[inline(never)] +#[unstable(feature = "oom", reason = "not a scrutinized interface")] pub fn oom() -> ! { // FIXME(#14674): This really needs to do something other than just abort // here, but any printing done must be *guaranteed* to not @@ -138,4 +147,5 @@ pub fn oom() -> ! { // to get linked in to libstd successfully (the linker won't // optimize it out). #[doc(hidden)] +#[unstable(feature = "issue_14344_fixme")] pub fn fixme_14344_be_sure_to_link_to_collections() {} diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 44f4a6a6290..d5b6c86ef35 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -32,7 +32,6 @@ //! and have the `Owner` remain allocated as long as any `Gadget` points at it. //! //! ```rust -//! # #![feature(alloc)] //! use std::rc::Rc; //! //! struct Owner { @@ -92,7 +91,7 @@ //! documentation for more details on interior mutability. //! //! ```rust -//! # #![feature(alloc)] +//! # #![feature(rc_weak)] //! use std::rc::Rc; //! use std::rc::Weak; //! use std::cell::RefCell; @@ -149,26 +148,24 @@ //! ``` #![stable(feature = "rust1", since = "1.0.0")] + +use core::prelude::*; + #[cfg(not(test))] -use boxed; +use boxed::Box; #[cfg(test)] -use std::boxed; +use std::boxed::Box; + use core::cell::Cell; -use core::clone::Clone; -use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; -use core::default::Default; +use core::cmp::Ordering; use core::fmt; use core::hash::{Hasher, Hash}; use core::intrinsics::{assume, drop_in_place}; -use core::marker::{self, Sized, Unsize}; +use core::marker::{self, Unsize}; use core::mem::{self, min_align_of, size_of, min_align_of_val, size_of_val, forget}; use core::nonzero::NonZero; -use core::ops::{CoerceUnsized, Deref, Drop}; -use core::option::Option; -use core::option::Option::{Some, None}; +use core::ops::{CoerceUnsized, Deref}; use core::ptr; -use core::result::Result; -use core::result::Result::{Ok, Err}; use heap::deallocate; @@ -213,7 +210,7 @@ impl<T> Rc<T> { // 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. - _ptr: NonZero::new(boxed::into_raw(box RcBox { + _ptr: NonZero::new(Box::into_raw(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value: value @@ -221,6 +218,42 @@ impl<T> Rc<T> { } } } + + /// Unwraps the contained value if the `Rc<T>` is unique. + /// + /// If the `Rc<T>` is not unique, an `Err` is returned with the same + /// `Rc<T>`. + /// + /// # Examples + /// + /// ``` + /// # #![feature(rc_unique)] + /// use std::rc::Rc; + /// + /// let x = Rc::new(3); + /// assert_eq!(Rc::try_unwrap(x), Ok(3)); + /// + /// let x = Rc::new(4); + /// let _y = x.clone(); + /// assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); + /// ``` + #[inline] + #[unstable(feature = "rc_unique")] + pub fn try_unwrap(rc: Rc<T>) -> Result<T, Rc<T>> { + if Rc::is_unique(&rc) { + unsafe { + let val = ptr::read(&*rc); // copy the contained object + // destruct the box and skip our Drop + // we can ignore the refcounts because we know we're unique + deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(), + min_align_of::<RcBox<T>>()); + forget(rc); + Ok(val) + } + } else { + Err(rc) + } + } } impl<T: ?Sized> Rc<T> { @@ -229,30 +262,90 @@ impl<T: ?Sized> Rc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(rc_weak)] /// use std::rc::Rc; /// /// let five = Rc::new(5); /// /// let weak_five = five.downgrade(); /// ``` - #[unstable(feature = "alloc", + #[unstable(feature = "rc_weak", reason = "Weak pointers may not belong in this module")] pub fn downgrade(&self) -> Weak<T> { self.inc_weak(); Weak { _ptr: self._ptr } } + + /// Get the number of weak references to this value. + #[inline] + #[unstable(feature = "rc_counts")] + pub fn weak_count(this: &Rc<T>) -> usize { this.weak() - 1 } + + /// Get the number of strong references to this value. + #[inline] + #[unstable(feature = "rc_counts")] + pub fn strong_count(this: &Rc<T>) -> usize { this.strong() } + + /// Returns true if there are no other `Rc` or `Weak<T>` values that share + /// the same inner value. + /// + /// # Examples + /// + /// ``` + /// # #![feature(rc_unique)] + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// + /// assert!(Rc::is_unique(&five)); + /// ``` + #[inline] + #[unstable(feature = "rc_unique")] + pub fn is_unique(rc: &Rc<T>) -> bool { + Rc::weak_count(rc) == 0 && Rc::strong_count(rc) == 1 + } + + /// Returns a mutable reference to the contained value if the `Rc<T>` is + /// unique. + /// + /// Returns `None` if the `Rc<T>` is not unique. + /// + /// # Examples + /// + /// ``` + /// # #![feature(rc_unique)] + /// use std::rc::Rc; + /// + /// let mut x = Rc::new(3); + /// *Rc::get_mut(&mut x).unwrap() = 4; + /// assert_eq!(*x, 4); + /// + /// let _y = x.clone(); + /// assert!(Rc::get_mut(&mut x).is_none()); + /// ``` + #[inline] + #[unstable(feature = "rc_unique")] + pub fn get_mut(rc: &mut Rc<T>) -> Option<&mut T> { + if Rc::is_unique(rc) { + let inner = unsafe { &mut **rc._ptr }; + Some(&mut inner.value) + } else { + None + } + } } /// Get the number of weak references to this value. #[inline] -#[unstable(feature = "alloc")] -pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { this.weak() - 1 } +#[unstable(feature = "rc_counts")] +#[deprecated(since = "1.2.0", reason = "renamed to Rc::weak_count")] +pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::weak_count(this) } /// Get the number of strong references to this value. #[inline] -#[unstable(feature = "alloc")] -pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() } +#[unstable(feature = "rc_counts")] +#[deprecated(since = "1.2.0", reason = "renamed to Rc::strong_count")] +pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::strong_count(this) } /// Returns true if there are no other `Rc` or `Weak<T>` values that share the /// same inner value. @@ -260,7 +353,7 @@ pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() } /// # Examples /// /// ``` -/// # #![feature(alloc)] +/// # #![feature(rc_unique)] /// use std::rc; /// use std::rc::Rc; /// @@ -269,10 +362,9 @@ pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() } /// rc::is_unique(&five); /// ``` #[inline] -#[unstable(feature = "alloc")] -pub fn is_unique<T>(rc: &Rc<T>) -> bool { - weak_count(rc) == 0 && strong_count(rc) == 1 -} +#[unstable(feature = "rc_unique")] +#[deprecated(since = "1.2.0", reason = "renamed to Rc::is_unique")] +pub fn is_unique<T>(rc: &Rc<T>) -> bool { Rc::is_unique(rc) } /// Unwraps the contained value if the `Rc<T>` is unique. /// @@ -281,7 +373,7 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool { /// # Examples /// /// ``` -/// # #![feature(alloc)] +/// # #![feature(rc_unique)] /// use std::rc::{self, Rc}; /// /// let x = Rc::new(3); @@ -292,22 +384,9 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool { /// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4))); /// ``` #[inline] -#[unstable(feature = "alloc")] -pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { - if is_unique(&rc) { - unsafe { - let val = ptr::read(&*rc); // copy the contained object - // destruct the box and skip our Drop - // we can ignore the refcounts because we know we're unique - deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(), - min_align_of::<RcBox<T>>()); - forget(rc); - Ok(val) - } - } else { - Err(rc) - } -} +#[unstable(feature = "rc_unique")] +#[deprecated(since = "1.2.0", reason = "renamed to Rc::try_unwrap")] +pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { Rc::try_unwrap(rc) } /// Returns a mutable reference to the contained value if the `Rc<T>` is unique. /// @@ -316,7 +395,7 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { /// # Examples /// /// ``` -/// # #![feature(alloc)] +/// # #![feature(rc_unique)] /// use std::rc::{self, Rc}; /// /// let mut x = Rc::new(3); @@ -327,15 +406,9 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { /// assert!(rc::get_mut(&mut x).is_none()); /// ``` #[inline] -#[unstable(feature = "alloc")] -pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> { - if is_unique(rc) { - let inner = unsafe { &mut **rc._ptr }; - Some(&mut inner.value) - } else { - None - } -} +#[unstable(feature = "rc_unique")] +#[deprecated(since = "1.2.0", reason = "renamed to Rc::get_mut")] +pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> { Rc::get_mut(rc) } impl<T: Clone> Rc<T> { /// Make a mutable reference from the given `Rc<T>`. @@ -346,7 +419,7 @@ impl<T: Clone> Rc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(rc_unique)] /// use std::rc::Rc; /// /// let mut five = Rc::new(5); @@ -354,9 +427,9 @@ impl<T: Clone> Rc<T> { /// let mut_five = five.make_unique(); /// ``` #[inline] - #[unstable(feature = "alloc")] + #[unstable(feature = "rc_unique")] pub fn make_unique(&mut self) -> &mut T { - if !is_unique(self) { + if !Rc::is_unique(self) { *self = Rc::new((**self).clone()) } // This unsafety is ok because we're guaranteed that the pointer @@ -390,7 +463,6 @@ impl<T: ?Sized> Drop for Rc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] /// use std::rc::Rc; /// /// { @@ -443,7 +515,6 @@ impl<T: ?Sized> Clone for Rc<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] /// use std::rc::Rc; /// /// let five = Rc::new(5); @@ -652,7 +723,7 @@ impl<T> fmt::Pointer for Rc<T> { /// /// See the [module level documentation](./index.html) for more. #[unsafe_no_drop_flag] -#[unstable(feature = "alloc", +#[unstable(feature = "rc_weak", reason = "Weak pointers may not belong in this module.")] pub struct Weak<T: ?Sized> { // FIXME #12808: strange names to try to avoid interfering with @@ -663,7 +734,7 @@ pub struct Weak<T: ?Sized> { impl<T: ?Sized> !marker::Send for Weak<T> {} impl<T: ?Sized> !marker::Sync for Weak<T> {} -#[unstable(feature = "alloc", +#[unstable(feature = "rc_weak", reason = "Weak pointers may not belong in this module.")] impl<T: ?Sized> Weak<T> { @@ -677,7 +748,7 @@ impl<T: ?Sized> Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(rc_weak)] /// use std::rc::Rc; /// /// let five = Rc::new(5); @@ -705,7 +776,7 @@ impl<T: ?Sized> Drop for Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(rc_weak)] /// use std::rc::Rc; /// /// { @@ -741,7 +812,7 @@ impl<T: ?Sized> Drop for Weak<T> { } } -#[unstable(feature = "alloc", +#[unstable(feature = "rc_weak", reason = "Weak pointers may not belong in this module.")] impl<T: ?Sized> Clone for Weak<T> { @@ -752,7 +823,7 @@ impl<T: ?Sized> Clone for Weak<T> { /// # Examples /// /// ``` - /// # #![feature(alloc)] + /// # #![feature(rc_weak)] /// use std::rc::Rc; /// /// let weak_five = Rc::new(5).downgrade(); |
