internal: replace internal.CoreValue with more type-safe variant

CoreValue is now typed throught the internal/{value|types} packages.

Change-Id: I4b2df582a21fff2aaa83df61735141de11b6acbf
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9366
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/core/convert/go.go b/internal/core/convert/go.go
index 5191467..5c4d646 100644
--- a/internal/core/convert/go.go
+++ b/internal/core/convert/go.go
@@ -33,10 +33,9 @@
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/parser"
 	"cuelang.org/go/cue/token"
-	"cuelang.org/go/internal"
 	"cuelang.org/go/internal/core/adt"
 	"cuelang.org/go/internal/core/compile"
-	"cuelang.org/go/internal/core/runtime"
+	"cuelang.org/go/internal/types"
 )
 
 // This file contains functionality for converting Go to CUE.
@@ -225,14 +224,9 @@
 }
 
 func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
-	if internal.CoreValue != nil {
-		if ii, iv := internal.CoreValue(x); ii != nil {
-			i := ii.(*runtime.Runtime)
-			v := iv.(*adt.Vertex)
-			// TODO: panic if nto the same runtime.
-			_ = i
-			return v
-		}
+	if t := (&types.Value{}); types.CastValue(t, x) {
+		// TODO: panic if nto the same runtime.
+		return t.V
 	}
 	src := ctx.Source()
 	switch v := x.(type) {
diff --git a/internal/core/convert/go_test.go b/internal/core/convert/go_test.go
index 1a034c7..9d3a35f 100644
--- a/internal/core/convert/go_test.go
+++ b/internal/core/convert/go_test.go
@@ -23,7 +23,6 @@
 	"github.com/cockroachdb/apd/v2"
 	"github.com/google/go-cmp/cmp"
 
-	_ "cuelang.org/go/cue" // set internal.CoreValue
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/internal/core/adt"
 	"cuelang.org/go/internal/core/convert"
diff --git a/internal/core/dep/dep_test.go b/internal/core/dep/dep_test.go
index 6fb476b..449279b 100644
--- a/internal/core/dep/dep_test.go
+++ b/internal/core/dep/dep_test.go
@@ -20,14 +20,13 @@
 	"testing"
 
 	"cuelang.org/go/cue"
-	"cuelang.org/go/internal"
 	"cuelang.org/go/internal/core/adt"
 	"cuelang.org/go/internal/core/debug"
 	"cuelang.org/go/internal/core/dep"
 	"cuelang.org/go/internal/core/eval"
-	"cuelang.org/go/internal/core/runtime"
 	"cuelang.org/go/internal/cuetest"
 	"cuelang.org/go/internal/cuetxtar"
+	"cuelang.org/go/internal/value"
 )
 
 func TestVisit(t *testing.T) {
@@ -45,8 +44,7 @@
 			t.Fatal(inst.Err())
 		}
 
-		rx, nx := internal.CoreValue(inst)
-		ctxt := eval.NewContext(rx.(*runtime.Runtime), nx.(*adt.Vertex))
+		ctxt := eval.NewContext(value.ToInternal(inst))
 
 		testCases := []struct {
 			name string
@@ -69,8 +67,7 @@
 		for _, tc := range testCases {
 			v := inst.LookupPath(cue.ParsePath(tc.root))
 
-			_, nx = internal.CoreValue(v)
-			n := nx.(*adt.Vertex)
+			_, n := value.ToInternal(v)
 			w := t.Writer(tc.name)
 
 			t.Run(tc.name, func(sub *testing.T) {
@@ -105,9 +102,7 @@
 
 	v := inst.Lookup("a")
 
-	rx, nx := internal.CoreValue(v)
-	r := rx.(*runtime.Runtime)
-	n := nx.(*adt.Vertex)
+	r, n := value.ToInternal(v)
 
 	ctxt := eval.NewContext(r, n)
 
diff --git a/internal/internal.go b/internal/internal.go
index 7544d95..31112fe 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -70,10 +70,6 @@
 // GetRuntime reports the runtime for an Instance or Value.
 var GetRuntime func(instance interface{}) interface{}
 
-// CoreValue returns an *runtime.Index and *adt.Vertex for a cue.Value.
-// It returns nil if value is not a cue.Value.
-var CoreValue func(value interface{}) (runtime, vertex interface{})
-
 // MakeInstance makes a new instance from a value.
 var MakeInstance func(value interface{}) (instance interface{})
 
diff --git a/internal/task/task.go b/internal/task/task.go
index b0af1d1..1b43bb4 100644
--- a/internal/task/task.go
+++ b/internal/task/task.go
@@ -23,8 +23,7 @@
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/token"
-	"cuelang.org/go/internal"
-	"cuelang.org/go/internal/core/adt"
+	"cuelang.org/go/internal/value"
 )
 
 // A Context provides context for running a task.
@@ -117,9 +116,9 @@
 }
 
 func (t *taskError) InputPositions() (a []token.Pos) {
-	_, nx := internal.CoreValue(t.v)
+	_, nx := value.ToInternal(t.v)
 
-	for _, x := range nx.(*adt.Vertex).Conjuncts {
+	for _, x := range nx.Conjuncts {
 		if src := x.Source(); src != nil {
 			a = append(a, src.Pos())
 		}
diff --git a/internal/types/value.go b/internal/types/value.go
new file mode 100644
index 0000000..7b0301f
--- /dev/null
+++ b/internal/types/value.go
@@ -0,0 +1,37 @@
+// 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 types
+
+import (
+	"cuelang.org/go/internal/core/adt"
+	"cuelang.org/go/internal/core/runtime"
+)
+
+type Value struct {
+	R *runtime.Runtime
+	V *adt.Vertex
+}
+
+type Interface interface {
+	Core(v *Value)
+}
+
+func CastValue(t *Value, x interface{}) bool {
+	c, ok := x.(Interface)
+	if ok {
+		c.Core(t)
+	}
+	return ok
+}
diff --git a/internal/value/value.go b/internal/value/value.go
new file mode 100644
index 0000000..62a127d
--- /dev/null
+++ b/internal/value/value.go
@@ -0,0 +1,40 @@
+// 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 value contains functions for converting values to internal types
+// and various other Value-related utilities.
+package value
+
+import (
+	"cuelang.org/go/cue"
+	"cuelang.org/go/internal/core/adt"
+	"cuelang.org/go/internal/core/runtime"
+	"cuelang.org/go/internal/types"
+)
+
+func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) {
+	var t types.Value
+	v.Core(&t)
+	return t.R, t.V
+}
+
+// TODO:
+//
+// func Make(r *runtime.Runtime, v *adt.Vertex) cue.Value {
+// 	return cue.Value{}
+// }
+
+// func MakeError(r *runtime.Runtime, err error) cue.Value {
+// 	return cue.Value{}
+// }