OpaqueStructLangItem, // 38
EventLoopFactoryLangItem, // 39
+
+ TypeIdLangItem, // 40
}
pub struct LanguageItems {
- items: [Option<ast::DefId>, ..40]
+ items: [Option<ast::DefId>, ..41]
}
impl LanguageItems {
pub fn new() -> LanguageItems {
LanguageItems {
- items: [ None, ..40 ]
+ items: [ None, ..41 ]
}
}
39 => "event_loop_factory",
+ 40 => "type_id",
+
_ => "???"
}
}
pub fn event_loop_factory(&self) -> Option<ast::DefId> {
self.items[EventLoopFactoryLangItem as uint]
}
+ pub fn type_id(&self) -> Option<ast::DefId> {
+ self.items[TypeIdLangItem as uint]
+ }
}
struct LanguageItemCollector {
item_refs.insert("ty_visitor", TyVisitorTraitLangItem as uint);
item_refs.insert("opaque", OpaqueStructLangItem as uint);
item_refs.insert("event_loop_factory", EventLoopFactoryLangItem as uint);
+ item_refs.insert("type_id", TypeIdLangItem as uint);
LanguageItemCollector {
session: session,
"type_id" => {
let hash = ty::hash_crate_independent(ccx.tcx, substs.tys[0],
ccx.link_meta.extras_hash);
- Ret(bcx, C_i64(hash as i64))
+ // NB: This needs to be kept in lockstep with the TypeId struct in
+ // libstd/unstable/intrinsics.rs
+ let val = C_named_struct(type_of::type_of(ccx, output_type), [C_u64(hash)]);
+ match bcx.fcx.llretptr {
+ Some(ptr) => {
+ Store(bcx, val, ptr);
+ RetVoid(bcx);
+ },
+ None => Ret(bcx, val)
+ }
}
"init" => {
let tp_ty = substs.tys[0];
use middle::typeck::{lookup_def_ccx};
use middle::typeck::no_params;
use middle::typeck::{require_same_types, method_map, vtable_map};
+use middle::lang_items::TypeIdLangItem;
use util::common::{block_query, indenter, loop_query};
use util::ppaux::UserString;
use util::ppaux;
});
(1u, ~[], td_ptr)
}
- "type_id" => (1u, ~[], ty::mk_u64()),
+ "type_id" => {
+ let langid = ccx.tcx.lang_items.require(TypeIdLangItem);
+ match langid {
+ Ok(did) => (1u, ~[], ty::mk_struct(ccx.tcx, did, substs {
+ self_ty: None,
+ tps: ~[],
+ regions: ty::NonerasedRegions(opt_vec::Empty)
+ }) ),
+ Err(msg) => { tcx.sess.span_fatal(it.span, msg); }
+ }
+ },
"visit_tydesc" => {
let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
Ok(t) => t,
//! of any type.
use cast::transmute;
+#[cfg(stage0)]
use cmp::Eq;
use option::{Option, Some, None};
+#[cfg(stage0)]
use to_bytes::{IterBytes, Cb};
use to_str::ToStr;
use unstable::intrinsics;
use util::Void;
+#[cfg(not(stage0))]
+use unstable::intrinsics::TypeId;
///////////////////////////////////////////////////////////////////////////////
// TypeId
///////////////////////////////////////////////////////////////////////////////
/// `TypeId` represents a globally unique identifier for a type
+#[cfg(stage0)]
pub struct TypeId {
priv t: u64,
}
+#[cfg(stage0)]
impl TypeId {
/// Returns the `TypeId` of the type this generic function has been instantiated with
#[inline]
}
}
+#[cfg(stage0)]
impl Eq for TypeId {
#[inline]
fn eq(&self, &other: &TypeId) -> bool {
}
}
+#[cfg(stage0)]
impl IterBytes for TypeId {
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
self.t.iter_bytes(lsb0, f)
static TEST: &'static str = "Test";
- #[test]
- fn type_id() {
- let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
- TypeId::of::<Test>());
- let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
- TypeId::of::<Test>());
-
- assert!(a != b);
- assert!(a != c);
- assert!(b != c);
-
- assert_eq!(a, d);
- assert_eq!(b, e);
- assert_eq!(c, f);
- }
-
- #[test]
- fn type_id_hash() {
- let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
-
- assert_eq!(a.hash(), b.hash());
- }
-
#[test]
fn any_as_void_ptr() {
let (a, b, c) = (~5u as ~Any, ~TEST as ~Any, ~Test as ~Any);
// This is needed to prevent duplicate lang item definitions.
#[cfg(test)]
-pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
+pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId};
pub type GlueFn = extern "Rust" fn(*i8);
/// 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(stage0)]
pub fn type_id<T: 'static>() -> u64;
+ #[cfg(not(stage0))]
+ pub fn type_id<T: 'static>() -> TypeId;
+
/// Create a value initialized to zero.
///
#[cfg(target_endian = "big")] pub fn to_be32(x: i32) -> i32 { x }
#[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } }
#[cfg(target_endian = "big")] pub fn to_be64(x: i64) -> i64 { x }
+
+
+/// `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
+#[deriving(Eq, IterBytes)]
+#[cfg(not(test))]
+pub struct TypeId {
+ priv t: u64,
+}
+
+#[cfg(not(test))]
+impl TypeId {
+ /// Returns the `TypeId` of the type this generic function has been instantiated with
+ #[cfg(not(stage0))]
+ pub fn of<T: 'static>() -> TypeId {
+ unsafe { type_id::<T>() }
+ }
+}
// except according to those terms.
use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
pub struct A;
pub struct B(Option<A>);
pub type G = uint;
pub type H = &'static str;
-pub unsafe fn id_A() -> u64 { intrinsics::type_id::<A>() }
-pub unsafe fn id_B() -> u64 { intrinsics::type_id::<B>() }
-pub unsafe fn id_C() -> u64 { intrinsics::type_id::<C>() }
-pub unsafe fn id_D() -> u64 { intrinsics::type_id::<D>() }
-pub unsafe fn id_E() -> u64 { intrinsics::type_id::<E>() }
-pub unsafe fn id_F() -> u64 { intrinsics::type_id::<F>() }
-pub unsafe fn id_G() -> u64 { intrinsics::type_id::<G>() }
-pub unsafe fn id_H() -> u64 { intrinsics::type_id::<H>() }
+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 foo<T: 'static>() -> u64 { intrinsics::type_id::<T>() }
+pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
// except according to those terms.
use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
pub struct A;
pub struct B(Option<A>);
pub type G = uint;
pub type H = &'static str;
-pub unsafe fn id_A() -> u64 { intrinsics::type_id::<A>() }
-pub unsafe fn id_B() -> u64 { intrinsics::type_id::<B>() }
-pub unsafe fn id_C() -> u64 { intrinsics::type_id::<C>() }
-pub unsafe fn id_D() -> u64 { intrinsics::type_id::<D>() }
-pub unsafe fn id_E() -> u64 { intrinsics::type_id::<E>() }
-pub unsafe fn id_F() -> u64 { intrinsics::type_id::<F>() }
-pub unsafe fn id_G() -> u64 { intrinsics::type_id::<G>() }
-pub unsafe fn id_H() -> u64 { intrinsics::type_id::<H>() }
+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 foo<T: 'static>() -> u64 { intrinsics::type_id::<T>() }
+pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
extern mod other2(name = "typeid-intrinsic2");
use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
struct A;
+struct Test;
fn main() {
unsafe {
assert_eq!(intrinsics::type_id::<A>(), other1::foo::<A>());
assert_eq!(other2::foo::<A>(), other1::foo::<A>());
}
+
+ // sanity test of TypeId
+ let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+ TypeId::of::<Test>());
+ let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+ TypeId::of::<Test>());
+
+ assert!(a != b);
+ assert!(a != c);
+ assert!(b != c);
+
+ assert_eq!(a, d);
+ assert_eq!(b, e);
+ assert_eq!(c, f);
+
+ // check it has a hash
+ let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
+
+ assert_eq!(a.hash(), b.hash());
}