Skip to content

Commit b7aae1b

Browse files
committed
Provide convenience functions exists, is_file, and is_dir, in fs.
1 parent 5dfd1c1 commit b7aae1b

File tree

20 files changed

+158
-73
lines changed

20 files changed

+158
-73
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,8 @@ fn thin_lto(
496496
// If the previous file was deleted, or we get an IO error
497497
// reading the file, then we'll just use `None` as the
498498
// prev_key_map, which will force the code to be recompiled.
499-
let prev = if fs::metadata(&path).is_ok() {
500-
ThinLTOKeysMap::load_from_file(&path).ok()
501-
} else {
502-
None
503-
};
499+
let prev =
500+
if fs::exists(&path) { ThinLTOKeysMap::load_from_file(&path).ok() } else { None };
504501
let curr = ThinLTOKeysMap::from_thin_lto_modules(&data, &thin_modules, &module_names);
505502
(Some(path), prev, curr)
506503
} else {

compiler/rustc_codegen_ssa/src/back/archive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) -> P
1515
for path in search_paths {
1616
debug!("looking for {} inside {:?}", name, path);
1717
let test = path.join(&oslibname);
18-
if fs::metadata(&test).is_ok() {
18+
if fs::exists(&test) {
1919
return test;
2020
}
2121
if oslibname != unixlibname {
2222
let test = path.join(&unixlibname);
23-
if fs::metadata(&test).is_ok() {
23+
if fs::exists(&test) {
2424
return test;
2525
}
2626
}

compiler/rustc_codegen_ssa/src/back/link.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -1110,19 +1110,19 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
11101110
fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf {
11111111
let fs = sess.target_filesearch(PathKind::Native);
11121112
let file_path = fs.get_lib_path().join(name);
1113-
if fs::metadata(&file_path).is_ok() {
1113+
if fs::exists(&file_path) {
11141114
return file_path;
11151115
}
11161116
// Special directory with objects used only in self-contained linkage mode
11171117
if self_contained {
11181118
let file_path = fs.get_self_contained_lib_path().join(name);
1119-
if fs::metadata(&file_path).is_ok() {
1119+
if fs::exists(&file_path) {
11201120
return file_path;
11211121
}
11221122
}
11231123
for search_path in fs.search_paths() {
11241124
let file_path = search_path.dir.join(name);
1125-
if fs::metadata(&file_path).is_ok() {
1125+
if fs::exists(&file_path) {
11261126
return file_path;
11271127
}
11281128
}
@@ -1312,9 +1312,7 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
13121312
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
13131313
let full_path = dir.join(&linker_with_extension);
13141314
// If linker comes from sysroot assume self-contained mode
1315-
if fs::metadata(&full_path).map(|m| m.is_file()).unwrap_or(false)
1316-
&& !full_path.starts_with(&sess.sysroot)
1317-
{
1315+
if fs::is_file(&full_path) && !full_path.starts_with(&sess.sysroot) {
13181316
return false;
13191317
}
13201318
}
@@ -2230,7 +2228,7 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
22302228
if sdkroot.contains("iPhoneOS.platform")
22312229
|| sdkroot.contains("iPhoneSimulator.platform") => {}
22322230
// Ignore `SDKROOT` if it's not a valid path.
2233-
_ if !p.is_absolute() || p == Path::new("/") || fs::metadata(p).is_err() => {}
2231+
_ if !p.is_absolute() || p == Path::new("/") || !fs::exists(p) => {}
22342232
_ => return Ok(sdkroot),
22352233
}
22362234
}

compiler/rustc_codegen_ssa/src/back/linker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ impl<'a> Linker for MsvcLinker<'a> {
695695
// check to see if the file is there and just omit linking to it if it's
696696
// not present.
697697
let name = format!("{}.dll.lib", lib);
698-
if fs::metadata(&path.join(&name)).is_ok() {
698+
if fs::exists(&path.join(&name)) {
699699
self.cmd.arg(name);
700700
}
701701
}

compiler/rustc_incremental/src/persist/load.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
143143
let mut all_files_exist = true;
144144
if let Some(ref file_name) = swp.work_product.saved_file {
145145
let path = in_incr_comp_dir_sess(sess, file_name);
146-
if fs::metadata(&path).is_err() {
146+
if !fs::exists(&path) {
147147
all_files_exist = false;
148148

149149
if sess.opts.debugging_opts.incremental_info {

compiler/rustc_incremental/src/persist/save.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub fn save_work_product_index(
7474
if !new_work_products.contains_key(id) {
7575
work_product::delete_workproduct_files(sess, wp);
7676
debug_assert!(wp.saved_file.as_ref().map_or(true, |file_name| {
77-
fs::metadata(in_incr_comp_dir_sess(sess, &file_name)).is_err()
77+
!fs::exists(in_incr_comp_dir_sess(sess, &file_name))
7878
}));
7979
}
8080
}
@@ -85,7 +85,7 @@ pub fn save_work_product_index(
8585
.iter()
8686
.flat_map(|(_, wp)| wp.saved_file.iter())
8787
.map(|name| in_incr_comp_dir_sess(sess, name))
88-
.all(|path| fs::metadata(path).is_ok())
88+
.all(|path| fs::exists(path))
8989
});
9090
}
9191

compiler/rustc_interface/src/passes.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,7 @@ fn output_contains_path(output_paths: &[PathBuf], input_path: &PathBuf) -> bool
517517
}
518518

519519
fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> {
520-
let check = |output_path: &PathBuf| {
521-
fs::metadata(output_path).map(|m| m.is_dir()).unwrap_or(false).then(|| output_path.clone())
522-
};
520+
let check = |output_path: &PathBuf| fs::is_dir(output_path).then(|| output_path.clone());
523521
check_output(output_paths, check)
524522
}
525523

compiler/rustc_interface/src/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
270270
} else {
271271
"rustc"
272272
});
273-
fs::metadata(&candidate).is_ok().then_some(candidate)
273+
fs::exists(&candidate).then_some(candidate)
274274
})
275275
}
276276

@@ -398,7 +398,7 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend
398398
})
399399
.find(|f| {
400400
info!("codegen backend candidate: {}", f.display());
401-
fs::metadata(f).is_ok()
401+
fs::exists(f)
402402
});
403403
let sysroot = sysroot.unwrap_or_else(|| {
404404
let candidates = sysroot_candidates

compiler/rustc_llvm/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ fn main() {
206206
stripped
207207
} else if let Some(stripped) = lib.strip_prefix('-') {
208208
stripped
209-
} else if fs::metadata(Path::new(lib)).is_ok() {
209+
} else if fs::exists(Path::new(lib)) {
210210
// On MSVC llvm-config will print the full name to libraries, but
211211
// we're only interested in the name part
212212
let name = Path::new(lib).file_name().unwrap().to_str().unwrap();

compiler/rustc_metadata/src/locator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ impl<'a> CrateLocator<'a> {
664664
let mut rmetas = FxHashMap::default();
665665
let mut dylibs = FxHashMap::default();
666666
for loc in &self.exact_paths {
667-
if fs::metadata(loc).is_err() {
667+
if !fs::exists(loc) {
668668
return Err(CrateError::ExternLocationNotExist(self.crate_name, loc.clone()));
669669
}
670670
let file = match loc.file_name().and_then(|s| s.to_str()) {
@@ -738,7 +738,7 @@ fn get_metadata_section(
738738
filename: &Path,
739739
loader: &dyn MetadataLoader,
740740
) -> Result<MetadataBlob, String> {
741-
if fs::metadata(filename).is_err() {
741+
if !fs::exists(filename) {
742742
return Err(format!("no such file: '{}'", filename.display()));
743743
}
744744
let raw_bytes: MetadataRef = match flavor {

compiler/rustc_session/src/filesearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn find_libdir(sysroot: &Path) -> Cow<'static, str> {
154154

155155
match option_env!("CFG_LIBDIR_RELATIVE") {
156156
None | Some("lib") => {
157-
if fs::metadata(sysroot.join(PRIMARY_LIB_DIR).join(RUST_LIB_DIR)).is_ok() {
157+
if fs::exists(sysroot.join(PRIMARY_LIB_DIR).join(RUST_LIB_DIR)) {
158158
PRIMARY_LIB_DIR.into()
159159
} else {
160160
SECONDARY_LIB_DIR.into()

compiler/rustc_session/src/session.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
14851485
// Make sure that any given profiling data actually exists so LLVM can't
14861486
// decide to silently skip PGO.
14871487
if let Some(ref path) = sess.opts.cg.profile_use {
1488-
if fs::metadata(path).is_err() {
1488+
if !fs::exists(path) {
14891489
sess.err(&format!(
14901490
"File `{}` passed to `-C profile-use` does not exist.",
14911491
path.display()

compiler/rustc_span/src/source_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub struct RealFileLoader;
109109

110110
impl FileLoader for RealFileLoader {
111111
fn file_exists(&self, path: &Path) -> bool {
112-
fs::metadata(path).is_ok()
112+
fs::exists(path)
113113
}
114114

115115
fn read_file(&self, path: &Path) -> io::Result<String> {

compiler/rustc_target/src/spec/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1600,14 +1600,14 @@ impl Target {
16001600

16011601
for dir in env::split_paths(&target_path) {
16021602
let p = dir.join(&path);
1603-
if fs::metadata(&p).map(|m| m.is_file()).unwrap_or(false) {
1603+
if fs::is_file(&p) {
16041604
return load_file(&p);
16051605
}
16061606
}
16071607
Err(format!("Could not find specification for target {:?}", target_triple))
16081608
}
16091609
TargetTriple::TargetPath(ref target_path) => {
1610-
if fs::metadata(target_path).map(|m| m.is_file()).unwrap_or(false) {
1610+
if fs::is_file(target_path) {
16111611
return load_file(&target_path);
16121612
}
16131613
Err(format!("Target path {:?} is not a valid file", target_path))

library/std/src/fs.rs

+89-3
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,92 @@ pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result
21082108
fs_imp::set_perm(path.as_ref(), perm.0)
21092109
}
21102110

2111+
/// Returns `true` if the path points at an existing entity.
2112+
///
2113+
/// This function will traverse symbolic links to query information about the
2114+
/// destination file. In case of broken symbolic links this will return `false`.
2115+
///
2116+
/// If you cannot access the directory containing the file, e.g., because of a
2117+
/// permission error, this will return `false`.
2118+
///
2119+
/// # Examples
2120+
///
2121+
/// ```no_run
2122+
/// use std::path::Path;
2123+
/// assert!(!Path::new("does_not_exist.txt").exists());
2124+
/// ```
2125+
///
2126+
/// # See Also
2127+
///
2128+
/// This is a convenience function that coerces errors to false. If you want to
2129+
/// check errors, call [`metadata`].
2130+
#[stable(feature = "fs_path_convenience", since = "1.51.0")]
2131+
pub fn exists<P: AsRef<Path>>(path: P) -> bool {
2132+
metadata(path).is_ok()
2133+
}
2134+
2135+
/// Returns `true` if the path exists on disk and is pointing at a regular file.
2136+
///
2137+
/// This function will traverse symbolic links to query information about the
2138+
/// destination file. In case of broken symbolic links this will return `false`.
2139+
///
2140+
/// If you cannot access the directory containing the file, e.g., because of a
2141+
/// permission error, this will return `false`.
2142+
///
2143+
/// # Examples
2144+
///
2145+
/// ```no_run
2146+
/// use std::path::Path;
2147+
/// assert_eq!(Path::new("./is_a_directory/").is_file(), false);
2148+
/// assert_eq!(Path::new("a_file.txt").is_file(), true);
2149+
/// ```
2150+
///
2151+
/// # See Also
2152+
///
2153+
/// This is a convenience function that coerces errors to false. If you want to
2154+
/// check errors, call [`metadata`] and handle its [`Result`]. Then call
2155+
/// [`Metadata::is_file`] if it was [`Ok`].
2156+
///
2157+
/// When the goal is simply to read from (or write to) the source, the most
2158+
/// reliable way to test the source can be read (or written to) is to open
2159+
/// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
2160+
/// a Unix-like system for example. See [`File::open`] or
2161+
/// [`OpenOptions::open`] for more information.
2162+
#[stable(feature = "fs_path_convenience", since = "1.51.0")]
2163+
pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
2164+
metadata(path).map(|m| m.is_file()).unwrap_or(false)
2165+
}
2166+
2167+
/// Returns `true` if the path exists on disk and is pointing at a directory.
2168+
///
2169+
/// This function will traverse symbolic links to query information about the
2170+
/// destination file. In case of broken symbolic links this will return `false`.
2171+
///
2172+
/// If you cannot access the directory containing the file, e.g., because of a
2173+
/// permission error, this will return `false`.
2174+
///
2175+
/// # Examples
2176+
///
2177+
/// ```no_run
2178+
/// use std::path::Path;
2179+
/// assert_eq!(Path::new("./is_a_directory/").is_dir(), true);
2180+
/// assert_eq!(Path::new("a_file.txt").is_dir(), false);
2181+
/// ```
2182+
///
2183+
/// # See Also
2184+
///
2185+
/// This is a convenience function that coerces errors to false. If you want to
2186+
/// check errors, call [`metadata`] and handle its [`Result`]. Then call
2187+
/// [`Metadata::is_dir`] if it was [`Ok`].
2188+
///
2189+
/// When the goal is simply to read from the source, the most reliable way to
2190+
/// test the source can be read is to open it. See [`read_dir`] for more
2191+
/// information.
2192+
#[stable(feature = "fs_path_convenience", since = "1.51.0")]
2193+
pub fn is_dir<P: AsRef<Path>>(path: P) -> bool {
2194+
metadata(path).map(|m| m.is_dir()).unwrap_or(false)
2195+
}
2196+
21112197
impl DirBuilder {
21122198
/// Creates a new set of options with default mode/security settings for all
21132199
/// platforms and also non-recursive.
@@ -2160,7 +2246,7 @@ impl DirBuilder {
21602246
/// .recursive(true)
21612247
/// .create(path).unwrap();
21622248
///
2163-
/// assert!(fs::metadata(path).unwrap().is_dir());
2249+
/// assert!(fs::is_dir(path));
21642250
/// ```
21652251
#[stable(feature = "dir_builder", since = "1.6.0")]
21662252
pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
@@ -2179,7 +2265,7 @@ impl DirBuilder {
21792265
match self.inner.mkdir(path) {
21802266
Ok(()) => return Ok(()),
21812267
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
2182-
Err(_) if metadata(path).map(|m| m.is_dir()).unwrap_or(false) => return Ok(()),
2268+
Err(_) if is_dir(path) => return Ok(()),
21832269
Err(e) => return Err(e),
21842270
}
21852271
match path.parent() {
@@ -2190,7 +2276,7 @@ impl DirBuilder {
21902276
}
21912277
match self.inner.mkdir(path) {
21922278
Ok(()) => Ok(()),
2193-
Err(_) if metadata(path).map(|m| m.is_dir()).unwrap_or(false) => Ok(()),
2279+
Err(_) if is_dir(path) => Ok(()),
21942280
Err(e) => Err(e),
21952281
}
21962282
}

0 commit comments

Comments
 (0)