diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-02-24 19:45:20 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-02-28 10:48:04 -0800 |
| commit | ec57db083ff10fc4da0a2f25df5acf1d4398e560 (patch) | |
| tree | 335775f0a85a2a892dc3ed8fdb4091d4b3440ba1 /src/librustc/metadata/creader.rs | |
| parent | 8213e184477c19eba75840e9310266a6529de20a (diff) | |
| download | rust-ec57db083ff10fc4da0a2f25df5acf1d4398e560.tar.gz rust-ec57db083ff10fc4da0a2f25df5acf1d4398e560.zip | |
rustc: Add the concept of a Strict Version Hash
This new SVH is used to uniquely identify all crates as a snapshot in time of their ABI/API/publicly reachable state. This current calculation is just a hash of the entire crate's AST. This is obviously incorrect, but it is currently the reality for today. This change threads through the new Svh structure which originates from crate dependencies. The concept of crate id hash is preserved to provide efficient matching on filenames for crate loading. The inspected hash once crate metadata is opened has been changed to use the new Svh. The goal of this hash is to identify when upstream crates have changed but downstream crates have not been recompiled. This will prevent the def-id drift problem where upstream crates were recompiled, thereby changing their metadata, but downstream crates were not recompiled. In the future this hash can be expanded to exclude contents of the AST like doc comments, but limitations in the compiler prevent this change from being made at this time. Closes #10207
Diffstat (limited to 'src/librustc/metadata/creader.rs')
| -rw-r--r-- | src/librustc/metadata/creader.rs | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 1108917cdb1..165c1abdeed 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -12,6 +12,8 @@ //! Validates all used crates and extern libraries and loads their metadata +use back::link; +use back::svh::Svh; use driver::{driver, session}; use driver::session::Session; use metadata::csearch; @@ -78,7 +80,7 @@ impl<'a> visit::Visitor<()> for ReadCrateVisitor<'a> { struct cache_entry { cnum: ast::CrateNum, span: Span, - hash: ~str, + hash: Svh, crate_id: CrateId, } @@ -148,7 +150,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) { match extract_crate_info(e, i) { Some(info) => { - let cnum = resolve_crate(e, None, info.ident, &info.crate_id, "", + let cnum = resolve_crate(e, None, info.ident, &info.crate_id, None, i.span); e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); } @@ -276,12 +278,13 @@ fn visit_item(e: &Env, i: &ast::Item) { } fn existing_match(e: &Env, crate_id: &CrateId, - hash: &str) -> Option<ast::CrateNum> { + hash: Option<&Svh>) -> Option<ast::CrateNum> { let crate_cache = e.crate_cache.borrow(); for c in crate_cache.get().iter() { - if crate_id.matches(&c.crate_id) && - (hash.is_empty() || hash == c.hash.as_slice()) { - return Some(c.cnum) + if !crate_id.matches(&c.crate_id) { continue } + match hash { + Some(hash) if *hash != c.hash => {} + Some(..) | None => return Some(c.cnum) } } None @@ -291,19 +294,22 @@ fn resolve_crate(e: &mut Env, root_ident: Option<&str>, ident: &str, crate_id: &CrateId, - hash: &str, + hash: Option<&Svh>, span: Span) -> ast::CrateNum { match existing_match(e, crate_id, hash) { None => { - let load_ctxt = loader::Context { + let id_hash = link::crate_id_hash(crate_id); + let mut load_ctxt = loader::Context { sess: e.sess, span: span, ident: ident, crate_id: crate_id, - hash: hash, + id_hash: id_hash, + hash: hash.map(|a| &*a), os: e.os, - intr: e.intr + intr: e.intr, + rejected_via_hash: false, }; let loader::Library { dylib, rlib, metadata @@ -375,7 +381,7 @@ fn resolve_crate_deps(e: &mut Env, let local_cnum = resolve_crate(e, root_ident, dep.crate_id.name.as_slice(), &dep.crate_id, - dep.hash, + Some(&dep.hash), span); cnum_map.insert(extrn_cnum, local_cnum); } @@ -406,7 +412,7 @@ impl CrateLoader for Loader { fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate { let info = extract_crate_info(&self.env, krate).unwrap(); let cnum = resolve_crate(&mut self.env, None, info.ident, - &info.crate_id, "", krate.span); + &info.crate_id, None, krate.span); let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap(); MacroCrate { lib: library.dylib, |
