Skip to content

Commit 5e667d3

Browse files
authored
Use absolute_path instead of fs::canonicalize (#4131)
1 parent ef3def5 commit 5e667d3

File tree

13 files changed

+89
-21
lines changed

13 files changed

+89
-21
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustfmt-core/rustfmt-bin/src/bin/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use structopt::StructOpt;
1414
use thiserror::Error;
1515

1616
use rustfmt_lib::{
17-
load_config, CliOptions, Config, Edition, EmitMode, FileLines, FileName,
17+
absolute_path, load_config, CliOptions, Config, Edition, EmitMode, FileLines, FileName,
1818
FormatReportFormatterBuilder, Input, Session, Verbosity,
1919
};
2020

@@ -252,7 +252,7 @@ enum OptError {
252252
impl Opt {
253253
fn canonicalize(&mut self) {
254254
for f in &mut self.files {
255-
if let Ok(canonical_path) = f.canonicalize() {
255+
if let Ok(canonical_path) = absolute_path(&f) {
256256
*f = canonical_path;
257257
}
258258
}

rustfmt-core/rustfmt-bin/src/cargo-fmt/main.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::path::{Path, PathBuf};
1313
use std::process::Command;
1414
use std::str;
1515

16+
use rustfmt_lib::absolute_path;
1617
use structopt::StructOpt;
1718

1819
#[derive(StructOpt, Debug)]
@@ -288,7 +289,7 @@ impl Target {
288289
nested_int_test_files: Option<Vec<PathBuf>>,
289290
) -> Self {
290291
let path = PathBuf::from(&target.src_path);
291-
let canonicalized = fs::canonicalize(&path).unwrap_or(path);
292+
let canonicalized = absolute_path(&path).unwrap_or(path);
292293
let test_files = nested_int_test_files.unwrap_or_else(Vec::new);
293294

294295
Self {
@@ -388,14 +389,14 @@ fn get_targets_root_only(
388389
include_nested_test_files: bool,
389390
) -> Result<(), io::Error> {
390391
let metadata = get_cargo_metadata(manifest_path, false)?;
391-
let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?;
392+
let workspace_root_path = absolute_path(PathBuf::from(&metadata.workspace_root))?;
392393
let (in_workspace_root, current_dir_manifest) = if let Some(target_manifest) = manifest_path {
393394
(
394395
workspace_root_path == target_manifest,
395-
target_manifest.canonicalize()?,
396+
absolute_path(target_manifest)?,
396397
)
397398
} else {
398-
let current_dir = env::current_dir()?.canonicalize()?;
399+
let current_dir = absolute_path(env::current_dir()?)?;
399400
(
400401
workspace_root_path == current_dir,
401402
current_dir.join("Cargo.toml"),
@@ -413,9 +414,7 @@ fn get_targets_root_only(
413414
.into_iter()
414415
.filter(|p| {
415416
in_workspace_root
416-
|| PathBuf::from(&p.manifest_path)
417-
.canonicalize()
418-
.unwrap_or_default()
417+
|| absolute_path(PathBuf::from(&p.manifest_path)).unwrap_or_default()
419418
== current_dir_manifest
420419
})
421420
.map(|p| p.targets)
@@ -1052,7 +1051,7 @@ mod cargo_fmt_tests {
10521051
edition: &str,
10531052
) -> Target {
10541053
let path = PathBuf::from(src_path);
1055-
let canonicalized = fs::canonicalize(&path).unwrap_or(path);
1054+
let canonicalized = absolute_path(&path).unwrap_or(path);
10561055
Target {
10571056
path: canonicalized,
10581057
kind: String::from(kind),

rustfmt-core/rustfmt-lib/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ serde = { version = "1.0", features = ["derive"], optional = true }
5050
serde_json = { version = "1.0", optional = true }
5151
toml = { version = "0.5", optional = true }
5252

53+
[target.'cfg(windows)'.dependencies]
54+
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi"] }
55+
5356
[dev-dependencies]
5457
env_logger = "0.7"
5558

rustfmt-core/rustfmt-lib/src/config.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ use std::{env, fs};
88
use regex::Regex;
99
use thiserror::Error;
1010

11-
use crate::config::config_type::ConfigType;
1211
pub use crate::config::file_lines::{FileLines, FileName, Range};
1312
pub use crate::config::lists::*;
1413
pub use crate::config::options::*;
1514

15+
use crate::config::config_type::ConfigType;
16+
use crate::utils::absolute_path;
17+
1618
#[macro_use]
1719
pub mod config_type;
1820
#[macro_use]
@@ -236,7 +238,7 @@ impl Config {
236238
dir.to_path_buf()
237239
};
238240

239-
current = fs::canonicalize(current)?;
241+
current = absolute_path(current)?;
240242

241243
loop {
242244
match get_toml_path(&current) {

rustfmt-core/rustfmt-lib/src/config/file_lines.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use thiserror::Error;
1212

1313
use rustc_span::{self, SourceFile};
1414

15+
use crate::utils::absolute_path;
16+
1517
/// A range of lines in a file, inclusive of both ends.
1618
pub struct LineRange {
1719
pub file: Rc<SourceFile>,
@@ -295,7 +297,7 @@ impl<'a> iter::Iterator for Files<'a> {
295297

296298
fn canonicalize_path_string(file: &FileName) -> std::io::Result<FileName> {
297299
match *file {
298-
FileName::Real(ref path) => path.canonicalize().map(FileName::Real),
300+
FileName::Real(ref path) => absolute_path(path).map(FileName::Real),
299301
_ => Ok(file.clone()),
300302
}
301303
}

rustfmt-core/rustfmt-lib/src/lib.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ use std::rc::Rc;
1818
use rustc_ast::ast;
1919
use thiserror::Error;
2020

21-
use crate::comment::LineClasses;
22-
use crate::formatting::{FormatErrorMap, FormattingError, ReportedErrors, SourceFile};
23-
use crate::shape::Indent;
24-
use crate::syntux::parser::DirectoryOwnership;
25-
use crate::utils::indent_next_line;
26-
2721
pub use crate::config::{
2822
load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle,
2923
Range, Verbosity,
3024
};
31-
25+
pub use crate::emitter::rustfmt_diff::{ModifiedChunk, ModifiedLines};
3226
pub use crate::format_report_formatter::{FormatReportFormatter, FormatReportFormatterBuilder};
27+
pub use crate::utils::absolute_path;
3328

34-
pub use crate::emitter::rustfmt_diff::{ModifiedChunk, ModifiedLines};
29+
use crate::comment::LineClasses;
3530
use crate::emitter::Emitter;
31+
use crate::formatting::{FormatErrorMap, FormattingError, ReportedErrors, SourceFile};
32+
use crate::shape::Indent;
33+
use crate::syntux::parser::DirectoryOwnership;
34+
use crate::utils::indent_next_line;
3635

3736
#[macro_use]
3837
mod utils;

rustfmt-core/rustfmt-lib/src/test/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const SKIP_FILE_WHITE_LIST: &[&str] = &[
4040
// these files directly
4141
"configs/recursive/disabled/foo.rs",
4242
"configs/recursive/enabled/foo.rs",
43+
"mods-relative-path/mod_b.rs",
4344
];
4445

4546
fn init_log() {

rustfmt-core/rustfmt-lib/src/utils.rs

+43
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use std::borrow::Cow;
2+
use std::io;
3+
use std::path;
24

35
use rustc_ast::ast::{
46
self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem, NodeId, Path, Visibility,
@@ -661,6 +663,47 @@ pub(crate) fn unicode_str_width(s: &str) -> usize {
661663
s.width()
662664
}
663665

666+
#[cfg(windows)]
667+
pub fn absolute_path<P: AsRef<path::Path>>(p: P) -> io::Result<path::PathBuf> {
668+
use std::ffi::OsString;
669+
use std::iter::once;
670+
use std::os::windows::ffi::{OsStrExt, OsStringExt};
671+
use std::ptr::null_mut;
672+
use winapi::um::errhandlingapi::GetLastError;
673+
use winapi::um::fileapi::GetFullPathNameW;
674+
675+
// FIXME: This `MAX_PATH` may be valid only from Windows 10, version 1607.
676+
// https://docs.microsoft.com/ja-jp/windows/desktop/FileIO/naming-a-file#paths
677+
const MAX_PATH: usize = 32767;
678+
let wide: Vec<u16> = p
679+
.as_ref()
680+
.as_os_str()
681+
.encode_wide()
682+
.chain(once(0))
683+
.collect();
684+
let mut buffer: Vec<u16> = vec![0; MAX_PATH];
685+
unsafe {
686+
let result = GetFullPathNameW(
687+
wide.as_ptr(),
688+
MAX_PATH as u32,
689+
buffer.as_mut_ptr(),
690+
null_mut(),
691+
);
692+
if result == 0 {
693+
Err(io::Error::from_raw_os_error(GetLastError() as i32))
694+
} else {
695+
Ok(path::PathBuf::from(OsString::from_wide(
696+
&buffer[..result as usize],
697+
)))
698+
}
699+
}
700+
}
701+
702+
#[cfg(not(windows))]
703+
pub fn absolute_path<P: AsRef<path::Path>>(p: P) -> io::Result<path::PathBuf> {
704+
std::fs::canonicalize(p)
705+
}
706+
664707
#[cfg(test)]
665708
mod test {
666709
use super::*;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// rustfmt-recursive: true
2+
3+
#[path = "../mods-relative-paths/mod_b.rs"]
4+
mod b;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn
2+
3+
4+
5+
foo() {
6+
println!("toto")
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// rustfmt-recursive: true
2+
3+
#[path = "../mods-relative-paths/mod_b.rs"]
4+
mod b;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn foo() {
2+
println!("toto")
3+
}

0 commit comments

Comments
 (0)