internal/core/eval: add more tests for embedding

Note that in order to use structs as embeddings, one has
to embed the return type (or _).

Change-Id: I2e74109be6269b47cc8fbd69fafa78b195432148
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7902
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/testdata/scalars/embed.txtar b/cue/testdata/scalars/embed.txtar
index e3c9e28..e25ba14 100644
--- a/cue/testdata/scalars/embed.txtar
+++ b/cue/testdata/scalars/embed.txtar
@@ -1,125 +1,250 @@
 -- in.cue --
 import "strings"
 
-a1: {
-    2
-}
-a2: {
-    v: {
-        3
-        #foo: a2.v + 1
+intEmbed: {
+    a1: {
+        2
     }
-    w: v
-    x: v.#foo
+    a2: {
+        v: {
+            3
+            #foo: a2.v + 1
+        }
+        w: v
+        x: v.#foo
+    }
+    a3: a1 + a2.v
 }
-a3: a1 + a2.v
 
-b3: {
-    [1, 2]
-    #foo: 1
+listEmbed: {
+    a1: {
+        2
+    }
+    b3: {
+        [1, 2]
+        #foo: 1
+    }
+    b4: b3 + b3
+    b5: b3[1]
+    b6: b3[5]
+    b7: b4[a1] // 1
 }
-b4: b3 + b3
-b5: b3[1]
-b6: b3[5]
-b7: b4[a1] // 1
 
-s1: {
-    "foo"
-    #bar: "bar"
+stringEmbed: {
+    s1: {
+        "foo"
+        #bar: "bar"
+    }
+    s2: [ s1, { s1.#bar, #baz: 4 } ]
+    s3: strings.Join(s2, "--")
 }
-s2: [ s1, { s1.#bar, #baz: 4 } ]
-s3: strings.Join(s2, "--")
+
+
+outPattern: {
+    sum: {
+        out: #a + #b
+        #a: int
+        #b: int
+    }
+    used: sum&{#a: 1, #b: 3}
+}
+
+arithmetic: {
+    sum: {
+        #a + #b
+        #a: int
+        #b: int
+    }
+    a1: (sum&{_, #a: 1, #b: 3}) + 2
+    a2: 2 + (sum&{_, #a: 1, #b: 3})
+    a3: 2 + (2 + (sum&{_, #a: 1, #b: 3}))
+}
+
+defCheck: {
+    a: {
+      #def: 1
+    }
+    b: a.#def
+}
 
 -- out/eval --
 Errors:
-b6: invalid list index 5 (out of bounds):
-    ./in.cue:22:8
+listEmbed.b6: invalid list index 5 (out of bounds):
+    ./in.cue:28:12
 
 Result:
 (_|_){
   // [eval]
-  a1: (int){ 2 }
-  a2: (struct){
-    v: (int){
-      3
-      #foo: (int){ 4 }
+  intEmbed: (struct){
+    a1: (int){ 2 }
+    a2: (struct){
+      v: (int){
+        3
+        #foo: (int){ 4 }
+      }
+      w: (int){
+        3
+        #foo: (int){ 4 }
+      }
+      x: (int){ 4 }
     }
-    w: (int){
-      3
-      #foo: (int){ 4 }
+    a3: (int){ 5 }
+  }
+  listEmbed: (_|_){
+    // [eval]
+    a1: (int){ 2 }
+    b3: (#list){
+      #foo: (int){ 1 }
+      0: (int){ 1 }
+      1: (int){ 2 }
     }
-    x: (int){ 4 }
+    b4: (#list){
+      0: (int){ 1 }
+      1: (int){ 2 }
+      2: (int){ 1 }
+      3: (int){ 2 }
+    }
+    b5: (int){ 2 }
+    b6: (_|_){
+      // [eval] listEmbed.b6: invalid list index 5 (out of bounds):
+      //     ./in.cue:28:12
+    }
+    b7: (int){ 1 }
   }
-  a3: (int){ 5 }
-  b3: (#list){
-    #foo: (int){ 1 }
-    0: (int){ 1 }
-    1: (int){ 2 }
-  }
-  b4: (#list){
-    0: (int){ 1 }
-    1: (int){ 2 }
-    2: (int){ 1 }
-    3: (int){ 2 }
-  }
-  b5: (int){ 2 }
-  b6: (_|_){
-    // [eval] b6: invalid list index 5 (out of bounds):
-    //     ./in.cue:22:8
-  }
-  b7: (int){ 1 }
-  s1: (string){
-    "foo"
-    #bar: (string){ "bar" }
-  }
-  s2: (#list){
-    0: (string){
+  stringEmbed: (struct){
+    s1: (string){
       "foo"
       #bar: (string){ "bar" }
     }
-    1: (string){
-      "bar"
-      #baz: (int){ 4 }
+    s2: (#list){
+      0: (string){
+        "foo"
+        #bar: (string){ "bar" }
+      }
+      1: (string){
+        "bar"
+        #baz: (int){ 4 }
+      }
+    }
+    s3: (string){ "foo--bar" }
+  }
+  outPattern: (struct){
+    sum: (struct){
+      out: (_|_){
+        // [incomplete] outPattern.sum.out: non-concrete value int in operand to +:
+        //     ./in.cue:44:14
+      }
+      #a: (int){ int }
+      #b: (int){ int }
+    }
+    used: (struct){
+      out: (int){ 4 }
+      #a: (int){ 1 }
+      #b: (int){ 3 }
     }
   }
-  s3: (string){ "foo--bar" }
+  arithmetic: (struct){
+    sum: (_|_){
+      // [incomplete] arithmetic.sum: non-concrete value int in operand to +:
+      //     ./in.cue:53:9
+      #a: (int){ int }
+      #b: (int){ int }
+    }
+    a1: (int){ 6 }
+    a2: (int){ 6 }
+    a3: (int){ 8 }
+  }
+  defCheck: (struct){
+    a: (struct){
+      #def: (int){ 1 }
+    }
+    b: (int){ 1 }
+  }
 }
 -- out/compile --
 --- in.cue
 {
-  a1: {
-    2
-  }
-  a2: {
-    v: {
-      3
-      #foo: (〈2;a2〉.v + 1)
+  intEmbed: {
+    a1: {
+      2
     }
-    w: 〈0;v〉
-    x: 〈0;v〉.#foo
+    a2: {
+      v: {
+        3
+        #foo: (〈2;a2〉.v + 1)
+      }
+      w: 〈0;v〉
+      x: 〈0;v〉.#foo
+    }
+    a3: (〈0;a1〉 + 〈0;a2〉.v)
   }
-  a3: (〈0;a1〉 + 〈0;a2〉.v)
-  b3: {
-    [
-      1,
-      2,
+  listEmbed: {
+    a1: {
+      2
+    }
+    b3: {
+      [
+        1,
+        2,
+      ]
+      #foo: 1
+    }
+    b4: (〈0;b3〉 + 〈0;b3〉)
+    b5: 〈0;b3〉[1]
+    b6: 〈0;b3〉[5]
+    b7: 〈0;b4〉[〈0;a1〉]
+  }
+  stringEmbed: {
+    s1: {
+      "foo"
+      #bar: "bar"
+    }
+    s2: [
+      〈0;s1〉,
+      {
+        〈1;s1〉.#bar
+        #baz: 4
+      },
     ]
-    #foo: 1
+    s3: 〈import;strings〉.Join(〈0;s2〉, "--")
   }
-  b4: (〈0;b3〉 + 〈0;b3〉)
-  b5: 〈0;b3〉[1]
-  b6: 〈0;b3〉[5]
-  b7: 〈0;b4〉[〈0;a1〉]
-  s1: {
-    "foo"
-    #bar: "bar"
+  outPattern: {
+    sum: {
+      out: (〈0;#a〉 + 〈0;#b〉)
+      #a: int
+      #b: int
+    }
+    used: (〈0;sum〉 & {
+      #a: 1
+      #b: 3
+    })
   }
-  s2: [
-    〈0;s1〉,
-    {
-      〈1;s1〉.#bar
-      #baz: 4
-    },
-  ]
-  s3: 〈import;strings〉.Join(〈0;s2〉, "--")
+  arithmetic: {
+    sum: {
+      (〈0;#a〉 + 〈0;#b〉)
+      #a: int
+      #b: int
+    }
+    a1: ((〈0;sum〉 & {
+      _
+      #a: 1
+      #b: 3
+    }) + 2)
+    a2: (2 + (〈0;sum〉 & {
+      _
+      #a: 1
+      #b: 3
+    }))
+    a3: (2 + (2 + (〈0;sum〉 & {
+      _
+      #a: 1
+      #b: 3
+    })))
+  }
+  defCheck: {
+    a: {
+      #def: 1
+    }
+    b: 〈0;a〉.#def
+  }
 }