diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index d5532f8f835..551825cc354 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -615,150 +615,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } -pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> { - tcx: TyCtxt<'a, 'gcx, 'tcx>, - state: StableHasher, -} - -impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W> - where W: StableHasherResult -{ - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { - TypeIdHasher { tcx: tcx, state: StableHasher::new() } - } - - pub fn finish(self) -> W { - self.state.finish() - } - - pub fn hash(&mut self, x: T) { - x.hash(&mut self.state); - } - - fn hash_discriminant_u8(&mut self, x: &T) { - let v = unsafe { - intrinsics::discriminant_value(x) - }; - let b = v as u8; - assert_eq!(v, b as u64); - self.hash(b) - } - - fn def_id(&mut self, did: DefId) { - // Hash the DefPath corresponding to the DefId, which is independent - // of compiler internal state. We already have a stable hash value of - // all DefPaths available via tcx.def_path_hash(), so we just feed that - // into the hasher. - let hash = self.tcx.def_path_hash(did); - self.hash(hash); - } -} - -impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> - where W: StableHasherResult -{ - fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { - // Distinguish between the Ty variants uniformly. - self.hash_discriminant_u8(&ty.sty); - - match ty.sty { - TyInt(i) => self.hash(i), - TyUint(u) => self.hash(u), - TyFloat(f) => self.hash(f), - TyArray(_, n) => { - self.hash_discriminant_u8(&n.val); - match n.val { - ConstVal::Value(alloc) => self.hash(alloc), - ConstVal::Unevaluated(def_id, _) => self.def_id(def_id), - } - } - TyRawPtr(m) => self.hash(m.mutbl), - TyRef(_, _, mutbl) => self.hash(mutbl), - TyClosure(def_id, _) | - TyGenerator(def_id, _, _) | - TyAnon(def_id, _) | - TyFnDef(def_id, _) => self.def_id(def_id), - TyAdt(d, _) => self.def_id(d.did), - TyForeign(def_id) => self.def_id(def_id), - TyFnPtr(f) => { - self.hash(f.unsafety()); - self.hash(f.abi()); - self.hash(f.variadic()); - self.hash(f.inputs().skip_binder().len()); - } - TyDynamic(ref data, ..) => { - if let Some(p) = data.principal() { - self.def_id(p.def_id()); - } - for d in data.auto_traits() { - self.def_id(d); - } - } - TyGeneratorWitness(tys) => { - self.hash(tys.skip_binder().len()); - } - TyTuple(tys) => { - self.hash(tys.len()); - } - TyParam(p) => { - self.hash(p.idx); - self.hash(p.name); - } - TyProjection(ref data) => { - self.def_id(data.item_def_id); - } - TyNever | - TyBool | - TyChar | - TyStr | - TySlice(_) => {} - - TyError | - TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty) - } - - ty.super_visit_with(self) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - self.hash_discriminant_u8(r); - match *r { - ty::ReErased | - ty::ReStatic | - ty::ReEmpty => { - // No variant fields to hash for these ... - } - ty::ReCanonical(c) => { - self.hash(c); - } - ty::ReLateBound(db, ty::BrAnon(i)) => { - self.hash(db.depth); - self.hash(i); - } - ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) => { - self.def_id(def_id); - } - - ty::ReClosureBound(..) | - ty::ReLateBound(..) | - ty::ReFree(..) | - ty::ReScope(..) | - ty::ReVar(..) | - ty::ReSkolemized(..) => { - bug!("TypeIdHasher: unexpected region {:?}", r) - } - } - false - } - - fn visit_binder>(&mut self, x: &ty::Binder) -> bool { - // Anonymize late-bound regions so that, for example: - // `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)` - // result in the same TypeId (the two types are equivalent). - self.tcx.anonymize_late_bound_regions(x).super_visit_with(self) - } -} - impl<'a, 'tcx> ty::TyS<'tcx> { pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,