Skip to content

Commit 9f6a220

Browse files
committed
auto merge of #21165 : alexcrichton/rust/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.
2 parents 378fb58 + 80d73e9 commit 9f6a220

File tree

16 files changed

+102
-122
lines changed

16 files changed

+102
-122
lines changed

Diff for: src/liballoc/boxed.rs

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

135135
/// Extension methods for an owning `Any` trait object.
136-
#[unstable = "post-DST and coherence changes, this will not be a trait but \
137-
rather a direct `impl` on `Box<Any>`"]
136+
#[unstable = "this trait will likely disappear once compiler bugs blocking \
137+
a direct impl on `Box<Any>` have been fixed "]
138+
// FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're
139+
// removing this please make sure that you can downcase on
140+
// `Box<Any + Send>` as well as `Box<Any>`
138141
pub trait BoxAny {
139142
/// Returns the boxed value if it is of type `T`, or
140143
/// `Err(Self)` if it isn't.
141144
#[stable]
142145
fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
143146
}
144147

148+
#[stable]
145149
impl BoxAny for Box<Any> {
146150
#[inline]
147-
#[unstable = "method may be renamed with respect to other downcasting \
148-
methods"]
149151
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
150152
if self.is::<T>() {
151153
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

-16
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ mod impls {
126126
use prelude::*;
127127

128128
use borrow::{Cow, ToOwned};
129-
use intrinsics::TypeId;
130129
use mem;
131130
use super::{Hash, Writer};
132131
use num::Int;
@@ -260,13 +259,6 @@ mod impls {
260259
}
261260
}
262261

263-
impl<S: Writer> Hash<S> for TypeId {
264-
#[inline]
265-
fn hash(&self, state: &mut S) {
266-
self.hash().hash(state)
267-
}
268-
}
269-
270262
impl<'a, T, B: ?Sized, S> Hash<S> for Cow<'a, T, B>
271263
where B: Hash<S> + ToOwned<T>
272264
{
@@ -282,7 +274,6 @@ mod impls {
282274
use prelude::*;
283275

284276
use borrow::{Cow, ToOwned};
285-
use intrinsics::TypeId;
286277
use mem;
287278
use super::{Hash, Writer, Hasher};
288279
use num::Int;
@@ -416,13 +407,6 @@ mod impls {
416407
}
417408
}
418409

419-
impl<S: Writer + Hasher> Hash<S> for TypeId {
420-
#[inline]
421-
fn hash(&self, state: &mut S) {
422-
self.hash().hash(state)
423-
}
424-
}
425-
426410
impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B>
427411
where B: Hash<S> + ToOwned<T>
428412
{

Diff for: src/libcore/intrinsics.rs

+3-24
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#[cfg(not(stage0))]
4646
use marker::Sized;
4747

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

5052
#[lang="ty_desc"]
@@ -208,7 +210,7 @@ extern "rust-intrinsic" {
208210
/// function will return the same value for a type regardless of whichever
209211
/// crate it is invoked in.
210212
#[cfg(not(stage0))]
211-
pub fn type_id<T: ?Sized + 'static>() -> TypeId;
213+
pub fn type_id<T: ?Sized + 'static>() -> u64;
212214

213215
#[cfg(stage0)]
214216
pub fn type_id<T: 'static>() -> TypeId;
@@ -551,26 +553,3 @@ extern "rust-intrinsic" {
551553
pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
552554
}
553555

554-
555-
/// `TypeId` represents a globally unique identifier for a type
556-
#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and
557-
// middle/lang_items.rs
558-
#[derive(Clone, Copy, PartialEq, Eq, Show)]
559-
pub struct TypeId {
560-
t: u64,
561-
}
562-
563-
impl TypeId {
564-
/// Returns the `TypeId` of the type this generic function has been instantiated with
565-
#[cfg(not(stage0))]
566-
pub fn of<T: ?Sized + 'static>() -> TypeId {
567-
unsafe { type_id::<T>() }
568-
}
569-
570-
#[cfg(stage0)]
571-
pub fn of<T: 'static>() -> TypeId {
572-
unsafe { type_id::<T>() }
573-
}
574-
575-
pub fn hash(&self) -> u64 { self.t }
576-
}

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)