diff options
| author | bors <bors@rust-lang.org> | 2016-08-05 23:28:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-08-05 23:28:29 -0700 |
| commit | ecdd51b7bb7fd993acd2ff5dbd72209244b1e4aa (patch) | |
| tree | fac7836cc3ca826b97e7a96bae61165deaaba675 /src/test | |
| parent | 7bf54f90d619fc87af4c8b660a80166c40048cb5 (diff) | |
| parent | d42da7b8f36fe087b5fe2cb08c136ffd62f73e3d (diff) | |
| download | rust-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.rs | 20 | ||||
| -rw-r--r-- | src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs | 20 | ||||
| -rw-r--r-- | src/test/run-pass/type-id-higher-rank-2.rs | 40 | ||||
| -rw-r--r-- | src/test/run-pass/type-id-higher-rank.rs | 11 | ||||
| -rw-r--r-- | src/test/run-pass/typeid-intrinsic.rs | 55 |
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>(), |
