Auto merge of #16871 - Veykril:dev-dependency-cycles, r=Veykril

fix: Skip problematic cyclic dev-dependencies

Implements a workaround for https://github.com/rust-lang/rust-analyzer/issues/14167, notably it does not implement the ideas surfaced in the issue, but takes a simpler to implement approach (and one that is more consistent).

Effectively, all this does is discard dev-dependency edges that go from a workspace library target to another workspace library target. This means, using a dev-dependency to another workspace member inside unit tests will always fail to resolve for r-a now, (instead of being order dependent and causing problems elsewhere) while things will work out fine in integration tests, benches, examples etc. This effectively acknowledges package cycles to be okay, but crate graph cycles to be invalid:

Quoting https://github.com/rust-lang/rust-analyzer/issues/14167#issuecomment-1864145772
> Though, if you have “package cycle” in integration tests, you’d have “crate cycle” in unit test.

We disallow the latter here, while continuing to support the former

(What's missing is to supress diagnostics for such unit tests, though not doing so might be a good deterrent, making devs avoid the pattern altogether)
This commit is contained in:
bors 2024-03-18 20:54:38 +00:00
commit 59b9cc17f9

View file

@ -1091,6 +1091,24 @@ fn cargo_to_crate_graph(
continue;
}
// If the dependency is a dev-dependency with both crates being member libraries of
// the workspace we discard the edge. The reason can be read up on in
// https://github.com/rust-lang/rust-analyzer/issues/14167
// but in short, such an edge usually causes some form of cycle in the crate graph
// wrt to unit tests. Something we cannot reasonable support.
if dep.kind == DepKind::Dev
&& matches!(kind, TargetKind::Lib { .. })
&& cargo[dep.pkg].is_member
&& cargo[pkg].is_member
{
tracing::warn!(
"Discarding dev-dependency edge from library target `{}` to library target `{}` to prevent potential cycles",
cargo[dep.pkg].name,
cargo[pkg].name
);
continue;
}
add_dep(crate_graph, from, name.clone(), to)
}
}