internal/core/eval: nested comprehension fix
While iterating over comprehension to execute, new
ones may be added.
The iterator terminated at the end of the start of the
iteration, however, and the added elements were
promptly deleted.
Change-Id: I22b420e5d9fbb0a7c8b783ae1620aee3775f0bca
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6761
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/core/eval/eval.go b/internal/core/eval/eval.go
index 8b58c7e..3298f7d 100644
--- a/internal/core/eval/eval.go
+++ b/internal/core/eval/eval.go
@@ -1482,11 +1482,11 @@
return true
}
- if n.ifClauses, progress = n.injectEmbedded(n.ifClauses); progress {
+ if progress = n.injectEmbedded(&(n.ifClauses)); progress {
return true
}
- if n.forClauses, progress = n.injectEmbedded(n.forClauses); progress {
+ if progress = n.injectEmbedded(&(n.forClauses)); progress {
return true
}
@@ -1542,7 +1542,7 @@
// injectEmbedded evaluates and inserts embeddings. It first evaluates all
// embeddings before inserting the results to ensure that the order of
// evaluation does not matter.
-func (n *nodeContext) injectEmbedded(all []envYield) (a []envYield, progress bool) {
+func (n *nodeContext) injectEmbedded(all *[]envYield) (progress bool) {
ctx := n.ctx
type envStruct struct {
env *adt.Environment
@@ -1554,12 +1554,13 @@
}
k := 0
- for _, d := range all {
+ for i := 0; i < len(*all); i++ {
+ d := (*all)[i]
sa = sa[:0]
if err := ctx.Yield(d.env, d.yield, f); err != nil {
if err.IsIncomplete() {
- all[k] = d
+ (*all)[k] = d
k++
} else {
// continue to collect other errors.
@@ -1573,7 +1574,8 @@
}
}
- return all[:k], k < len(all)
+ *all = (*all)[:k]
+ return k < len(*all)
}
// addLists