Skip to content

Commit 70f7165

Browse files
committed
std: Stabilize TypeId and tweak BoxAny
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.
1 parent dcaeb6a commit 70f7165

File tree

16 files changed

+105
-108
lines changed

16 files changed

+105
-108
lines changed

Diff for: src/liballoc/boxed.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,21 @@ impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
125125
}
126126

127127
/// Extension methods for an owning `Any` trait object.
128-
#[unstable = "post-DST and coherence changes, this will not be a trait but \
129-
rather a direct `impl` on `Box<Any>`"]
128+
#[unstable = "this trait will likely disappear once compiler bugs blocking \
129+
a direct impl on `Box<Any>` have been fixed "]
130+
// FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're
131+
// removing this please make sure that you can downcase on
132+
// `Box<Any + Send>` as well as `Box<Any>`
130133
pub trait BoxAny {
131134
/// Returns the boxed value if it is of type `T`, or
132135
/// `Err(Self)` if it isn't.
133136
#[stable]
134137
fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
135138
}
136139

140+
#[stable]
137141
impl BoxAny for Box<Any> {
138142
#[inline]
139-
#[unstable = "method may be renamed with respect to other downcasting \
140-
methods"]
141143
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
142144
if self.is::<T>() {
143145
unsafe {

Diff for: src/libcore/any.rs

+45-9
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@
7171
7272
#![stable]
7373

74-
use mem::{transmute};
75-
use option::Option;
76-
use option::Option::{Some, None};
74+
use mem::transmute;
75+
use option::Option::{self, Some, None};
7776
use raw::TraitObject;
78-
use intrinsics::TypeId;
77+
use intrinsics;
78+
#[cfg(not(stage0))] use marker::Sized;
7979

8080
///////////////////////////////////////////////////////////////////////////////
8181
// Any trait
@@ -99,7 +99,6 @@ impl<T: 'static> Any for T {
9999

100100
///////////////////////////////////////////////////////////////////////////////
101101
// Extension methods for Any trait objects.
102-
// Implemented as three extension traits so that the methods can be generic.
103102
///////////////////////////////////////////////////////////////////////////////
104103

105104
impl Any {
@@ -119,9 +118,9 @@ impl Any {
119118

120119
/// Returns some reference to the boxed value if it is of type `T`, or
121120
/// `None` if it isn't.
122-
#[unstable = "naming conventions around acquiring references may change"]
121+
#[stable]
123122
#[inline]
124-
pub fn downcast_ref<'a, T: 'static>(&'a self) -> Option<&'a T> {
123+
pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
125124
if self.is::<T>() {
126125
unsafe {
127126
// Get the raw representation of the trait object
@@ -137,9 +136,9 @@ impl Any {
137136

138137
/// Returns some mutable reference to the boxed value if it is of type `T`, or
139138
/// `None` if it isn't.
140-
#[unstable = "naming conventions around acquiring references may change"]
139+
#[stable]
141140
#[inline]
142-
pub fn downcast_mut<'a, T: 'static>(&'a mut self) -> Option<&'a mut T> {
141+
pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
143142
if self.is::<T>() {
144143
unsafe {
145144
// Get the raw representation of the trait object
@@ -153,3 +152,40 @@ impl Any {
153152
}
154153
}
155154
}
155+
156+
///////////////////////////////////////////////////////////////////////////////
157+
// TypeID and its methods
158+
///////////////////////////////////////////////////////////////////////////////
159+
160+
/// A `TypeId` represents a globally unique identifier for a type.
161+
///
162+
/// Each `TypeId` is an opaque object which does not allow inspection of what's
163+
/// inside but does allow basic operations such as cloning, comparison,
164+
/// printing, and showing.
165+
///
166+
/// A `TypeId` is currently only available for types which ascribe to `'static`,
167+
/// but this limitation may be removed in the future.
168+
#[cfg_attr(stage0, lang = "type_id")]
169+
#[derive(Clone, Copy, PartialEq, Eq, Show, Hash)]
170+
#[stable]
171+
pub struct TypeId {
172+
t: u64,
173+
}
174+
175+
impl TypeId {
176+
/// Returns the `TypeId` of the type this generic function has been
177+
/// instantiated with
178+
#[cfg(not(stage0))]
179+
#[unstable = "may grow a `Reflect` bound soon via marker traits"]
180+
pub fn of<T: ?Sized + 'static>() -> TypeId {
181+
TypeId {
182+
t: unsafe { intrinsics::type_id::<T>() },
183+
}
184+
}
185+
186+
/// dox
187+
#[cfg(stage0)]
188+
pub fn of<T: 'static>() -> TypeId {
189+
unsafe { intrinsics::type_id::<T>() }
190+
}
191+
}

Diff for: src/libcore/hash/mod.rs

-8
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ use prelude::*;
6262

6363
use borrow::{Cow, ToOwned};
6464
use default::Default;
65-
use intrinsics::TypeId;
6665
use mem;
6766
use num::Int;
6867

@@ -243,13 +242,6 @@ impl<S: Writer + Hasher, T> Hash<S> for *mut T {
243242
}
244243
}
245244

246-
impl<S: Writer + Hasher> Hash<S> for TypeId {
247-
#[inline]
248-
fn hash(&self, state: &mut S) {
249-
self.hash().hash(state)
250-
}
251-
}
252-
253245
impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B>
254246
where B: Hash<S> + ToOwned<T>
255247
{

Diff for: src/libcore/intrinsics.rs

+6-18
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444

4545
use marker::Sized;
4646

47+
#[cfg(stage0)] use any::TypeId;
48+
4749
pub type GlueFn = extern "Rust" fn(*const i8);
4850

4951
#[lang="ty_desc"]
@@ -206,6 +208,10 @@ extern "rust-intrinsic" {
206208
/// Gets an identifier which is globally unique to the specified type. This
207209
/// function will return the same value for a type regardless of whichever
208210
/// crate it is invoked in.
211+
#[cfg(not(stage0))]
212+
pub fn type_id<T: ?Sized + 'static>() -> u64;
213+
214+
#[cfg(stage0)]
209215
pub fn type_id<T: ?Sized + 'static>() -> TypeId;
210216

211217
/// Create a value initialized to zero.
@@ -545,21 +551,3 @@ extern "rust-intrinsic" {
545551
/// Performs checked `u64` multiplication.
546552
pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
547553
}
548-
549-
550-
/// `TypeId` represents a globally unique identifier for a type
551-
#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and
552-
// middle/lang_items.rs
553-
#[derive(Clone, Copy, PartialEq, Eq, Show)]
554-
pub struct TypeId {
555-
t: u64,
556-
}
557-
558-
impl TypeId {
559-
/// Returns the `TypeId` of the type this generic function has been instantiated with
560-
pub fn of<T: ?Sized + 'static>() -> TypeId {
561-
unsafe { type_id::<T>() }
562-
}
563-
564-
pub fn hash(&self) -> u64 { self.t }
565-
}

Diff for: src/libcoretest/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use core::intrinsics::TypeId;
11+
use core::any::TypeId;
1212

1313
#[test]
1414
fn test_typeid_sized_types() {

Diff for: src/librustc/middle/lang_items.rs

-2
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,6 @@ lets_do_this! {
307307
TyDescStructLangItem, "ty_desc", ty_desc;
308308
OpaqueStructLangItem, "opaque", opaque;
309309

310-
TypeIdLangItem, "type_id", type_id;
311-
312310
EhPersonalityLangItem, "eh_personality", eh_personality;
313311

314312
ExchangeHeapLangItem, "exchange_heap", exchange_heap;

Diff for: src/librustc_trans/trans/intrinsic.rs

-2
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,6 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
355355
ccx.tcx(),
356356
*substs.types.get(FnSpace, 0),
357357
&ccx.link_meta().crate_hash);
358-
// NB: This needs to be kept in lockstep with the TypeId struct in
359-
// the intrinsic module
360358
C_u64(ccx, hash)
361359
}
362360
(_, "init") => {

Diff for: src/librustc_typeck/check/mod.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ use rscope::RegionScope;
104104
use session::Session;
105105
use {CrateCtxt, lookup_def_ccx, no_params, require_same_types};
106106
use TypeAndSubsts;
107-
use middle::lang_items::TypeIdLangItem;
108107
use lint;
109108
use util::common::{block_query, indenter, loop_query};
110109
use util::ppaux::{self, Repr};
@@ -5239,18 +5238,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
52395238
});
52405239
(1u, Vec::new(), td_ptr)
52415240
}
5242-
"type_id" => {
5243-
let langid = ccx.tcx.lang_items.require(TypeIdLangItem);
5244-
match langid {
5245-
Ok(did) => (1u,
5246-
Vec::new(),
5247-
ty::mk_struct(ccx.tcx, did,
5248-
ccx.tcx.mk_substs(subst::Substs::empty()))),
5249-
Err(msg) => {
5250-
tcx.sess.span_fatal(it.span, &msg[]);
5251-
}
5252-
}
5253-
},
5241+
"type_id" => (1u, Vec::new(), ccx.tcx.types.u64),
52545242
"offset" => {
52555243
(1,
52565244
vec!(

Diff for: src/test/auxiliary/issue13507.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
pub mod testtypes {
12-
use std::intrinsics::TypeId;
12+
use std::any::TypeId;
1313

1414
pub fn type_ids() -> Vec<TypeId> {
1515
let mut ids = vec!();

Diff for: src/test/auxiliary/typeid-intrinsic.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::intrinsics;
12-
use std::intrinsics::TypeId;
11+
use std::any::TypeId;
1312

1413
pub struct A;
1514
pub struct B(Option<A>);
@@ -21,13 +20,13 @@ pub type F = Option<int>;
2120
pub type G = uint;
2221
pub type H = &'static str;
2322

24-
pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() }
25-
pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() }
26-
pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() }
27-
pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() }
28-
pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() }
29-
pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() }
30-
pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() }
31-
pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() }
23+
pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
24+
pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
25+
pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
26+
pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
27+
pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
28+
pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
29+
pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
30+
pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
3231

33-
pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
32+
pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() }

Diff for: src/test/auxiliary/typeid-intrinsic2.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::intrinsics;
12-
use std::intrinsics::TypeId;
11+
use std::any::TypeId;
1312

1413
pub struct A;
1514
pub struct B(Option<A>);
@@ -21,13 +20,13 @@ pub type F = Option<int>;
2120
pub type G = uint;
2221
pub type H = &'static str;
2322

24-
pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() }
25-
pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() }
26-
pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() }
27-
pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() }
28-
pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() }
29-
pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() }
30-
pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() }
31-
pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() }
23+
pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
24+
pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
25+
pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
26+
pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
27+
pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
28+
pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
29+
pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
30+
pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
3231

