guppy 0.17.26
·
63 commits
to main
since this release
Fixed
A node with a self-loop edge -- typically a package with a path
dev-dependency on its own crate, or a feature node like base/[base]
arising from one -- was treated inconsistently by several APIs. The root
cause was that self-edges were counted as incoming edges in the SCC and
topological-sort machinery, which transitively confused everything built
on top:
Sccs::externals/ forward roots. Previously, a package whose only
incoming edge was its own self-loop was excluded from the set of forward
roots, so callers iterating over
query_workspace().resolve().root_ids(_)did not see it, and forward
link enumeration on it was broken. Now, self-loop edges no longer
disqualify a node from being a forward root: a single-node SCC is
external iff it has no incoming edges from outside its own SCC.
(#586)- Topological sort. Previously,
TopoWithCycles::newfiltered
self-looping nodes out of its root set for the same reason, dropping
them from the DFS and then placing them and their descendants at the
end of the topological order via a best-effort fallback. Now, the
root-set predicate accepts a node whose only incoming edge is its own
self-loop, so such nodes are visited in DFS order alongside other
roots. (#589) Cycles::is_cyclicandfeature::Cycles::is_cyclic. Previously,
these were reflexivelytruefor every package or feature, regardless
of actual cycle membership. Now, they returntrueonly when the
argument lies on a directed cycle: either in a multi-node SCC, or in a
single-node SCC with a self-loop edge. This is a behavior change, but
in the context of the rest of this release is being treated as a
bugfix. (#590)Cycles::all_cyclesandfeature::Cycles::all_cycles. Previously,
these reported only SCCs of two or more elements. Now, they also yield
single-node SCCs whose node has a self-loop edge, in topological order
alongside multi-node SCCs. This makesall_cycles()and
is_cyclic(x, x)agree on what counts as a cycle. (#590)FeatureGraphWarning::SelfLoop. Previously, this warning was
emitted for every self-loop edge in the feature graph, including
legitimate ones such as a path dev-dependency on the package's own
crate. Now, it is restricted to named-feature self-loops like
[features] a = ["a"], which really are user errors. (#592)
Documentation
PackageGraph::directly_depends_onand
FeatureGraph::directly_depends_on. Previously, both documented
themselves as returningfalsewhen the two IDs were equal. The
implementation has always calleddep_graph.contains_edge(a, b),
which correctly returnstruefor self-loop edges, so the
documentation contradicted the behavior. The documentation has now
been corrected to match.FeatureGraph::directly_depends_on. Previously, the docstring
read "returns true iffeature_ais a direct dependency of
feature_b," with the operands inverted relative to the actual
implementation. Now the docstring reflects the implementation:
returns true iffeature_bis a direct dependency offeature_a.
(#591)- [
Cycles] type-level documentation. Previously, the long-form
documentation talked exclusively about multi-node cycles (like
serdeandserde_derive). It now also acknowledges single-node
self-loop cycles as a case.