Skip to content

Commit

Permalink
Rollup merge of rust-lang#50531 - iancormac84:merge-typeidhasher-clea…
Browse files Browse the repository at this point in the history
…nup, r=michaelwoerister

Cleanup uses of TypeIdHasher and replace them with StableHasher

Fixes rust-lang#50424

r? @michaelwoerister
  • Loading branch information
kennytm authored May 19, 2018
2 parents ef8ee64 + 0349394 commit 9e914cc
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 220 deletions.
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ for ty::RegionKind {
ty::ReLateBound(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) => {
bug!("TypeIdHasher: unexpected region {:?}", *self)
bug!("StableHasher: unexpected region {:?}", *self)
}
}
}
Expand Down
151 changes: 1 addition & 150 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,18 @@ use hir::def_id::DefId;
use hir::map::{DefPathData, Node};
use hir;
use ich::NodeIdHashingMode;
use middle::const_val::ConstVal;
use traits::{self, ObligationCause};
use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use ty::fold::TypeVisitor;
use ty::subst::{Substs, UnpackedKind};
use ty::maps::TyCtxtAt;
use ty::TypeVariants::*;
use ty::layout::{Integer, IntegerExt};
use util::common::ErrorReported;
use middle::lang_items;

use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
HashStable};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::FxHashMap;
use std::{cmp, fmt};
use std::hash::Hash;
use std::intrinsics;
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
use syntax_pos::{Span, DUMMY_SP};
Expand Down Expand Up @@ -615,150 +610,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<W>,
}

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<T: Hash>(&mut self, x: T) {
x.hash(&mut self.state);
}

fn hash_discriminant_u8<T>(&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<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> 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>,
Expand Down
17 changes: 11 additions & 6 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ use llvm::{self, ValueRef};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use rustc::ty::fold::TypeVisitor;
use rustc::ty::util::TypeIdHasher;
use rustc::ich::Fingerprint;
use rustc::ich::{Fingerprint, NodeIdHashingMode};
use rustc::ty::Instance;
use common::CodegenCx;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
Expand Down Expand Up @@ -144,9 +143,15 @@ impl<'tcx> TypeMap<'tcx> {

// The hasher we are using to generate the UniqueTypeId. We want
// something that provides more than the 64 bits of the DefaultHasher.
let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx);
type_id_hasher.visit_ty(type_);
let unique_type_id = type_id_hasher.finish().to_hex();
let mut hasher = StableHasher::<Fingerprint>::new();
let mut hcx = cx.tcx.create_stable_hashing_context();
let type_ = cx.tcx.erase_regions(&type_);
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
type_.hash_stable(hcx, &mut hasher);
});
});
let unique_type_id = hasher.finish().to_hex();

let key = self.unique_id_interner.intern(&unique_type_id);
self.type_to_unique_id.insert(type_, UniqueTypeId(key));
Expand Down
Loading

0 comments on commit 9e914cc

Please sign in to comment.