cue: add NewList

Fixes #343: Fill already supports filling Values. There is a NewValue
planned as well, which adds full struct creation support, but with
this CL all requirements for this issue are satisfied.

Change-Id: Ia421ec0a9f16b3f73d4fce0a63dd4be8cec03181
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9502
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/context.go b/cue/context.go
index 63eaa13..3257fb7 100644
--- a/cue/context.go
+++ b/cue/context.go
@@ -249,16 +249,26 @@
 	return c.make(n)
 }
 
+// NewList creates a Value that is a list of the given values.
+//
+// All Values must be created by c.
+func (c *Context) NewList(v ...Value) Value {
+	a := make([]adt.Value, len(v))
+	for i, x := range v {
+		if x.idx != (*runtime.Runtime)(c) {
+			panic("values must be from same Context")
+		}
+		a[i] = x.v
+	}
+	return c.make(c.ctx().NewList(a...))
+}
+
 // TODO:
 
 // func (c *Context) NewExpr(op Op, v ...Value) Value {
 // 	return Value{}
 // }
 
-// func (c *Context) NewList(v ...Value) Value {
-// 	return Value{}
-// }
-
 // func (c *Context) NewValue(v ...ValueElem) Value {
 // 	return Value{}
 // }
diff --git a/cue/context_test.go b/cue/context_test.go
new file mode 100644
index 0000000..5839037
--- /dev/null
+++ b/cue/context_test.go
@@ -0,0 +1,82 @@
+// Copyright 2021 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cue_test
+
+import (
+	"fmt"
+	"testing"
+
+	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/cuecontext"
+)
+
+func TestNewList(t *testing.T) {
+	ctx := cuecontext.New()
+
+	intList := ctx.CompileString("[...int]")
+
+	l123 := ctx.NewList(
+		ctx.Encode(1),
+		ctx.Encode(2),
+		ctx.Encode(3),
+	)
+
+	testCases := []struct {
+		desc string
+		v    cue.Value
+		out  string
+	}{{
+		v:   ctx.NewList(),
+		out: `[]`,
+	}, {
+		v:   l123,
+		out: `[1, 2, 3]`,
+	}, {
+		v:   l123.Unify(intList),
+		out: `[1, 2, 3]`,
+	}, {
+		v:   l123.Unify(intList).Unify(l123),
+		out: `[1, 2, 3]`,
+	}, {
+		v:   intList.Unify(ctx.NewList(ctx.Encode("string"))),
+		out: `_|_ // 0: conflicting values "string" and int (mismatched types string and int)`,
+	}, {
+		v:   ctx.NewList().Unify(l123),
+		out: `_|_ // incompatible list lengths (0 and 3)`,
+	}, {
+		v: ctx.NewList(
+			intList,
+			intList,
+		).Unify(ctx.NewList(
+			ctx.NewList(
+				ctx.Encode(1),
+				ctx.Encode(3),
+			),
+			ctx.NewList(
+				ctx.Encode(5),
+				ctx.Encode(7),
+			),
+		)),
+		out: `[[1, 3], [5, 7]]`,
+	}}
+	for _, tc := range testCases {
+		t.Run(tc.desc, func(t *testing.T) {
+			got := fmt.Sprint(tc.v)
+			if got != tc.out {
+				t.Errorf(" got: %v\nwant: %v", got, tc.out)
+			}
+		})
+	}
+}
diff --git a/internal/core/adt/eval.go b/internal/core/adt/eval.go
index 416d515..6ff29b9 100644
--- a/internal/core/adt/eval.go
+++ b/internal/core/adt/eval.go
@@ -2074,7 +2074,7 @@
 
 			// Terminate early n case of runaway comprehension.
 			if !isOpen && int(index) > max {
-				n.invalidListLength(max, int(index), maxNode, l.list)
+				n.invalidListLength(max, len(l.list.Elems), maxNode, l.list)
 				continue outer
 			}
 		}