rollup merge of #20696: reem/unsized-typeid

This removes the needlessly constricting bound on `intrinsics::type_Id` and `TypeId::of`. Also fixes an ICE where using bounds on type parameters in extern blocks fails to resolve the used traits.
This commit is contained in:
Alex Crichton 2015-01-07 17:17:31 -08:00
commit f257848992
4 changed files with 82 additions and 2 deletions

View File

@ -42,6 +42,8 @@
#![experimental]
#![allow(missing_docs)]
use marker::Sized;
pub type GlueFn = extern "Rust" fn(*const i8);
#[lang="ty_desc"]
@ -200,6 +202,10 @@ pub struct TyDesc {
/// 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>() -> TypeId;
#[cfg(stage0)]
pub fn type_id<T: 'static>() -> TypeId;
/// Create a value initialized to zero.
@ -551,8 +557,15 @@ pub struct TypeId {
impl TypeId {
/// Returns the `TypeId` of the type this generic function has been instantiated with
#[cfg(not(stage0))]
pub fn of<T: ?Sized + 'static>() -> TypeId {
unsafe { type_id::<T>() }
}
#[cfg(stage0)]
pub fn of<T: 'static>() -> TypeId {
unsafe { type_id::<T>() }
}
pub fn hash(&self) -> u64 { self.t }
}

View File

@ -0,0 +1,31 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::intrinsics::TypeId;
#[test]
fn test_typeid_sized_types() {
struct X; struct Y(uint);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
assert!(TypeId::of::<X>() != TypeId::of::<Y>());
}
#[test]
fn test_typeid_unsized_types() {
trait Z {}
struct X(str); struct Y(Z + 'static);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
assert!(TypeId::of::<X>() != TypeId::of::<Y>());
}

View File

@ -2944,8 +2944,11 @@ fn resolve_item(&mut self, item: &Item) {
HasTypeParameters(
generics, FnSpace, foreign_item.id,
ItemRibKind),
|this| visit::walk_foreign_item(this,
&**foreign_item));
|this| {
this.resolve_type_parameters(&generics.ty_params);
this.resolve_where_clause(&generics.where_clause);
visit::walk_foreign_item(this, &**foreign_item)
});
}
ForeignItemStatic(..) => {
visit::walk_foreign_item(this,

View File

@ -0,0 +1,33 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(intrinsics)]
use std::intrinsics::TypeId;
extern "rust-intrinsic" {
// Real example from libcore
fn type_id<T: ?Sized + 'static>() -> TypeId;
// Silent bounds made explicit to make sure they are actually
// resolved.
fn transmute<T: Sized, U: Sized>(val: T) -> U;
// Bounds aren't checked right now, so this should work
// even though it's incorrect.
fn size_of<T: Clone>() -> uint;
// Unresolved bounds should still error.
fn align_of<T: NoSuchTrait>() -> uint;
//~^ ERROR attempt to bound type parameter with a nonexistent trait `NoSuchTrait`
}
fn main() {}