Skip to content

Commit 0082fc0

Browse files
committed
change svh to store a u64
We used to store a u64 converted to a String for some reason. Now we don't.
1 parent 08837d2 commit 0082fc0

File tree

6 files changed

+38
-55
lines changed

6 files changed

+38
-55
lines changed

src/librustc/hir/svh.rs

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,60 +10,34 @@
1010

1111
//! Calculation and management of a Strict Version Hash for crates
1212
//!
13-
//! # Today's ABI problem
14-
//!
15-
//! In today's implementation of rustc, it is incredibly difficult to achieve
16-
//! forward binary compatibility without resorting to C-like interfaces. Within
17-
//! rust code itself, abi details such as symbol names suffer from a variety of
18-
//! unrelated factors to code changing such as the "def id drift" problem. This
19-
//! ends up yielding confusing error messages about metadata mismatches and
20-
//! such.
21-
//!
22-
//! The core of this problem is when an upstream dependency changes and
23-
//! downstream dependents are not recompiled. This causes compile errors because
24-
//! the upstream crate's metadata has changed but the downstream crates are
25-
//! still referencing the older crate's metadata.
26-
//!
27-
//! This problem exists for many reasons, the primary of which is that rust does
28-
//! not currently support forwards ABI compatibility (in place upgrades of a
29-
//! crate).
30-
//!
31-
//! # SVH and how it alleviates the problem
32-
//!
33-
//! With all of this knowledge on hand, this module contains the implementation
34-
//! of a notion of a "Strict Version Hash" for a crate. This is essentially a
35-
//! hash of all contents of a crate which can somehow be exposed to downstream
36-
//! crates.
37-
//!
38-
//! This hash is currently calculated by just hashing the AST, but this is
39-
//! obviously wrong (doc changes should not result in an incompatible ABI).
40-
//! Implementation-wise, this is required at this moment in time.
41-
//!
42-
//! By encoding this strict version hash into all crate's metadata, stale crates
43-
//! can be detected immediately and error'd about by rustc itself.
44-
//!
45-
//! # Relevant links
46-
//!
47-
//! Original issue: https://github.com/rust-lang/rust/issues/10207
13+
//! The SVH is used for incremental compilation to track when HIR
14+
//! nodes have changed between compilations, and also to detect
15+
//! mismatches where we have two versions of the same crate that were
16+
//! compiled from distinct sources.
4817
4918
use std::fmt;
19+
use std::hash::{Hash, Hasher};
5020

51-
#[derive(Clone, Eq, Hash, PartialEq, Debug)]
21+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
5222
pub struct Svh {
53-
hash: String,
23+
hash: u64,
5424
}
5525

5626
impl Svh {
5727
/// Create a new `Svh` given the hash. If you actually want to
5828
/// compute the SVH from some HIR, you want the `calculate_svh`
59-
/// function found in `librustc_trans`.
60-
pub fn new(hash: String) -> Svh {
61-
assert!(hash.len() == 16);
29+
/// function found in `librustc_incremental`.
30+
pub fn new(hash: u64) -> Svh {
6231
Svh { hash: hash }
6332
}
6433

65-
pub fn from_hash(hash: u64) -> Svh {
66-
return Svh::new((0..64).step_by(4).map(|i| hex(hash >> i)).collect());
34+
pub fn as_u64(&self) -> u64 {
35+
self.hash
36+
}
37+
38+
pub fn to_string(&self) -> String {
39+
let hash = self.hash;
40+
return (0..64).step_by(4).map(|i| hex(hash >> i)).collect();
6741

6842
fn hex(b: u64) -> char {
6943
let b = (b & 0xf) as u8;
@@ -74,14 +48,16 @@ impl Svh {
7448
b as char
7549
}
7650
}
51+
}
7752

78-
pub fn as_str<'a>(&'a self) -> &'a str {
79-
&self.hash
53+
impl Hash for Svh {
54+
fn hash<H>(&self, state: &mut H) where H: Hasher {
55+
self.hash.to_le().hash(state);
8056
}
8157
}
8258

8359
impl fmt::Display for Svh {
8460
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85-
f.pad(self.as_str())
61+
f.pad(&self.to_string())
8662
}
8763
}

src/librustc/ty/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
368368
} else {
369369
tcx.sess.cstore.crate_hash(did.krate)
370370
};
371-
h.as_str().hash(state);
371+
h.hash(state);
372372
did.index.hash(state);
373373
};
374374
let mt = |state: &mut SipHasher, mt: TypeAndMut| {

src/librustc_incremental/calculate_svh.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,14 @@ impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx, 'tcx> {
7272
attr.node.value.hash(&mut state);
7373
}
7474

