Skip to content

Commit

Permalink
Auto merge of #9834 - ehuss:fix-build-std-proc-macro-only, r=alexcric…
Browse files Browse the repository at this point in the history
…hton

Fix panic with build-std of a proc-macro.

If you try to run `cargo build -Zbuild-std` in a proc-macro project, cargo would panic in [`check_collisions`](https://github.com/rust-lang/cargo/blob/835d5576e1f0b917a42ba18a9556242204377cd1/src/cargo/core/compiler/context/mod.rs#L427). This is because it iterates over every Unit in the build graph checking the `outputs` for filenames.  However, [`outputs`](https://github.com/rust-lang/cargo/blob/835d5576e1f0b917a42ba18a9556242204377cd1/src/cargo/core/compiler/context/compilation_files.rs#L109-L110) was missing the outputs for standard library units. That is because `outputs` is computed by walking the graph starting from the roots.

The bug here is that `attach_std_deps` was adding the standard library units to graph, even though they aren't reachable from the roots, thus creating orphans.

The solution is to avoid adding the standard library units if they are not needed (as is the case when building just a proc-macro).

Fixes #9828
  • Loading branch information
bors committed Aug 23, 2021
2 parents f066c50 + 00e925f commit 9b81660
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/cargo/core/compiler/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ fn attach_std_deps(
std_unit_deps: UnitGraph,
) {
// Attach the standard library as a dependency of every target unit.
let mut found = false;
for (unit, deps) in state.unit_dependencies.iter_mut() {
if !unit.kind.is_host() && !unit.mode.is_run_custom_build() {
deps.extend(std_roots[&unit.kind].iter().map(|unit| UnitDep {
Expand All @@ -152,12 +153,16 @@ fn attach_std_deps(
public: true,
noprelude: true,
}));
found = true;
}
}
// And also include the dependencies of the standard library itself.
for (unit, deps) in std_unit_deps.into_iter() {
if let Some(other_unit) = state.unit_dependencies.insert(unit, deps) {
panic!("std unit collision with existing unit: {:?}", other_unit);
// And also include the dependencies of the standard library itself. Don't
// include these if no units actually needed the standard library.
if found {
for (unit, deps) in std_unit_deps.into_iter() {
if let Some(other_unit) = state.unit_dependencies.insert(unit, deps) {
panic!("std unit collision with existing unit: {:?}", other_unit);
}
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions tests/testsuite/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,31 @@ fn no_roots() {
.with_stderr_contains("[FINISHED] [..]")
.run();
}

#[cargo_test]
fn proc_macro_only() {
// Checks for a bug where it would panic if building a proc-macro only
let setup = match setup() {
Some(s) => s,
None => return,
};
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "pm"
version = "0.1.0"
[lib]
proc-macro = true
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("build")
.build_std(&setup)
.target_host()
.with_stderr_contains("[FINISHED] [..]")
.run();
}

0 comments on commit 9b81660

Please sign in to comment.