From a8077cc04836389b750732839de540c06d0cce38 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Wed, 6 Feb 2019 21:31:15 +0900 Subject: [PATCH 1/5] Use absolute_path instead of fs::canonicalize --- Cargo.lock | 1 + Cargo.toml | 3 +++ src/bin/main.rs | 10 ++++----- src/cargo-fmt/main.rs | 12 ++++++----- src/config/config_type.rs | 2 +- src/config/file_lines.rs | 13 ++++++------ src/lib.rs | 4 ++++ src/utils.rs | 44 ++++++++++++++++++++++++++++++++++++++- 8 files changed, 71 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc52c406226..6ca1190293f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,6 +644,7 @@ dependencies = [ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b1e83e93b09..18d277cf431 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,9 @@ unicode-width = "0.1.5" unicode_categories = "0.1.1" dirs = "1.0.4" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["errhandlingapi", "fileapi"] } + # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` # for more information. diff --git a/src/bin/main.rs b/src/bin/main.rs index 53e95e8b5b6..2b612e158fd 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -25,8 +25,8 @@ use failure::err_msg; use getopts::{Matches, Options}; use crate::rustfmt::{ - load_config, CliOptions, Color, Config, Edition, EmitMode, ErrorKind, FileLines, FileName, - Input, Session, Verbosity, + absolute_path, load_config, CliOptions, Color, Config, Edition, EmitMode, ErrorKind, FileLines, + FileName, Input, Session, Verbosity, }; fn main() { @@ -414,9 +414,9 @@ fn determine_operation(matches: &Matches) -> Result { .iter() .map(|s| { let p = PathBuf::from(s); - // we will do comparison later, so here tries to canonicalize first - // to get the expected behavior. - p.canonicalize().unwrap_or(p) + // we will do comparison later, so here tries to get the absolute + // path first to get the expected behavior. + absolute_path(&p).unwrap_or(p) }) .collect(); diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 83a93240ff2..776450d0720 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -15,11 +15,11 @@ extern crate cargo_metadata; extern crate getopts; +extern crate rustfmt_nightly as rustfmt; extern crate serde_json as json; use std::collections::{HashMap, HashSet}; use std::env; -use std::fs; use std::hash::{Hash, Hasher}; use std::io::{self, Write}; use std::iter::FromIterator; @@ -29,6 +29,8 @@ use std::str; use getopts::{Matches, Options}; +use crate::rustfmt::absolute_path; + fn main() { let exit_status = execute(); std::io::stdout().flush().unwrap(); @@ -170,10 +172,10 @@ pub struct Target { impl Target { pub fn from_target(target: &cargo_metadata::Target) -> Self { let path = PathBuf::from(&target.src_path); - let canonicalized = fs::canonicalize(&path).unwrap_or(path); + let path = absolute_path(&path).unwrap_or(path); Target { - path: canonicalized, + path, kind: target.kind[0].clone(), edition: target.edition.clone(), } @@ -236,9 +238,9 @@ fn get_targets(strategy: &CargoFmtStrategy) -> Result, io::Error fn get_targets_root_only(targets: &mut HashSet) -> Result<(), io::Error> { let metadata = get_cargo_metadata(None)?; - let current_dir = env::current_dir()?.canonicalize()?; + let current_dir = absolute_path(env::current_dir()?)?; let current_dir_manifest = current_dir.join("Cargo.toml"); - let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?; + let workspace_root_path = absolute_path(PathBuf::from(&metadata.workspace_root))?; let in_workspace_root = workspace_root_path == current_dir; for package in metadata.packages { diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 09c41f8bb1d..ddc9df70854 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -334,7 +334,7 @@ macro_rules! create_config { dir.to_path_buf() }; - current = fs::canonicalize(current)?; + current = crate::utils::absolute_path(current)?; loop { match get_toml_path(¤t) { diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 07df0e32d9c..8b3debfc69d 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -18,9 +18,10 @@ use std::{cmp, fmt, iter, str}; use serde::de::{Deserialize, Deserializer}; use serde::ser::{self, Serialize, Serializer}; use serde_json as json; - use syntax::source_map::{self, SourceFile}; +use crate::utils::absolute_path; + /// A range of lines in a file, inclusive of both ends. pub struct LineRange { pub file: Rc, @@ -233,7 +234,7 @@ impl FileLines { Some(ref map) => map, }; - match canonicalize_path_string(file_name).and_then(|file| map.get(&file)) { + match absolute_path_string(file_name).and_then(|file| map.get(&file)) { Some(ranges) => ranges.iter().any(f), None => false, } @@ -272,9 +273,9 @@ impl<'a> iter::Iterator for Files<'a> { } } -fn canonicalize_path_string(file: &FileName) -> Option { +fn absolute_path_string(file: &FileName) -> Option { match *file { - FileName::Real(ref path) => path.canonicalize().ok().map(FileName::Real), + FileName::Real(ref path) => absolute_path(path).ok().map(FileName::Real), _ => Some(file.clone()), } } @@ -304,8 +305,8 @@ pub struct JsonSpan { impl JsonSpan { fn into_tuple(self) -> Result<(FileName, Range), String> { let (lo, hi) = self.range; - let canonical = canonicalize_path_string(&self.file) - .ok_or_else(|| format!("Can't canonicalize {}", &self.file))?; + let canonical = absolute_path_string(&self.file) + .ok_or_else(|| format!("Can't get absolute path {}", &self.file))?; Ok((canonical, Range::new(lo, hi))) } } diff --git a/src/lib.rs b/src/lib.rs index 6fc3dc85945..a7f89b2b801 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,9 @@ extern crate unicode_categories; extern crate unicode_segmentation; extern crate unicode_width; +#[cfg(windows)] +extern crate winapi; + use std::cell::RefCell; use std::collections::HashMap; use std::fmt; @@ -55,6 +58,7 @@ pub use crate::config::{ load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle, Range, Verbosity, }; +pub use crate::utils::absolute_path; #[macro_use] mod utils; diff --git a/src/utils.rs b/src/utils.rs index 06f1ca2d8d8..ab05d0ac6de 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -9,9 +9,10 @@ // except according to those terms. use std::borrow::Cow; +use std::io; +use std::path; use bytecount; - use rustc_target::spec::abi; use syntax::ast::{ self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind, @@ -604,6 +605,47 @@ pub(crate) fn unicode_str_width(s: &str) -> usize { s.width() } +#[cfg(windows)] +pub fn absolute_path>(p: P) -> io::Result { + use std::ffi::OsString; + use std::iter::once; + use std::os::windows::ffi::{OsStrExt, OsStringExt}; + use std::ptr::null_mut; + use winapi::um::errhandlingapi::GetLastError; + use winapi::um::fileapi::GetFullPathNameW; + + // FIXME: This `MAX_PATH` may be valid only from Windows 10, version 1607. + // https://docs.microsoft.com/ja-jp/windows/desktop/FileIO/naming-a-file#paths + const MAX_PATH: usize = 32767; + let wide: Vec = p + .as_ref() + .as_os_str() + .encode_wide() + .chain(once(0)) + .collect(); + let mut buffer: Vec = vec![0; MAX_PATH]; + unsafe { + let result = GetFullPathNameW( + wide.as_ptr(), + MAX_PATH as u32, + buffer.as_mut_ptr(), + null_mut(), + ); + if result == 0 { + Err(std::io::Error::from_raw_os_error(GetLastError() as i32)) + } else { + Ok(path::PathBuf::from(OsString::from_wide( + &buffer[..result as usize], + ))) + } + } +} + +#[cfg(not(windows))] +pub fn absolute_path>(p: P) -> io::Result { + std::fs::canonicalize(p) +} + #[cfg(test)] mod test { use super::*; From 57119d38011b05bb36e7e5154f9871c4413beacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Campinas?= Date: Tue, 14 May 2019 10:42:43 +0200 Subject: [PATCH 2/5] fix import order --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 449132a8877..33bae11467f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -16,7 +16,7 @@ use getopts::{Matches, Options}; use crate::rustfmt::{ absolute_path, load_config, CliOptions, Color, Config, Edition, EmitMode, ErrorKind, FileLines, - FormatReportFormatterBuilder, FileName, Input, Session, Verbosity, + FileName, FormatReportFormatterBuilder, Input, Session, Verbosity, }; fn main() { From 13893465710bfef653661d0ffdb30c9a6607df94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Campinas?= Date: Mon, 27 May 2019 12:48:56 +0200 Subject: [PATCH 3/5] fix compilation on windows --- Cargo.lock | 2 +- src/lib.rs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edad278e6e1..e0156f3ed71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,7 +827,7 @@ dependencies = [ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/src/lib.rs b/src/lib.rs index baff6925c19..ffc5a92ffc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,9 +9,6 @@ extern crate lazy_static; #[macro_use] extern crate log; -#[cfg(windows)] -extern crate winapi; - use std::cell::RefCell; use std::collections::HashMap; use std::fmt; From 394597d135e106ba37e289db1373163e2ef387dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Campinas?= Date: Tue, 28 May 2019 00:36:33 +0200 Subject: [PATCH 4/5] add test for relative path to modules --- tests/source/mods-relative-paths/lib.rs | 2 ++ tests/source/mods-relative-paths/mod_b.rs | 7 +++++++ tests/target/mods-relative-paths/lib.rs | 2 ++ tests/target/mods-relative-paths/mod_b.rs | 3 +++ 4 files changed, 14 insertions(+) create mode 100644 tests/source/mods-relative-paths/lib.rs create mode 100644 tests/source/mods-relative-paths/mod_b.rs create mode 100644 tests/target/mods-relative-paths/lib.rs create mode 100644 tests/target/mods-relative-paths/mod_b.rs diff --git a/tests/source/mods-relative-paths/lib.rs b/tests/source/mods-relative-paths/lib.rs new file mode 100644 index 00000000000..c8648249177 --- /dev/null +++ b/tests/source/mods-relative-paths/lib.rs @@ -0,0 +1,2 @@ +#[path = "../mods-relative-paths/mod_b.rs"] +mod b; diff --git a/tests/source/mods-relative-paths/mod_b.rs b/tests/source/mods-relative-paths/mod_b.rs new file mode 100644 index 00000000000..85f9f3f0a4f --- /dev/null +++ b/tests/source/mods-relative-paths/mod_b.rs @@ -0,0 +1,7 @@ +fn + + + +foo() { + println!("toto") +} diff --git a/tests/target/mods-relative-paths/lib.rs b/tests/target/mods-relative-paths/lib.rs new file mode 100644 index 00000000000..c8648249177 --- /dev/null +++ b/tests/target/mods-relative-paths/lib.rs @@ -0,0 +1,2 @@ +#[path = "../mods-relative-paths/mod_b.rs"] +mod b; diff --git a/tests/target/mods-relative-paths/mod_b.rs b/tests/target/mods-relative-paths/mod_b.rs new file mode 100644 index 00000000000..3b0991e5071 --- /dev/null +++ b/tests/target/mods-relative-paths/mod_b.rs @@ -0,0 +1,3 @@ +fn foo() { + println!("toto") +} From 130fa514ff1a52f8cbb0ffbb486961fb69a01006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Campinas?= Date: Fri, 20 Sep 2019 11:16:28 +0200 Subject: [PATCH 5/5] update winapi from 0.3.7 to 0.3.8 --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ceff9f86032..729ad141e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -894,7 +894,7 @@ dependencies = [ "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]]