Auto merge of #51278 - EPashkin:fix_mod_with_multilevel_paths_on_windows, r=nikomatsakis
Fix processing mod with multi-level path on Windows
Fix error in [rustfmt](https://github.com/rust-lang-nursery/rustfmt/issues/1754) because libsyntax can not handle `mod` with multilevel path on Windows.
Alternative is do almost same in https://github.com/rust-lang/rust/blob/master/src/libstd/sys/windows/fs.rs#L717 to allow work on paths with different separators, Ex. "\\\\?\\c:\\windows/temp"
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 530094e..1735951 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6128,7 +6128,19 @@
}
pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
- attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&d.as_str()))
+ if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
+ let s = s.as_str();
+
+ // On windows, the base path might have the form
+ // `\\?\foo\bar` in which case it does not tolerate
+ // mixed `/` and `\` separators, so canonicalize
+ // `/` to `\`.
+ #[cfg(windows)]
+ let s = s.replace("/", "\\");
+ Some(dir_path.join(s))
+ } else {
+ None
+ }
}
/// Returns either a path to a module, or .
diff --git a/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs b/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs
new file mode 100644
index 0000000..3bf5065
--- /dev/null
+++ b/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs
@@ -0,0 +1,38 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Testing that a libsyntax can parse modules with canonicalized base path
+// ignore-cross-compile
+
+#![feature(rustc_private)]
+
+extern crate syntax;
+
+use std::path::Path;
+use syntax::codemap::FilePathMapping;
+use syntax::parse::{self, ParseSess};
+
+#[path = "mod_dir_simple/test.rs"]
+mod gravy;
+
+pub fn main() {
+ syntax::with_globals(|| parse());
+
+ assert_eq!(gravy::foo(), 10);
+}
+
+fn parse() {
+ let parse_session = ParseSess::new(FilePathMapping::empty());
+
+ let path = Path::new(file!());
+ let path = path.canonicalize().unwrap();
+ let mut parser = parse::new_parser_from_file(&parse_session, &path);
+ let _ = parser.parse_crate_mod();
+}
diff --git a/src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir b/src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/test/run-pass-fulldeps/mod_dir_simple/compiletest-ignore-dir
diff --git a/src/test/run-pass-fulldeps/mod_dir_simple/test.rs b/src/test/run-pass-fulldeps/mod_dir_simple/test.rs
new file mode 100644
index 0000000..58c1bee
--- /dev/null
+++ b/src/test/run-pass-fulldeps/mod_dir_simple/test.rs
@@ -0,0 +1,11 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() -> isize { 10 }