Skip to content

Commit 4f7cd3d

Browse files
committed
Add try_canonicalize to rustc_fs_util and use it over fs::canonicalize
1 parent 7ac4b82 commit 4f7cd3d

File tree

11 files changed

+31
-14
lines changed

11 files changed

+31
-14
lines changed

Cargo.lock

+3
Original file line numberDiff line numberDiff line change
@@ -4826,6 +4826,7 @@ dependencies = [
48264826
"rustc_data_structures",
48274827
"rustc_errors",
48284828
"rustc_expand",
4829+
"rustc_fs_util",
48294830
"rustc_hir",
48304831
"rustc_hir_analysis",
48314832
"rustc_hir_typeck",
@@ -4950,6 +4951,7 @@ dependencies = [
49504951
"rustc_errors",
49514952
"rustc_expand",
49524953
"rustc_feature",
4954+
"rustc_fs_util",
49534955
"rustc_hir",
49544956
"rustc_hir_pretty",
49554957
"rustc_index",
@@ -5334,6 +5336,7 @@ dependencies = [
53345336
"rustc_abi",
53355337
"rustc_data_structures",
53365338
"rustc_feature",
5339+
"rustc_fs_util",
53375340
"rustc_index",
53385341
"rustc_macros",
53395342
"rustc_serialize",

compiler/rustc_fs_util/src/lib.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
#![feature(absolute_path)]
12
#![deny(rustc::untranslatable_diagnostic)]
23
#![deny(rustc::diagnostic_outside_of_impl)]
34

45
use std::ffi::CString;
56
use std::fs;
67
use std::io;
7-
use std::path::{Path, PathBuf};
8+
use std::path::{absolute, Path, PathBuf};
89

910
// Unfortunately, on windows, it looks like msvcrt.dll is silently translating
1011
// verbatim paths under the hood to non-verbatim paths! This manifests itself as
@@ -91,3 +92,8 @@ pub fn path_to_c_string(p: &Path) -> CString {
9192
pub fn path_to_c_string(p: &Path) -> CString {
9293
CString::new(p.to_str().unwrap()).unwrap()
9394
}
95+
96+
#[inline]
97+
pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
98+
fs::canonicalize(&path).or_else(|_| absolute(&path))
99+
}

compiler/rustc_incremental/src/persist/fs.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
108108
use rustc_data_structures::svh::Svh;
109109
use rustc_data_structures::{base_n, flock};
110110
use rustc_errors::ErrorGuaranteed;
111-
use rustc_fs_util::{link_or_copy, LinkOrCopy};
111+
use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy};
112112
use rustc_session::{Session, StableCrateId};
113113
use rustc_span::Symbol;
114114

@@ -223,7 +223,7 @@ pub fn prepare_session_directory(
223223
// because, on windows, long paths can cause problems;
224224
// canonicalization inserts this weird prefix that makes windows
225225
// tolerate long paths.
226-
let crate_dir = match crate_dir.canonicalize() {
226+
let crate_dir = match try_canonicalize(&crate_dir) {
227227
Ok(v) => v,
228228
Err(err) => {
229229
return Err(sess.emit_err(errors::CanonicalizePath { path: crate_dir, err }));
@@ -867,7 +867,7 @@ fn all_except_most_recent(
867867
/// before passing it to std::fs::remove_dir_all(). This will convert the path
868868
/// into the '\\?\' format, which supports much longer paths.
869869
fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
870-
let canonicalized = match std_fs::canonicalize(p) {
870+
let canonicalized = match try_canonicalize(p) {
871871
Ok(canonicalized) => canonicalized,
872872
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
873873
Err(err) => return Err(err),
@@ -877,7 +877,7 @@ fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
877877
}
878878

879879
fn safe_remove_file(p: &Path) -> io::Result<()> {
880-
let canonicalized = match std_fs::canonicalize(p) {
880+
let canonicalized = match try_canonicalize(p) {
881881
Ok(canonicalized) => canonicalized,
882882
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
883883
Err(err) => return Err(err),

compiler/rustc_interface/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rustc_attr = { path = "../rustc_attr" }
1616
rustc_borrowck = { path = "../rustc_borrowck" }
1717
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
1818
rustc_expand = { path = "../rustc_expand" }
19+
rustc_fs_util = { path = "../rustc_fs_util" }
1920
rustc_macros = { path = "../rustc_macros" }
2021
rustc_parse = { path = "../rustc_parse" }
2122
rustc_session = { path = "../rustc_session" }

compiler/rustc_interface/src/passes.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_data_structures::steal::Steal;
1212
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
1313
use rustc_errors::PResult;
1414
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
15+
use rustc_fs_util::try_canonicalize;
1516
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
1617
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
1718
use rustc_metadata::creader::CStore;
@@ -405,12 +406,12 @@ where
405406
}
406407

407408
fn output_contains_path(output_paths: &[PathBuf], input_path: &Path) -> bool {
408-
let input_path = input_path.canonicalize().ok();
409+
let input_path = try_canonicalize(input_path).ok();
409410
if input_path.is_none() {
410411
return false;
411412
}
412413
let check = |output_path: &PathBuf| {
413-
if output_path.canonicalize().ok() == input_path { Some(()) } else { None }
414+
if try_canonicalize(output_path).ok() == input_path { Some(()) } else { None }
414415
};
415416
check_output(output_paths, check).is_some()
416417
}

compiler/rustc_metadata/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rustc_attr = { path = "../rustc_attr" }
1818
rustc_data_structures = { path = "../rustc_data_structures" }
1919
rustc_errors = { path = "../rustc_errors" }
2020
rustc_feature = { path = "../rustc_feature" }
21+
rustc_fs_util = { path = "../rustc_fs_util" }
2122
rustc_hir = { path = "../rustc_hir" }
2223
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2324
rustc_target = { path = "../rustc_target" }

compiler/rustc_metadata/src/locator.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ use rustc_data_structures::owning_ref::OwningRef;
222222
use rustc_data_structures::svh::Svh;
223223
use rustc_data_structures::sync::MetadataRef;
224224
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
225+
use rustc_fs_util::try_canonicalize;
225226
use rustc_session::config::{self, CrateType};
226227
use rustc_session::cstore::{CrateSource, MetadataLoader};
227228
use rustc_session::filesearch::FileSearch;
@@ -236,7 +237,7 @@ use snap::read::FrameDecoder;
236237
use std::borrow::Cow;
237238
use std::io::{Read, Result as IoResult, Write};
238239
use std::path::{Path, PathBuf};
239-
use std::{cmp, fmt, fs};
240+
use std::{cmp, fmt};
240241

241242
#[derive(Clone)]
242243
pub(crate) struct CrateLocator<'a> {
@@ -441,7 +442,7 @@ impl<'a> CrateLocator<'a> {
441442
info!("lib candidate: {}", spf.path.display());
442443

443444
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
444-
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
445+
let path = try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
445446
if seen_paths.contains(&path) {
446447
continue;
447448
};
@@ -636,7 +637,7 @@ impl<'a> CrateLocator<'a> {
636637
// as well.
637638
if let Some((prev, _)) = &ret {
638639
let sysroot = self.sysroot;
639-
let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf());
640+
let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf());
640641
if prev.starts_with(&sysroot) {
641642
continue;
642643
}

compiler/rustc_session/src/filesearch.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! A module for searching for libraries
22
3+
use rustc_fs_util::try_canonicalize;
34
use smallvec::{smallvec, SmallVec};
45
use std::env;
56
use std::fs;
@@ -122,7 +123,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
122123
let target = crate::config::host_triple();
123124
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
124125
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
125-
let path = current_dll_path().and_then(|s| s.canonicalize().map_err(|e| e.to_string()));
126+
let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
126127
if let Ok(dll) = path {
127128
// use `parent` twice to chop off the file name and then also the
128129
// directory containing the dll which should be either `lib` or `bin`.
@@ -157,7 +158,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
157158
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
158159
// Follow symlinks. If the resolved path is relative, make it absolute.
159160
fn canonicalize(path: PathBuf) -> PathBuf {
160-
let path = fs::canonicalize(&path).unwrap_or(path);
161+
let path = try_canonicalize(&path).unwrap_or(path);
161162
// See comments on this target function, but the gist is that
162163
// gcc chokes on verbatim paths which fs::canonicalize generates
163164
// so we try to avoid those kinds of paths.

compiler/rustc_session/src/utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::session::Session;
22
use rustc_data_structures::profiling::VerboseTimingGuard;
3+
use rustc_fs_util::try_canonicalize;
34
use std::path::{Path, PathBuf};
45

56
impl Session {
@@ -91,7 +92,7 @@ pub struct CanonicalizedPath {
9192

9293
impl CanonicalizedPath {
9394
pub fn new(path: &Path) -> Self {
94-
Self { original: path.to_owned(), canonicalized: std::fs::canonicalize(path).ok() }
95+
Self { original: path.to_owned(), canonicalized: try_canonicalize(path).ok() }
9596
}
9697

9798
pub fn canonicalized(&self) -> &PathBuf {

compiler/rustc_target/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2021"
77
bitflags = "1.2.1"
88
tracing = "0.1"
99
serde_json = "1.0.59"
10+
rustc_fs_util = { path = "../rustc_fs_util" }
1011
rustc_abi = { path = "../rustc_abi" }
1112
rustc_data_structures = { path = "../rustc_data_structures" }
1213
rustc_feature = { path = "../rustc_feature" }

compiler/rustc_target/src/spec/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use crate::json::{Json, ToJson};
4040
use crate::spec::abi::{lookup as lookup_abi, Abi};
4141
use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
4242
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
43+
use rustc_fs_util::try_canonicalize;
4344
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
4445
use rustc_span::symbol::{sym, Symbol};
4546
use serde_json::Value;
@@ -2949,7 +2950,7 @@ impl TargetTriple {
29492950

29502951
/// Creates a target triple from the passed target path.
29512952
pub fn from_path(path: &Path) -> Result<Self, io::Error> {
2952-
let canonicalized_path = path.canonicalize()?;
2953+
let canonicalized_path = try_canonicalize(path)?;
29532954
let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
29542955
io::Error::new(
29552956
io::ErrorKind::InvalidInput,

0 commit comments

Comments
 (0)