Skip to content

Commit 32fd96c

Browse files
committed
Give dynamically generated instructions on how to replicate errors during the build progress
1 parent 18840b0 commit 32fd96c

File tree

5 files changed

+87
-16
lines changed

5 files changed

+87
-16
lines changed

src/bootstrap/builder.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::cell::{Cell, RefCell};
33
use std::collections::BTreeSet;
44
use std::env;
55
use std::ffi::OsStr;
6-
use std::fmt::Debug;
6+
use std::fmt::{self, Debug, Display};
77
use std::fs;
88
use std::hash::Hash;
99
use std::ops::Deref;
@@ -62,6 +62,17 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
6262
/// If true, then this rule should be skipped if --target was specified, but --host was not
6363
const ONLY_HOSTS: bool = false;
6464

65+
/// A user-visible name to display if this step fails.
66+
fn name(&self) -> &'static str {
67+
std::any::type_name::<Self>()
68+
}
69+
70+
/// The path that should be used on the command line to run this step.
71+
fn path(&self, builder: &Builder<'_>) -> PathBuf {
72+
let paths = Self::should_run(ShouldRun::new(builder)).paths;
73+
paths.iter().map(|pathset| pathset.path(builder)).next().expect("no paths for step")
74+
}
75+
6576
/// Primary function to execute this rule. Can call `builder.ensure()`
6677
/// with other steps to run those.
6778
fn run(self, builder: &Builder<'_>) -> Self::Output;
@@ -351,6 +362,26 @@ pub enum Kind {
351362
Run,
352363
}
353364

365+
impl Display for Kind {
366+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367+
use Kind::*;
368+
let s = match self {
369+
Build => "build",
370+
Check => "check",
371+
Clippy => "clippy",
372+
Fix => "fix",
373+
Format => "fmt",
374+
Test => "test",
375+
Bench => "bench",
376+
Dist => "dist",
377+
Doc => "doc",
378+
Install => "install",
379+
Run => "run",
380+
};
381+
f.write_str(s)
382+
}
383+
}
384+
354385
impl<'a> Builder<'a> {
355386
fn get_step_descriptions(kind: Kind) -> Vec<StepDescription> {
356387
macro_rules! describe {
@@ -610,6 +641,29 @@ impl<'a> Builder<'a> {
610641
StepDescription::run(v, self, paths);
611642
}
612643

644+
/// Print a command that will run the current step.
645+
///
646+
/// This serves two purposes:
647+
/// 1. Describe what step is currently being run.
648+
/// 2. Describe how to run only this step in case it fails.
649+
pub(crate) fn step_info(&self, step: &impl Step) {
650+
if self.config.dry_run {
651+
return;
652+
}
653+
print!(
654+
"{} {} --stage {}",
655+
// TODO: this is wrong, e.g. `check --stage 1` runs build commands first
656+
self.kind,
657+
step.path(self).display(),
658+
// FIXME: top_stage might be higher than the stage of the step
659+
self.top_stage,
660+
);
661+
for arg in self.config.cmd.test_args() {
662+
print!(" --test-args \"{}\"", arg);
663+
}
664+
println!();
665+
}
666+
613667
/// Obtain a compiler at a given stage and for a given host. Explicitly does
614668
/// not take `Compiler` since all `Compiler` instances are meant to be
615669
/// obtained through this function, since it ensures that they are valid
@@ -1563,6 +1617,7 @@ impl<'a> Builder<'a> {
15631617
let out = step.clone().run(self);
15641618
let dur = start.elapsed();
15651619
let deps = self.time_spent_on_dependencies.replace(parent + dur);
1620+
15661621
(out, dur - deps)
15671622
};
15681623

src/bootstrap/builder/tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ mod dist {
511511
target: host,
512512
mode: Mode::Std,
513513
test_kind: test::TestKind::Test,
514-
krate: INTERNER.intern_str("std"),
514+
krate_name: INTERNER.intern_str("std"),
515+
krate_path: "library/std".into(),
515516
},]
516517
);
517518
}

