internal/core/compile: fix issue in and builtin

The builtin called Value() on its argument, which is
incorrect for embedded scalars.

Change-Id: I63be5847c81a146bba786e2e9f4c3c822c455764
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7782
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/testdata/builtins/all.txtar b/cue/testdata/builtins/all.txtar
new file mode 100644
index 0000000..b6c5c20
--- /dev/null
+++ b/cue/testdata/builtins/all.txtar
@@ -0,0 +1,84 @@
+-- in.cue --
+
+fatalArg: {
+    x: len("eee" + 'eee')
+}
+
+// don't call builtin for a permanent error of a child node
+fatalChild: {
+    #b: {}
+    x: and([{a: #b.c}])
+}
+
+// allow incomplete child values. The error will persist after `and` is
+// evaluated down the line. This allows the and-ing of templates that may
+// complete later.
+okIncompleteChild: {
+    b: {}
+    x: and([{a: b.c}, {b: 1}])
+}
+
+-- out/eval --
+Errors:
+fatalArg.x: invalid operands "eee" and 'eee' to '+' (type string and bytes):
+    ./in.cue:3:12
+0.a: undefined field c:
+    ./in.cue:9:20
+
+Result:
+(_|_){
+  // [eval]
+  fatalArg: (_|_){
+    // [eval]
+    x: (_|_){
+      // [eval] fatalArg.x: invalid operands "eee" and 'eee' to '+' (type string and bytes):
+      //     ./in.cue:3:12
+    }
+  }
+  fatalChild: (_|_){
+    // [eval]
+    #b: (#struct){
+    }
+    x: (_|_){
+      // [eval] 0.a: undefined field c:
+      //     ./in.cue:9:20
+    }
+  }
+  okIncompleteChild: (struct){
+    b: (struct){
+    }
+    x: (struct){
+      a: (_|_){
+        // [incomplete] okIncompleteChild.x.a: undefined field c:
+        //     ./in.cue:17:19
+      }
+      b: (int){ 1 }
+    }
+  }
+}
+-- out/compile --
+--- in.cue
+{
+  fatalArg: {
+    x: len(("eee" + 'eee'))
+  }
+  fatalChild: {
+    #b: {}
+    x: and([
+      {
+        a: 〈1;#b〉.c
+      },
+    ])
+  }
+  okIncompleteChild: {
+    b: {}
+    x: and([
+      {
+        a: 〈1;b〉.c
+      },
+      {
+        b: 1
+      },
+    ])
+  }
+}
diff --git a/cue/testdata/builtins/and.txtar b/cue/testdata/builtins/and.txtar
new file mode 100644
index 0000000..3d48229
--- /dev/null
+++ b/cue/testdata/builtins/and.txtar
@@ -0,0 +1,42 @@
+-- in.cue --
+merge: and([1, 1])
+
+// ensure definitions along embedded scalars are preserved.
+embed: and([{2, #x: 1}, {2, #x: 2}])
+-- out/eval --
+Errors:
+embed.#x: conflicting values 2 and 1:
+    ./in.cue:4:21
+    ./in.cue:4:33
+
+Result:
+(_|_){
+  // [eval]
+  merge: (int){ 1 }
+  embed: (_|_){
+    // [eval]
+    #x: (_|_){
+      // [eval] embed.#x: conflicting values 2 and 1:
+      //     ./in.cue:4:21
+      //     ./in.cue:4:33
+    }
+  }
+}
+-- out/compile --
+--- in.cue
+{
+  merge: and([
+    1,
+    1,
+  ])
+  embed: and([
+    {
+      2
+      #x: 1
+    },
+    {
+      2
+      #x: 2
+    },
+  ])
+}
diff --git a/cue/testdata/builtins/or.txtar b/cue/testdata/builtins/or.txtar
new file mode 100644
index 0000000..e74e09f
--- /dev/null
+++ b/cue/testdata/builtins/or.txtar
@@ -0,0 +1,10 @@
+// unwrap into single value
+unwrap: or([1, 1, 1])
+
+// unique duplicate values
+unique1: or([2, 1, 1, 2])
+
+unique2: or([{a: 1}, {a: 1}, {a: 2}])
+
+// do not unique embedded scalars with differing values for child definitions.
+embed1: or([{2, #x: 1}, {2, #x: 2}])
diff --git a/internal/core/adt/expr.go b/internal/core/adt/expr.go
index 4870ca7..216647e 100644
--- a/internal/core/adt/expr.go
+++ b/internal/core/adt/expr.go
@@ -908,15 +908,11 @@
 			c.Assertf(pos(x.Fun), c.HasErr(),
 				"argument %d to function %s is incomplete", i, c.Str(x.Fun))
 
-		case *Vertex:
-			// Remove the path of the origin for arguments. This results in
-			// more sensible error messages: an error should refer to the call
-			// site, not the original location of the argument.
-			// TODO: alternative, explicitly mark the argument number and use
-			// that in error messages.
-			w := *v
-			w.Parent = nil
-			args = append(args, &w)
+		case *Bottom:
+			// TODO(errors): consider adding an argument index for this errors.
+			// On the other hand, this error is really not related to the
+			// argument itself, so maybe it is good as it is.
+			c.AddBottom(v)
 
 		default:
 			args = append(args, expr)
diff --git a/internal/core/compile/builtin.go b/internal/core/compile/builtin.go
index b4c282e..99fe450 100644
--- a/internal/core/compile/builtin.go
+++ b/internal/core/compile/builtin.go
@@ -98,7 +98,7 @@
 		}
 		a := []adt.Value{}
 		for _, c := range list {
-			a = append(a, c.Value())
+			a = append(a, c)
 		}
 		return &adt.Conjunction{Values: a}
 	},