about summary refs log tree commit diff
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r--compiler/rustc_session/src/config.rs10
-rw-r--r--compiler/rustc_session/src/utils.rs23
2 files changed, 29 insertions, 4 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f9e40919149..9d73c3b4424 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -5,7 +5,7 @@ pub use crate::options::*;
 
 use crate::lint;
 use crate::search_paths::SearchPath;
-use crate::utils::NativeLibKind;
+use crate::utils::{CanonicalizedPath, NativeLibKind};
 use crate::{early_error, early_warn, Session};
 
 use rustc_data_structures::fx::FxHashSet;
@@ -436,7 +436,7 @@ pub enum ExternLocation {
     /// which one to use.
     ///
     /// Added via `--extern prelude_name=some_file.rlib`
-    ExactPaths(BTreeSet<String>),
+    ExactPaths(BTreeSet<CanonicalizedPath>),
 }
 
 impl Externs {
@@ -458,7 +458,7 @@ impl ExternEntry {
         ExternEntry { location, is_private_dep: false, add_prelude: false }
     }
 
-    pub fn files(&self) -> Option<impl Iterator<Item = &String>> {
+    pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
         match &self.location {
             ExternLocation::ExactPaths(set) => Some(set.iter()),
             _ => None,
@@ -1639,13 +1639,15 @@ pub fn parse_externs(
     for arg in matches.opt_strs("extern") {
         let (name, path) = match arg.split_once('=') {
             None => (arg, None),
-            Some((name, path)) => (name.to_string(), Some(path.to_string())),
+            Some((name, path)) => (name.to_string(), Some(Path::new(path))),
         };
         let (options, name) = match name.split_once(':') {
             None => (None, name),
             Some((opts, name)) => (Some(opts), name.to_string()),
         };
 
+        let path = path.map(|p| CanonicalizedPath::new(p));
+
         let entry = externs.entry(name.to_owned());
 
         use std::collections::btree_map::Entry;
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 15447c01d1e..f3d33309124 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -1,5 +1,6 @@
 use crate::session::Session;
 use rustc_data_structures::profiling::VerboseTimingGuard;
+use std::path::{Path, PathBuf};
 
 impl Session {
     pub fn timer<'a>(&'a self, what: &'static str) -> VerboseTimingGuard<'a> {
@@ -30,3 +31,25 @@ pub enum NativeLibKind {
 }
 
 rustc_data_structures::impl_stable_hash_via_hash!(NativeLibKind);
+
+/// A path that has been canonicalized along with its original, non-canonicalized form
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct CanonicalizedPath {
+    // Optional since canonicalization can sometimes fail
+    canonicalized: Option<PathBuf>,
+    original: PathBuf,
+}
+
+impl CanonicalizedPath {
+    pub fn new(path: &Path) -> Self {
+        Self { original: path.to_owned(), canonicalized: std::fs::canonicalize(path).ok() }
+    }
+
+    pub fn canonicalized(&self) -> &PathBuf {
+        self.canonicalized.as_ref().unwrap_or(self.original())
+    }
+
+    pub fn original(&self) -> &PathBuf {
+        &self.original
+    }
+}