Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add try_canonicalize to rustc_fs_util and use it over fs::canonicalize #109231

Merged
merged 1 commit into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4826,6 +4826,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
"rustc_fs_util",
"rustc_hir",
"rustc_hir_analysis",
"rustc_hir_typeck",
Expand Down Expand Up @@ -4950,6 +4951,7 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fs_util",
"rustc_hir",
"rustc_hir_pretty",
"rustc_index",
Expand Down Expand Up @@ -5334,6 +5336,7 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_feature",
"rustc_fs_util",
"rustc_index",
"rustc_macros",
"rustc_serialize",
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_fs_util/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![feature(absolute_path)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

use std::ffi::CString;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::path::{absolute, Path, PathBuf};

// Unfortunately, on windows, it looks like msvcrt.dll is silently translating
// verbatim paths under the hood to non-verbatim paths! This manifests itself as
Expand Down Expand Up @@ -91,3 +92,8 @@ pub fn path_to_c_string(p: &Path) -> CString {
pub fn path_to_c_string(p: &Path) -> CString {
CString::new(p.to_str().unwrap()).unwrap()
}

#[inline]
pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
fs::canonicalize(&path).or_else(|_| absolute(&path))
}
8 changes: 4 additions & 4 deletions compiler/rustc_incremental/src/persist/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::svh::Svh;
use rustc_data_structures::{base_n, flock};
use rustc_errors::ErrorGuaranteed;
use rustc_fs_util::{link_or_copy, LinkOrCopy};
use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy};
use rustc_session::{Session, StableCrateId};
use rustc_span::Symbol;

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

fn safe_remove_file(p: &Path) -> io::Result<()> {
let canonicalized = match std_fs::canonicalize(p) {
let canonicalized = match try_canonicalize(p) {
Ok(canonicalized) => canonicalized,
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
Err(err) => return Err(err),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_expand = { path = "../rustc_expand" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::PResult;
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
use rustc_fs_util::try_canonicalize;
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
use rustc_metadata::creader::CStore;
Expand Down Expand Up @@ -405,12 +406,12 @@ where
}

fn output_contains_path(output_paths: &[PathBuf], input_path: &Path) -> bool {
let input_path = input_path.canonicalize().ok();
let input_path = try_canonicalize(input_path).ok();
if input_path.is_none() {
return false;
}
let check = |output_path: &PathBuf| {
if output_path.canonicalize().ok() == input_path { Some(()) } else { None }
if try_canonicalize(output_path).ok() == input_path { Some(()) } else { None }
};
check_output(output_paths, check).is_some()
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_target = { path = "../rustc_target" }
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::MetadataRef;
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
use rustc_fs_util::try_canonicalize;
use rustc_session::config::{self, CrateType};
use rustc_session::cstore::{CrateSource, MetadataLoader};
use rustc_session::filesearch::FileSearch;
Expand All @@ -236,7 +237,7 @@ use snap::read::FrameDecoder;
use std::borrow::Cow;
use std::io::{Read, Result as IoResult, Write};
use std::path::{Path, PathBuf};
use std::{cmp, fmt, fs};
use std::{cmp, fmt};

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

let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
let path = try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
if seen_paths.contains(&path) {
continue;
};
Expand Down Expand Up @@ -636,7 +637,7 @@ impl<'a> CrateLocator<'a> {
// as well.
if let Some((prev, _)) = &ret {
let sysroot = self.sysroot;
let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf());
let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf());
if prev.starts_with(&sysroot) {
continue;
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! A module for searching for libraries

use rustc_fs_util::try_canonicalize;
use smallvec::{smallvec, SmallVec};
use std::env;
use std::fs;
Expand Down Expand Up @@ -122,7 +123,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
let target = crate::config::host_triple();
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
let path = current_dll_path().and_then(|s| s.canonicalize().map_err(|e| e.to_string()));
let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
if let Ok(dll) = path {
// use `parent` twice to chop off the file name and then also the
// directory containing the dll which should be either `lib` or `bin`.
Expand Down Expand Up @@ -157,7 +158,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: PathBuf) -> PathBuf {
let path = fs::canonicalize(&path).unwrap_or(path);
let path = try_canonicalize(&path).unwrap_or(path);
// See comments on this target function, but the gist is that
// gcc chokes on verbatim paths which fs::canonicalize generates
// so we try to avoid those kinds of paths.
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_session/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::session::Session;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_fs_util::try_canonicalize;
use std::path::{Path, PathBuf};

impl Session {
Expand Down Expand Up @@ -91,7 +92,7 @@ pub struct CanonicalizedPath {

impl CanonicalizedPath {
pub fn new(path: &Path) -> Self {
Self { original: path.to_owned(), canonicalized: std::fs::canonicalize(path).ok() }
Self { original: path.to_owned(), canonicalized: try_canonicalize(path).ok() }
}

pub fn canonicalized(&self) -> &PathBuf {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
bitflags = "1.2.1"
tracing = "0.1"
serde_json = "1.0.59"
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_abi = { path = "../rustc_abi" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_feature = { path = "../rustc_feature" }
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use crate::json::{Json, ToJson};
use crate::spec::abi::{lookup as lookup_abi, Abi};
use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_fs_util::try_canonicalize;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::symbol::{sym, Symbol};
use serde_json::Value;
Expand Down Expand Up @@ -2949,7 +2950,7 @@ impl TargetTriple {

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