Skip to content

driver: Really don't lose track of nodes when we fail to resolve cycles

Zubin requested to merge wip/24275 into master

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)

Edited by Zubin

Merge request reports