Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
internal/core/adt: fix nil panic
Browse files Browse the repository at this point in the history
A vertex should always be associated with state in case
it is under evaluation. However, when it was "virtually"
tagged as evaluating, this would sometimes be missed.

Once we have redone the cycle detection algorithm,
this "virtual" state will probably go.

Fixes #672

Change-Id: I9b41be5cd6e87f7387fcdb7bfef64abc1d75f814
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8303
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
  • Loading branch information
mpvl committed Jan 28, 2021
1 parent c866a51 commit ee78ec3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
19 changes: 19 additions & 0 deletions internal/core/adt/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,25 @@ const (
Finalized
)

func (s VertexStatus) String() string {
switch s {
case Unprocessed:
return "unprocessed"
case Evaluating:
return "evaluating"
case Partial:
return "partial"
case AllArcs:
return "allarcs"
case EvaluatingArcs:
return "evaluatingArcs"
case Finalized:
return "finalized"
default:
return "unknown"
}
}

func (v *Vertex) Status() VertexStatus {
if v.EvalCount > 0 {
return EvaluatingArcs
Expand Down
10 changes: 6 additions & 4 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (e *Unifier) evaluate(c *OpContext, v *Vertex, state VertexStatus) Value {
return &w
}
}
panic("nil value")
Assertf(false, "no BaseValue: state: %v; requested: %v", v.status, state)
}

if v.status < Finalized && v.state != nil {
Expand All @@ -180,15 +180,17 @@ func (e *Unifier) evaluate(c *OpContext, v *Vertex, state VertexStatus) Value {
func (e *Unifier) Unify(c *OpContext, v *Vertex, state VertexStatus) {
// defer c.PopVertex(c.PushVertex(v))

// Ensure a node will always have a nodeContext after calling Unify if it is
// not yet Finalized.
n := v.getNodeContext(c)
defer v.freeNode(n)

if state <= v.Status() {
if v.Status() != Partial && state != Partial {
return
}
}

n := v.getNodeContext(c)
defer v.freeNode(n)

switch v.Status() {
case Evaluating:
return
Expand Down

0 comments on commit ee78ec3

Please sign in to comment.