Skip to content

Commit 1696dcf

Browse files
committed
Auto merge of #24711 - alexcrichton:fs2.1, r=alexcrichton
This commit is an implementation of [RFC 1044][rfc] which adds additional surface area to the `std::fs` module. All new APIs are `#[unstable]` behind assorted feature names for each one. [rfc]: rust-lang/rfcs#1044 The new APIs added are: * `fs::canonicalize` - bindings to `realpath` on unix and `GetFinalPathNameByHandle` on windows. * `fs::symlink_metadata` - similar to `lstat` on unix * `fs::FileType` and accessor methods as `is_{file,dir,symlink}` * `fs::Metadata::file_type` - accessor for the raw file type * `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows but requires a syscall on unix. * `fs::DirEntry::file_type` - access the file type which may not require a syscall on most platforms. * `fs::DirEntry::file_name` - access just the file name without leading components. * `fs::PathExt::symlink_metadata` - convenience method for the top-level function. * `fs::PathExt::canonicalize` - convenience method for the top-level function. * `fs::PathExt::read_link` - convenience method for the top-level function. * `fs::PathExt::read_dir` - convenience method for the top-level function. * `std::os::raw` - type definitions for raw OS/C types available on all platforms. * `std::os::$platform` - new modules have been added for all currently supported platforms (e.g. those more specific than just `unix`). * `std::os::$platform::raw` - platform-specific type definitions. These modules are populated with the bare essentials necessary for lowing I/O types into their raw representations, and currently largely consist of the `stat` definition for unix platforms. This commit also deprecates `Metadata::{modified, accessed}` in favor of inspecting the raw representations via the lowering methods of `Metadata`. Closes #24796
2 parents 551a74d + 0368abb commit 1696dcf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2508
-932
lines changed

src/librustc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#![feature(path_ext)]
4040
#![feature(str_char)]
4141
#![feature(into_cow)]
42+
#![feature(fs_canonicalize)]
4243
#![feature(slice_patterns)]
4344
#![cfg_attr(test, feature(test))]
4445

@@ -138,7 +139,6 @@ pub mod plugin;
138139
pub mod lint;
139140

