Skip to content

Commit 54660fc

Browse files
committed
Auto merge of #23316 - alexcrichton:less-question-sized, r=aturon
It is a frequent pattern among I/O functions to take `P: AsPath + ?Sized` or `AsOsStr` instead of `AsPath`. Most of these functions do not need to take ownership of their argument, but for libraries in general it's much more ergonomic to not deal with `?Sized` at all and simply require an argument `P` instead of `&P`. This change is aimed at removing unsightly `?Sized` bounds while retaining the same level of usability as before. All affected functions now take ownership of their arguments instead of taking them by reference, but due to the forwarding implementations of `AsOsStr` and `AsPath` all code should continue to work as it did before. This is strictly speaking a breaking change due to the signatures of these functions changing, but normal idiomatic usage of these APIs should not break in practice. [breaking-change]
2 parents f59af75 + 60a4a2d commit 54660fc

File tree

4 files changed

+39
-43
lines changed

4 files changed

+39
-43
lines changed

src/libstd/fs/mod.rs

+20-24
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl File {
124124
/// This function will return an error if `path` does not already exist.
125125
/// Other errors may also be returned according to `OpenOptions::open`.
126126
#[stable(feature = "rust1", since = "1.0.0")]
127-
pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
127+
pub fn open<P: AsPath>(path: P) -> io::Result<File> {
128128
OpenOptions::new().read(true).open(path)
129129
}
130130

@@ -135,7 +135,7 @@ impl File {
135135
///
136136
/// See the `OpenOptions::open` function for more details.
137137
#[stable(feature = "rust1", since = "1.0.0")]
138-
pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
138+
pub fn create<P: AsPath>(path: P) -> io::Result<File> {
139139
OpenOptions::new().write(true).create(true).truncate(true).open(path)
140140
}
141141

@@ -297,7 +297,7 @@ impl OpenOptions {
297297
/// permissions for
298298
/// * Filesystem-level errors (full disk, etc)
299299
#[stable(feature = "rust1", since = "1.0.0")]
300-
pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
300+
pub fn open<P: AsPath>(&self, path: P) -> io::Result<File> {
301301
let path = path.as_path();
302302
let inner = try!(fs_imp::File::open(path, &self.0));
303303
Ok(File { path: path.to_path_buf(), inner: inner })
@@ -410,7 +410,7 @@ impl DirEntry {
410410
/// user lacks permissions to remove the file, or if some other filesystem-level
411411
/// error occurs.
412412
#[stable(feature = "rust1", since = "1.0.0")]
413-
pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
413+
pub fn remove_file<P: AsPath>(path: P) -> io::Result<()> {
414414
fs_imp::unlink(path.as_path())
415415
}
416416

@@ -438,7 +438,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
438438
/// permissions to perform a `metadata` call on the given `path` or if there
439439
/// is no entry in the filesystem at the provided path.
440440
#[stable(feature = "rust1", since = "1.0.0")]
441-
pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
441+
pub fn metadata<P: AsPath>(path: P) -> io::Result<Metadata> {
442442
fs_imp::stat(path.as_path()).map(Metadata)
443443
}
444444

@@ -459,8 +459,7 @@ pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
459459
/// reside on separate filesystems, or if some other intermittent I/O error
460460
/// occurs.
461461
#[stable(feature = "rust1", since = "1.0.0")]
462-
pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
463-
-> io::Result<()> {
462+
pub fn rename<P: AsPath, Q: AsPath>(from: P, to: Q) -> io::Result<()> {
464463
fs_imp::rename(from.as_path(), to.as_path())
465464
}
466465

@@ -490,9 +489,9 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
490489
/// * The current process does not have the permission rights to access
491490
/// `from` or write `to`
492491
#[stable(feature = "rust1", since = "1.0.0")]
493-
pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
494-
-> io::Result<u64> {
492+
pub fn copy<P: AsPath, Q: AsPath>(from: P, to: Q) -> io::Result<u64> {
495493
let from = from.as_path();
494+
let to = to.as_path();
496495
if !from.is_file() {
497496
return Err(Error::new(ErrorKind::MismatchedFileTypeForOperation,
498497
"the source path is not an existing file",
@@ -513,17 +512,15 @@ pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
513512
/// The `dst` path will be a link pointing to the `src` path. Note that systems
514513
/// often require these two paths to both be located on the same filesystem.
515514
#[stable(feature = "rust1", since = "1.0.0")]
516-
pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
517-
-> io::Result<()> {
515+
pub fn hard_link<P: AsPath, Q: AsPath>(src: P, dst: Q) -> io::Result<()> {
518516
fs_imp::link(src.as_path(), dst.as_path())
519517
}
520518

521519
/// Creates a new soft link on the filesystem.
522520
///
523521
/// The `dst` path will be a soft link pointing to the `src` path.
524522
#[stable(feature = "rust1", since = "1.0.0")]
525-
pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
526-
-> io::Result<()> {
523+
pub fn soft_link<P: AsPath, Q: AsPath>(src: P, dst: Q) -> io::Result<()> {
527524
fs_imp::symlink(src.as_path(), dst.as_path())
528525
}
529526

@@ -535,7 +532,7 @@ pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
535532
/// reading a file that does not exist or reading a file that is not a soft
536533
/// link.
537534
#[stable(feature = "rust1", since = "1.0.0")]
538-
pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
535+
pub fn read_link<P: AsPath>(path: P) -> io::Result<PathBuf> {
539536
fs_imp::readlink(path.as_path())
540537
}
541538

@@ -554,7 +551,7 @@ pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
554551
/// This function will return an error if the user lacks permissions to make a
555552
/// new directory at the provided `path`, or if the directory already exists.
556553
#[stable(feature = "rust1", since = "1.0.0")]
557-
pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
554+
pub fn create_dir<P: AsPath>(path: P) -> io::Result<()> {
558555
fs_imp::mkdir(path.as_path())
559556
}
560557

@@ -568,7 +565,7 @@ pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
568565
/// error conditions for when a directory is being created (after it is
569566
/// determined to not exist) are outlined by `fs::create_dir`.
570567
#[stable(feature = "rust1", since = "1.0.0")]
571-
pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
568+
pub fn create_dir_all<P: AsPath>(path: P) -> io::Result<()> {
572569
let path = path.as_path();
573570
if path.is_dir() { return Ok(()) }
574571
if let Some(p) = path.parent() { try!(create_dir_all(p)) }
@@ -590,7 +587,7 @@ pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
590587
/// This function will return an error if the user lacks permissions to remove
591588
/// the directory at the provided `path`, or if the directory isn't empty.
592589
#[stable(feature = "rust1", since = "1.0.0")]
593-
pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
590+
pub fn remove_dir<P: AsPath>(path: P) -> io::Result<()> {
594591
fs_imp::rmdir(path.as_path())
595592
}
596593

@@ -604,7 +601,7 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
604601
///
605602
/// See `file::remove_file` and `fs::remove_dir`
606603
#[stable(feature = "rust1", since = "1.0.0")]
607-
pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
604+
pub fn remove_dir_all<P: AsPath>(path: P) -> io::Result<()> {
608605
let path = path.as_path();
609606
for child in try!(read_dir(path)) {
610607
let child = try!(child).path();
@@ -657,7 +654,7 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
657654
/// the process lacks permissions to view the contents or if the `path` points
658655
/// at a non-directory file
659656
#[stable(feature = "rust1", since = "1.0.0")]
660-
pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
657+
pub fn read_dir<P: AsPath>(path: P) -> io::Result<ReadDir> {
661658
fs_imp::readdir(path.as_path()).map(ReadDir)
662659
}
663660

@@ -673,7 +670,7 @@ pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
673670
reason = "the precise semantics and defaults for a recursive walk \
674671
may change and this may end up accounting for files such \
675672
as symlinks differently")]
676-
pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> {
673+
pub fn walk_dir<P: AsPath>(path: P) -> io::Result<WalkDir> {
677674
let start = try!(read_dir(path));
678675
Ok(WalkDir { cur: Some(start), stack: Vec::new() })
679676
}
@@ -759,8 +756,8 @@ impl PathExt for Path {
759756
reason = "the argument type of u64 is not quite appropriate for \
760757
this function and may change if the standard library \
761758
gains a type to represent a moment in time")]
762-
pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
763-
modified: u64) -> io::Result<()> {
759+
pub fn set_file_times<P: AsPath>(path: P, accessed: u64,
760+
modified: u64) -> io::Result<()> {
764761
fs_imp::utimes(path.as_path(), accessed, modified)
765762
}
766763

@@ -788,8 +785,7 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
788785
reason = "a more granual ability to set specific permissions may \
789786
be exposed on the Permissions structure itself and this \
790787
method may not always exist")]
791-
pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
792-
-> io::Result<()> {
788+
pub fn set_permissions<P: AsPath>(path: P, perm: Permissions) -> io::Result<()> {
793789
fs_imp::set_perm(path.as_path(), perm.0)
794790
}
795791

src/libstd/path.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ impl PathBuf {
877877
/// Allocate a `PathBuf` with initial contents given by the
878878
/// argument.
879879
#[stable(feature = "rust1", since = "1.0.0")]
880-
pub fn new<S: ?Sized + AsOsStr>(s: &S) -> PathBuf {
880+
pub fn new<S: AsOsStr>(s: S) -> PathBuf {
881881
PathBuf { inner: s.as_os_str().to_os_string() }
882882
}
883883

@@ -891,7 +891,7 @@ impl PathBuf {
891891
/// replaces everything except for the prefix (if any) of `self`.
892892
/// * if `path` has a prefix but no root, it replaces `self.
893893
#[stable(feature = "rust1", since = "1.0.0")]
894-
pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath {
894+
pub fn push<P: AsPath>(&mut self, path: P) {
895895
let path = path.as_path();
896896

897897
// in general, a separator is needed if the rightmost byte is not a separator
@@ -959,7 +959,7 @@ impl PathBuf {
959959
/// assert!(buf == PathBuf::new("/baz.txt"));
960960
/// ```
961961
#[stable(feature = "rust1", since = "1.0.0")]
962-
pub fn set_file_name<S: ?Sized>(&mut self, file_name: &S) where S: AsOsStr {
962+
pub fn set_file_name<S: AsOsStr>(&mut self, file_name: S) {
963963
if self.file_name().is_some() {
964964
let popped = self.pop();
965965
debug_assert!(popped);
@@ -974,7 +974,7 @@ impl PathBuf {
974974
/// Otherwise, returns `true`; if `self.extension()` is `None`, the extension
975975
/// is added; otherwise it is replaced.
976976
#[stable(feature = "rust1", since = "1.0.0")]
977-
pub fn set_extension<S: ?Sized + AsOsStr>(&mut self, extension: &S) -> bool {
977+
pub fn set_extension<S: AsOsStr>(&mut self, extension: S) -> bool {
978978
if self.file_name().is_none() { return false; }
979979

980980
let mut stem = match self.file_stem() {
@@ -1000,17 +1000,17 @@ impl PathBuf {
10001000
}
10011001

10021002
#[stable(feature = "rust1", since = "1.0.0")]
1003-
impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
1004-
fn from_iter<I: IntoIterator<Item = &'a P>>(iter: I) -> PathBuf {
1003+
impl<P: AsPath> iter::FromIterator<P> for PathBuf {
1004+
fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
10051005
let mut buf = PathBuf::new("");
10061006
buf.extend(iter);
10071007
buf
10081008
}
10091009
}
10101010

10111011
#[stable(feature = "rust1", since = "1.0.0")]
1012-
impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath {
1013-
fn extend<I: IntoIterator<Item = &'a P>>(&mut self, iter: I) {
1012+
impl<P: AsPath> iter::Extend<P> for PathBuf {
1013+
fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
10141014
for p in iter {
10151015
self.push(p)
10161016
}
@@ -1253,13 +1253,13 @@ impl Path {
12531253

12541254
/// Determines whether `base` is a prefix of `self`.
12551255
#[stable(feature = "rust1", since = "1.0.0")]
1256-
pub fn starts_with<P: ?Sized>(&self, base: &P) -> bool where P: AsPath {
1256+
pub fn starts_with<P: AsPath>(&self, base: P) -> bool {
12571257
iter_after(self.components(), base.as_path().components()).is_some()
12581258
}
12591259

12601260
/// Determines whether `child` is a suffix of `self`.
12611261
#[stable(feature = "rust1", since = "1.0.0")]
1262-
pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath {
1262+
pub fn ends_with<P: AsPath>(&self, child: P) -> bool {
12631263
iter_after(self.components().rev(), child.as_path().components().rev()).is_some()
12641264
}
12651265

@@ -1293,7 +1293,7 @@ impl Path {
12931293
///
12941294
/// See `PathBuf::push` for more details on what it means to adjoin a path.
12951295
#[stable(feature = "rust1", since = "1.0.0")]
1296-
pub fn join<P: ?Sized>(&self, path: &P) -> PathBuf where P: AsPath {
1296+
pub fn join<P: AsPath>(&self, path: P) -> PathBuf {
12971297
let mut buf = self.to_path_buf();
12981298
buf.push(path);
12991299
buf
@@ -1303,7 +1303,7 @@ impl Path {
13031303
///
13041304
/// See `PathBuf::set_file_name` for more details.
13051305
#[stable(feature = "rust1", since = "1.0.0")]
1306-
pub fn with_file_name<S: ?Sized>(&self, file_name: &S) -> PathBuf where S: AsOsStr {
1306+
pub fn with_file_name<S: AsOsStr>(&self, file_name: S) -> PathBuf {
13071307
let mut buf = self.to_path_buf();
13081308
buf.set_file_name(file_name);
13091309
buf
@@ -1313,7 +1313,7 @@ impl Path {
13131313
///
13141314
/// See `PathBuf::set_extension` for more details.
13151315
#[stable(feature = "rust1", since = "1.0.0")]
1316-
pub fn with_extension<S: ?Sized>(&self, extension: &S) -> PathBuf where S: AsOsStr {
1316+
pub fn with_extension<S: AsOsStr>(&self, extension: S) -> PathBuf {
13171317
let mut buf = self.to_path_buf();
13181318
buf.set_extension(extension);
13191319
buf

src/libstd/process.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl Command {
147147
/// Builder methods are provided to change these defaults and
148148
/// otherwise configure the process.
149149
#[stable(feature = "process", since = "1.0.0")]
150-
pub fn new<S: AsOsStr + ?Sized>(program: &S) -> Command {
150+
pub fn new<S: AsOsStr>(program: S) -> Command {
151151
Command {
152152
inner: CommandImp::new(program.as_os_str()),
153153
stdin: None,
@@ -158,7 +158,7 @@ impl Command {
158158

159159
/// Add an argument to pass to the program.
160160
#[stable(feature = "process", since = "1.0.0")]
161-
pub fn arg<S: AsOsStr + ?Sized>(&mut self, arg: &S) -> &mut Command {
161+
pub fn arg<S: AsOsStr>(&mut self, arg: S) -> &mut Command {
162162
self.inner.arg(arg.as_os_str());
163163
self
164164
}
@@ -175,7 +175,7 @@ impl Command {
175175
/// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
176176
/// and case-sensitive on all other platforms.
177177
#[stable(feature = "process", since = "1.0.0")]
178-
pub fn env<K: ?Sized, V: ?Sized>(&mut self, key: &K, val: &V) -> &mut Command
178+
pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
179179
where K: AsOsStr, V: AsOsStr
180180
{
181181
self.inner.env(key.as_os_str(), val.as_os_str());
@@ -184,7 +184,7 @@ impl Command {
184184

185185
/// Removes an environment variable mapping.
186186
#[stable(feature = "process", since = "1.0.0")]
187-
pub fn env_remove<K: ?Sized + AsOsStr>(&mut self, key: &K) -> &mut Command {
187+
pub fn env_remove<K: AsOsStr>(&mut self, key: K) -> &mut Command {
188188
self.inner.env_remove(key.as_os_str());
189189
self
190190
}
@@ -198,7 +198,7 @@ impl Command {
198198

199199
/// Set the working directory for the child process.
200200
#[stable(feature = "process", since = "1.0.0")]
201-
pub fn current_dir<P: AsPath + ?Sized>(&mut self, dir: &P) -> &mut Command {
201+
pub fn current_dir<P: AsPath>(&mut self, dir: P) -> &mut Command {
202202
self.inner.cwd(dir.as_path().as_os_str());
203203
self
204204
}

src/libstd/sys/unix/os.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
253253
let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
254254
if err != 0 { return Err(io::Error::last_os_error()); }
255255
v.set_len(sz as uint - 1); // chop off trailing NUL
256-
Ok(PathBuf::new::<OsString>(&OsStringExt::from_vec(v)))
256+
Ok(PathBuf::new(OsString::from_vec(v)))
257257
}
258258
}
259259

0 commit comments

Comments
 (0)