diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/any.rs | 24 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 43 |
3 files changed, 57 insertions, 11 deletions
diff --git a/src/libcore/any.rs b/src/libcore/any.rs index c94d8e2ed0c..d3bc07b173a 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -55,7 +55,7 @@ //! } //! //! // This function wants to log its parameter out prior to doing work with it. -//! fn do_work<T: Debug + 'static>(value: &T) { +//! fn do_work<T: Any + Debug>(value: &T) { //! log(value); //! // ...do some other work //! } @@ -76,7 +76,7 @@ use mem::transmute; use option::Option::{self, Some, None}; use raw::TraitObject; use intrinsics; -use marker::Sized; +use marker::{Reflect, Sized}; /////////////////////////////////////////////////////////////////////////////// // Any trait @@ -88,14 +88,16 @@ use marker::Sized; /// /// [mod]: ../index.html #[stable(feature = "rust1", since = "1.0.0")] -pub trait Any: 'static { +pub trait Any: Reflect + 'static { /// Get the `TypeId` of `self` #[unstable(feature = "core", reason = "this method will likely be replaced by an associated static")] fn get_type_id(&self) -> TypeId; } -impl<T: 'static> Any for T { +impl<T> Any for T + where T: Reflect + 'static +{ fn get_type_id(&self) -> TypeId { TypeId::of::<T>() } } @@ -107,7 +109,7 @@ impl Any { /// Returns true if the boxed type is the same as `T` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn is<T: 'static>(&self) -> bool { + pub fn is<T: Any>(&self) -> bool { // Get TypeId of the type this function is instantiated with let t = TypeId::of::<T>(); @@ -122,7 +124,7 @@ impl Any { /// `None` if it isn't. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { + pub fn downcast_ref<T: Any>(&self) -> Option<&T> { if self.is::<T>() { unsafe { // Get the raw representation of the trait object @@ -140,7 +142,7 @@ impl Any { /// `None` if it isn't. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> { + pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> { if self.is::<T>() { unsafe { // Get the raw representation of the trait object @@ -159,21 +161,21 @@ impl Any+Send { /// Forwards to the method defined on the type `Any`. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn is<T: 'static>(&self) -> bool { + pub fn is<T: Any>(&self) -> bool { Any::is::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { + pub fn downcast_ref<T: Any>(&self) -> Option<&T> { Any::downcast_ref::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> { + pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> { Any::downcast_mut::<T>(self) } } @@ -202,7 +204,7 @@ impl TypeId { /// instantiated with #[unstable(feature = "core", reason = "may grow a `Reflect` bound soon via marker traits")] - pub fn of<T: ?Sized + 'static>() -> TypeId { + pub fn of<T: ?Sized + Any>() -> TypeId { TypeId { t: unsafe { intrinsics::type_id::<T>() }, } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a2b13584270..7225b016e6b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -72,6 +72,7 @@ #![feature(rustc_attrs)] #![feature(optin_builtin_traits)] #![feature(concat_idents)] +#![feature(reflect)] #[macro_use] mod macros; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 88c10e3661e..35fde2cb64a 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -450,3 +450,46 @@ pub struct CovariantType<T>; #[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")] #[lang="invariant_type"] pub struct InvariantType<T>; + +/// A marker trait indicates a type that can be reflected over. This +/// trait is implemented for all types. Its purpose is to ensure that +/// when you write a generic function that will employ reflection, +/// that must be reflected (no pun intended) in the generic bounds of +/// that function. Here is an example: +/// +/// ``` +/// #![feature(core)] +/// use std::marker::Reflect; +/// use std::any::Any; +/// fn foo<T:Reflect+'static>(x: &T) { +/// let any: &Any = x; +/// if any.is::<u32>() { println!("u32"); } +/// } +/// ``` +/// +/// Without the declaration `T:Reflect`, `foo` would not type check +/// (note: as a matter of style, it would be preferable to to write +/// `T:Any`, because `T:Any` implies `T:Reflect` and `T:'static`, but +/// we use `Reflect` here to show how it works). The `Reflect` bound +/// thus serves to alert `foo`'s caller to the fact that `foo` may +/// behave differently depending on whether `T=u32` or not. In +/// particular, thanks to the `Reflect` bound, callers know that a +/// function declared like `fn bar<T>(...)` will always act in +/// precisely the same way no matter what type `T` is supplied, +/// beacuse there are no bounds declared on `T`. (The ability for a +/// caller to reason about what a function may do based solely on what +/// generic bounds are declared is often called the ["parametricity +/// property"][1].) +/// +/// [1]: http://en.wikipedia.org/wiki/Parametricity +#[rustc_reflect_like] +#[unstable(feature = "core", reason = "requires RFC and more experience")] +pub trait Reflect : MarkerTrait { +} + +#[cfg(stage0)] +impl<T> Reflect for T { } + +#[cfg(not(stage0))] +impl Reflect for .. { } + |