140141
pub mod util {
141-
pub use rustc_back::fs;
142142
pub use rustc_back::sha2;
143143

144144
pub mod common;

src/librustc/metadata/creader.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ use metadata::decoder;
2121
use metadata::loader;
2222
use metadata::loader::CratePaths;
2323

24-
use std::path::{Path, PathBuf};
24+
use std::path::PathBuf;
2525
use std::rc::Rc;
26+
use std::fs;
27+
2628
use syntax::ast;
2729
use syntax::abi;
2830
use syntax::attr;
@@ -32,7 +34,6 @@ use syntax::parse;
3234
use syntax::parse::token::InternedString;
3335
use syntax::parse::token;
3436
use syntax::visit;
35-
use util::fs;
3637
use log;
3738

3839
pub struct CrateReader<'a> {
@@ -322,7 +323,7 @@ impl<'a> CrateReader<'a> {
322323
let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
323324
if let Some(locs) = self.sess.opts.externs.get(name) {
324325
let found = locs.iter().any(|l| {
325-
let l = fs::realpath(&Path::new(&l[..])).ok();
326+
let l = fs::canonicalize(l).ok();
326327
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
327328
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
328329
});

src/librustc/metadata/filesearch.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use std::fs;
1818
use std::io::prelude::*;
1919
use std::path::{Path, PathBuf};
2020

21-
use util::fs as myfs;
2221
use session::search_paths::{SearchPaths, PathKind};
2322

2423
#[derive(Copy, Clone)]
@@ -191,7 +190,7 @@ pub fn get_or_default_sysroot() -> PathBuf {
191190
// Follow symlinks. If the resolved path is relative, make it absolute.
192191
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
193192
path.and_then(|path| {
194-
match myfs::realpath(&path) {
193+
match fs::canonicalize(&path) {
195194
Ok(canon) => Some(canon),
196195
Err(e) => panic!("failed to get realpath: {}", e),
197196
}

src/librustc/metadata/loader.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,12 @@ use metadata::encoder;
225225
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
226226
use syntax::codemap::Span;
227227
use syntax::diagnostic::SpanHandler;
228-
use util::fs;
229228
use util::common;
230229
use rustc_back::target::Target;
231230

232231
use std::cmp;
233232
use std::collections::HashMap;
233+
use std::fs;
234234
use std::io::prelude::*;
235235
use std::io;
236236
use std::path::{Path, PathBuf};
@@ -430,9 +430,9 @@ impl<'a> Context<'a> {
430430
.or_insert_with(|| (HashMap::new(), HashMap::new()));
431431
let (ref mut rlibs, ref mut dylibs) = *slot;
432432
if rlib {
433-
rlibs.insert(fs::realpath(path).unwrap(), kind);
433+
rlibs.insert(fs::canonicalize(path).unwrap(), kind);
434434
} else {
435-
dylibs.insert(fs::realpath(path).unwrap(), kind);
435+
dylibs.insert(fs::canonicalize(path).unwrap(), kind);
436436
}
437437

438438
FileMatches
@@ -660,10 +660,10 @@ impl<'a> Context<'a> {
660660
// there's at most one rlib and at most one dylib.
661661
for loc in locs {
662662
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
663-
rlibs.insert(fs::realpath(&loc).unwrap(),
663+
rlibs.insert(fs::canonicalize(&loc).unwrap(),
664664
PathKind::ExternFlag);
665665
} else {
666-
dylibs.insert(fs::realpath(&loc).unwrap(),
666+
dylibs.insert(fs::canonicalize(&loc).unwrap(),
667667
PathKind::ExternFlag);
668668
}
669669
}

src/librustc_back/fs.rs

-91
This file was deleted.

src/librustc_back/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#![feature(path_ext)]
4242
#![feature(step_by)]
4343
#![feature(libc)]
44+
#![feature(fs_canonicalize)]
4445
#![cfg_attr(test, feature(test, rand))]
4546

4647
extern crate syntax;
@@ -53,7 +54,6 @@ pub mod abi;
5354
pub mod archive;
5455
pub mod tempdir;
5556
pub mod arm;
56-
pub mod fs;
5757
pub mod mips;
5858
pub mod mipsel;
5959
pub mod rpath;

src/librustc_back/rpath.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
use std::collections::HashSet;
1212
use std::env;
13-
use std::io;
1413
use std::path::{Path, PathBuf};
14+
use std::fs;
1515
use syntax::ast;
1616

1717
pub struct RPathConfig<'a> {
@@ -20,7 +20,6 @@ pub struct RPathConfig<'a> {
2020
pub is_like_osx: bool,
2121
pub has_rpath: bool,
2222
pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
23-
pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>,
2423
}
2524

2625
pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
@@ -95,11 +94,11 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
9594
};
9695

9796
let cwd = env::current_dir().unwrap();
98-
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
97+
let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or(cwd.join(lib));
9998
lib.pop();
10099
let mut output = cwd.join(&config.out_filename);
101100
output.pop();
102-
let output = (config.realpath)(&output).unwrap();
101+
let output = fs::canonicalize(&output).unwrap_or(output);
103102
let relative = path_relative_from(&lib, &output)
104103
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
105104
// FIXME (#9639): This needs to handle non-utf8 paths
@@ -231,7 +230,6 @@ mod tests {
231230
is_like_osx: true,
232231
out_filename: PathBuf::from("bin/rustc"),
233232
get_install_prefix_lib_path: &mut || panic!(),
234-
realpath: &mut |p| Ok(p.to_path_buf()),
235233
};
236234
let res = get_rpath_relative_to_output(config,
237235
Path::new("lib/libstd.so"));
@@ -243,7 +241,6 @@ mod tests {
243241
get_install_prefix_lib_path: &mut || panic!(),
244242
has_rpath: true,
245243
is_like_osx: false,
246-
realpath: &mut |p| Ok(p.to_path_buf()),
247244
};
248245
let res = get_rpath_relative_to_output(config,
249246
Path::new("lib/libstd.so"));

src/librustc_trans/back/link.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use std::ffi::OsString;
3232
use std::fs::{self, PathExt};
3333
use std::io::{self, Read, Write};
3434
use std::mem;
35-
use std::path::{Path, PathBuf};
35+
use std::path::{self, Path, PathBuf};
3636
use std::process::Command;
3737
use std::str;
3838
use flate;
@@ -872,7 +872,7 @@ fn link_args(cmd: &mut Command,
872872
// target descriptor
873873
let t = &sess.target.target;
874874

875-
cmd.arg("-L").arg(&lib_path);
875+
cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(&lib_path));
876876

877877
cmd.arg("-o").arg(out_filename).arg(obj_filename);
878878

@@ -924,8 +924,9 @@ fn link_args(cmd: &mut Command,
924924
// stripped away as much as it could. This has not been seen to impact
925925
// link times negatively.
926926
//
927-
// -dead_strip can't be part of the pre_link_args because it's also used for partial
928-
// linking when using multiple codegen units (-r). So we insert it here.
927+
// -dead_strip can't be part of the pre_link_args because it's also used
928+
// for partial linking when using multiple codegen units (-r). So we
929+
// insert it here.
929930
cmd.arg("-Wl,-dead_strip");
930931
}
931932

@@ -1051,7 +1052,6 @@ fn link_args(cmd: &mut Command,
10511052
has_rpath: sess.target.target.options.has_rpath,
10521053
is_like_osx: sess.target.target.options.is_like_osx,
10531054
get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
1054-
realpath: &mut ::util::fs::realpath
10551055
};
10561056
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
10571057
}
@@ -1266,7 +1266,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
12661266
}
12671267
});
12681268
} else {
1269-
cmd.arg(cratepath);
1269+
cmd.arg(&fix_windows_verbatim_for_gcc(cratepath));
12701270
}
12711271
}
12721272

@@ -1279,7 +1279,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
12791279
// Just need to tell the linker about where the library lives and
12801280
// what its name is
12811281
if let Some(dir) = cratepath.parent() {
1282-
cmd.arg("-L").arg(dir);
1282+
cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(dir));
12831283
}
12841284
let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
12851285
cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
@@ -1333,3 +1333,29 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
13331333
}
13341334
}
13351335
}
1336+
1337+
// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
1338+
// (a verbatim path). This form of path is generally pretty rare, but the
1339+
// implementation of `fs::canonicalize` currently generates paths of this form,
1340+
// meaning that we're going to be passing quite a few of these down to gcc.
1341+
//
1342+
// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
1343+
// will probably lose information in some cases, but there's not a whole lot
1344+
// more we can do with a buggy gcc...
1345+
fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
1346+
if !cfg!(windows) {
1347+
return p.to_path_buf()
1348+
}
1349+
let mut components = p.components();
1350+
let prefix = match components.next() {
1351+
Some(path::Component::Prefix(p)) => p,
1352+
_ => return p.to_path_buf(),
1353+
};
1354+
let disk = match prefix.kind() {
1355+
path::Prefix::VerbatimDisk(disk) => disk,
1356+
_ => return p.to_path_buf(),
1357+
};
1358+
let mut base = OsString::from(format!("{}:", disk as char));
1359+
base.push(components.as_path());
1360+
PathBuf::from(base)
1361+
}

0 commit comments

Comments
 (0)