Remove the unneeded Sized bound on TypeId creation

This bound is probably unintentional and is unnecessarily
constricting.

To facilitate this change, it was also necessary to modify
resolve to recurse on and resolve type parameters in extern { }
blocks. This fixes an ICE when using bounds on type parameters
during the declaration of intrinsics.

This also adds tests for TypeId on both Sized and Unsized
tests as well as a test for using type parameters and bounds
in extern { } blocks.
This commit is contained in:
Jonathan Reem 2015-01-06 22:59:07 +01:00
parent dfd557bd73
commit 2606f99871
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 @@ 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>() -> 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

@ -2943,8 +2943,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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() {}