about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-01-16 14:27:33 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-01-16 14:46:44 +0000
commit13555593672b49b5306990d63d0e61a49e17d9f0 (patch)
tree9bad8c0892a3e86efeb0f1c6d010de2da23d028c
parent44ef075aeb308422ac513ddc8f18978d9b92eea4 (diff)
downloadrust-13555593672b49b5306990d63d0e61a49e17d9f0.tar.gz
rust-13555593672b49b5306990d63d0e61a49e17d9f0.zip
Avoid an unnecessary allocation
-rw-r--r--compiler/rustc_save_analysis/src/span_utils.rs8
-rw-r--r--compiler/rustc_session/src/config.rs16
-rw-r--r--compiler/rustc_session/src/session.rs2
-rw-r--r--compiler/rustc_span/src/source_map.rs27
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs2
5 files changed, 28 insertions, 27 deletions
diff --git a/compiler/rustc_save_analysis/src/span_utils.rs b/compiler/rustc_save_analysis/src/span_utils.rs
index 8d6758f40f9..e65d57bb3db 100644
--- a/compiler/rustc_save_analysis/src/span_utils.rs
+++ b/compiler/rustc_save_analysis/src/span_utils.rs
@@ -18,13 +18,7 @@ impl<'a> SpanUtils<'a> {
         match &file.name {
             FileName::Real(RealFileName::LocalPath(path)) => {
                 if path.is_absolute() {
-                    self.sess
-                        .source_map()
-                        .path_mapping()
-                        .map_prefix(path.into())
-                        .0
-                        .display()
-                        .to_string()
+                    self.sess.source_map().path_mapping().map_prefix(path).0.display().to_string()
                 } else {
                     self.sess
                         .opts
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 2679164b927..df6b30bfee9 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -592,11 +592,11 @@ impl Input {
         }
     }
 
-    pub fn opt_path(&self) -> Option<PathBuf> {
+    pub fn opt_path(&self) -> Option<&Path> {
         match self {
-            Input::File(file) => Some(file.clone()),
+            Input::File(file) => Some(file),
             Input::Str { name, .. } => match name {
-                FileName::Real(real) => real.local_path().map(|p| p.to_owned()),
+                FileName::Real(real) => real.local_path(),
                 FileName::QuoteExpansion(_) => None,
                 FileName::Anon(_) => None,
                 FileName::MacroExpansion(_) => None,
@@ -604,7 +604,7 @@ impl Input {
                 FileName::CfgSpec(_) => None,
                 FileName::CliCrateAttr(_) => None,
                 FileName::Custom(_) => None,
-                FileName::DocTest(path, _) => Some(path.to_owned()),
+                FileName::DocTest(path, _) => Some(path),
                 FileName::InlineAsm(_) => None,
             },
         }
@@ -2509,12 +2509,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         early_error(error_format, &format!("Current directory is invalid: {e}"));
     });
 
-    let (path, remapped) =
-        FilePathMapping::new(remap_path_prefix.clone()).map_prefix(working_dir.clone());
+    let remap = FilePathMapping::new(remap_path_prefix.clone());
+    let (path, remapped) = remap.map_prefix(&working_dir);
     let working_dir = if remapped {
-        RealFileName::Remapped { local_path: Some(working_dir), virtual_name: path }
+        RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) }
     } else {
-        RealFileName::LocalPath(path)
+        RealFileName::LocalPath(path.into_owned())
     };
 
     Options {
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index fe992b91561..d4a1e849b2a 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -237,7 +237,7 @@ impl Session {
 
     pub fn local_crate_source_file(&self) -> Option<PathBuf> {
         let path = self.io.input.opt_path()?;
-        Some(self.opts.file_path_mapping().map_prefix(path).0)
+        Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned())
     }
 
     fn check_miri_unleashed_features(&self) {
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index fa09b4faa44..5bfe247c58d 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -1138,7 +1138,8 @@ impl FilePathMapping {
     /// Applies any path prefix substitution as defined by the mapping.
     /// The return value is the remapped path and a boolean indicating whether
     /// the path was affected by the mapping.
-    pub fn map_prefix(&self, path: PathBuf) -> (PathBuf, bool) {
+    pub fn map_prefix<'a>(&'a self, path: impl Into<Cow<'a, Path>>) -> (Cow<'a, Path>, bool) {
+        let path = path.into();
         if path.as_os_str().is_empty() {
             // Exit early if the path is empty and therefore there's nothing to remap.
             // This is mostly to reduce spam for `RUSTC_LOG=[remap_path_prefix]`.
@@ -1148,7 +1149,10 @@ impl FilePathMapping {
         return remap_path_prefix(&self.mapping, path);
 
         #[instrument(level = "debug", skip(mapping), ret)]
-        fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf, bool) {
+        fn remap_path_prefix<'a>(
+            mapping: &'a [(PathBuf, PathBuf)],
+            path: Cow<'a, Path>,
+        ) -> (Cow<'a, Path>, bool) {
             // NOTE: We are iterating over the mapping entries from last to first
             //       because entries specified later on the command line should
             //       take precedence.
@@ -1163,9 +1167,9 @@ impl FilePathMapping {
                         // in remapped paths down the line.
                         // So, if we have an exact match, we just return that without a call
                         // to `Path::join()`.
-                        to.clone()
+                        to.into()
                     } else {
-                        to.join(rest)
+                        to.join(rest).into()
                     };
                     debug!("Match - remapped");
 
@@ -1183,11 +1187,11 @@ impl FilePathMapping {
     fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
         match file {
             FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => {
-                let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
+                let (mapped_path, mapped) = self.map_prefix(local_path);
                 let realfile = if mapped {
                     RealFileName::Remapped {
                         local_path: Some(local_path.clone()),
-                        virtual_name: mapped_path,
+                        virtual_name: mapped_path.into_owned(),
                     }
                 } else {
                     realfile.clone()
@@ -1228,14 +1232,17 @@ impl FilePathMapping {
                 let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
                 if was_remapped {
                     // It was remapped, so don't modify further
-                    return RealFileName::Remapped { local_path: None, virtual_name: new_path };
+                    return RealFileName::Remapped {
+                        local_path: None,
+                        virtual_name: new_path.into_owned(),
+                    };
                 }
 
                 if new_path.is_absolute() {
                     // No remapping has applied to this path and it is absolute,
                     // so the working directory cannot influence it either, so
                     // we are done.
-                    return RealFileName::LocalPath(new_path);
+                    return RealFileName::LocalPath(new_path.into_owned());
                 }
 
                 debug_assert!(new_path.is_relative());
@@ -1253,12 +1260,12 @@ impl FilePathMapping {
                             RealFileName::Remapped {
                                 // Erase the actual path
                                 local_path: None,
-                                virtual_name: file_path_abs,
+                                virtual_name: file_path_abs.into_owned(),
                             }
                         } else {
                             // No kind of remapping applied to this path, so
                             // we leave it as it is.
-                            RealFileName::LocalPath(file_path_abs)
+                            RealFileName::LocalPath(file_path_abs.into_owned())
                         }
                     }
                     RealFileName::Remapped {
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index 3cab59e8dbe..86712677252 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -387,7 +387,7 @@ fn path_prefix_remapping_expand_to_absolute() {
     let working_directory = path("/foo");
     let working_directory = RealFileName::Remapped {
         local_path: Some(working_directory.clone()),
-        virtual_name: mapping.map_prefix(working_directory).0,
+        virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
     };
 
     assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));