about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-09-19 12:37:12 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-09-20 20:30:55 +0300
commita2726f4a548f77f0443701c457f9f7628b5c6b6c (patch)
treebd77138c4a3f029dc2931bce8acdd98baeb35f8d
parentade79d760905ab589851ca9e9ab3bb583e4da7c4 (diff)
downloadrust-a2726f4a548f77f0443701c457f9f7628b5c6b6c.tar.gz
rust-a2726f4a548f77f0443701c457f9f7628b5c6b6c.zip
rustc: allow less and handle fn pointers in the type hashing algorithm.
-rw-r--r--src/librustc/ty/util.rs15
-rw-r--r--src/librustc_trans/glue.rs2
-rw-r--r--src/test/run-pass/typeid-intrinsic.rs4
3 files changed, 15 insertions, 6 deletions
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 5c71f348b99..d834a7d485a 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -436,17 +436,18 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
             TyInt(i) => self.hash(i),
             TyUint(u) => self.hash(u),
             TyFloat(f) => self.hash(f),
-            TyAdt(d, _) => self.def_id(d.did),
             TyArray(_, n) => self.hash(n),
             TyRawPtr(m) |
             TyRef(_, m) => self.hash(m.mutbl),
             TyClosure(def_id, _) |
             TyAnon(def_id, _) |
             TyFnDef(def_id, ..) => self.def_id(def_id),
+            TyAdt(d, _) => self.def_id(d.did),
             TyFnPtr(f) => {
                 self.hash(f.unsafety);
                 self.hash(f.abi);
                 self.hash(f.sig.variadic());
+                self.hash(f.sig.inputs().skip_binder().len());
             }
             TyTrait(ref data) => {
                 self.def_id(data.principal.def_id());
@@ -468,9 +469,10 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
             TyChar |
             TyStr |
             TyBox(_) |
-            TySlice(_) |
-            TyError => {}
-            TyInfer(_) => bug!()
+            TySlice(_) => {}
+
+            TyError |
+            TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty)
         }
 
         ty.super_visit_with(self)
@@ -478,7 +480,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
 
     fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
         match *r {
-            ty::ReStatic | ty::ReErased => {
+            ty::ReErased => {
                 self.hash::<u32>(0);
             }
             ty::ReLateBound(db, ty::BrAnon(i)) => {
@@ -486,6 +488,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
                 self.hash::<u32>(db.depth);
                 self.hash(i);
             }
+            ty::ReStatic |
             ty::ReEmpty |
             ty::ReEarlyBound(..) |
             ty::ReLateBound(..) |
@@ -493,7 +496,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
             ty::ReScope(..) |
             ty::ReVar(..) |
             ty::ReSkolemized(..) => {
-                bug!("unexpected region found when hashing a type")
+                bug!("TypeIdHasher: unexpected region {:?}", r)
             }
         }
         false
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index 3073b1dbfae..7b012279872 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -92,6 +92,8 @@ pub fn get_drop_glue_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     t: Ty<'tcx>) -> Ty<'tcx> {
     assert!(t.is_normalized_for_trans());
 
+    let t = tcx.erase_regions(&t);
+
     // Even if there is no dtor for t, there might be one deeper down and we
     // might need to pass in the vtable ptr.
     if !type_is_sized(tcx, t) {
diff --git a/src/test/run-pass/typeid-intrinsic.rs b/src/test/run-pass/typeid-intrinsic.rs
index 36650368d57..54d5415a553 100644
--- a/src/test/run-pass/typeid-intrinsic.rs
+++ b/src/test/run-pass/typeid-intrinsic.rs
@@ -87,4 +87,8 @@ pub fn main() {
     assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator());
     assert!(other1::id_i32_iterator() != other1::id_u32_iterator());
     assert!(TypeId::of::<other1::I32Iterator>() != TypeId::of::<other1::U32Iterator>());
+
+    // Check fn pointer against collisions
+    assert!(TypeId::of::<fn(fn(A) -> A) -> A>() !=
+            TypeId::of::<fn(fn() -> A, A) -> A>());
 }