Skip to content

Commit 216ecd6

Browse files
committed
coverage-tool: fix config wiring and remove private field access
Forward all args to parse_config instead of building a stub config. Extract rustc_path and sysroot from CLI args directly so we don't need to access private Config fields. Also add coverage-tool to the workspace Cargo.toml. Note: requires rust-lang#154997 to merge before Config and related types are publicly accessible from compiletest.
1 parent 534e6af commit 216ecd6

2 files changed

Lines changed: 56 additions & 36 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ members = [
1616
"src/tools/collect-license-metadata",
1717
"src/tools/compiletest",
1818
"src/tools/coverage-dump",
19+
"src/tools/coverage-tool",
1920
"src/tools/features-status-dump",
2021
"src/tools/generate-copyright",
2122
"src/tools/generate-windows-sys",

src/tools/coverage-tool/src/main.rs

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,38 @@
22
// instrumented stage1 rustc and merging the resulting profraw files eagerly.
33
//
44
// Usage:
5-
// coverage-tool --config <compiletest-args> [--suite tests/ui/generics] [--out coverage/]
5+
// coverage-tool --out coverage/ [compiletest args...]
6+
//
7+
// All flags except --out are forwarded to compiletest's config parser,
8+
// so this tool is intended to be invoked by bootstrap the same way
9+
// compiletest is, with --out added.
610

711
use std::path::PathBuf;
812
use std::process::Command;
913
use std::sync::Arc;
1014
use std::{env, fs};
1115

1216
use compiletest::{collect_and_make_tests, parse_config};
13-
use compiletest::common::Config;
1417

1518
fn main() {
1619
let args: Vec<String> = env::args().collect();
1720

18-
// Minimal CLI: --suite <dir> --out <dir>
19-
// Everything else is passed through to compiletest's config parser.
20-
let suite = arg_value(&args, "--suite")
21-
.unwrap_or_else(|| "tests/ui".to_string());
21+
// Extract tool-specific flags; everything else goes to parse_config.
2222
let out_dir = arg_value(&args, "--out")
2323
.unwrap_or_else(|| "coverage".to_string());
2424

25+
// Read rustc-path and sysroot-base from args so we can invoke rustc
26+
// directly without touching private Config fields.
27+
let rustc_path = arg_value(&args, "--rustc-path")
28+
.unwrap_or_else(find_stage1_rustc);
29+
let sysroot = arg_value(&args, "--sysroot-base")
30+
.unwrap_or_else(find_stage1_sysroot);
31+
2532
fs::create_dir_all(&out_dir).expect("failed to create output dir");
2633

27-
// Build a minimal compiletest Config pointing at the test suite.
28-
// In practice this would be constructed from bootstrap's config,
29-
// but for now we parse the same flags compiletest accepts.
30-
let config = build_config(&suite);
34+
// Strip --out <val> from args and pass the rest to parse_config.
35+
let config_args = strip_flag(args, "--out");
36+
let config = parse_config(config_args);
3137
let config = Arc::new(config);
3238

3339
// Use compiletest to collect the full test list with all directives resolved.
@@ -53,17 +59,15 @@ fn main() {
5359

5460
// Compile the test with LLVM_PROFILE_FILE set so the instrumented
5561
// rustc emits a profraw file.
56-
let _result = Command::new(config.rustc_path.as_str())
62+
let _result = Command::new(&rustc_path)
5763
.arg("--sysroot")
58-
.arg(config.sysroot_base.as_str())
64+
.arg(&sysroot)
5965
.arg(test_file)
60-
.arg("--edition")
61-
.arg(test.revision.as_deref().unwrap_or("2015"))
62-
.args(&["-o", "/dev/null", "--crate-type", "bin"])
66+
.args(&["-o", "/dev/null"])
6367
.env("LLVM_PROFILE_FILE", &profile_file)
6468
.output();
6569

66-
// Collect any profraw files written
70+
// Collect any profraw files written.
6771
let profraws: Vec<PathBuf> = fs::read_dir(&tmpdir)
6872
.unwrap()
6973
.filter_map(|e| e.ok())
@@ -77,7 +81,7 @@ fn main() {
7781
continue;
7882
}
7983

80-
// Eager merge into running profdata, then delete profraws
84+
// Eager merge into running profdata, then delete profraws.
8185
merge_profraws(&profraws, &profdata_path);
8286
for f in &profraws {
8387
let _ = fs::remove_file(f);
@@ -105,7 +109,6 @@ fn merge_profraws(profraws: &[PathBuf], profdata: &PathBuf) {
105109
}
106110

107111
fn find_llvm_profdata() -> String {
108-
// Look in the same place bootstrap puts it
109112
glob::glob("build/*/ci-llvm/bin/llvm-profdata")
110113
.unwrap()
111114
.filter_map(|p| p.ok())
@@ -114,6 +117,24 @@ fn find_llvm_profdata() -> String {
114117
.unwrap_or_else(|| "llvm-profdata".to_string())
115118
}
116119

120+
fn find_stage1_rustc() -> String {
121+
glob::glob("build/*/stage1/bin/rustc")
122+
.unwrap()
123+
.filter_map(|p| p.ok())
124+
.next()
125+
.map(|p| p.display().to_string())
126+
.unwrap_or_else(|| "rustc".to_string())
127+
}
128+
129+
fn find_stage1_sysroot() -> String {
130+
glob::glob("build/*/stage1")
131+
.unwrap()
132+
.filter_map(|p| p.ok())
133+
.next()
134+
.map(|p| p.display().to_string())
135+
.unwrap_or_else(|| "build/host/stage1".to_string())
136+
}
137+
117138
fn tempdir() -> PathBuf {
118139
let dir = std::env::temp_dir().join("cov_profraws");
119140
fs::create_dir_all(&dir).unwrap();
@@ -126,22 +147,20 @@ fn arg_value(args: &[String], flag: &str) -> Option<String> {
126147
.map(|w| w[1].clone())
127148
}
128149

129-
fn build_config(suite: &str) -> Config {
130-
// Construct a minimal Config from environment/args.
131-
// This is a stub — in practice bootstrap would pass the full config.
132-
parse_config(vec![
133-
"coverage-tool".to_string(),
134-
"--mode".to_string(), "ui".to_string(),
135-
"--suite-path".to_string(), suite.to_string(),
136-
"--rustc-path".to_string(), find_stage1_rustc(),
137-
])
138-
}
139-
140-
fn find_stage1_rustc() -> String {
141-
glob::glob("build/*/stage1/bin/rustc")
142-
.unwrap()
143-
.filter_map(|p| p.ok())
144-
.next()
145-
.map(|p| p.display().to_string())
146-
.unwrap_or_else(|| "rustc".to_string())
150+
/// Remove --flag <value> from an args list and return the rest.
151+
fn strip_flag(args: Vec<String>, flag: &str) -> Vec<String> {
152+
let mut out = Vec::with_capacity(args.len());
153+
let mut skip = false;
154+
for arg in args {
155+
if skip {
156+
skip = false;
157+
continue;
158+
}
159+
if arg == flag {
160+
skip = true;
161+
continue;
162+
}
163+
out.push(arg);
164+
}
165+
out
147166
}

0 commit comments

Comments
 (0)