]> git.lizzy.rs Git - rust.git/commitdiff
Remove the unneeded Sized bound on TypeId creation
authorJonathan Reem <jonathan.reem@gmail.com>
Tue, 6 Jan 2015 21:59:07 +0000 (22:59 +0100)
committerJonathan Reem <jonathan.reem@gmail.com>
Wed, 7 Jan 2015 23:49:19 +0000 (00:49 +0100)
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.

src/libcore/intrinsics.rs
src/libcoretest/intrinsics.rs [new file with mode: 0644]
src/librustc_resolve/lib.rs
src/test/compile-fail/extern-with-type-bounds.rs [new file with mode: 0644]

index 822416a387e63405b152d460baafb786cabdc659..bb2bfa953722e34a5895185f834e8771f645e74d 100644 (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 }
 }
diff --git a/src/libcoretest/intrinsics.rs b/src/libcoretest/intrinsics.rs
new file mode 100644 (file)
index 0000000..bcf8a6a
--- /dev/null
@@ -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>());
+}
+
index 93ad69e03b17f1af3eb84dd1850b74a14e52a266..cc52211de2081f6677cb53e0e9b7765eb98282b6 100644 (file)
@@ -2943,8 +2943,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,
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 (file)
index 0000000..8c7d00a
--- /dev/null
@@ -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() {}
+