Skip to content

std: Stabilize unit, bool, ty, tuple, arc, any #15936

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
* Concurrency-enabled mechanisms for sharing mutable and/or immutable state
* between tasks.
*/
#![stable]

//! Concurrency-enabled mechanisms for sharing mutable and/or immutable state
//! between tasks.

use core::atomics;
use core::clone::Clone;
Expand Down Expand Up @@ -51,6 +51,7 @@ use heap::deallocate;
/// }
/// ```
#[unsafe_no_drop_flag]
#[stable]
pub struct Arc<T> {
// FIXME #12808: strange name to try to avoid interfering with
// field accesses of the contained type via Deref
Expand All @@ -62,6 +63,7 @@ pub struct 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]
#[experimental = "Weak pointers may not belong in this module."]
pub struct Weak<T> {
// FIXME #12808: strange name to try to avoid interfering with
// field accesses of the contained type via Deref
Expand All @@ -77,6 +79,7 @@ struct ArcInner<T> {
impl<T: Share + Send> Arc<T> {
/// Create an atomically reference counted wrapper.
#[inline]
#[stable]
pub fn new(data: T) -> Arc<T> {
// Start the weak pointer count as 1 which is the weak pointer that's
// held by all the strong pointers (kinda), see std/rc.rs for more info
Expand All @@ -103,14 +106,15 @@ impl<T: Share + Send> Arc<T> {
/// Weak pointers will not keep the data alive. Once all strong references
/// to the underlying data have been dropped, the data itself will be
/// destroyed.
#[experimental = "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, atomics::Relaxed);
Weak { _ptr: self._ptr }
}
}

#[unstable]
#[unstable = "waiting on stability of Clone"]
impl<T: Share + Send> Clone for Arc<T> {
/// Duplicate an atomically reference counted wrapper.
///
Expand All @@ -135,6 +139,7 @@ impl<T: Share + Send> Clone for Arc<T> {
}
}

#[experimental = "Deref is experimental."]
impl<T: Send + Share> Deref<T> for Arc<T> {
#[inline]
fn deref<'a>(&'a self) -> &'a T {
Expand Down Expand Up @@ -169,6 +174,7 @@ impl<T: Send + Share + Clone> Arc<T> {
}

#[unsafe_destructor]
#[experimental = "waiting on stability of Drop"]
impl<T: Share + Send> Drop for Arc<T> {
fn drop(&mut self) {
// This structure has #[unsafe_no_drop_flag], so this drop glue may run
Expand Down Expand Up @@ -212,6 +218,7 @@ impl<T: Share + Send> Drop for Arc<T> {
}
}

#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Weak<T> {
/// Attempts to upgrade this weak reference to a strong reference.
///
Expand All @@ -237,7 +244,7 @@ impl<T: Share + Send> Weak<T> {
}
}

#[unstable]
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Clone for Weak<T> {
#[inline]
fn clone(&self) -> Weak<T> {
Expand All @@ -248,6 +255,7 @@ impl<T: Share + Send> Clone for Weak<T> {
}

#[unsafe_destructor]
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Drop for Weak<T> {
fn drop(&mut self) {
// see comments above for why this check is here
Expand Down
5 changes: 4 additions & 1 deletion src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ impl<T: Ord> Ord for Box<T> {
impl<T: Eq> Eq for Box<T> {}

/// Extension methods for an owning `Any` trait object
#[unstable = "post-DST, the signature of `downcast` will change to take `Box<Self>`"]
#[unstable = "post-DST and coherence changes, this will not be a trait but \
rather a direct `impl` on `Box<Any>`"]
pub trait BoxAny {
/// Returns the boxed value if it is of type `T`, or
/// `Err(Self)` if it isn't.
#[unstable = "naming conventions around accessing innards may change"]
fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;

/// Deprecated; this method has been renamed to `downcast`.
Expand All @@ -100,6 +102,7 @@ pub trait BoxAny {
}
}

#[stable]
impl BoxAny for Box<Any> {
#[inline]
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
Expand Down
1 change: 0 additions & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ impl<T> Drop for Weak<T> {
}
}

#[unstable]
#[experimental = "Weak pointers may not belong in this module."]
impl<T> Clone for Weak<T> {
#[inline]
Expand Down
62 changes: 48 additions & 14 deletions src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
//! // try to convert our value to a String. If successful, we want to
//! // output the String's length as well as its value. If not, it's a
//! // different type: just print it out unadorned.
//! match value_any.as_ref::<String>() {
//! match value_any.downcast_ref::<String>() {
//! Some(as_string) => {
//! println!("String ({}): {}", as_string.len(), as_string);
//! }
Expand All @@ -69,51 +69,72 @@
//! }
//! ```

#![stable]

use mem::{transmute, transmute_copy};
use option::{Option, Some, None};
use raw::TraitObject;
use intrinsics::TypeId;

/// A type with no inhabitants
#[deprecated = "this type is being removed, define a type locally if \
necessary"]
pub enum Void { }

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// The `Any` trait is implemented by all `'static` types, and can be used for dynamic typing
/// The `Any` trait is implemented by all `'static` types, and can be used for
/// dynamic typing
///
/// Every type with no non-`'static` references implements `Any`, so `Any` can be used as a trait
/// object to emulate the effects dynamic typing.
pub trait Any {
/// Every type with no non-`'static` references implements `Any`, so `Any` can
/// be used as a trait object to emulate the effects dynamic typing.
#[stable]
pub trait Any: AnyPrivate {}

/// An inner trait to ensure that only this module can call `get_type_id()`.
trait AnyPrivate {
/// Get the `TypeId` of `self`
fn get_type_id(&self) -> TypeId;
}

impl<T: 'static> Any for T {
/// Get the `TypeId` of `self`
fn get_type_id(&self) -> TypeId {
TypeId::of::<T>()
}
impl<T: 'static> AnyPrivate for T {
fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

impl<T: 'static + AnyPrivate> Any for T {}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
// Implemented as three extension traits so that the methods can be generic.
///////////////////////////////////////////////////////////////////////////////

/// Extension methods for a referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
part of `impl Any`"]
pub trait AnyRefExt<'a> {
/// Returns true if the boxed type is the same as `T`
#[stable]
fn is<T: 'static>(self) -> bool;

/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
fn as_ref<T: 'static>(self) -> Option<&'a T>;
#[unstable = "naming conventions around acquiring references may change"]
fn downcast_ref<T: 'static>(self) -> Option<&'a T>;

/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[deprecated = "this function has been renamed to `downcast_ref`"]
fn as_ref<T: 'static>(self) -> Option<&'a T> {
self.downcast_ref::<T>()
}
}

#[stable]
impl<'a> AnyRefExt<'a> for &'a Any {
#[inline]
#[stable]
fn is<T: 'static>(self) -> bool {
// Get TypeId of the type this function is instantiated with
let t = TypeId::of::<T>();
Expand All @@ -126,7 +147,8 @@ impl<'a> AnyRefExt<'a> for &'a Any {
}

#[inline]
fn as_ref<T: 'static>(self) -> Option<&'a T> {
#[unstable = "naming conventions around acquiring references may change"]
fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
Expand All @@ -142,15 +164,27 @@ impl<'a> AnyRefExt<'a> for &'a Any {
}

/// Extension methods for a mutable referenced `Any` trait object
#[unstable = "this trait will not be necessary once DST lands, it will be a \
part of `impl Any`"]
pub trait AnyMutRefExt<'a> {
/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
fn as_mut<T: 'static>(self) -> Option<&'a mut T>;
#[unstable = "naming conventions around acquiring references may change"]
fn downcast_mut<T: 'static>(self) -> Option<&'a mut T>;

/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[deprecated = "this function has been renamed to `downcast_mut`"]
fn as_mut<T: 'static>(self) -> Option<&'a mut T> {
self.downcast_mut::<T>()
}
}

#[stable]
impl<'a> AnyMutRefExt<'a> for &'a mut Any {
#[inline]
fn as_mut<T: 'static>(self) -> Option<&'a mut T> {
#[unstable = "naming conventions around acquiring references may change"]
fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
Expand Down
33 changes: 15 additions & 18 deletions src/libcore/atomics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,29 @@

use intrinsics;
use std::kinds::marker;
use ty::Unsafe;
use cell::UnsafeCell;

/// An atomic boolean type.
pub struct AtomicBool {
v: Unsafe<uint>,
v: UnsafeCell<uint>,
nocopy: marker::NoCopy
}

/// A signed atomic integer type, supporting basic atomic arithmetic operations
pub struct AtomicInt {
v: Unsafe<int>,
v: UnsafeCell<int>,
nocopy: marker::NoCopy
}

/// An unsigned atomic integer type, supporting basic atomic arithmetic operations
pub struct AtomicUint {
v: Unsafe<uint>,
v: UnsafeCell<uint>,
nocopy: marker::NoCopy
}

/// An unsafe atomic pointer. Only supports basic atomic operations
pub struct AtomicPtr<T> {
p: Unsafe<uint>,
p: UnsafeCell<uint>,
nocopy: marker::NoCopy
}

Expand Down Expand Up @@ -69,17 +69,14 @@ pub enum Ordering {
}

/// An `AtomicBool` initialized to `false`
pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v: Unsafe{value: 0,
marker1: marker::InvariantType},
nocopy: marker::NoCopy };
pub static INIT_ATOMIC_BOOL: AtomicBool =
AtomicBool { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
/// An `AtomicInt` initialized to `0`
pub static INIT_ATOMIC_INT : AtomicInt = AtomicInt { v: Unsafe{value: 0,
marker1: marker::InvariantType},
nocopy: marker::NoCopy };
pub static INIT_ATOMIC_INT: AtomicInt =
AtomicInt { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
/// An `AtomicUint` initialized to `0`
pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v: Unsafe{value: 0,
marker1: marker::InvariantType},
nocopy: marker::NoCopy };
pub static INIT_ATOMIC_UINT: AtomicUint =
AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy };

// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
static UINT_TRUE: uint = -1;
Expand All @@ -88,7 +85,7 @@ impl AtomicBool {
/// Create a new `AtomicBool`
pub fn new(v: bool) -> AtomicBool {
let val = if v { UINT_TRUE } else { 0 };
AtomicBool { v: Unsafe::new(val), nocopy: marker::NoCopy }
AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
}

/// Load the value
Expand Down Expand Up @@ -289,7 +286,7 @@ impl AtomicBool {
impl AtomicInt {
/// Create a new `AtomicInt`
pub fn new(v: int) -> AtomicInt {
AtomicInt {v: Unsafe::new(v), nocopy: marker::NoCopy}
AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
}

/// Load the value
Expand Down Expand Up @@ -401,7 +398,7 @@ impl AtomicInt {
impl AtomicUint {
/// Create a new `AtomicUint`
pub fn new(v: uint) -> AtomicUint {
AtomicUint { v: Unsafe::new(v), nocopy: marker::NoCopy }
AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
}

/// Load the value
Expand Down Expand Up @@ -513,7 +510,7 @@ impl AtomicUint {
impl<T> AtomicPtr<T> {
/// Create a new `AtomicPtr`
pub fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: Unsafe::new(p as uint), nocopy: marker::NoCopy }
AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
}

/// Load the value
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
//! The boolean type

#![doc(primitive = "bool")]
#![unstable = "this module is purely for documentation and it will likely be \
removed from the public api"]

Loading