about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-08-05 23:28:29 -0700
committerGitHub <noreply@github.com>2016-08-05 23:28:29 -0700
commitecdd51b7bb7fd993acd2ff5dbd72209244b1e4aa (patch)
treefac7836cc3ca826b97e7a96bae61165deaaba675 /src/test
parent7bf54f90d619fc87af4c8b660a80166c40048cb5 (diff)
parentd42da7b8f36fe087b5fe2cb08c136ffd62f73e3d (diff)
downloadrust-ecdd51b7bb7fd993acd2ff5dbd72209244b1e4aa.tar.gz
rust-ecdd51b7bb7fd993acd2ff5dbd72209244b1e4aa.zip
Auto merge of #35267 - eddyb:ty-hash, r=nikomatsakis
Rewrite TypeId computation to not miss anything and work cross-crate.

Fixes #33703 and also some soundness holes in `Any` due to `TypeId` ignoring most lifetimes.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs20
-rw-r--r--src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs20
-rw-r--r--src/test/run-pass/type-id-higher-rank-2.rs40
-rw-r--r--src/test/run-pass/type-id-higher-rank.rs11
-rw-r--r--src/test/run-pass/typeid-intrinsic.rs55
5 files changed, 101 insertions, 45 deletions
diff --git a/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
index 388d3238d42..42c0da6286b 100644
--- a/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
+++ b/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
@@ -21,14 +21,16 @@ pub struct E(Result<&'static str, isize>);
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
diff --git a/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
index 3ad307fd3b5..42c0da6286b 100644
--- a/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
+++ b/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
@@ -21,14 +21,16 @@ pub struct E(Result<&'static str, isize>);
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T:Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
diff --git a/src/test/run-pass/type-id-higher-rank-2.rs b/src/test/run-pass/type-id-higher-rank-2.rs
new file mode 100644
index 00000000000..aead8bc264d
--- /dev/null
+++ b/src/test/run-pass/type-id-higher-rank-2.rs
@@ -0,0 +1,40 @@
+// Copyright 2016 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.
+
+// Test that we can't ignore lifetimes by going through Any.
+
+use std::any::Any;
+
+struct Foo<'a>(&'a str);
+
+fn good(s: &String) -> Foo { Foo(s) }
+
+fn bad1(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(good as fn(&String) -> Foo);
+    a.downcast_ref::<fn(&String) -> Foo<'static>>().map(|f| f(&s).0)
+}
+
+trait AsStr<'a, 'b> {
+    fn get(&'a self) -> &'b str;
+}
+
+impl<'a> AsStr<'a, 'a> for String {
+   fn get(&'a self) -> &'a str { self }
+}
+
+fn bad2(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(Box::new(s) as Box<for<'a> AsStr<'a, 'a>>);
+    a.downcast_ref::<Box<for<'a> AsStr<'a, 'static>>>().map(|x| x.get())
+}
+
+fn main() {
+    assert_eq!(bad1(String::from("foo")), None);
+    assert_eq!(bad2(String::from("bar")), None);
+}
diff --git a/src/test/run-pass/type-id-higher-rank.rs b/src/test/run-pass/type-id-higher-rank.rs
index c29fb5e86f5..827b05c0801 100644
--- a/src/test/run-pass/type-id-higher-rank.rs
+++ b/src/test/run-pass/type-id-higher-rank.rs
@@ -16,6 +16,9 @@
 
 use std::any::{Any, TypeId};
 
+struct Struct<'a>(&'a ());
+trait Trait<'a> {}
+
 fn main() {
     // Bare fns
     {
@@ -34,6 +37,14 @@ fn main() {
         let e = TypeId::of::<for<'a> fn(fn(&'a isize) -> &'a isize)>();
         let f = TypeId::of::<fn(for<'a> fn(&'a isize) -> &'a isize)>();
         assert!(e != f);
+
+        // Make sure lifetime parameters of items are not ignored.
+        let g = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'a>>();
+        let h = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'static>>();
+        let i = TypeId::of::<for<'a, 'b> fn(&'a Trait<'b>) -> Struct<'b>>();
+        assert!(g != h);
+        assert!(g != i);
+        assert!(h != i);
     }
     // Boxed unboxed closures
     {
diff --git a/src/test/run-pass/typeid-intrinsic.rs b/src/test/run-pass/typeid-intrinsic.rs
index 4bd82baafeb..e99a5f69af4 100644
--- a/src/test/run-pass/typeid-intrinsic.rs
+++ b/src/test/run-pass/typeid-intrinsic.rs
@@ -23,36 +23,37 @@ struct A;
 struct Test;
 
 pub fn main() {
-    unsafe {
-        assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
-        assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
-        assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
-        assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
-        assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
-        assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
-        assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
-        assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
+    assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
+    assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
+    assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
+    assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
+    assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
+    assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
+    assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other1::id_I());
 
-        assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
-        assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
-        assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
-        assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
-        assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
-        assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
-        assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
-        assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
+    assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
+    assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
+    assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
+    assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
+    assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
+    assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
+    assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other2::id_I());
 
-        assert_eq!(other1::id_F(), other2::id_F());
-        assert_eq!(other1::id_G(), other2::id_G());
-        assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_F(), other2::id_F());
+    assert_eq!(other1::id_G(), other2::id_G());
+    assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_I(), other2::id_I());
 
-        assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
-        assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
-        assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
-        assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
-        assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
-        assert_eq!(other2::foo::<A>(), other1::foo::<A>());
-    }
+    assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
+    assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
+    assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
+    assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
+    assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
+    assert_eq!(other2::foo::<A>(), other1::foo::<A>());
 
     // sanity test of TypeId
     let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(),