cue: for structs, iterate only on non-optional regular fields
Change-Id: If516e96e68b135972942b9f5cfdfb49df3231297
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3187
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index b1c776c..4697e85 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -1580,8 +1580,12 @@
sub as: a
}
}
+
+ for k, v in { def :: 1, opt?: 2, _hid: 3, reg: 4 } {
+ "\(k)": v
+ }
`,
- out: `<0>{obj: <1>{<>: <2>(Name: string)-><3>{a: (*"dummy" | string) if true yield <4>{sub: <5>{as: <3>.a}}}, foo: <6>{a: "bar", sub: <7>{as: "bar"}}}}`,
+ out: `<0>{obj: <1>{<>: <2>(Name: string)-><3>{a: (*"dummy" | string) if true yield <4>{sub: <5>{as: <3>.a}}}, foo: <6>{a: "bar", sub: <7>{as: "bar"}}}, reg: 4}`,
}, {
desc: "builtins",
in: `
diff --git a/cue/value.go b/cue/value.go
index 6f5f659..14b380e 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -1455,6 +1455,9 @@
ctx.labelStr(a.feature),
nil,
}
+ if a.definition || a.optional || a.feature&hidden != 0 {
+ continue
+ }
val := src.at(ctx, i)
v := fn.call(ctx, x, key, val)
if err, ok := v.(*bottom); ok {
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index 088436d..3569fa8 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -1239,8 +1239,7 @@
A _closed struct_ `c` is a struct whose instances may not have regular fields
not defined in `c`.
-For the purpose of unification,
-closing a struct is equivalent to adding an optional field with value `_|_`
+Closing a struct is equivalent to adding an optional field with value `_|_`
for all undefined fields.
Syntactically, closed structs can be explicitly created with the `close` builtin
@@ -2570,11 +2569,14 @@
The `for` clause binds the defined identifiers, on each iteration, to the next
value of some iterable value in a new scope.
A `for` clause may bind one or two identifiers.
-If there is one identifier, it binds it to the value, for instance
-a list element, a struct field value or a range element.
+If there is one identifier, it binds it to the value of
+a list element or struct field value.
If there are two identifiers, the first value will be the key or index,
if available, and the second will be the value.
+For lists, `for` iterates over all elements in the list after closing it.
+For structs, `for` iterates over all non-optional regular fields.
+
An `if` clause, or guard, specifies an expression that terminates the current
iteration if it evaluates to false.