mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #28256 - petrochenkov:conv, r=alexcrichton
This patch transforms functions of the form ``` fn f<Generic: AsRef<Concrete>>(arg: Generic) { let arg: &Concrete = arg.as_ref(); // Code using arg } ``` to the next form: ``` #[inline] fn f<Generic: AsRef<Concrete>>(arg: Generic) { fn f_inner(arg: &Concrete) { // Code using arg } f_inner(arg.as_ref()); } ``` Therefore, most of the code is concrete and not duplicated during monomorphisation (unless inlined) and only the tiny bit of conversion code is duplicated. This method was mentioned by @aturon in the Conversion Traits RFC (https://github.com/rust-lang/rfcs/blame/master/text/0529-conversion-traits.md#L249) and similar techniques are not uncommon in C++ template libraries. This patch goes to the extremes and applies the transformation even to smaller functions<sup>1</sup> for purity of the experiment. *Some of them can be rolled back* if considered too ridiculous. <sup>1</sup> However who knows how small are these functions are after inlining and everything. The functions in question are mostly `fs`/`os` functions and not used especially often with variety of argument types, so the code size reduction is rather small (but consistent). Here are the sizes of stage2 artifacts before and after the patch: https://gist.github.com/petrochenkov/e76a6b280f382da13c5d https://gist.github.com/petrochenkov/6cc28727d5256dbdfed0 Note: All the `inner` functions are concrete and unavailable for cross-crate inlining, some of them may need `#[inline]` annotations in the future. r? @aturon
This commit is contained in:
commit
e629dba0ee
@ -38,8 +38,12 @@ impl TempDir {
|
|||||||
#[allow(deprecated)] // rand usage
|
#[allow(deprecated)] // rand usage
|
||||||
pub fn new_in<P: AsRef<Path>>(tmpdir: P, prefix: &str)
|
pub fn new_in<P: AsRef<Path>>(tmpdir: P, prefix: &str)
|
||||||
-> io::Result<TempDir> {
|
-> io::Result<TempDir> {
|
||||||
|
Self::_new_in(tmpdir.as_ref(), prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _new_in(tmpdir: &Path, prefix: &str) -> io::Result<TempDir> {
|
||||||
let storage;
|
let storage;
|
||||||
let mut tmpdir = tmpdir.as_ref();
|
let mut tmpdir = tmpdir;
|
||||||
if !tmpdir.is_absolute() {
|
if !tmpdir.is_absolute() {
|
||||||
let cur_dir = try!(env::current_dir());
|
let cur_dir = try!(env::current_dir());
|
||||||
storage = cur_dir.join(tmpdir);
|
storage = cur_dir.join(tmpdir);
|
||||||
|
@ -174,6 +174,10 @@ impl Iterator for VarsOs {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "env", since = "1.0.0")]
|
#[stable(feature = "env", since = "1.0.0")]
|
||||||
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
|
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
|
||||||
|
_var(key.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _var(key: &OsStr) -> Result<String, VarError> {
|
||||||
match var_os(key) {
|
match var_os(key) {
|
||||||
Some(s) => s.into_string().map_err(VarError::NotUnicode),
|
Some(s) => s.into_string().map_err(VarError::NotUnicode),
|
||||||
None => Err(VarError::NotPresent)
|
None => Err(VarError::NotPresent)
|
||||||
@ -196,8 +200,12 @@ pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "env", since = "1.0.0")]
|
#[stable(feature = "env", since = "1.0.0")]
|
||||||
pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
|
pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
|
||||||
|
_var_os(key.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _var_os(key: &OsStr) -> Option<OsString> {
|
||||||
let _g = ENV_LOCK.lock();
|
let _g = ENV_LOCK.lock();
|
||||||
os_imp::getenv(key.as_ref())
|
os_imp::getenv(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible errors from the `env::var` method.
|
/// Possible errors from the `env::var` method.
|
||||||
@ -263,8 +271,12 @@ impl Error for VarError {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "env", since = "1.0.0")]
|
#[stable(feature = "env", since = "1.0.0")]
|
||||||
pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
|
pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
|
||||||
|
_set_var(k.as_ref(), v.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _set_var(k: &OsStr, v: &OsStr) {
|
||||||
let _g = ENV_LOCK.lock();
|
let _g = ENV_LOCK.lock();
|
||||||
os_imp::setenv(k.as_ref(), v.as_ref())
|
os_imp::setenv(k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an environment variable from the environment of the currently running process.
|
/// Removes an environment variable from the environment of the currently running process.
|
||||||
@ -294,8 +306,12 @@ pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "env", since = "1.0.0")]
|
#[stable(feature = "env", since = "1.0.0")]
|
||||||
pub fn remove_var<K: AsRef<OsStr>>(k: K) {
|
pub fn remove_var<K: AsRef<OsStr>>(k: K) {
|
||||||
|
_remove_var(k.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _remove_var(k: &OsStr) {
|
||||||
let _g = ENV_LOCK.lock();
|
let _g = ENV_LOCK.lock();
|
||||||
os_imp::unsetenv(k.as_ref())
|
os_imp::unsetenv(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over `Path` instances for parsing an environment variable
|
/// An iterator over `Path` instances for parsing an environment variable
|
||||||
|
@ -181,7 +181,10 @@ impl CString {
|
|||||||
/// the position of the nul byte.
|
/// the position of the nul byte.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
|
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
|
||||||
let bytes = t.into();
|
Self::_new(t.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
|
||||||
match bytes.iter().position(|x| *x == 0) {
|
match bytes.iter().position(|x| *x == 0) {
|
||||||
Some(i) => Err(NulError(i, bytes)),
|
Some(i) => Err(NulError(i, bytes)),
|
||||||
None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
|
None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
|
||||||
|
@ -73,20 +73,20 @@ impl OsString {
|
|||||||
/// convert; non UTF-8 data will produce `None`.
|
/// convert; non UTF-8 data will produce `None`.
|
||||||
#[unstable(feature = "convert", reason = "recently added", issue = "27704")]
|
#[unstable(feature = "convert", reason = "recently added", issue = "27704")]
|
||||||
pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
|
pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
|
||||||
|
Self::_from_bytes(bytes.into())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
|
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
|
||||||
use os::unix::ffi::OsStringExt;
|
use os::unix::ffi::OsStringExt;
|
||||||
Some(OsString::from_vec(vec))
|
Some(OsString::from_vec(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
|
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
|
||||||
String::from_utf8(vec).ok().map(OsString::from)
|
String::from_utf8(vec).ok().map(OsString::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
from_bytes_inner(bytes.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts to an `OsStr` slice.
|
/// Converts to an `OsStr` slice.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn as_os_str(&self) -> &OsStr {
|
pub fn as_os_str(&self) -> &OsStr {
|
||||||
|
@ -184,7 +184,7 @@ impl File {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
||||||
OpenOptions::new().read(true).open(path)
|
OpenOptions::new().read(true).open(path.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a file in write-only mode.
|
/// Opens a file in write-only mode.
|
||||||
@ -206,7 +206,7 @@ impl File {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
||||||
OpenOptions::new().write(true).create(true).truncate(true).open(path)
|
OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to sync all OS-internal metadata to disk.
|
/// Attempts to sync all OS-internal metadata to disk.
|
||||||
@ -494,7 +494,10 @@ impl OpenOptions {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
|
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
|
||||||
let path = path.as_ref();
|
self._open(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _open(&self, path: &Path) -> io::Result<File> {
|
||||||
let inner = try!(fs_imp::File::open(path, &self.0));
|
let inner = try!(fs_imp::File::open(path, &self.0));
|
||||||
Ok(File { inner: inner })
|
Ok(File { inner: inner })
|
||||||
}
|
}
|
||||||
@ -1048,7 +1051,10 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
||||||
let path = path.as_ref();
|
_remove_dir_all(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _remove_dir_all(path: &Path) -> io::Result<()> {
|
||||||
for child in try!(read_dir(path)) {
|
for child in try!(read_dir(path)) {
|
||||||
let child = try!(child).path();
|
let child = try!(child).path();
|
||||||
let stat = try!(symlink_metadata(&*child));
|
let stat = try!(symlink_metadata(&*child));
|
||||||
@ -1113,6 +1119,10 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
|
|||||||
as symlinks differently",
|
as symlinks differently",
|
||||||
issue = "27707")]
|
issue = "27707")]
|
||||||
pub fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<WalkDir> {
|
pub fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<WalkDir> {
|
||||||
|
_walk_dir(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _walk_dir(path: &Path) -> io::Result<WalkDir> {
|
||||||
let start = try!(read_dir(path));
|
let start = try!(read_dir(path));
|
||||||
Ok(WalkDir { cur: Some(start), stack: Vec::new() })
|
Ok(WalkDir { cur: Some(start), stack: Vec::new() })
|
||||||
}
|
}
|
||||||
@ -1272,7 +1282,10 @@ impl DirBuilder {
|
|||||||
/// Create the specified directory with the options configured in this
|
/// Create the specified directory with the options configured in this
|
||||||
/// builder.
|
/// builder.
|
||||||
pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
let path = path.as_ref();
|
self._create(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _create(&self, path: &Path) -> io::Result<()> {
|
||||||
if self.recursive {
|
if self.recursive {
|
||||||
self.create_dir_all(path)
|
self.create_dir_all(path)
|
||||||
} else {
|
} else {
|
||||||
|
@ -191,10 +191,14 @@ impl Error {
|
|||||||
pub fn new<E>(kind: ErrorKind, error: E) -> Error
|
pub fn new<E>(kind: ErrorKind, error: E) -> Error
|
||||||
where E: Into<Box<error::Error+Send+Sync>>
|
where E: Into<Box<error::Error+Send+Sync>>
|
||||||
{
|
{
|
||||||
|
Self::_new(kind, error.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
|
||||||
Error {
|
Error {
|
||||||
repr: Repr::Custom(Box::new(Custom {
|
repr: Repr::Custom(Box::new(Custom {
|
||||||
kind: kind,
|
kind: kind,
|
||||||
error: error.into(),
|
error: error,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -965,8 +965,10 @@ impl PathBuf {
|
|||||||
/// * if `path` has a prefix but no root, it replaces `self`.
|
/// * if `path` has a prefix but no root, it replaces `self`.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn push<P: AsRef<Path>>(&mut self, path: P) {
|
pub fn push<P: AsRef<Path>>(&mut self, path: P) {
|
||||||
let path = path.as_ref();
|
self._push(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _push(&mut self, path: &Path) {
|
||||||
// in general, a separator is needed if the rightmost byte is not a separator
|
// in general, a separator is needed if the rightmost byte is not a separator
|
||||||
let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
|
let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
|
||||||
|
|
||||||
@ -1033,11 +1035,15 @@ impl PathBuf {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) {
|
pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) {
|
||||||
|
self._set_file_name(file_name.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _set_file_name(&mut self, file_name: &OsStr) {
|
||||||
if self.file_name().is_some() {
|
if self.file_name().is_some() {
|
||||||
let popped = self.pop();
|
let popped = self.pop();
|
||||||
debug_assert!(popped);
|
debug_assert!(popped);
|
||||||
}
|
}
|
||||||
self.push(file_name.as_ref());
|
self.push(file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates `self.extension()` to `extension`.
|
/// Updates `self.extension()` to `extension`.
|
||||||
@ -1048,6 +1054,10 @@ impl PathBuf {
|
|||||||
/// is added; otherwise it is replaced.
|
/// is added; otherwise it is replaced.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn set_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
|
pub fn set_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
|
||||||
|
self._set_extension(extension.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _set_extension(&mut self, extension: &OsStr) -> bool {
|
||||||
if self.file_name().is_none() { return false; }
|
if self.file_name().is_none() { return false; }
|
||||||
|
|
||||||
let mut stem = match self.file_stem() {
|
let mut stem = match self.file_stem() {
|
||||||
@ -1055,7 +1065,6 @@ impl PathBuf {
|
|||||||
None => OsString::new(),
|
None => OsString::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let extension = extension.as_ref();
|
|
||||||
if !os_str_as_u8_slice(extension).is_empty() {
|
if !os_str_as_u8_slice(extension).is_empty() {
|
||||||
stem.push(".");
|
stem.push(".");
|
||||||
stem.push(extension);
|
stem.push(extension);
|
||||||
@ -1106,7 +1115,7 @@ impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
|
|||||||
impl<P: AsRef<Path>> iter::Extend<P> for PathBuf {
|
impl<P: AsRef<Path>> iter::Extend<P> for PathBuf {
|
||||||
fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
|
fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
|
||||||
for p in iter {
|
for p in iter {
|
||||||
self.push(p)
|
self.push(p.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1452,7 +1461,11 @@ impl Path {
|
|||||||
issue = "23284")]
|
issue = "23284")]
|
||||||
pub fn relative_from<'a, P: ?Sized + AsRef<Path>>(&'a self, base: &'a P) -> Option<&Path>
|
pub fn relative_from<'a, P: ?Sized + AsRef<Path>>(&'a self, base: &'a P) -> Option<&Path>
|
||||||
{
|
{
|
||||||
iter_after(self.components(), base.as_ref().components()).map(|c| c.as_path())
|
self._relative_from(base.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _relative_from<'a>(&'a self, base: &'a Path) -> Option<&'a Path> {
|
||||||
|
iter_after(self.components(), base.components()).map(|c| c.as_path())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether `base` is a prefix of `self`.
|
/// Determines whether `base` is a prefix of `self`.
|
||||||
@ -1472,7 +1485,11 @@ impl Path {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
|
pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
|
||||||
iter_after(self.components(), base.as_ref().components()).is_some()
|
self._starts_with(base.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _starts_with(&self, base: &Path) -> bool {
|
||||||
|
iter_after(self.components(), base.components()).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether `child` is a suffix of `self`.
|
/// Determines whether `child` is a suffix of `self`.
|
||||||
@ -1490,7 +1507,11 @@ impl Path {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
|
pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
|
||||||
iter_after(self.components().rev(), child.as_ref().components().rev()).is_some()
|
self._ends_with(child.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _ends_with(&self, child: &Path) -> bool {
|
||||||
|
iter_after(self.components().rev(), child.components().rev()).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the stem (non-extension) portion of `self.file_name()`.
|
/// Extracts the stem (non-extension) portion of `self.file_name()`.
|
||||||
@ -1552,6 +1573,10 @@ impl Path {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
|
pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
|
||||||
|
self._join(path.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _join(&self, path: &Path) -> PathBuf {
|
||||||
let mut buf = self.to_path_buf();
|
let mut buf = self.to_path_buf();
|
||||||
buf.push(path);
|
buf.push(path);
|
||||||
buf
|
buf
|
||||||
@ -1571,6 +1596,10 @@ impl Path {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
|
pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
|
||||||
|
self._with_file_name(file_name.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _with_file_name(&self, file_name: &OsStr) -> PathBuf {
|
||||||
let mut buf = self.to_path_buf();
|
let mut buf = self.to_path_buf();
|
||||||
buf.set_file_name(file_name);
|
buf.set_file_name(file_name);
|
||||||
buf
|
buf
|
||||||
@ -1590,6 +1619,10 @@ impl Path {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
|
pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
|
||||||
|
self._with_extension(extension.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _with_extension(&self, extension: &OsStr) -> PathBuf {
|
||||||
let mut buf = self.to_path_buf();
|
let mut buf = self.to_path_buf();
|
||||||
buf.set_extension(extension);
|
buf.set_extension(extension);
|
||||||
buf
|
buf
|
||||||
|
Loading…
Reference in New Issue
Block a user