Skip to content

Commit 2718709

Browse files
committed
Auto merge of #8942 - ehuss:panic-no-roots, r=alexcrichton
Fix panic with -Zbuild-std and no roots. If a build command is run without any roots (like `cargo build` in a project with only tests), then cargo would panic with `-Z build-std`. This is because some parts of the code assumes that all units in the unit graph are reachable from the roots. However, the code was "attaching" the std units to the graph without a root. The particular line that was panicking was [this one](https://github.com/rust-lang/cargo/blob/5c40b7f6dc94cffae0107d034ac1d1c6d3da18bf/src/cargo/core/compiler/context/mod.rs#L475) where it iterates over the units to check for collisions. The outputs are calculated based on the roots (since they metadata computation has to walk the dep graph), so without any roots there was no metadata, and thus no outputs.
2 parents 5c40b7f + 6b472c9 commit 2718709

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ pub fn build_unit_dependencies<'a, 'cfg>(
6262
profiles: &'a Profiles,
6363
interner: &'a UnitInterner,
6464
) -> CargoResult<UnitGraph> {
65+
if roots.is_empty() {
66+
// If -Zbuild-std, don't attach units if there is nothing to build.
67+
// Otherwise, other parts of the code may be confused by seeing units
68+
// in the dep graph without a root.
69+
return Ok(HashMap::new());
70+
}
6571
let (std_resolve, std_features) = match std_resolve {
6672
Some((r, f)) => (Some(r), Some(f)),
6773
None => (None, None),

tests/testsuite/standard_lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,3 +677,23 @@ fn different_features() {
677677
.target_host()
678678
.run();
679679
}
680+
681+
#[cargo_test]
682+
fn no_roots() {
683+
// Checks for a bug where it would panic if there are no roots.
684+
let setup = match setup() {
685+
Some(s) => s,
686+
None => return,
687+
};
688+
let p = project().file("tests/t1.rs", "").build();
689+
p.cargo("build")
690+
.build_std(&setup)
691+
.target_host()
692+
.with_stderr(
693+
"\
694+
[UPDATING] [..]
695+
[FINISHED] [..]
696+
",
697+
)
698+
.run();
699+
}

0 commit comments

Comments
 (0)