Skip to content

Commit a3932ea

Browse files
committed
add unstable -Zroot-path flag to configure the path from which rustc should be invoked
1 parent 06e0ef4 commit a3932ea

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

src/cargo/core/features.rs

+11
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
use std::collections::BTreeSet;
122122
use std::env;
123123
use std::fmt::{self, Write};
124+
use std::path::PathBuf;
124125
use std::str::FromStr;
125126

126127
use anyhow::{bail, Error};
@@ -783,6 +784,7 @@ unstable_cli_options!(
783784
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
784785
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
785786
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
787+
root_path: Option<PathBuf> = ("Invoke rustc from the given root rather than the workspace root; affects diagnostics"),
786788
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
787789
rustdoc_scrape_examples: bool = ("Allows Rustdoc to scrape code examples from reverse-dependencies"),
788790
script: bool = ("Enable support for single-file, `.rs` packages"),
@@ -1287,6 +1289,15 @@ impl CliUnstable {
12871289
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
12881290
"trim-paths" => self.trim_paths = parse_empty(k, v)?,
12891291
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
1292+
"root-path" => self.root_path = v.map(|v| {
1293+
// Make the path absolute, if we can.
1294+
let v = PathBuf::from(v);
1295+
if v.is_absolute() {
1296+
v
1297+
} else {
1298+
v.canonicalize().unwrap_or(v)
1299+
}
1300+
}),
12901301
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
12911302
"rustdoc-scrape-examples" => self.rustdoc_scrape_examples = parse_empty(k, v)?,
12921303
"separate-nightlies" => self.separate_nightlies = parse_empty(k, v)?,

src/cargo/util/workspace.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,22 @@ pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions) -> Ca
109109
/// The first returned value here is the argument to pass to rustc, and the
110110
/// second is the cwd that rustc should operate in.
111111
pub fn path_args(ws: &Workspace<'_>, unit: &Unit) -> (PathBuf, PathBuf) {
112-
let ws_root = ws.root();
113112
let src = match unit.target.src_path() {
114113
TargetSourcePath::Path(path) => path.to_path_buf(),
115114
TargetSourcePath::Metabuild => unit.pkg.manifest().metabuild_path(ws.target_dir()),
116115
};
117116
assert!(src.is_absolute());
118117
if unit.pkg.package_id().source_id().is_path() {
119-
if let Ok(path) = src.strip_prefix(ws_root) {
120-
return (path.to_path_buf(), ws_root.to_path_buf());
118+
// Determine which path we make this relative to: usually it's the workspace root,
119+
// but this can be overwritten with a `-Z` flag.
120+
let root = ws
121+
.gctx()
122+
.cli_unstable()
123+
.root_path
124+
.as_deref()
125+
.unwrap_or(ws.root());
126+
if let Ok(path) = src.strip_prefix(root) {
127+
return (path.to_path_buf(), root.to_path_buf());
121128
}
122129
}
123130
(src, unit.pkg.root().to_path_buf())

tests/testsuite/directory.rs

+38
Original file line numberDiff line numberDiff line change
@@ -784,3 +784,41 @@ Caused by:
784784
.with_status(101)
785785
.run();
786786
}
787+
788+
#[cargo_test]
789+
fn custom_root_path() {
790+
let p = ProjectBuilder::new(paths::root())
791+
.no_manifest() // we are placing it in a different dir
792+
.file(
793+
"ws_root/Cargo.toml",
794+
r#"
795+
[package]
796+
name = "foo"
797+
version = "0.1.0"
798+
edition = "2015"
799+
authors = []
800+
"#,
801+
)
802+
.file("ws_root/src/lib.rs", "invalid;")
803+
.build();
804+
805+
// Crucially, the rustc error message below says `ws_root/...`, i.e.
806+
// it is relative to our fake home, not to the workspace root.
807+
p.cargo("check")
808+
.arg("-Zroot-path=.")
809+
.arg("--manifest-path=ws_root/Cargo.toml")
810+
.masquerade_as_nightly_cargo(&["-Zroot-path"])
811+
.with_status(101)
812+
.with_stderr_data(str![[r#"
813+
[CHECKING] foo v0.1.0 ([ROOT]/ws_root)
814+
[ERROR] expected one of `!` or `::`, found `;`
815+
--> ws_root/src/lib.rs:1:8
816+
|
817+
1 | invalid;
818+
| ^ expected one of `!` or `::`
819+
820+
[ERROR] could not compile `foo` (lib) due to 1 previous error
821+
822+
"#]])
823+
.run();
824+
}

0 commit comments

Comments
 (0)