Skip to content

Commit

Permalink
internal/core/adt: fix special cycle condition
Browse files Browse the repository at this point in the history
Where node could be used with a 0 status.
This will be fixed when cycle detection is fixed, which
can be done if structure sharing is implemented.

Change-Id: I001a4e4c2b880c2011f36ee34af4966114f1bca9
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8561
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
  • Loading branch information
mpvl committed Feb 5, 2021
1 parent e097927 commit e6a2fb0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# DO NOT EDIT; generated by go run testdata/gen.go
#
#name: resolved self-reference cycles with disjunction
#evalPartial

// TODO(cycle)
//
// Some of these examples used to work, but the changes corresponding to this
// addition, it ceased to do so. Fixing these cycle issues seemed more
// important than keeping this esoteric case working, which was already broken
// in the last release anyway.
//
// Reproducer of underlying problem. Still works, but triggers unexpected
// condition.
//
// xb1: xb2
// xb2: xb3
// xb3: xb2 + 0

-- in.cue --
// The second disjunct in xa1 is not resolvable and can be
// eliminated:
Expand Down Expand Up @@ -174,10 +187,16 @@ Result:
xa2: (int){ 8 }
xa3: (int){ 6 }
xa4: (int){ 10 }
xb1: (int){ 8 }
xb2: (int){ 8 }
xb3: (int){ 6 }
xb4: (int){ 10 }
xb1: (int){ 9 }
xb2: (_|_){
// [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
// ./in.cue:18:6
}
xb3: (int){ |((int){ 6 }, (int){ 9 }) }
xb4: (_|_){
// [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
// ./in.cue:18:6
}
xc1: (int){ |((int){ 8 }, (int){ 9 }) }
xc2: (int){ 8 }
xc3: (_|_){
Expand Down Expand Up @@ -220,10 +239,16 @@ Result:
// ./in.cue:45:6
// ./in.cue:45:10
}
xf1: (int){ 8 }
xf2: (int){ 8 }
xf3: (int){ 6 }
xf4: (int){ 10 }
xf1: (int){ 9 }
xf2: (_|_){
// [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
// ./in.cue:52:6
}
xf3: (int){ |((int){ 6 }, (int){ 9 }) }
xf4: (_|_){
// [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
// ./in.cue:52:6
}
z1: (int){ |((int){ 11 }, (int){ 13 }) }
z2: (int){ 10 }
z3: (_|_){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Result:
xa4: (int){ 10 }
xb1: (int){ 8 }
xb2: (int){ 8 }
xb3: (int){ 6 }
xb3: (int){ |(*(int){ 6 }, (int){ 9 }) }
xb4: (int){ 10 }
xc1: (int){ |(*(int){ 8 }, (int){ 9 }) }
xc2: (int){ 8 }
Expand Down
11 changes: 11 additions & 0 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func (c *OpContext) Unify(v *Vertex, state VertexStatus) {
return

case EvaluatingArcs:
Assertf(v.status > 0, "unexpected status %d", v.status)
return

case 0:
Expand Down Expand Up @@ -1321,6 +1322,16 @@ func (n *nodeContext) addVertexConjuncts(env *Environment, closeInfo CloseInfo,

closeInfo = closeInfo.SpawnRef(arc, IsDef(x), x)

if arc.status == 0 && !inline {
// This is a rare condition, but can happen in certain
// evaluation orders. Unfortunately, adding this breaks
// resolution of cyclic mutually referring disjunctions. But it
// is necessary to prevent lookups in unevaluated structs.
// TODO(cycles): this can probably most easily be fixed with a
// having a more recursive implementation.
n.ctx.Unify(arc, AllArcs)
}

for _, c := range arc.Conjuncts {
var a []*Vertex
if env != nil {
Expand Down

0 comments on commit e6a2fb0

Please sign in to comment.