From a2726f4a548f77f0443701c457f9f7628b5c6b6c Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Mon, 19 Sep 2016 12:37:12 +0300 Subject: [PATCH] rustc: allow less and handle fn pointers in the type hashing algorithm. --- src/librustc/ty/util.rs | 15 +++++++++------ src/librustc_trans/glue.rs | 2 ++ src/test/run-pass/typeid-intrinsic.rs | 4 ++++ 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::(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::(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::() != TypeId::of::()); + + // Check fn pointer against collisions + assert!(TypeId::of:: A) -> A>() != + TypeId::of:: A, A) -> A>()); }