]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_metadata/locator.rs
rustc_metadata: Pass SVH by value
[rust.git] / src / librustc_metadata / locator.rs
index d28f00b9168b9e30bcb92cc68466f671cbae7748..c6fb80eca055ad98cce36d9faa0cbc2028b4c4ff 100644 (file)
@@ -261,8 +261,9 @@ struct CrateMismatch {
 
     // Immutable per-search configuration.
     crate_name: Symbol,
-    pub hash: Option<&'a Svh>,
-    pub host_hash: Option<&'a Svh>,
+    exact_paths: Vec<PathBuf>,
+    pub hash: Option<Svh>,
+    pub host_hash: Option<Svh>,
     extra_filename: Option<&'a str>,
     pub target: &'a Target,
     pub triple: TargetTriple,
@@ -277,7 +278,6 @@ struct CrateMismatch {
     rejected_via_kind: Vec<CrateMismatch>,
     rejected_via_version: Vec<CrateMismatch>,
     rejected_via_filename: Vec<CrateMismatch>,
-    should_match_name: bool,
 }
 
 crate struct CratePaths {
@@ -313,8 +313,8 @@ impl<'a> CrateLocator<'a> {
         sess: &'a Session,
         metadata_loader: &'a dyn MetadataLoader,
         crate_name: Symbol,
-        hash: Option<&'a Svh>,
-        host_hash: Option<&'a Svh>,
+        hash: Option<Svh>,
+        host_hash: Option<Svh>,
         extra_filename: Option<&'a str>,
         is_host: bool,
         path_kind: PathKind,
@@ -326,6 +326,15 @@ impl<'a> CrateLocator<'a> {
             sess,
             metadata_loader,
             crate_name,
+            exact_paths: if hash.is_none() {
+                sess.opts.externs.get(&crate_name.as_str()).into_iter()
+                    .flat_map(|entry| entry.locations.iter())
+                    .filter_map(|location| location.clone().map(PathBuf::from)).collect()
+            } else {
+                // SVH being specified means this is a transitive dependency,
+                // so `--extern` options do not apply.
+                Vec::new()
+            },
             hash,
             host_hash,
             extra_filename,
@@ -348,7 +357,6 @@ impl<'a> CrateLocator<'a> {
             rejected_via_kind: Vec::new(),
             rejected_via_version: Vec::new(),
             rejected_via_filename: Vec::new(),
-            should_match_name: true,
         }
     }
 
@@ -361,6 +369,9 @@ impl<'a> CrateLocator<'a> {
     }
 
     crate fn maybe_load_library_crate(&mut self) -> Option<Library> {
+        if !self.exact_paths.is_empty() {
+            return self.find_commandline_library();
+        }
         let mut seen_paths = FxHashSet::default();
         match self.extra_filename {
             Some(s) => self.find_library_crate(s, &mut seen_paths)
@@ -486,21 +497,6 @@ fn find_library_crate(&mut self,
                           extra_prefix: &str,
                           seen_paths: &mut FxHashSet<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() {
-            self.should_match_name = false;
-            if let Some(entry) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
-                // Only use `--extern crate_name=path` here, not `--extern crate_name`.
-                if entry.locations.iter().any(|l| l.is_some()) {
-                    return self.find_commandline_library(
-                        entry.locations.iter().filter_map(|l| l.as_ref()),
-                    );
-                }
-            }
-            self.should_match_name = true;
-        }
-
         let dypair = self.dylibname();
         let staticpair = self.staticlibname();
 
@@ -601,7 +597,7 @@ fn find_library_crate(&mut self,
                                                "multiple matching crates for `{}`",
                                                self.crate_name);
                 let candidates = libraries.iter().filter_map(|(_, lib)| {
-                    let crate_name = &lib.metadata.get_root().name.as_str();
+                    let crate_name = &lib.metadata.get_root().name().as_str();
                     match &(&lib.source.dylib, &lib.source.rlib) {
                         &(&Some((ref pd, _)), &Some((ref pr, _))) => {
                             Some(format!("\ncrate `{}`: {}\n{:>padding$}",
@@ -768,44 +764,46 @@ fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<S
         }
 
         let root = metadata.get_root();
-        if let Some(is_proc_macro) = self.is_proc_macro {
-            if root.proc_macro_data.is_some() != is_proc_macro {
+        if let Some(expected_is_proc_macro) = self.is_proc_macro {
+            let is_proc_macro = root.is_proc_macro_crate();
+            if is_proc_macro != expected_is_proc_macro {
                 info!("Rejecting via proc macro: expected {} got {}",
-                      is_proc_macro, root.proc_macro_data.is_some());
+                      expected_is_proc_macro, is_proc_macro);
                 return None;
             }
         }
 
-        if self.should_match_name {
-            if self.crate_name != root.name {
+        if self.exact_paths.is_empty() {
+            if self.crate_name != root.name() {
                 info!("Rejecting via crate name");
                 return None;
             }
         }
 
-        if root.triple != self.triple {
+        if root.triple() != &self.triple {
             info!("Rejecting via crate triple: expected {} got {}",
                   self.triple,
-                  root.triple);
+                  root.triple());
             self.rejected_via_triple.push(CrateMismatch {
                 path: libpath.to_path_buf(),
-                got: root.triple.to_string(),
+                got: root.triple().to_string(),
             });
             return None;
         }
 
-        if let Some(myhash) = self.hash {
-            if *myhash != root.hash {
-                info!("Rejecting via hash: expected {} got {}", *myhash, root.hash);
+        let hash = root.hash();
+        if let Some(expected_hash) = self.hash {
+            if hash != expected_hash {
+                info!("Rejecting via hash: expected {} got {}", expected_hash, hash);
                 self.rejected_via_hash.push(CrateMismatch {
                     path: libpath.to_path_buf(),
-                    got: myhash.to_string(),
+                    got: hash.to_string(),
                 });
                 return None;
             }
         }
 
-        Some(root.hash)
+        Some(hash)
     }
 
 
@@ -823,9 +821,7 @@ fn staticlibname(&self) -> (String, String) {
         (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone())
     }
 
-    fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
-        where LOCS: Iterator<Item = &'b String>
-    {
+    fn find_commandline_library(&mut self) -> Option<Library> {
         // First, filter out all libraries that look suspicious. We only accept
         // files which actually exist that have the correct naming scheme for
         // rlibs/dylibs.
@@ -835,10 +831,12 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
         let mut rmetas = FxHashMap::default();
         let mut dylibs = FxHashMap::default();
         {
-            let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
+                let crate_name = self.crate_name;
+                let rejected_via_filename = &mut self.rejected_via_filename;
+                let locs = self.exact_paths.iter().filter(|loc| {
                 if !loc.exists() {
                     sess.err(&format!("extern location for {} does not exist: {}",
-                                      self.crate_name,
+                                      crate_name,
                                       loc.display()));
                     return false;
                 }
@@ -846,7 +844,7 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
                     Some(file) => file,
                     None => {
                         sess.err(&format!("extern location for {} is not a file: {}",
-                                          self.crate_name,
+                                          crate_name,
                                           loc.display()));
                         return false;
                     }
@@ -861,8 +859,8 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
                     }
                 }
 
-                self.rejected_via_filename.push(CrateMismatch {
-                    path: loc.clone(),
+                rejected_via_filename.push(CrateMismatch {
+                    path: (*loc).clone(),
                     got: String::new(),
                 });
 
@@ -1024,7 +1022,7 @@ pub fn find_plugin_registrar(
 
     match library.source.dylib {
         Some(dylib) => {
-            Some((dylib.0, library.metadata.get_root().disambiguator))
+            Some((dylib.0, library.metadata.get_root().disambiguator()))
         }
         None => {
             span_err!(sess, span, E0457,