diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 004d73da8cbda..5af60e9f19da7 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -438,7 +438,8 @@ impl<'a> CrateLocator<'a> { } if let Some(matches) = spf.query(prefix, suffix) { for (hash, spf) in matches { - info!("lib candidate: {}", spf.path.display()); + let spf_path = spf.path(&search_path.dir); + info!("lib candidate: {}", spf_path.display()); let (rlibs, rmetas, dylibs, interfaces) = candidates.entry(hash).or_default(); @@ -447,8 +448,8 @@ impl<'a> CrateLocator<'a> { // ones we've already seen. This allows us to ignore crates // we know are exactual equal to ones we've already found. // Going to the same crate through different symlinks does not change the result. - let path = try_canonicalize(&spf.path) - .unwrap_or_else(|_| spf.path.to_path_buf()); + let path = + try_canonicalize(&spf_path).unwrap_or_else(|_| spf_path.clone()); if seen_paths.contains(&path) { continue; }; @@ -456,12 +457,11 @@ impl<'a> CrateLocator<'a> { } // Use the original path (potentially with unresolved symlinks), // filesystem code should not care, but this is nicer for diagnostics. - let path = spf.path.to_path_buf(); match kind { - CrateFlavor::Rlib => rlibs.insert(path), - CrateFlavor::Rmeta => rmetas.insert(path), - CrateFlavor::Dylib => dylibs.insert(path), - CrateFlavor::SDylib => interfaces.insert(path), + CrateFlavor::Rlib => rlibs.insert(spf_path), + CrateFlavor::Rmeta => rmetas.insert(spf_path), + CrateFlavor::Dylib => dylibs.insert(spf_path), + CrateFlavor::SDylib => interfaces.insert(spf_path), }; } } @@ -472,7 +472,7 @@ impl<'a> CrateLocator<'a> { { for (_, spf) in static_matches { crate_rejections.via_kind.push(CrateMismatch { - path: spf.path.to_path_buf(), + path: spf.path(&search_path.dir), got: "static".to_string(), }); } diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 3e1fb4df4c3a5..c9c7b8a4d7827 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -16,7 +16,7 @@ pub struct SearchPath { /// [FilesIndex] contains paths that can be efficiently looked up with (prefix, suffix) pairs. #[derive(Clone, Debug)] -pub struct FilesIndex(Vec<(Arc, SearchPathFile)>); +pub struct FilesIndex(Vec); impl FilesIndex { /// Look up [SearchPathFile] by (prefix, suffix) pair. @@ -25,15 +25,15 @@ impl FilesIndex { prefix: &str, suffix: &str, ) -> Option> { - let start = self.0.partition_point(|(k, _)| **k < *prefix); + let start = self.0.partition_point(|v| *v.file_name_str < *prefix); if start == self.0.len() { return None; } - let end = self.0[start..].partition_point(|(k, _)| k.starts_with(prefix)); + let end = self.0[start..].partition_point(|v| v.file_name_str.starts_with(prefix)); let prefixed_items = &self.0[start..][..end]; - let ret = prefixed_items.into_iter().filter_map(move |(k, v)| { - k.ends_with(suffix).then(|| { + let ret = prefixed_items.into_iter().filter_map(move |v| { + v.file_name_str.ends_with(suffix).then(|| { ( String::from( &v.file_name_str[prefix.len()..v.file_name_str.len() - suffix.len()], @@ -45,7 +45,7 @@ impl FilesIndex { Some(ret) } pub fn retain(&mut self, prefixes: &[&str]) { - self.0.retain(|(k, _)| prefixes.iter().any(|prefix| k.starts_with(prefix))); + self.0.retain(|v| prefixes.iter().any(|prefix| v.file_name_str.starts_with(prefix))); } } /// The obvious implementation of `SearchPath::files` is a `Vec`. But @@ -61,8 +61,14 @@ impl FilesIndex { /// UTF-8, and so a non-UTF-8 filename couldn't be one we're looking for.) #[derive(Clone, Debug)] pub struct SearchPathFile { - pub path: Arc, - pub file_name_str: Arc, + file_name_str: Arc, +} + +impl SearchPathFile { + /// Constructs the full path to the file. + pub fn path(&self, dir: &Path) -> PathBuf { + dir.join(&*self.file_name_str) + } } #[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable, HashStable_Generic)] @@ -134,20 +140,14 @@ impl SearchPath { Ok(files) => files .filter_map(|e| { e.ok().and_then(|e| { - e.file_name().to_str().map(|s| { - let file_name_str: Arc = s.into(); - ( - Arc::clone(&file_name_str), - SearchPathFile { path: e.path().into(), file_name_str }, - ) - }) + e.file_name().to_str().map(|s| SearchPathFile { file_name_str: s.into() }) }) }) - .collect::>(), + .collect::>(), Err(..) => Default::default(), }; - files.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs)); + files.sort_unstable_by(|lhs, rhs| lhs.file_name_str.cmp(&rhs.file_name_str)); let files = FilesIndex(files); SearchPath { kind, dir, files } }