Skip to content

Commit c42e0a3

Browse files
committed
make svh independent of item ordering
1 parent f923083 commit c42e0a3

File tree

3 files changed

+68
-28
lines changed

3 files changed

+68
-28
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use rustc::hir::def_id::DefId;
12+
use rustc::ty::TyCtxt;
13+
use rustc::util::nodemap::DefIdMap;
14+
15+
pub struct DefPathHashes<'a, 'tcx: 'a> {
16+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
17+
data: DefIdMap<u64>,
18+
}
19+
20+
impl<'a, 'tcx> DefPathHashes<'a, 'tcx> {
21+
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
22+
DefPathHashes {
23+
tcx: tcx,
24+
data: DefIdMap()
25+
}
26+
}
27+
28+
pub fn hash(&mut self, def_id: DefId) -> u64 {
29+
let tcx = self.tcx;
30+
*self.data.entry(def_id)
31+
.or_insert_with(|| {
32+
let def_path = tcx.def_path(def_id);
33+
def_path.deterministic_hash(tcx)
34+
})
35+
}
36+
}

src/librustc_incremental/calculate_svh/mod.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ use rustc::hir;
3535
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
3636
use rustc::hir::intravisit as visit;
3737
use rustc::ty::TyCtxt;
38-
use rustc::util::nodemap::DefIdMap;
3938
use rustc_data_structures::fnv::FnvHashMap;
4039

40+
use self::def_path_hash::DefPathHashes;
4141
use self::svh_visitor::StrictVersionHashVisitor;
4242

43+
mod def_path_hash;
4344
mod svh_visitor;
4445

4546
pub type IncrementalHashesMap = FnvHashMap<DepNode<DefId>, u64>;
@@ -50,7 +51,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
5051
let krate = tcx.map.krate();
5152
let mut visitor = HashItemsVisitor { tcx: tcx,
5253
hashes: FnvHashMap(),
53-
def_path_hashes: DefIdMap() };
54+
def_path_hashes: DefPathHashes::new(tcx) };
5455
visitor.calculate_def_id(DefId::local(CRATE_DEF_INDEX), |v| visit::walk_crate(v, krate));
5556
krate.visit_all_items(&mut visitor);
5657
visitor.compute_crate_hash();
@@ -59,20 +60,20 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
5960

6061
struct HashItemsVisitor<'a, 'tcx: 'a> {
6162
tcx: TyCtxt<'a, 'tcx, 'tcx>,
62-
def_path_hashes: DefIdMap<u64>,
63+
def_path_hashes: DefPathHashes<'a, 'tcx>,
6364
hashes: IncrementalHashesMap,
6465
}
6566

6667
impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
6768
fn calculate_node_id<W>(&mut self, id: ast::NodeId, walk_op: W)
68-
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'tcx>)
69+
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
6970
{
7071
let def_id = self.tcx.map.local_def_id(id);
7172
self.calculate_def_id(def_id, walk_op)
7273
}
7374

7475
fn calculate_def_id<W>(&mut self, def_id: DefId, mut walk_op: W)
75-
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'tcx>)
76+
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
7677
{
7778
assert!(def_id.is_local());
7879
debug!("HashItemsVisitor::calculate(def_id={:?})", def_id);
@@ -99,15 +100,22 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
99100

100101
// add each item (in some deterministic order) to the overall
101102
// crate hash.
102-
//
103-
// FIXME -- it'd be better to sort by the hash of the def-path,
104-
// so that reordering items would not affect the crate hash.
105103
{
106-
let mut keys: Vec<_> = self.hashes.keys().collect();
107-
keys.sort();
108-
for key in keys {
109-
self.hashes[key].hash(&mut crate_state);
110-
}
104+
let def_path_hashes = &mut self.def_path_hashes;
105+
let mut item_hashes: Vec<_> =
106+
self.hashes.iter()
107+
.map(|(item_dep_node, &item_hash)| {
108+
// convert from a DepNode<DefId> tp a
109+
// DepNode<u64> where the u64 is the
110+
// hash of the def-id's def-path:
111+
let item_dep_node =
112+
item_dep_node.map_def(|&did| Some(def_path_hashes.hash(did)))
113+
.unwrap();
114+
(item_dep_node, item_hash)
115+
})
116+
.collect();
117+
item_hashes.sort(); // avoid artificial dependencies on item ordering
118+
item_hashes.hash(&mut crate_state);
111119
}
112120

113121
for attr in &krate.attrs {

src/librustc_incremental/calculate_svh/svh_visitor.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,29 @@ use rustc::hir::def_id::DefId;
2626
use rustc::hir::intravisit as visit;
2727
use rustc::hir::intravisit::{Visitor, FnKind};
2828
use rustc::ty::TyCtxt;
29-
use rustc::util::nodemap::DefIdMap;
3029

3130
use std::hash::{Hash, SipHasher};
3231

33-
pub struct StrictVersionHashVisitor<'a, 'tcx: 'a> {
34-
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
32+
use super::def_path_hash::DefPathHashes;
33+
34+
pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
35+
pub tcx: TyCtxt<'hash, 'tcx, 'tcx>,
3536
pub st: &'a mut SipHasher,
3637

3738
// collect a deterministic hash of def-ids that we have seen
38-
def_path_hashes: &'a mut DefIdMap<u64>,
39+
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
3940
}
4041

41-
impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
42+
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
4243
pub fn new(st: &'a mut SipHasher,
43-
tcx: TyCtxt<'a, 'tcx, 'tcx>,
44-
def_path_hashes: &'a mut DefIdMap<u64>)
44+
tcx: TyCtxt<'hash, 'tcx, 'tcx>,
45+
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>)
4546
-> Self {
4647
StrictVersionHashVisitor { st: st, tcx: tcx, def_path_hashes: def_path_hashes }
4748
}
4849

4950
fn compute_def_id_hash(&mut self, def_id: DefId) -> u64 {
50-
let tcx = self.tcx;
51-
*self.def_path_hashes.entry(def_id)
52-
.or_insert_with(|| {
53-
let def_path = tcx.def_path(def_id);
54-
def_path.deterministic_hash(tcx)
55-
})
51+
self.def_path_hashes.hash(def_id)
5652
}
5753
}
5854

@@ -196,7 +192,7 @@ pub enum SawStmtComponent {
196192
SawStmtSemi,
197193
}
198194

199-
impl<'a, 'tcx> Visitor<'tcx> for StrictVersionHashVisitor<'a, 'tcx> {
195+
impl<'a, 'hash, 'tcx> Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
200196
fn visit_nested_item(&mut self, _: ItemId) {
201197
// Each item is hashed independently; ignore nested items.
202198
}
@@ -370,7 +366,7 @@ pub enum DefHash {
370366
SawErr,
371367
}
372368

373-
impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
369+
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
374370
fn hash_resolve(&mut self, id: ast::NodeId) {
375371
// Because whether or not a given id has an entry is dependent
376372
// solely on expr variant etc, we don't need to hash whether

0 commit comments

Comments
 (0)