Rollup merge of #41056 - michaelwoerister:central-defpath-hashes, r=nikomatsakis

Handle DefPath hashing centrally as part of DefPathTable (+ save work during SVH calculation)

In almost all cases where we construct a `DefPath`, we just hash it and throw it away again immediately.
With this PR, the compiler will immediately compute and store the hash for each `DefPath` as it is allocated. This way we
+ can get rid of any subsequent `DefPath` hash caching (e.g. the `DefPathHashes`),
+ don't need to allocate a transient `Vec` for holding the `DefPath` (although I'm always surprised how little these small, dynamic allocations seem to hurt performance), and
+ we don't hash `DefPath` prefixes over and over again.

That last part is because we construct the hash for `prefix::foo` by hashing `(hash(prefix), foo)` instead of hashing every component of prefix.

The last commit of this PR is pretty neat, I think:
```
The SVH (Strict Version Hash) of a crate is currently computed
by hashing the ICHes (Incremental Computation Hashes) of the
crate's HIR. This is fine, expect that for incr. comp. we compute
two ICH values for each HIR item, one for the complete item and
one that just includes the item's interface. The two hashes are
are needed for dependency tracking but if we are compiling
non-incrementally and just need the ICH values for the SVH,
one of them is enough, giving us the opportunity to save some
work in this case.
```

r? @nikomatsakis

This PR depends on https://github.com/rust-lang/rust/pull/40878 to be merged first (you can ignore the first commit for reviewing, that's just https://github.com/rust-lang/rust/pull/40878).
This commit is contained in:
Corey Farwell 2017-04-07 09:20:05 -04:00 committed by GitHub
commit 88e97f0541
19 changed files with 161 additions and 131 deletions

View File

