about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Manchester <cmanchester@mozilla.com>2018-03-13 11:58:53 -0700
committerChris Manchester <cmanchester@mozilla.com>2018-03-28 23:24:41 -0700
commitbd8154784ea205d78c30c18a5908e97718f7a489 (patch)
treef45c3418846cccf8f57f1c255bc918ff5523418f
parent9942012f41620e097d37a6d737584a3790f6b88b (diff)
downloadrust-bd8154784ea205d78c30c18a5908e97718f7a489.tar.gz
rust-bd8154784ea205d78c30c18a5908e97718f7a489.zip
Take the original extra-filename passed to a crate into account when
resolving it as a dependency.

Fixes #46816
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/ty/maps/config.rs6
-rw-r--r--src/librustc/ty/maps/mod.rs1
-rw-r--r--src/librustc/ty/maps/plumbing.rs1
-rw-r--r--src/librustc_metadata/creader.rs22
-rw-r--r--src/librustc_metadata/cstore_impl.rs3
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_metadata/locator.rs30
-rw-r--r--src/librustc_metadata/schema.rs5
9 files changed, 57 insertions, 14 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 42cda6a05a1..d1f3736556c 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -589,6 +589,7 @@ define_dep_nodes!( <'tcx>
     [input] CrateDisambiguator(CrateNum),
     [input] CrateHash(CrateNum),
     [input] OriginalCrateName(CrateNum),
+    [input] ExtraFileName(CrateNum),
 
     [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
     [] AllTraitImplementations(CrateNum),
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index bb9467305e3..a08cd57b1f7 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -466,6 +466,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the extra filename for a crate")
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
     fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
         format!("looking up implementations of a trait in a crate")
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 2bfb6870329..8651619705b 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -328,6 +328,7 @@ define_maps! { <'tcx>
     [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
     [] fn crate_hash: CrateHash(CrateNum) -> Svh,
     [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
+    [] fn extra_filename: ExtraFileName(CrateNum) -> String,
 
     [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
         -> Lrc<Vec<DefId>>,
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 50a19526ba8..fa69eb8e5bc 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -881,6 +881,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
         DepKind::CrateHash => { force!(crate_hash, krate!()); }
         DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
+        DepKind::ExtraFileName => { force!(extra_filename, krate!()); }
 
         DepKind::AllTraitImplementations => {
             force!(all_trait_implementations, krate!());
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 13ebb5f6166..86f495c5fac 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -262,6 +262,7 @@ impl<'a> CrateLoader<'a> {
                      ident: Symbol,
                      name: Symbol,
                      hash: Option<&Svh>,
+                     extra_filename: Option<&str>,
                      span: Span,
                      path_kind: PathKind,
                      mut dep_kind: DepKind)
@@ -277,6 +278,7 @@ impl<'a> CrateLoader<'a> {
                 ident,
                 crate_name: name,
                 hash: hash.map(|a| &*a),
+                extra_filename: extra_filename,
                 filesearch: self.sess.target_filesearch(path_kind),
                 target: &self.sess.target.target,
                 triple: &self.sess.opts.target_triple,
@@ -409,7 +411,8 @@ impl<'a> CrateLoader<'a> {
         ::std::iter::once(krate).chain(crate_root.crate_deps
                                                  .decode(metadata)
                                                  .map(|dep| {
-            debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
+            info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash,
+                  dep.extra_filename);
             if dep.kind == DepKind::UnexportedMacrosOnly {
                 return krate;
             }
@@ -418,7 +421,8 @@ impl<'a> CrateLoader<'a> {
                 _ => dep.kind,
             };
             let (local_cnum, ..) = self.resolve_crate(
-                root, dep.name, dep.name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
+                root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
+                PathKind::Dependency, dep_kind,
             );
             local_cnum
         })).collect()
@@ -437,6 +441,7 @@ impl<'a> CrateLoader<'a> {
             ident: orig_name,
             crate_name: rename,
             hash: None,
+            extra_filename: None,
             filesearch: self.sess.host_filesearch(PathKind::Crate),
             target: &self.sess.host,
             triple: &host_triple,
@@ -664,7 +669,7 @@ impl<'a> CrateLoader<'a> {
 
         let dep_kind = DepKind::Implicit;
         let (cnum, data) =
-            self.resolve_crate(&None, name, name, None, DUMMY_SP, PathKind::Crate, dep_kind);
+            self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind);
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
         // and the panic strategy is indeed what we thought it was.
@@ -771,7 +776,7 @@ impl<'a> CrateLoader<'a> {
                 let symbol = Symbol::intern(name);
                 let dep_kind = DepKind::Explicit;
                 let (_, data) =
-                    self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
+                    self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
                                        PathKind::Crate, dep_kind);
 
                 // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
@@ -794,7 +799,7 @@ impl<'a> CrateLoader<'a> {
             let symbol = Symbol::intern("profiler_builtins");
             let dep_kind = DepKind::Implicit;
             let (_, data) =
-                self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
+                self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
                                    PathKind::Crate, dep_kind);
 
             // Sanity check the loaded crate to ensure it is indeed a profiler runtime
@@ -909,6 +914,7 @@ impl<'a> CrateLoader<'a> {
                                                               name,
                                                               name,
                                                               None,
+                                                              None,
                                                               DUMMY_SP,
                                                               PathKind::Crate,
                                                               DepKind::Implicit);
@@ -1059,7 +1065,8 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
                 };
 
                 let (cnum, ..) = self.resolve_crate(
-                    &None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind,
+                    &None, item.ident.name, orig_name, None, None,
+                    item.span, PathKind::Crate, dep_kind,
                 );
 
                 let def_id = definitions.opt_local_def_id(item.id).unwrap();
@@ -1074,6 +1081,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
     }
 
     fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum {
-        self.resolve_crate(&None, name, name, None, span, PathKind::Crate, DepKind::Explicit).0
+        self.resolve_crate(&None, name, name, None, None, span, PathKind::Crate,
+                           DepKind::Explicit).0
     }
 }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 5fd8ebaa9b4..f63edf07fa8 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -213,6 +213,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     crate_hash => { cdata.hash() }
     original_crate_name => { cdata.name() }
 
+    extra_filename => { cdata.root.extra_filename.clone() }
+
+
     implementations_of_trait => {
         let mut result = vec![];
         let filter = Some(other);
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 39de1ec852e..0da6fc5b9ed 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -462,6 +462,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let has_global_allocator = tcx.sess.has_global_allocator.get();
         let root = self.lazy(&CrateRoot {
             name: tcx.crate_name(LOCAL_CRATE),
+            extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
             triple: tcx.sess.opts.target_triple.clone(),
             hash: link_meta.crate_hash,
             disambiguator: tcx.sess.local_crate_disambiguator(),
@@ -1357,6 +1358,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                     name: self.tcx.original_crate_name(cnum),
                     hash: self.tcx.crate_hash(cnum),
                     kind: self.tcx.dep_kind(cnum),
+                    extra_filename: self.tcx.extra_filename(cnum),
                 };
                 (cnum, dep)
             })
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 41e10b4755d..f553c55ae56 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -83,7 +83,10 @@
 //! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
 //!    filename have the right prefix/suffix?
 //! 2. Does the filename have the right prefix for the crate name being queried?
-//!    This is filtering for files like `libfoo*.rlib` and such.
+//!    This is filtering for files like `libfoo*.rlib` and such. If the crate
+//!    we're looking for was originally compiled with -C extra-filename, the
+//!    extra filename will be included in this prefix to reduce reading
+//!    metadata from crates that would otherwise share our prefix.
 //! 3. Is the file an actual rust library? This is done by loading the metadata
 //!    from the library and making sure it's actually there.
 //! 4. Does the name in the metadata agree with the name of the library?
@@ -236,6 +239,7 @@ use syntax_pos::Span;
 use rustc_back::target::{Target, TargetTriple};
 
 use std::cmp;
+use std::collections::HashSet;
 use std::fmt;
 use std::fs;
 use std::io::{self, Read};
@@ -256,6 +260,7 @@ pub struct Context<'a> {
     pub ident: Symbol,
     pub crate_name: Symbol,
     pub hash: Option<&'a Svh>,
+    pub extra_filename: Option<&'a str>,
     // points to either self.sess.target.target or self.sess.host, must match triple
     pub target: &'a Target,
     pub triple: &'a TargetTriple,
@@ -303,7 +308,12 @@ impl CratePaths {
 
 impl<'a> Context<'a> {
     pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
-        self.find_library_crate()
+        let mut seen_paths = HashSet::new();
+        match self.extra_filename {
+            Some(s) => self.find_library_crate(s, &mut seen_paths)
+                .or_else(|| self.find_library_crate("", &mut seen_paths)),
+            None => self.find_library_crate("", &mut seen_paths)
+        }
     }
 
     pub fn report_errs(&mut self) -> ! {
@@ -419,7 +429,10 @@ impl<'a> Context<'a> {
         unreachable!();
     }
 
-    fn find_library_crate(&mut self) -> Option<Library> {
+    fn find_library_crate(&mut self,
+                          extra_prefix: &str,
+                          seen_paths: &mut HashSet<PathBuf>)
+                          -> Option<Library> {
         // If an SVH is specified, then this is a transitive dependency that
         // must be loaded via -L plus some filtering.
         if self.hash.is_none() {
@@ -434,9 +447,9 @@ impl<'a> Context<'a> {
         let staticpair = self.staticlibname();
 
         // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
-        let dylib_prefix = format!("{}{}", dypair.0, self.crate_name);
-        let rlib_prefix = format!("lib{}", self.crate_name);
-        let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name);
+        let dylib_prefix = format!("{}{}{}", dypair.0, self.crate_name, extra_prefix);
+        let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix);
+        let staticlib_prefix = format!("{}{}{}", staticpair.0, self.crate_name, extra_prefix);
 
         let mut candidates = FxHashMap();
         let mut staticlibs = vec![];
@@ -476,6 +489,7 @@ impl<'a> Context<'a> {
                     }
                     return FileDoesntMatch;
                 };
+
             info!("lib candidate: {}", path.display());
 
             let hash_str = hash.to_string();
@@ -484,6 +498,10 @@ impl<'a> Context<'a> {
             let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot;
             fs::canonicalize(path)
                 .map(|p| {
+                    if seen_paths.contains(&p) {
+                        return FileDoesntMatch
+                    };
+                    seen_paths.insert(p.clone());
                     match found_kind {
                         CrateFlavor::Rlib => { rlibs.insert(p, kind); }
                         CrateFlavor::Rmeta => { rmetas.insert(p, kind); }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index d04a4001c50..a7ee0e7e9a9 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -188,6 +188,7 @@ pub enum LazyState {
 pub struct CrateRoot {
     pub name: Symbol,
     pub triple: TargetTriple,
+    pub extra_filename: String,
     pub hash: hir::svh::Svh,
     pub disambiguator: CrateDisambiguator,
     pub panic_strategy: PanicStrategy,
@@ -216,12 +217,14 @@ pub struct CrateDep {
     pub name: ast::Name,
     pub hash: hir::svh::Svh,
     pub kind: DepKind,
+    pub extra_filename: String,
 }
 
 impl_stable_hash_for!(struct CrateDep {
     name,
     hash,
-    kind
+    kind,
+    extra_filename
 });
 
 #[derive(RustcEncodable, RustcDecodable)]