cue: fix lookup
optionals were not always inserted at evaluation time
This was a regression introduced in v0.0.14, where
references were partially evaluated in certain cases,
causing a non-expanded value to be used for lookup.
Fixes #202
Change-Id: Ie541f5be315eeb0fa929a52477020ba464b57623
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4207
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index da385ee..e161ab8 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -2763,6 +2763,7 @@
}`,
out: `<0>{t: <1>{ok :: true, x: int}, s: <2>{ok :: false}}`,
}, {
+ desc: "cross-dependent comprehension",
// TODO(eval): fix: c should ultimately be allowed the struct. Current
// semantics require, however, that generated fields are not available
// for evaluation. This, however, does not have to hold, for closedness
@@ -2781,6 +2782,21 @@
// c should not be allowed, as it would break commutativiy.
// See comments above.
out: `<0>{a :: <1>C{b: bool if <2>.b yield <3>C{c: 4}}, x: _|_(4:field "c" not allowed in closed struct), y: _|_(4:field "c" not allowed in closed struct)}`,
+ }, {
+ desc: "optional expanded before lookup",
+ in: `
+ test: [ID=_]: {
+ name: ID
+ }
+
+ test: A: {
+ field1: "1"
+ field2: "2"
+ }
+
+ B: test.A & {}
+ `,
+ out: `<0>{test: <1>{[]: <2>(ID: string)-><3>{name: <2>.ID}, A: <4>{name: "A", field1: "1", field2: "2"}}, B: <5>{name: "A", field1: "1", field2: "2"}}`,
}}
rewriteHelper(t, testCases, evalFull)
}
diff --git a/cue/value.go b/cue/value.go
index 858fa44..2ed0746 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -984,7 +984,18 @@
// noderef will have ensured that the ancestors were evaluated.
for i, a := range x.arcs {
if a.feature == f {
- a.cache = x.at(ctx, i)
+ a := x.iterAt(ctx, i)
+ // TODO: adding more technical debt here. The evaluator should be
+ // rewritten.
+ if x.optionals != nil {
+ name := ctx.labelStr(x.arcs[i].feature)
+ arg := &stringLit{x.baseValue, name, nil}
+
+ val, _ := x.optionals.constraint(ctx, arg)
+ if val != nil {
+ a.v = mkBin(ctx, x.Pos(), opUnify, a.v, val)
+ }
+ }
return a
}
}
@@ -1014,13 +1025,8 @@
//
// Allow import of CUE files. These cannot have a package clause.
- x, err := x.expandFields(ctx)
- if err != nil {
- return err
- }
- // if x.emit != nil && isBottom(x.emit) {
- // return x.emit.(evaluated)
- // }
+ var err *bottom
+
// Lookup is done by selector or index references. Either this is done on
// literal nodes or nodes obtained from references. In the later case,
// noderef will have ensured that the ancestors were evaluated.