driver: Really don't lose track of nodes when we fail to resolve cycles
This fixes a bug in 8db8d2fd, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components.
As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC:
When viewed without boot files, we have a single SCC
[REC main:T24275B [main:T24275B {-# SOURCE #-},
main:T24275A {-# SOURCE #-}]
main:T24275A [main:T24275A {-# SOURCE #-}]]
But with boot files this turns into
[NONREC main:T24275B {-# SOURCE #-} [],
REC main:T24275B [main:T24275B {-# SOURCE #-},
main:T24275A {-# SOURCE #-}]
main:T24275A {-# SOURCE #-} [main:T24275B],
NONREC main:T24275A [main:T24275A {-# SOURCE #-}]]
Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account.
Indeed, we must return a single ResolvedCycle
element in the BuildPlan
for this
as described in Note [Upsweep]
.
However, since after resolving this is not a true SCC anymore, findCycle
fails
to find a cycle and we have a sub-optimal error message as a result.
To handle this, I extended findCycle
to not assume its input is an SCC, and to
try harder to find cycles in its input.
Fixes #24275 (closed)