internal/core/export: bug fixes for exporting API-generated values

1) if a field had an error, it could be incorrectly marked
as an optional field.

2) sometimes, incomplete errors were incorrectly shown
as actual errors.

Change-Id: I67c1a59c09f27f30f508d9110484ae7f08b138fa
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9484
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/internal/core/export/export_test.go b/internal/core/export/export_test.go
index a47d92a..41d40eb 100644
--- a/internal/core/export/export_test.go
+++ b/internal/core/export/export_test.go
@@ -19,6 +19,7 @@
 
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/cuecontext"
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/parser"
@@ -32,6 +33,7 @@
 	"cuelang.org/go/internal/core/runtime"
 	"cuelang.org/go/internal/cuetest"
 	"cuelang.org/go/internal/cuetxtar"
+	"cuelang.org/go/internal/value"
 	"github.com/rogpeppe/go-internal/txtar"
 )
 
@@ -78,6 +80,7 @@
 	testCases := []struct {
 		in  func(ctx *adt.OpContext) (adt.Expr, error)
 		out string
+		p   *export.Profile
 	}{{
 		in: func(ctx *adt.OpContext) (adt.Expr, error) {
 			in := &C{
@@ -131,7 +134,28 @@
 
 			return n, nil
 		},
-		out: `<[l2// x: undefined field #Terminal] _|_>`,
+		// TODO: should probably print path.
+		out: `<[l2// undefined field #Terminal] _|_>`,
+		p:   export.Final,
+	}, {
+		in: func(ctx *adt.OpContext) (adt.Expr, error) {
+			c := cuecontext.New()
+			v := c.CompileString(`
+				#Provider: {
+					ID: string
+					notConcrete: bool
+					a: int
+					b: a + 1
+				}`)
+
+			spec := v.LookupPath(cue.ParsePath("#Provider"))
+			spec2 := spec.FillPath(cue.ParsePath("ID"), "12345")
+			root := v.FillPath(cue.ParsePath("providers.foo"), spec2)
+			_, n := value.ToInternal(root)
+
+			return n, nil
+		},
+		out: `{#Provider: {ID: string, notConcrete: bool, a: int, b: a+1}, providers: {foo: {ID: "12345", notConcrete: bool, a: int, b: a+1}}}`,
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
@@ -142,7 +166,13 @@
 			if err != nil {
 				t.Fatal("failed test case: ", err)
 			}
-			expr, err := export.Expr(ctx, "", v)
+
+			p := tc.p
+			if p == nil {
+				p = export.Simplified
+			}
+
+			expr, err := p.Expr(ctx, "", v)
 			if err != nil {
 				t.Fatal("failed export: ", err)
 			}
diff --git a/internal/core/export/expr.go b/internal/core/export/expr.go
index cdd5b28..7770954 100644
--- a/internal/core/export/expr.go
+++ b/internal/core/export/expr.go
@@ -275,6 +275,7 @@
 		if isComplexStruct(x) {
 			_, saved := e.pushFrame(nil)
 			e.embed = append(e.embed, e.adt(x, nil))
+			e.top().upCount-- // not necessary, but for proper form
 			e.popFrame(saved)
 			return
 		}
@@ -331,7 +332,13 @@
 				x = nil
 
 			case adt.Value:
-				e.values.AddConjunct(adt.MakeRootConjunct(env, y)) // GOBBLE TOP
+				if v.IsData() {
+					e.values.AddConjunct(adt.MakeRootConjunct(env, y))
+					break
+				}
+				for _, c := range v.Conjuncts {
+					e.values.AddConjunct(c)
+				}
 			}
 
 			// generated, only consider arcs.
@@ -377,6 +384,9 @@
 		return false
 	}
 	for _, c := range a {
+		if v, ok := c.Expr().(*adt.Vertex); ok && !v.IsData() && len(v.Conjuncts) > 0 {
+			return isOptional(v.Conjuncts)
+		}
 		switch f := c.Source().(type) {
 		case nil:
 			return false