diff options
| author | bors <bors@rust-lang.org> | 2015-01-19 23:35:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-19 23:35:12 +0000 |
| commit | 65b61ffb3f55c996eceded6c91281911b671d978 (patch) | |
| tree | d0ab6ddb6042d3fdaf3824372a8e2d6fc9def19a /src | |
| parent | 7f8c687fdfbf076ef1667f4d95633d4e0812b516 (diff) | |
| parent | 70f7165cc8975337964118af4d30f40b98f5edeb (diff) | |
| download | rust-65b61ffb3f55c996eceded6c91281911b671d978.tar.gz rust-65b61ffb3f55c996eceded6c91281911b671d978.zip | |
Auto merge of #21165 - alexcrichton:second-pass-type-id, r=aturon
This commit aims to stabilize the `TypeId` abstraction by moving it out of the `intrinsics` module into the `any` module of the standard library. Specifically, * `TypeId` is now defined at `std::any::TypeId` * `TypeId::hash` has been removed in favor of an implementation of `Hash`. This commit also performs a final pass over the `any` module, confirming the following: * `Any::get_type_id` remains unstable as *usage* of the `Any` trait will likely never require this, and the `Any` trait does not need to be implemented for any other types. As a result, this implementation detail can remain unstable until associated statics are implemented. * `Any::downcast_ref` is now stable * `Any::downcast_mut` is now stable * `BoxAny` remains unstable. While a direct impl on `Box<Any>` is allowed today it does not allow downcasting of trait objects like `Box<Any + Send>` (those returned from `Thread::join`). This is covered by #18737. * `BoxAny::downcast` is now stable.
Diffstat (limited to 'src')
| -rw-r--r-- | src/liballoc/boxed.rs | 10 | ||||
| -rw-r--r-- | src/libcore/any.rs | 54 | ||||
| -rw-r--r-- | src/libcore/hash/mod.rs | 8 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 24 | ||||
| -rw-r--r-- | src/libcoretest/intrinsics.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/lang_items.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/trans/intrinsic.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 14 | ||||
| -rw-r--r-- | src/test/auxiliary/issue13507.rs | 2 | ||||
| -rw-r--r-- | src/test/auxiliary/typeid-intrinsic.rs | 21 | ||||
| -rw-r--r-- | src/test/auxiliary/typeid-intrinsic2.rs | 21 | ||||
| -rw-r--r-- | src/test/compile-fail/extern-with-type-bounds.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-18389.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/issue-13507-2.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/type-id-higher-rank.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/typeid-intrinsic.rs | 43 |
16 files changed, 105 insertions, 108 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8ad0c152dc8..a2cc98c7d01 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -125,8 +125,11 @@ impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> { } /// Extension methods for an owning `Any` trait object. -#[unstable = "post-DST and coherence changes, this will not be a trait but \ - rather a direct `impl` on `Box<Any>`"] +#[unstable = "this trait will likely disappear once compiler bugs blocking \ + a direct impl on `Box<Any>` have been fixed "] +// FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're +// removing this please make sure that you can downcase on +// `Box<Any + Send>` as well as `Box<Any>` pub trait BoxAny { /// Returns the boxed value if it is of type `T`, or /// `Err(Self)` if it isn't. @@ -134,10 +137,9 @@ pub trait BoxAny { fn downcast<T: 'static>(self) -> Result<Box<T>, Self>; } +#[stable] impl BoxAny for Box<Any> { #[inline] - #[unstable = "method may be renamed with respect to other downcasting \ - methods"] fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> { if self.is::<T>() { unsafe { diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 797687a9ad9..20ed2253861 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -71,11 +71,11 @@ #![stable] -use mem::{transmute}; -use option::Option; -use option::Option::{Some, None}; +use mem::transmute; +use option::Option::{self, Some, None}; use raw::TraitObject; -use intrinsics::TypeId; +use intrinsics; +#[cfg(not(stage0))] use marker::Sized; /////////////////////////////////////////////////////////////////////////////// // Any trait @@ -99,7 +99,6 @@ impl<T: 'static> Any for T { /////////////////////////////////////////////////////////////////////////////// // Extension methods for Any trait objects. -// Implemented as three extension traits so that the methods can be generic. /////////////////////////////////////////////////////////////////////////////// impl Any { @@ -119,9 +118,9 @@ impl Any { /// Returns some reference to the boxed value if it is of type `T`, or /// `None` if it isn't. - #[unstable = "naming conventions around acquiring references may change"] + #[stable] #[inline] - pub fn downcast_ref<'a, T: 'static>(&'a self) -> Option<&'a T> { + pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { if self.is::<T>() { unsafe { // Get the raw representation of the trait object @@ -137,9 +136,9 @@ impl Any { /// Returns some mutable reference to the boxed value if it is of type `T`, or /// `None` if it isn't. - #[unstable = "naming conventions around acquiring references may change"] + #[stable] #[inline] - pub fn downcast_mut<'a, T: 'static>(&'a mut self) -> Option<&'a mut T> { + pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> { if self.is::<T>() { unsafe { // Get the raw representation of the trait object @@ -153,3 +152,40 @@ impl Any { } } } + +/////////////////////////////////////////////////////////////////////////////// +// TypeID and its methods +/////////////////////////////////////////////////////////////////////////////// + +/// A `TypeId` represents a globally unique identifier for a type. +/// +/// Each `TypeId` is an opaque object which does not allow inspection of what's +/// inside but does allow basic operations such as cloning, comparison, +/// printing, and showing. +/// +/// A `TypeId` is currently only available for types which ascribe to `'static`, +/// but this limitation may be removed in the future. +#[cfg_attr(stage0, lang = "type_id")] +#[derive(Clone, Copy, PartialEq, Eq, Show, Hash)] +#[stable] +pub struct TypeId { + t: u64, +} + +impl TypeId { + /// Returns the `TypeId` of the type this generic function has been + /// instantiated with + #[cfg(not(stage0))] + #[unstable = "may grow a `Reflect` bound soon via marker traits"] + pub fn of<T: ?Sized + 'static>() -> TypeId { + TypeId { + t: unsafe { intrinsics::type_id::<T>() }, + } + } + + /// dox + #[cfg(stage0)] + pub fn of<T: 'static>() -> TypeId { + unsafe { intrinsics::type_id::<T>() } + } +} diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 37e4a105a30..742e6239017 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -62,7 +62,6 @@ use prelude::*; use borrow::{Cow, ToOwned}; use default::Default; -use intrinsics::TypeId; use mem; use num::Int; @@ -243,13 +242,6 @@ impl<S: Writer + Hasher, T> Hash<S> for *mut T { } } -impl<S: Writer + Hasher> Hash<S> for TypeId { - #[inline] - fn hash(&self, state: &mut S) { - self.hash().hash(state) - } -} - impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B> where B: Hash<S> + ToOwned<T> { diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 40db0def626..73be68289c9 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -44,6 +44,8 @@ use marker::Sized; +#[cfg(stage0)] use any::TypeId; + pub type GlueFn = extern "Rust" fn(*const i8); #[lang="ty_desc"] @@ -206,6 +208,10 @@ extern "rust-intrinsic" { /// Gets an identifier which is globally unique to the specified type. This /// function will return the same value for a type regardless of whichever /// crate it is invoked in. + #[cfg(not(stage0))] + pub fn type_id<T: ?Sized + 'static>() -> u64; + + #[cfg(stage0)] pub fn type_id<T: ?Sized + 'static>() -> TypeId; /// Create a value initialized to zero. @@ -545,21 +551,3 @@ extern "rust-intrinsic" { /// Performs checked `u64` multiplication. pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool); } - - -/// `TypeId` represents a globally unique identifier for a type -#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and - // middle/lang_items.rs -#[derive(Clone, Copy, PartialEq, Eq, Show)] -pub struct TypeId { - t: u64, -} - -impl TypeId { - /// Returns the `TypeId` of the type this generic function has been instantiated with - pub fn of<T: ?Sized + 'static>() -> TypeId { - unsafe { type_id::<T>() } - } - - pub fn hash(&self) -> u64 { self.t } -} diff --git a/src/libcoretest/intrinsics.rs b/src/libcoretest/intrinsics.rs index bcf8a6a433b..b836f5f3f69 100644 --- a/src/libcoretest/intrinsics.rs +++ b/src/libcoretest/intrinsics.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::intrinsics::TypeId; +use core::any::TypeId; #[test] fn test_typeid_sized_types() { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index db6a4768857..ff79ace9924 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -307,8 +307,6 @@ lets_do_this! { TyDescStructLangItem, "ty_desc", ty_desc; OpaqueStructLangItem, "opaque", opaque; - TypeIdLangItem, "type_id", type_id; - EhPersonalityLangItem, "eh_personality", eh_personality; ExchangeHeapLangItem, "exchange_heap", exchange_heap; diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 6d0f7746cad..771c51d629f 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -355,8 +355,6 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, ccx.tcx(), *substs.types.get(FnSpace, 0), &ccx.link_meta().crate_hash); - // NB: This needs to be kept in lockstep with the TypeId struct in - // the intrinsic module C_u64(ccx, hash) } (_, "init") => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a4fa594621e..f610456f73c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -104,7 +104,6 @@ use rscope::RegionScope; use session::Session; use {CrateCtxt, lookup_def_ccx, no_params, require_same_types}; use TypeAndSubsts; -use middle::lang_items::TypeIdLangItem; use lint; use util::common::{block_query, indenter, loop_query}; use util::ppaux::{self, Repr}; @@ -5239,18 +5238,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { }); (1u, Vec::new(), td_ptr) } - "type_id" => { - let langid = ccx.tcx.lang_items.require(TypeIdLangItem); - match langid { - Ok(did) => (1u, - Vec::new(), - ty::mk_struct(ccx.tcx, did, - ccx.tcx.mk_substs(subst::Substs::empty()))), - Err(msg) => { - tcx.sess.span_fatal(it.span, &msg[]); - } - } - }, + "type_id" => (1u, Vec::new(), ccx.tcx.types.u64), "offset" => { (1, vec!( diff --git a/src/test/auxiliary/issue13507.rs b/src/test/auxiliary/issue13507.rs index c2820a8d4ae..f24721adb5d 100644 --- a/src/test/auxiliary/issue13507.rs +++ b/src/test/auxiliary/issue13507.rs @@ -9,7 +9,7 @@ // except according to those terms. pub mod testtypes { - use std::intrinsics::TypeId; + use std::any::TypeId; pub fn type_ids() -> Vec<TypeId> { let mut ids = vec!(); diff --git a/src/test/auxiliary/typeid-intrinsic.rs b/src/test/auxiliary/typeid-intrinsic.rs index b6c35f48010..82f613ee117 100644 --- a/src/test/auxiliary/typeid-intrinsic.rs +++ b/src/test/auxiliary/typeid-intrinsic.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::intrinsics; -use std::intrinsics::TypeId; +use std::any::TypeId; pub struct A; pub struct B(Option<A>); @@ -21,13 +20,13 @@ pub type F = Option<int>; pub type G = uint; pub type H = &'static str; -pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() } -pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() } -pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() } -pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() } -pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() } -pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() } -pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() } -pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() } +pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() } +pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() } +pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() } +pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() } +pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() } +pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() } +pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() } +pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() } -pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() } +pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() } diff --git a/src/test/auxiliary/typeid-intrinsic2.rs b/src/test/auxiliary/typeid-intrinsic2.rs index b6c35f48010..82f613ee117 100644 --- a/src/test/auxiliary/typeid-intrinsic2.rs +++ b/src/test/auxiliary/typeid-intrinsic2.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::intrinsics; -use std::intrinsics::TypeId; +use std::any::TypeId; pub struct A; pub struct B(Option<A>); @@ -21,13 +20,13 @@ pub type F = Option<int>; pub type G = uint; pub type H = &'static str; -pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() } -pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() } -pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() } -pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() } -pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() } -pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() } -pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() } -pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() } +pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() } +pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() } +pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() } +pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() } +pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() } +pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() } +pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() } +pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() } -pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() } +pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() } diff --git a/src/test/compile-fail/extern-with-type-bounds.rs b/src/test/compile-fail/extern-with-type-bounds.rs index d2c88865d54..ade8b397e00 100644 --- a/src/test/compile-fail/extern-with-type-bounds.rs +++ b/src/test/compile-fail/extern-with-type-bounds.rs @@ -10,11 +10,9 @@ #![feature(intrinsics)] -use std::intrinsics::TypeId; - extern "rust-intrinsic" { // Real example from libcore - fn type_id<T: ?Sized + 'static>() -> TypeId; + fn type_id<T: ?Sized + 'static>() -> u64; // Silent bounds made explicit to make sure they are actually // resolved. diff --git a/src/test/compile-fail/issue-18389.rs b/src/test/compile-fail/issue-18389.rs index 37bb1cb1911..20323e99003 100644 --- a/src/test/compile-fail/issue-18389.rs +++ b/src/test/compile-fail/issue-18389.rs @@ -11,7 +11,7 @@ #![feature(unboxed_closures)] use std::any::Any; -use std::intrinsics::TypeId; +use std::any::TypeId; pub trait Pt {} pub trait Rt {} diff --git a/src/test/run-pass/issue-13507-2.rs b/src/test/run-pass/issue-13507-2.rs index 4d150e7a68e..1c0283070a2 100644 --- a/src/test/run-pass/issue-13507-2.rs +++ b/src/test/run-pass/issue-13507-2.rs @@ -12,7 +12,7 @@ extern crate issue13507; use issue13507::testtypes; -use std::intrinsics::TypeId; +use std::any::TypeId; pub fn type_ids() -> Vec<TypeId> { let mut ids = vec!(); diff --git a/src/test/run-pass/type-id-higher-rank.rs b/src/test/run-pass/type-id-higher-rank.rs index 7287d149f51..b114391a36d 100644 --- a/src/test/run-pass/type-id-higher-rank.rs +++ b/src/test/run-pass/type-id-higher-rank.rs @@ -13,7 +13,7 @@ #![feature(unboxed_closures)] -use std::intrinsics::TypeId; +use std::any::TypeId; fn main() { // Bare fns diff --git a/src/test/run-pass/typeid-intrinsic.rs b/src/test/run-pass/typeid-intrinsic.rs index e346c4ff349..a251fcc7327 100644 --- a/src/test/run-pass/typeid-intrinsic.rs +++ b/src/test/run-pass/typeid-intrinsic.rs @@ -15,41 +15,40 @@ extern crate "typeid-intrinsic" as other1; extern crate "typeid-intrinsic2" as other2; use std::hash::{self, SipHasher}; -use std::intrinsics; -use std::intrinsics::TypeId; +use std::any::TypeId; struct A; struct Test; pub fn main() { unsafe { - assert_eq!(intrinsics::type_id::<other1::A>(), other1::id_A()); - assert_eq!(intrinsics::type_id::<other1::B>(), other1::id_B()); - assert_eq!(intrinsics::type_id::<other1::C>(), other1::id_C()); - assert_eq!(intrinsics::type_id::<other1::D>(), other1::id_D()); - assert_eq!(intrinsics::type_id::<other1::E>(), other1::id_E()); - assert_eq!(intrinsics::type_id::<other1::F>(), other1::id_F()); - assert_eq!(intrinsics::type_id::<other1::G>(), other1::id_G()); - assert_eq!(intrinsics::type_id::<other1::H>(), other1::id_H()); + assert_eq!(TypeId::of::<other1::A>(), other1::id_A()); + assert_eq!(TypeId::of::<other1::B>(), other1::id_B()); + assert_eq!(TypeId::of::<other1::C>(), other1::id_C()); + assert_eq!(TypeId::of::<other1::D>(), other1::id_D()); + assert_eq!(TypeId::of::<other1::E>(), other1::id_E()); + assert_eq!(TypeId::of::<other1::F>(), other1::id_F()); + assert_eq!(TypeId::of::<other1::G>(), other1::id_G()); + assert_eq!(TypeId::of::<other1::H>(), other1::id_H()); - assert_eq!(intrinsics::type_id::<other2::A>(), other2::id_A()); - assert_eq!(intrinsics::type_id::<other2::B>(), other2::id_B()); - assert_eq!(intrinsics::type_id::<other2::C>(), other2::id_C()); - assert_eq!(intrinsics::type_id::<other2::D>(), other2::id_D()); - assert_eq!(intrinsics::type_id::<other2::E>(), other2::id_E()); - assert_eq!(intrinsics::type_id::<other2::F>(), other2::id_F()); - assert_eq!(intrinsics::type_id::<other2::G>(), other2::id_G()); - assert_eq!(intrinsics::type_id::<other2::H>(), other2::id_H()); + assert_eq!(TypeId::of::<other2::A>(), other2::id_A()); + assert_eq!(TypeId::of::<other2::B>(), other2::id_B()); + assert_eq!(TypeId::of::<other2::C>(), other2::id_C()); + assert_eq!(TypeId::of::<other2::D>(), other2::id_D()); + assert_eq!(TypeId::of::<other2::E>(), other2::id_E()); + assert_eq!(TypeId::of::<other2::F>(), other2::id_F()); + assert_eq!(TypeId::of::<other2::G>(), other2::id_G()); + assert_eq!(TypeId::of::<other2::H>(), other2::id_H()); assert_eq!(other1::id_F(), other2::id_F()); assert_eq!(other1::id_G(), other2::id_G()); assert_eq!(other1::id_H(), other2::id_H()); - assert_eq!(intrinsics::type_id::<int>(), other2::foo::<int>()); - assert_eq!(intrinsics::type_id::<int>(), other1::foo::<int>()); + assert_eq!(TypeId::of::<int>(), other2::foo::<int>()); + assert_eq!(TypeId::of::<int>(), other1::foo::<int>()); assert_eq!(other2::foo::<int>(), other1::foo::<int>()); - assert_eq!(intrinsics::type_id::<A>(), other2::foo::<A>()); - assert_eq!(intrinsics::type_id::<A>(), other1::foo::<A>()); + assert_eq!(TypeId::of::<A>(), other2::foo::<A>()); + assert_eq!(TypeId::of::<A>(), other1::foo::<A>()); assert_eq!(other2::foo::<A>(), other1::foo::<A>()); } |
