about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-07 17:17:31 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-07 17:17:31 -0800
commitf25784899209f5c97bc32cbb4abf9ba57f1b12b8 (patch)
tree6227f3c8b7b9bd8ccba849c555b561ea97ef81cf
parentcedaf4696ffe76afdebbd5183269d91176c97a94 (diff)
parent2606f99871511acaabd8aaec87913a5203beb39f (diff)
downloadrust-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.rs13
-rw-r--r--src/libcoretest/intrinsics.rs31
-rw-r--r--src/librustc_resolve/lib.rs7
-rw-r--r--src/test/compile-fail/extern-with-type-bounds.rs33
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() {}
+