Skip to content

Commit edc97a0

Browse files
committed
Fix verbatim paths used with include!
When using `concat!` to join paths, the Unix path separator (`/`) is often used. This breaks on Windows if the base path is a verbatim path (i.e. starts with `\\?\`).
1 parent 83dcdb3 commit edc97a0

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

compiler/rustc_expand/src/base.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::default::Default;
22
use std::iter;
3+
use std::path::Component::Prefix;
34
use std::path::{Path, PathBuf};
45
use std::rc::Rc;
56

@@ -1293,7 +1294,12 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
12931294
base_path.push(path);
12941295
Ok(base_path)
12951296
} else {
1296-
Ok(path)
1297+
// This ensures that Windows verbatim paths are fixed if mixed path separators are used,
1298+
// which can happen when `concat!` is used to join paths.
1299+
match path.components().next() {
1300+
Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1301+
_ => Ok(path),
1302+
}
12971303
}
12981304
}
12991305

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
static TEST: &str = "Hello World!";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ only-windows other platforms do not have Windows verbatim paths
2+
use run_make_support::rustc;
3+
fn main() {
4+
// Canonicalizing the path ensures that it's verbatim (i.e. starts with `\\?\`)
5+
let mut path = std::fs::canonicalize(file!()).unwrap();
6+
path.pop();
7+
rustc().input("verbatim.rs").env("VERBATIM_DIR", path).run();
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Include a file by concating the verbatim path using `/` instead of `\`
2+
3+
include!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
4+
fn main() {
5+
assert_eq!(TEST, "Hello World!");
6+
7+
let s = include_str!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
8+
assert_eq!(s, "static TEST: &str = \"Hello World!\";\n");
9+
10+
let b = include_bytes!(concat!(env!("VERBATIM_DIR"), "/include/include.txt"));
11+
assert_eq!(b, b"static TEST: &str = \"Hello World!\";\n");
12+
}

0 commit comments

Comments
 (0)