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:
parent
dfd557bd73
commit
2606f99871
4 changed files with 82 additions and 2 deletions
|
@ -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 }
|
||||
}
|
||||
|
|
31
src/libcoretest/intrinsics.rs
Normal file
31
src/libcoretest/intrinsics.rs
Normal 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>());
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
33
src/test/compile-fail/extern-with-type-bounds.rs
Normal file
33
src/test/compile-fail/extern-with-type-bounds.rs
Normal 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() {}
|
||||
|
Loading…
Reference in a new issue