Rollup merge of #109231 - Zoxc:fs-non-canon, r=eholk
Add `try_canonicalize` to `rustc_fs_util` and use it over `fs::canonicalize` This adds `try_canonicalize` which tries to call `fs::canonicalize`, but falls back to `std::path::absolute` if it fails. Existing `canonicalize` calls are replaced with it. `fs::canonicalize` is not guaranteed to work on Windows.
This commit is contained in:
commit
2a39cf560f
@ -4827,6 +4827,7 @@ dependencies = [
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_expand",
|
||||
"rustc_fs_util",
|
||||
"rustc_hir",
|
||||
"rustc_hir_analysis",
|
||||
"rustc_hir_typeck",
|
||||
@ -4951,6 +4952,7 @@ dependencies = [
|
||||
"rustc_errors",
|
||||
"rustc_expand",
|
||||
"rustc_feature",
|
||||
"rustc_fs_util",
|
||||
"rustc_hir",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_index",
|
||||
@ -5336,6 +5338,7 @@ dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_feature",
|
||||
"rustc_fs_util",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
|
@ -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
|
||||
@ -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))
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
@ -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 }));
|
||||
@ -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),
|
||||
@ -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),
|
||||
|
@ -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" }
|
||||
|
@ -11,6 +11,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;
|
||||
@ -408,12 +409,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()
|
||||
}
|
||||
|
@ -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" }
|
||||
|
@ -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;
|
||||
@ -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> {
|
||||
@ -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;
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -125,7 +126,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`.
|
||||
@ -160,7 +161,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.
|
||||
|
@ -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 {
|
||||
@ -98,7 +99,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 {
|
||||
|
@ -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" }
|
||||
|
@ -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;
|
||||
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user