@ -2697,7 +2697,7 @@ impl<'a> LoweringContext<'a> {
fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
-> P<hir::Pat> {
let id = self.next_id();
let parent_def = self.parent_def;
let parent_def = self.parent_def.unwrap();
let def_id = {
let defs = self.resolver.definitions();
let def_path_data = DefPathData::Binding(name.as_str());

View File

@ -40,11 +40,9 @@ impl<'a> DefCollector<'a> {
}
}
pub fn collect_root(&mut self) {
let root = self.create_def_with_parent(None,
CRATE_NODE_ID,
DefPathData::CrateRoot,
ITEM_LIKE_SPACE);
pub fn collect_root(&mut self, crate_name: &str, crate_disambiguator: &str) {
let root = self.definitions.create_root_def(crate_name,
crate_disambiguator);
assert_eq!(root, CRATE_DEF_INDEX);
self.parent_def = Some(root);
}
@ -54,20 +52,11 @@ impl<'a> DefCollector<'a> {
data: DefPathData,
address_space: DefIndexAddressSpace)
-> DefIndex {
let parent_def = self.parent_def;
let parent_def = self.parent_def.unwrap();
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
self.definitions.create_def_with_parent(parent_def, node_id, data, address_space)
}
fn create_def_with_parent(&mut self,
parent: Option<DefIndex>,
node_id: NodeId,
data: DefPathData,
address_space: DefIndexAddressSpace)
-> DefIndex {
self.definitions.create_def_with_parent(parent, node_id, data, address_space)
}
pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
let parent = self.parent_def;
self.parent_def = Some(parent_def);

View File

@ -21,7 +21,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::stable_hasher::StableHasher;
use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::fmt::Write;
use std::hash::{Hash, Hasher};
use std::hash::Hash;
use syntax::ast;
use syntax::symbol::{Symbol, InternedString};
use ty::TyCtxt;
@ -34,6 +34,7 @@ use util::nodemap::NodeMap;
pub struct DefPathTable {
index_to_key: [Vec<DefKey>; 2],
key_to_index: FxHashMap<DefKey, DefIndex>,
def_path_hashes: [Vec<u64>; 2],
}
// Unfortunately we have to provide a manual impl of Clone because of the
@ -44,6 +45,8 @@ impl Clone for DefPathTable {
index_to_key: [self.index_to_key[0].clone(),
self.index_to_key[1].clone()],
key_to_index: self.key_to_index.clone(),
def_path_hashes: [self.def_path_hashes[0].clone(),
self.def_path_hashes[1].clone()],
}
}
}
@ -52,6 +55,7 @@ impl DefPathTable {
fn allocate(&mut self,
key: DefKey,
def_path_hash: u64,
address_space: DefIndexAddressSpace)
-> DefIndex {
let index = {
@ -62,6 +66,9 @@ impl DefPathTable {
index
};
self.key_to_index.insert(key, index);
self.def_path_hashes[address_space.index()].push(def_path_hash);
debug_assert!(self.def_path_hashes[address_space.index()].len() ==
self.index_to_key[address_space.index()].len());
index
}
@ -71,6 +78,12 @@ impl DefPathTable {
[index.as_array_index()].clone()
}
#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
self.def_path_hashes[index.address_space().index()]
[index.as_array_index()]
}
#[inline(always)]
pub fn def_index_for_def_key(&self, key: &DefKey) -> Option<DefIndex> {
self.key_to_index.get(key).cloned()
@ -116,17 +129,28 @@ impl DefPathTable {
impl Encodable for DefPathTable {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
// Index to key
self.index_to_key[DefIndexAddressSpace::Low.index()].encode(s)?;
self.index_to_key[DefIndexAddressSpace::High.index()].encode(s)
self.index_to_key[DefIndexAddressSpace::High.index()].encode(s)?;
// DefPath hashes
self.def_path_hashes[DefIndexAddressSpace::Low.index()].encode(s)?;
self.def_path_hashes[DefIndexAddressSpace::High.index()].encode(s)?;
Ok(())
}
}
impl Decodable for DefPathTable {
fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key_high: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key_hi: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key = [index_to_key_lo, index_to_key_high];
let def_path_hashes_lo: Vec<u64> = Decodable::decode(d)?;
let def_path_hashes_hi: Vec<u64> = Decodable::decode(d)?;
let index_to_key = [index_to_key_lo, index_to_key_hi];
let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi];
let mut key_to_index = FxHashMap();
@ -141,6 +165,7 @@ impl Decodable for DefPathTable {
Ok(DefPathTable {
index_to_key: index_to_key,
key_to_index: key_to_index,
def_path_hashes: def_path_hashes,
})
}
}
@ -184,6 +209,29 @@ pub struct DefKey {
pub disambiguated_data: DisambiguatedDefPathData,
}
impl DefKey {
fn compute_stable_hash(&self, parent_hash: u64) -> u64 {
let mut hasher = StableHasher::new();
// We hash a 0u8 here to disambiguate between regular DefPath hashes,
// and the special "root_parent" below.
0u8.hash(&mut hasher);
parent_hash.hash(&mut hasher);
self.disambiguated_data.hash(&mut hasher);
hasher.finish()
}
fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 {
let mut hasher = StableHasher::new();
// Disambiguate this from a regular DefPath hash,
// see compute_stable_hash() above.
1u8.hash(&mut hasher);
crate_name.hash(&mut hasher);
crate_disambiguator.hash(&mut hasher);
hasher.finish()
}
}
/// Pair of `DefPathData` and an integer disambiguator. The integer is
/// normally 0, but in the event that there are multiple defs with the
/// same `parent` and `data`, we use this field to disambiguate
@ -271,19 +319,6 @@ impl DefPath {
s
}
pub fn deterministic_hash(&self, tcx: TyCtxt) -> u64 {
debug!("deterministic_hash({:?})", self);
let mut state = StableHasher::new();
self.deterministic_hash_to(tcx, &mut state);
state.finish()
}
pub fn deterministic_hash_to<H: Hasher>(&self, tcx: TyCtxt, state: &mut H) {
tcx.original_crate_name(self.krate).as_str().hash(state);
tcx.crate_disambiguator(self.krate).as_str().hash(state);
self.data.hash(state);
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
@ -338,6 +373,7 @@ impl Definitions {
table: DefPathTable {
index_to_key: [vec![], vec![]],
key_to_index: FxHashMap(),
def_path_hashes: [vec![], vec![]],
},
node_to_def_index: NodeMap(),
def_index_to_node: [vec![], vec![]],
@ -359,6 +395,11 @@ impl Definitions {
self.table.def_key(index)
}
#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
self.table.def_path_hash(index)
}
pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
self.table.def_index_for_def_key(&key)
}
@ -398,12 +439,38 @@ impl Definitions {
self.node_to_hir_id[node_id]
}
/// Add a definition with a parent definition.
pub fn create_root_def(&mut self,
crate_name: &str,
crate_disambiguator: &str)
-> DefIndex {
let key = DefKey {
parent: None,
disambiguated_data: DisambiguatedDefPathData {
data: DefPathData::CrateRoot,
disambiguator: 0
}
};
let parent_hash = DefKey::root_parent_stable_hash(crate_name,
crate_disambiguator);
let def_path_hash = key.compute_stable_hash(parent_hash);
// Create the definition.
let address_space = super::ITEM_LIKE_SPACE;
let index = self.table.allocate(key, def_path_hash, address_space);
assert!(self.def_index_to_node[address_space.index()].is_empty());
self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
self.node_to_def_index.insert(ast::CRATE_NODE_ID, index);
index
}
/// Add a definition with a parent definition.
pub fn create_def_with_parent(&mut self,
parent: Option<DefIndex>,
parent: DefIndex,
node_id: ast::NodeId,
data: DefPathData,
// is_owner: bool)
address_space: DefIndexAddressSpace)
-> DefIndex {
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
@ -415,12 +482,13 @@ impl Definitions {
data,
self.table.def_key(self.node_to_def_index[&node_id]));
assert_eq!(parent.is_some(), data != DefPathData::CrateRoot);
// The root node must be created with create_root_def()
assert!(data != DefPathData::CrateRoot);
// Find a unique DefKey. This basically means incrementing the disambiguator
// until we get no match.
let mut key = DefKey {
parent: parent,
parent: Some(parent),
disambiguated_data: DisambiguatedDefPathData {
data: data,
disambiguator: 0
@ -431,10 +499,13 @@ impl Definitions {
key.disambiguated_data.disambiguator += 1;
}
let parent_hash = self.table.def_path_hash(parent);
let def_path_hash = key.compute_stable_hash(parent_hash);
debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
// Create the definition.
let index = self.table.allocate(key, address_space);
let index = self.table.allocate(key, def_path_hash, address_space);
assert_eq!(index.as_array_index(),
self.def_index_to_node[address_space.index()].len());
self.def_index_to_node[address_space.index()].push(node_id);

View File

@ -1,36 +0,0 @@
// Copyright 2012-2014 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.
use hir::def_id::DefId;
use ty::TyCtxt;
use util::nodemap::DefIdMap;
pub struct DefPathHashes<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
data: DefIdMap<u64>,
}
impl<'a, 'tcx> DefPathHashes<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
DefPathHashes {
tcx: tcx,
data: DefIdMap()
}
}
pub fn hash(&mut self, def_id: DefId) -> u64 {
let tcx = self.tcx;
*self.data.entry(def_id)
.or_insert_with(|| {
let def_path = tcx.def_path(def_id);
def_path.deterministic_hash(tcx)
})
}
}

View File

@ -10,7 +10,7 @@
use hir;
use hir::def_id::DefId;
use ich::{self, CachingCodemapView, DefPathHashes};
use ich::{self, CachingCodemapView};
use session::config::DebugInfoLevel::NoDebugInfo;
use ty;
@ -32,7 +32,6 @@ use rustc_data_structures::accumulate_vec::AccumulateVec;
/// things (e.g. each DefId/DefPath is only hashed once).
pub struct StableHashingContext<'a, 'tcx: 'a> {
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
def_path_hashes: DefPathHashes<'a, 'tcx>,
codemap: CachingCodemapView<'tcx>,
hash_spans: bool,
hash_bodies: bool,
@ -64,7 +63,6 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
StableHashingContext {
tcx: tcx,
def_path_hashes: DefPathHashes::new(tcx),
codemap: CachingCodemapView::new(tcx),
hash_spans: hash_spans_initial,
hash_bodies: true,
@ -111,7 +109,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
#[inline]
pub fn def_path_hash(&mut self, def_id: DefId) -> u64 {
self.def_path_hashes.hash(def_id)
self.tcx.def_path_hash(def_id)
}
#[inline]

View File

@ -11,12 +11,10 @@
//! ICH - Incremental Compilation Hash
pub use self::fingerprint::Fingerprint;
pub use self::def_path_hash::DefPathHashes;
pub use self::caching_codemap_view::CachingCodemapView;
pub use self::hcx::{StableHashingContext, NodeIdHashingMode};
mod fingerprint;
mod def_path_hash;
mod caching_codemap_view;
mod hcx;

View File

@ -230,6 +230,7 @@ pub trait CrateStore {
-> Option<DefId>;
fn def_key(&self, def: DefId) -> DefKey;
fn def_path(&self, def: DefId) -> hir_map::DefPath;
fn def_path_hash(&self, def: DefId) -> u64;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<def::Export>;
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
@ -377,6 +378,9 @@ impl CrateStore for DummyCrateStore {
fn def_path(&self, def: DefId) -> hir_map::DefPath {
bug!("relative_def_path")
}
fn def_path_hash(&self, def: DefId) -> u64 {
bug!("wa")
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }

View File

@ -2227,6 +2227,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
#[inline]
pub fn def_path_hash(self, def_id: DefId) -> u64 {
if def_id.is_local() {
self.hir.definitions().def_path_hash(def_id.index)
} else {
self.sess.cstore.def_path_hash(def_id)
}
}
pub fn def_span(self, def_id: DefId) -> Span {
if let Some(id) = self.hir.as_local_node_id(def_id) {
self.hir.span(id)

View File

@ -13,7 +13,7 @@
use hir::def_id::{DefId, LOCAL_CRATE};
use hir::map::DefPathData;
use infer::InferCtxt;
use hir::map as hir_map;
// use hir::map as hir_map;
use traits::{self, Reveal};
use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
use ty::ParameterEnvironment;
@ -441,13 +441,11 @@ impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W>
fn def_id(&mut self, did: DefId) {
// Hash the DefPath corresponding to the DefId, which is independent
// of compiler internal state.
let path = self.tcx.def_path(did);
self.def_path(&path)
}
pub fn def_path(&mut self, def_path: &hir_map::DefPath) {
def_path.deterministic_hash_to(self.tcx, &mut self.state);
// 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);
}
}

View File

@ -647,8 +647,12 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name);
crate_loader.preprocess(&krate);
let resolver_arenas = Resolver::arenas();
let mut resolver =
Resolver::new(sess, &krate, make_glob_map, &mut crate_loader, &resolver_arenas);
let mut resolver = Resolver::new(sess,
&krate,
crate_name,
make_glob_map,
&mut crate_loader,
&resolver_arenas);
resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives;
syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features.borrow().quote);

View File

@ -99,6 +99,13 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
item_like: T)
where T: HashStable<StableHashingContext<'a, 'tcx>>
{
if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() {
// If we just need the hashes in order to compute the SVH, we don't
// need have two hashes per item. Just the one containing also the
// item's body is sufficient.
return
}
let mut hasher = IchHasher::new();
self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
item_like.hash_stable(hcx, &mut hasher);
@ -143,7 +150,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
(item_dep_node, item_hash)
})
.collect();
item_hashes.sort(); // avoid artificial dependencies on item ordering
item_hashes.sort_unstable(); // avoid artificial dependencies on item ordering
item_hashes.hash(&mut crate_state);
}

View File

@ -23,6 +23,7 @@
#![feature(staged_api)]
#![feature(rand)]
#![feature(conservative_impl_trait)]
#![feature(sort_unstable)]
#![cfg_attr(stage0, feature(pub_restricted))]
extern crate graphviz;

View File

@ -186,10 +186,6 @@ impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> {
.clone()
}
pub fn lookup_def_path(&self, id: DefPathIndex) -> &DefPath {
&self.directory.paths[id.index as usize]
}
pub fn map(&mut self, node: &DepNode<DefId>) -> DepNode<DefPathIndex> {
node.map_def(|&def_id| Some(self.add(def_id))).unwrap()
}

View File

@ -258,8 +258,6 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
index_map: FxHashMap()
};
let mut def_id_hashes = FxHashMap();
for (index, target) in preds.reduced_graph.all_nodes().iter().enumerate() {
let index = NodeIndex(index);
let def_id = match *target.data {
@ -267,15 +265,6 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
_ => continue,
};
let mut def_id_hash = |def_id: DefId| -> u64 {
*def_id_hashes.entry(def_id)
.or_insert_with(|| {
let index = builder.add(def_id);
let path = builder.lookup_def_path(index);
path.deterministic_hash(tcx)
})
};
// To create the hash for each item `X`, we don't hash the raw
// bytes of the metadata (though in principle we
// could). Instead, we walk the predecessors of `MetaData(X)`
@ -295,7 +284,7 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
.map(|index| preds.reduced_graph.node_data(index))
.filter(|dep_node| HashContext::is_hashable(dep_node))
.map(|dep_node| {
let hash_dep_node = dep_node.map_def(|&def_id| Some(def_id_hash(def_id)))
let hash_dep_node = dep_node.map_def(|&def_id| Some(tcx.def_path_hash(def_id)))
.unwrap();
let hash = preds.hashes[dep_node];
(hash_dep_node, hash)

View File

@ -73,7 +73,7 @@ provide! { <'tcx> tcx, def_id, cdata
predicates => { cdata.get_predicates(def_id.index, tcx) }
super_predicates => { cdata.get_super_predicates(def_id.index, tcx) }
trait_def => {
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx))
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index))
}
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
adt_destructor => {
@ -370,6 +370,10 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(def.krate).def_path(def.index)
}
fn def_path_hash(&self, def: DefId) -> u64 {
self.get_crate_data(def.krate).def_path_hash(def.index)
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
{
self.dep_graph.read(DepNode::MetaData(def));

View File

@ -492,10 +492,7 @@ impl<'a, 'tcx> CrateMetadata {
}
}
pub fn get_trait_def(&self,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::TraitDef {
pub fn get_trait_def(&self, item_id: DefIndex) -> ty::TraitDef {
let data = match self.entry(item_id).kind {
EntryKind::Trait(data) => data.decode(self),
_ => bug!(),
@ -504,7 +501,7 @@ impl<'a, 'tcx> CrateMetadata {
let def = ty::TraitDef::new(self.local_def_id(item_id),
data.unsafety,
data.paren_sugar,
self.def_path(item_id).deterministic_hash(tcx));
self.def_path_table.def_path_hash(item_id));
if data.has_default_impl {
def.record_has_default_impl();
@ -1053,6 +1050,7 @@ impl<'a, 'tcx> CrateMetadata {
}
}
#[inline]
pub fn def_key(&self, index: DefIndex) -> DefKey {
self.def_path_table.def_key(index)
}
@ -1063,6 +1061,11 @@ impl<'a, 'tcx> CrateMetadata {
DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent))
}
#[inline]
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
self.def_path_table.def_path_hash(index)
}
/// Imports the codemap from an external crate into the codemap of the crate
/// currently being compiled (the "local crate").
///

View File

@ -1289,6 +1289,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
impl<'a> Resolver<'a> {
pub fn new(session: &'a Session,
krate: &Crate,
crate_name: &str,
make_glob_map: MakeGlobMap,
crate_loader: &'a mut CrateLoader,
arenas: &'a ResolverArenas<'a>)
@ -1303,7 +1304,8 @@ impl<'a> Resolver<'a> {
module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
let mut definitions = Definitions::new();
DefCollector::new(&mut definitions).collect_root();
DefCollector::new(&mut definitions)
.collect_root(crate_name, &session.local_crate_disambiguator().as_str());
let mut invocations = FxHashMap();
invocations.insert(Mark::root(),

View File

@ -101,13 +101,13 @@ use common::SharedCrateContext;
use monomorphize::Instance;
use rustc::middle::weak_lang_items;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir::def_id::DefId;
use rustc::hir::map as hir_map;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::fold::TypeVisitor;
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::subst::Substs;
use rustc::hir::map::definitions::{DefPath, DefPathData};
use rustc::hir::map::definitions::DefPathData;
use rustc::util::common::record_time;
use syntax::attr;
@ -115,8 +115,8 @@ use syntax::symbol::{Symbol, InternedString};
fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// path to the item this name is for
def_path: &DefPath,
// the DefId of the item this name is for
def_id: Option<DefId>,
// type of the item, without any generic
// parameters substituted; this is
@ -128,8 +128,7 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// if any.
substs: Option<&'tcx Substs<'tcx>>)
-> String {
debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
def_path, substs);
debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
let tcx = scx.tcx();
@ -139,7 +138,7 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// the main symbol name is not necessarily unique; hash in the
// compiler's internal def-path, guaranteeing each symbol has a
// truly unique path
hasher.def_path(def_path);
hasher.hash(def_id.map(|def_id| tcx.def_path_hash(def_id)));
// Include the main item-type. Note that, in this case, the
// assertions about `needs_subst` may not hold, but this item-type
@ -224,8 +223,6 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
return scx.tcx().item_name(def_id).as_str().to_string();
}
let def_path = scx.tcx().def_path(def_id);
// We want to compute the "type" of this item. Unfortunately, some
// kinds of items (e.g., closures) don't have an entry in the
// item-type array. So walk back up the find the closest parent
@ -256,10 +253,10 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
// and should not matter anyhow.
let instance_ty = scx.tcx().erase_regions(&instance_ty);
let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs));
let hash = get_symbol_hash(scx, Some(def_id), instance_ty, Some(substs));
let mut buffer = SymbolPathBuffer {
names: Vec::with_capacity(def_path.data.len())
names: Vec::new()
};
item_path::with_forced_absolute_paths(|| {
@ -288,11 +285,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a,
t: Ty<'tcx>,
prefix: &str)
-> String {
let empty_def_path = DefPath {
data: vec![],
krate: LOCAL_CRATE,
};
let hash = get_symbol_hash(scx, &empty_def_path, t, None);
let hash = get_symbol_hash(scx, None, t, None);
let path = [Symbol::intern(prefix).as_str()];
mangle(path.iter().cloned(), &hash)
}

View File

@ -806,7 +806,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
err.emit();
}
let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
let def_path_hash = tcx.def_path_hash(def_id);
let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash);
if tcx.hir.trait_is_auto(def_id) {