33-
pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
32+
pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() }

Diff for: src/test/compile-fail/extern-with-type-bounds.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010

1111
#![feature(intrinsics)]
1212

13-
use std::intrinsics::TypeId;
14-
1513
extern "rust-intrinsic" {
1614
// Real example from libcore
17-
fn type_id<T: ?Sized + 'static>() -> TypeId;
15+
fn type_id<T: ?Sized + 'static>() -> u64;
1816

1917
// Silent bounds made explicit to make sure they are actually
2018
// resolved.

Diff for: src/test/compile-fail/issue-18389.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![feature(unboxed_closures)]
1212

1313
use std::any::Any;
14-
use std::intrinsics::TypeId;
14+
use std::any::TypeId;
1515

1616
pub trait Pt {}
1717
pub trait Rt {}

Diff for: src/test/run-pass/issue-13507-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
extern crate issue13507;
1313
use issue13507::testtypes;
1414

15-
use std::intrinsics::TypeId;
15+
use std::any::TypeId;
1616

1717
pub fn type_ids() -> Vec<TypeId> {
1818
let mut ids = vec!();

Diff for: src/test/run-pass/type-id-higher-rank.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#![feature(unboxed_closures)]
1515

16-
use std::intrinsics::TypeId;
16+
use std::any::TypeId;
1717

1818
fn main() {
1919
// Bare fns

0 commit comments

Comments
 (0)