cue: don't extract embedded values
Only non-value expressions are extracted.
Change-Id: Iecbcc66036cea68acf0679ef1a6d9a647bba4672
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9861
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/cue/types.go b/cue/types.go
index 3502e4a..32af926 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -2392,6 +2392,10 @@
ctx := v.ctx()
for _, d := range x.Decls {
switch x := d.(type) {
+ default:
+ fields = append(fields, d)
+ case adt.Value:
+ fields = append(fields, d)
case adt.Expr:
// embedding
n := &adt.Vertex{Label: v.v.Label}
@@ -2400,9 +2404,6 @@
n.Finalize(ctx)
n.Parent = v.v.Parent
a = append(a, makeValue(v.idx, n, v.parent_))
-
- default:
- fields = append(fields, d)
}
}
if len(a) == 0 {
@@ -2414,9 +2415,16 @@
n := &adt.Vertex{
Label: v.v.Label,
}
- c := adt.MakeRootConjunct(env, &adt.StructLit{
- Decls: fields,
- })
+ s := &adt.StructLit{}
+ if k := v.v.Kind(); k != adt.StructKind && k != BottomKind {
+ // TODO: we should also add such a declaration for embeddings
+ // of structs with definitions. However, this is currently
+ // also not supported at the CUE level. If we do, it may be
+ // best handled with a special mode of unification.
+ s.Decls = append(s.Decls, &adt.BasicType{K: k})
+ }
+ s.Decls = append(s.Decls, fields...)
+ c := adt.MakeRootConjunct(env, s)
n.AddConjunct(c)
n.Finalize(ctx)
n.Parent = v.v.Parent
diff --git a/cue/types_test.go b/cue/types_test.go
index c792e27..ba1494d 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -3331,9 +3331,19 @@
input: `v: "Hello, \(x)! Welcome to \(place)", place: string, x: string`,
want: `\()("Hello, " .(〈〉 "x") "! Welcome to " .(〈〉 "place") "")`,
}, {
+ // Split out the reference, but ensure the split-off outer struct
+ // remains valid.
+ input: `v: { a, #b: 1 }, a: 2`,
+ want: `&(.(〈〉 "a") {int,#b:1})`,
+ }, {
+ // Result is an error, no need to split off.
input: `v: { a, b: 1 }, a: 2`,
want: `&(.(〈〉 "a") {b:1})`,
}, {
+ // Don't split of concrete values.
+ input: `v: { "foo", #def: 1 }`,
+ want: `{"foo",#def:1}`,
+ }, {
input: `v: { {c: a}, b: a }, a: int`,
want: `&({c:a} {b:a})`,
}, {