75-
Svh::from_hash(state.finish())
75+
Svh::new(state.finish())
7676
}
7777

7878
fn calculate_item_hash(self, def_id: DefId) -> u64 {
7979
assert!(def_id.is_local());
8080

81+
debug!("calculate_item_hash(def_id={:?})", def_id);
82+
8183
let mut state = SipHasher::new();
8284

8385
{
@@ -89,11 +91,16 @@ impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx, 'tcx> {
8991
intravisit::walk_crate(&mut visit, krate);
9092
} else {
9193
let node_id = self.map.as_local_node_id(def_id).unwrap();
92-
visit.visit_item(self.map.expect_item(node_id));
94+
let item = self.map.expect_item(node_id);
95+
visit.visit_item(item);
9396
}
9497
}
9598

96-
state.finish()
99+
let hash = state.finish();
100+
101+
debug!("calculate_item_hash: def_id={:?} hash={:?}", def_id, hash);
102+
103+
hash
97104
}
98105
}
99106

src/librustc_metadata/decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
12511251

12521252
reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
12531253
let name = docstr(depdoc, tag_crate_dep_crate_name);
1254-
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash));
1254+
let hash = Svh::new(reader::doc_as_u64(reader::get_doc(depdoc, tag_crate_dep_hash)));
12551255
let doc = reader::get_doc(depdoc, tag_crate_dep_explicitly_linked);
12561256
let explicitly_linked = reader::doc_as_u8(doc) != 0;
12571257
CrateDep {
@@ -1275,14 +1275,14 @@ fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
12751275
pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
12761276
let cratedoc = rbml::Doc::new(data);
12771277
reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
1278-
Svh::new(doc.as_str_slice().to_string())
1278+
Svh::new(reader::doc_as_u64(doc))
12791279
})
12801280
}
12811281

12821282
pub fn get_crate_hash(data: &[u8]) -> Svh {
12831283
let cratedoc = rbml::Doc::new(data);
12841284
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
1285-
Svh::new(hashdoc.as_str_slice().to_string())
1285+
Svh::new(reader::doc_as_u64(hashdoc))
12861286
}
12871287

12881288
pub fn maybe_get_crate_name(data: &[u8]) -> Option<&str> {

src/librustc_metadata/encoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,14 +1793,14 @@ fn encode_crate_dep(rbml_w: &mut Encoder,
17931793
rbml_w.start_tag(tag_crate_dep);
17941794
rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name());
17951795
let hash = decoder::get_crate_hash(dep.data());
1796-
rbml_w.wr_tagged_str(tag_crate_dep_hash, hash.as_str());
1796+
rbml_w.wr_tagged_u64(tag_crate_dep_hash, hash.as_u64());
17971797
rbml_w.wr_tagged_u8(tag_crate_dep_explicitly_linked,
17981798
dep.explicitly_linked.get() as u8);
17991799
rbml_w.end_tag();
18001800
}
18011801

18021802
fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
1803-
rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
1803+
rbml_w.wr_tagged_u64(tag_crate_hash, hash.as_u64());
18041804
}
18051805

18061806
fn encode_rustc_version(rbml_w: &mut Encoder) {

src/librustc_metadata/loader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ impl<'a> Context<'a> {
620620
info!("Rejecting via hash: expected {} got {}", *myhash, hash);
621621
self.rejected_via_hash.push(CrateMismatch {
622622
path: libpath.to_path_buf(),
623-
got: myhash.as_str().to_string()
623+
got: myhash.to_string()
624624
});
625625
return None;
626626
}

0 commit comments

Comments
 (0)