diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-07 17:17:31 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-07 17:17:31 -0800 |
| commit | f25784899209f5c97bc32cbb4abf9ba57f1b12b8 (patch) | |
| tree | 6227f3c8b7b9bd8ccba849c555b561ea97ef81cf | |
| parent | cedaf4696ffe76afdebbd5183269d91176c97a94 (diff) | |
| parent | 2606f99871511acaabd8aaec87913a5203beb39f (diff) | |
| download | rust-f25784899209f5c97bc32cbb4abf9ba57f1b12b8.tar.gz rust-f25784899209f5c97bc32cbb4abf9ba57f1b12b8.zip | |
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.
| -rw-r--r-- | src/libcore/intrinsics.rs | 13 | ||||
| -rw-r--r-- | src/libcoretest/intrinsics.rs | 31 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 7 | ||||
| -rw-r--r-- | src/test/compile-fail/extern-with-type-bounds.rs | 33 |
4 files changed, 82 insertions, 2 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 822416a387e..bb2bfa95372 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -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 } } diff --git a/src/libcoretest/intrinsics.rs b/src/libcoretest/intrinsics.rs new file mode 100644 index 00000000000..bcf8a6a433b --- /dev/null +++ b/src/libcoretest/intrinsics.rs @@ -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>()); +} + diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 845db8aa5df..f21297c60d6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2944,8 +2944,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, diff --git a/src/test/compile-fail/extern-with-type-bounds.rs b/src/test/compile-fail/extern-with-type-bounds.rs new file mode 100644 index 00000000000..8c7d00a9a11 --- /dev/null +++ b/src/test/compile-fail/extern-with-type-bounds.rs @@ -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() {} + |
