Rollup merge of #97912 - Kixunil:stabilize_path_try_exists, r=dtolnay
Stabilize `Path::try_exists()` and improve doc This stabilizes the `Path::try_exists()` method which returns `Result<bool, io::Error>` instead of `bool` allowing handling of errors unrelated to the file not existing. (e.g permission errors) Along with the stabilization it also: * Warns that the `exists()` method is error-prone and suggests to use the newly stabilized one. * Suggests it instead of `metadata()` to handle errors. * Mentions TOCTOU bugs to avoid false assumption that `try_exists()` is completely safe fixed version of `exists()`. * Renames the feature of still-unstable `std::fs::try_exists()` to `fs_try_exists` to avoid name conflict. The tracking issue #83186 remains open to track `fs_try_exists`.
This commit is contained in:
commit
77316a4aaa
3 changed files with 17 additions and 9 deletions
|
@ -1,6 +1,5 @@
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(path_try_exists)]
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
|
|
@ -2317,10 +2317,14 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
|
||||||
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
||||||
/// denied on some of the parent directories.)
|
/// denied on some of the parent directories.)
|
||||||
///
|
///
|
||||||
|
/// Note that while this avoids some pitfalls of the `exists()` method, it still can not
|
||||||
|
/// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
|
||||||
|
/// where those bugs are not an issue.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(path_try_exists)]
|
/// #![feature(fs_try_exists)]
|
||||||
/// use std::fs;
|
/// use std::fs;
|
||||||
///
|
///
|
||||||
/// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
|
/// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
|
||||||
|
@ -2330,7 +2334,7 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
|
||||||
/// [`Path::exists`]: crate::path::Path::exists
|
/// [`Path::exists`]: crate::path::Path::exists
|
||||||
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
|
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
|
||||||
// instead.
|
// instead.
|
||||||
#[unstable(feature = "path_try_exists", issue = "83186")]
|
#[unstable(feature = "fs_try_exists", issue = "83186")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_exists<P: AsRef<Path>>(path: P) -> io::Result<bool> {
|
pub fn try_exists<P: AsRef<Path>>(path: P) -> io::Result<bool> {
|
||||||
fs_imp::try_exists(path.as_ref())
|
fs_imp::try_exists(path.as_ref())
|
||||||
|
|
|
@ -2705,6 +2705,9 @@ impl Path {
|
||||||
|
|
||||||
/// Returns `true` if the path points at an existing entity.
|
/// Returns `true` if the path points at an existing entity.
|
||||||
///
|
///
|
||||||
|
/// Warning: this method may be error-prone, consider using [`try_exists()`] instead!
|
||||||
|
/// It also has a risk of introducing time-of-check to time-of-use (TOCTOU) bugs.
|
||||||
|
///
|
||||||
/// This function will traverse symbolic links to query information about the
|
/// This function will traverse symbolic links to query information about the
|
||||||
/// destination file.
|
/// destination file.
|
||||||
///
|
///
|
||||||
|
@ -2721,7 +2724,9 @@ impl Path {
|
||||||
/// # See Also
|
/// # See Also
|
||||||
///
|
///
|
||||||
/// This is a convenience function that coerces errors to false. If you want to
|
/// This is a convenience function that coerces errors to false. If you want to
|
||||||
/// check errors, call [`fs::metadata`].
|
/// check errors, call [`Path::try_exists`].
|
||||||
|
///
|
||||||
|
/// [`try_exists()`]: Self::try_exists
|
||||||
#[stable(feature = "path_ext", since = "1.5.0")]
|
#[stable(feature = "path_ext", since = "1.5.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2738,20 +2743,20 @@ impl Path {
|
||||||
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
||||||
/// denied on some of the parent directories.)
|
/// denied on some of the parent directories.)
|
||||||
///
|
///
|
||||||
|
/// Note that while this avoids some pitfalls of the `exists()` method, it still can not
|
||||||
|
/// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
|
||||||
|
/// where those bugs are not an issue.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(path_try_exists)]
|
|
||||||
///
|
|
||||||
/// use std::path::Path;
|
/// use std::path::Path;
|
||||||
/// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
|
/// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
|
||||||
/// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
|
/// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`exists()`]: Self::exists
|
/// [`exists()`]: Self::exists
|
||||||
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
|
#[stable(feature = "path_try_exists", since = "1.63.0")]
|
||||||
// instead.
|
|
||||||
#[unstable(feature = "path_try_exists", issue = "83186")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_exists(&self) -> io::Result<bool> {
|
pub fn try_exists(&self) -> io::Result<bool> {
|
||||||
fs::try_exists(self)
|
fs::try_exists(self)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue