From 13555593672b49b5306990d63d0e61a49e17d9f0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 16 Jan 2023 14:27:33 +0000 Subject: [PATCH] Avoid an unnecessary allocation --- .../rustc_save_analysis/src/span_utils.rs | 8 +----- compiler/rustc_session/src/config.rs | 16 +++++------ compiler/rustc_session/src/session.rs | 2 +- compiler/rustc_span/src/source_map.rs | 27 ++++++++++++------- compiler/rustc_span/src/source_map/tests.rs | 2 +- 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 8d6758f40f965..e65d57bb3db3e 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 2679164b927e5..df6b30bfee9e4 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 { + 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 fe992b915613b..d4a1e849b2a09 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 { 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 fa09b4faa441f..5bfe247c58d8d 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>, 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 3cab59e8dbe6c..8671267725230 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"));