Skip to content

Commit

Permalink
internal/core/debug: add cycle detector
Browse files Browse the repository at this point in the history
Sometimes nodes are shared (using structure sharing)
that have a structural cycle without reporting on
that structural cycle. This caused printing to hang.

This change detects such cases and modifies to output
to inform about such cycles.

Issue #2850

Signed-off-by: Marcel van Lohuizen <[email protected]>
Change-Id: Iba74c91729507a4782c7f5902ef2ac6ed2770716
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201896
Reviewed-by: Matthew Sackman <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
  • Loading branch information
mpvl committed Oct 1, 2024
1 parent 4140094 commit 06141e4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions internal/core/adt/unify.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ func (n *nodeContext) updateScalar() {
}

func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool {
// TODO: this can go when lookup vs evaluation distinction
// has been improved.
if n.node.status == evaluatingArcs {
// NOTE: this was an "incomplete" error pre v0.6. If this is a problem
// we could make this a CycleError. Technically, this may be correct,
Expand Down
1 change: 1 addition & 0 deletions internal/core/debug/compact.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (w *compactPrinter) node(n adt.Node) {
case *adt.Vertex:
if v, ok := w.printShared(x); !ok {
w.node(v)
w.popVertex()
}

case adt.Value:
Expand Down
27 changes: 27 additions & 0 deletions internal/core/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ type printer struct {
indent string
cfg *Config

// keep track of vertices to avoid cycles.
stack []*adt.Vertex

// modes:
// - show vertex
// - show original conjuncts
Expand Down Expand Up @@ -144,9 +147,32 @@ func (w *printer) printShared(v *adt.Vertex) (x *adt.Vertex, ok bool) {
w.shared(s)
return v, true
}
if !w.pushVertex(v) {
if s != nil {
w.shared(s)
w.string(" =>")
}
w.shared(v)
return v, true
}
return v, false
}

func (w *printer) pushVertex(v *adt.Vertex) bool {
for _, x := range w.stack {
if x == v {
w.string("<TODO: unmarked structural cycle>")
return false
}
}
w.stack = append(w.stack, v)
return true
}

func (w *printer) popVertex() {
w.stack = w.stack[:len(w.stack)-1]
}

func (w *printer) shortError(errs errors.Error) {
for {
msg, args := errs.Msg()
Expand Down Expand Up @@ -201,6 +227,7 @@ func (w *printer) node(n adt.Node) {
if ok {
return
}
defer w.popVertex()

var kind adt.Kind
if x.BaseValue != nil {
Expand Down

0 comments on commit 06141e4

Please sign in to comment.