internal/core/adt: treat files as belonging to same struct

The bug fix that treats {#A} as #A
(2ef72d85b1ed1311e5c54c176e6bfc7244e46990)
caused this to matter. This fixes that.

Also adds a previously forgotten test for embedding
definitions, related to this.

Change-Id: Ieae00bb2c4c3d537f21b8a5123741a7ffce9a7bd
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8229
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
diff --git a/cue/testdata/definitions/defembed.txtar b/cue/testdata/definitions/defembed.txtar
new file mode 100644
index 0000000..6aee167
--- /dev/null
+++ b/cue/testdata/definitions/defembed.txtar
@@ -0,0 +1,47 @@
+-- in.cue --
+a: {
+    #A
+}
+
+a: c: 1
+
+#A: b: 1
+-- out/eval --
+Errors:
+a: field `c` not allowed:
+    ./in.cue:1:4
+    ./in.cue:2:5
+    ./in.cue:5:4
+    ./in.cue:7:5
+
+Result:
+(_|_){
+  // [eval]
+  a: (_|_){
+    // [eval]
+    b: (int){ 1 }
+    c: (_|_){
+      // [eval] a: field `c` not allowed:
+      //     ./in.cue:1:4
+      //     ./in.cue:2:5
+      //     ./in.cue:5:4
+      //     ./in.cue:7:5
+    }
+  }
+  #A: (#struct){
+    b: (int){ 1 }
+  }
+}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    〈1;#A〉
+  }
+  a: {
+    c: 1
+  }
+  #A: {
+    b: 1
+  }
+}
diff --git a/cue/testdata/definitions/files.txtar b/cue/testdata/definitions/files.txtar
new file mode 100644
index 0000000..a95a0e0
--- /dev/null
+++ b/cue/testdata/definitions/files.txtar
@@ -0,0 +1,79 @@
+// Treat fields of different files as belonging to the same struct.
+// This means that a closed embedding in one file should not restrict the
+// fields of another.
+
+-- in.cue --
+#theme: {
+	color:   string
+	ctermbg: string
+}
+dark: #theme & {
+	color:   "dark"
+	ctermbg: "239"
+}
+light: #theme & {
+	color:   "light"
+	ctermbg: "254"
+}
+#Config: {
+	console: dark | *light
+}
+
+-- box.cue --
+#Config & {
+	console: dark
+}
+
+-- out/eval --
+(#struct){
+  #theme: (#struct){
+    color: (string){ string }
+    ctermbg: (string){ string }
+  }
+  dark: (#struct){
+    color: (string){ "dark" }
+    ctermbg: (string){ "239" }
+  }
+  light: (#struct){
+    color: (string){ "light" }
+    ctermbg: (string){ "254" }
+  }
+  #Config: (#struct){
+    console: (struct){ |(*(#struct){
+        color: (string){ "light" }
+        ctermbg: (string){ "254" }
+      }, (#struct){
+        color: (string){ "dark" }
+        ctermbg: (string){ "239" }
+      }) }
+  }
+  console: (#struct){
+    color: (string){ "dark" }
+    ctermbg: (string){ "239" }
+  }
+}
+-- out/compile --
+--- in.cue
+{
+  #theme: {
+    color: string
+    ctermbg: string
+  }
+  dark: (〈0;#theme〉 & {
+    color: "dark"
+    ctermbg: "239"
+  })
+  light: (〈0;#theme〉 & {
+    color: "light"
+    ctermbg: "254"
+  })
+  #Config: {
+    console: (〈1;dark〉|*〈1;light〉)
+  }
+}
+--- box.cue
+{
+  (〈0;#Config〉 & {
+    console: 〈1;dark〉
+  })
+}
diff --git a/internal/core/adt/eval.go b/internal/core/adt/eval.go
index 3053294..54058de 100644
--- a/internal/core/adt/eval.go
+++ b/internal/core/adt/eval.go
@@ -1539,7 +1539,7 @@
 
 	s.Init()
 
-	if s.HasEmbed {
+	if s.HasEmbed && !s.IsFile() {
 		closeInfo = closeInfo.SpawnGroup(nil)
 	}
 
diff --git a/internal/core/adt/expr.go b/internal/core/adt/expr.go
index cb25c4c..2a6e1aa 100644
--- a/internal/core/adt/expr.go
+++ b/internal/core/adt/expr.go
@@ -56,6 +56,11 @@
 	// hasReferences bool
 }
 
+func (o *StructLit) IsFile() bool {
+	_, ok := o.Src.(*ast.File)
+	return ok
+}
+
 type FieldInfo struct {
 	Label    Feature
 	Optional []Node