src/bootstrap/cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,15 @@ impl Cache {
271271

272272
#[cfg(test)]
273273
impl Cache {
274-
pub fn all<S: Ord + Copy + Step>(&mut self) -> Vec<(S, S::Output)> {
274+
pub fn all<S: Ord + Step>(&mut self) -> Vec<(S, S::Output)> {
275275
let cache = self.0.get_mut();
276276
let type_id = TypeId::of::<S>();
277277
let mut v = cache
278278
.remove(&type_id)
279279
.map(|b| b.downcast::<HashMap<S, S::Output>>().expect("correct type"))
280280
.map(|m| m.into_iter().collect::<Vec<_>>())
281281
.unwrap_or_default();
282-
v.sort_by_key(|&(a, _)| a);
282+
v.sort_by_key(|(a, _)| a.clone());
283283
v
284284
}
285285

src/bootstrap/compile.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ impl Step for Std {
107107
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
108108
std_cargo(builder, target, compiler.stage, &mut cargo);
109109

110-
builder.info(&format!(
111-
"Building stage{} std artifacts ({} -> {})",
112-
compiler.stage, &compiler.host, target
113-
));
110+
builder.step_info(&self);
111+
// builder.info(&format!(
112+
// "Building stage{} std artifacts ({} -> {})",
113+
// compiler.stage, &compiler.host, target
114+
// ));
114115
run_cargo(
115116
builder,
116117
cargo,

src/bootstrap/test.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,11 @@ impl Step for Compiletest {
12151215
run.never()
12161216
}
12171217

1218+
fn path(&self, _builder: &Builder<'_>) -> PathBuf {
1219+
// FIXME: it would be nice to suggest exactly the tests that fail, but that info isn't known without first running compiletest.
1220+
self.path.into()
1221+
}
1222+
12181223
/// Executes the `compiletest` tool to run a suite of tests.
12191224
///
12201225
/// Compiles all tests with `compiler` for `target` with the specified
@@ -1856,12 +1861,13 @@ impl Step for RustcGuide {
18561861
}
18571862
}
18581863

1859-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1864+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18601865
pub struct CrateLibrustc {
18611866
compiler: Compiler,
18621867
target: TargetSelection,
18631868
test_kind: TestKind,
1864-
krate: Interned<String>,
1869+
krate_name: Interned<String>,
1870+
krate_path: PathBuf,
18651871
}
18661872

18671873
impl Step for CrateLibrustc {
@@ -1885,7 +1891,8 @@ impl Step for CrateLibrustc {
18851891
compiler,
18861892
target: run.target,
18871893
test_kind,
1888-
krate: krate.name,
1894+
krate_name: krate.name,
1895+
krate_path: krate.local_path(builder.build),
18891896
});
18901897
}
18911898
}
@@ -1897,18 +1904,20 @@ impl Step for CrateLibrustc {
18971904
target: self.target,
18981905
mode: Mode::Rustc,
18991906
test_kind: self.test_kind,
1900-
krate: self.krate,
1907+
krate_name: self.krate_name,
1908+
krate_path: self.krate_path.clone(),
19011909
});
19021910
}
19031911
}
19041912

1905-
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1913+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19061914
pub struct Crate {
19071915
pub compiler: Compiler,
19081916
pub target: TargetSelection,
19091917
pub mode: Mode,
19101918
pub test_kind: TestKind,
1911-
pub krate: Interned<String>,
1919+
pub krate_name: Interned<String>,
1920+
pub krate_path: PathBuf,
19121921
}
19131922

19141923
impl Step for Crate {
@@ -1931,7 +1940,8 @@ impl Step for Crate {
19311940
target: run.target,
19321941
mode,
19331942
test_kind,
1934-
krate: krate.name,
1943+
krate_name: krate.name,
1944+
krate_path: krate.local_path(builder.build),
19351945
});
19361946
};
19371947

@@ -1942,6 +1952,10 @@ impl Step for Crate {
19421952
}
19431953
}
19441954

1955+
fn path(&self, _builder: &Builder<'_>) -> PathBuf {
1956+
self.krate_path.file_name().expect("top-level directory is not a crate").into()
1957+
}
1958+
19451959
/// Runs all unit tests plus documentation tests for a given crate defined
19461960
/// by a `Cargo.toml` (single manifest)
19471961
///
@@ -1955,7 +1969,7 @@ impl Step for Crate {
19551969
let target = self.target;
19561970
let mode = self.mode;
19571971
let test_kind = self.test_kind;
1958-
let krate = self.krate;
1972+
let krate = self.krate_name;
19591973

19601974
builder.ensure(compile::Std { compiler, target });
19611975
builder.ensure(RemoteCopyLibs { compiler, target });

0 commit comments

Comments
 (0)