cue: add fallback mode for unresolved disjunctions

In case of unresolved references, there is no possibility
to obey the original requirements so we switch off options
that can lead to cycles.

Closes #217

Change-Id: I6e1c49eef586175f2646e1dd5de817a9c94877d9
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5120
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/testdata/script/issue217.txt b/cmd/cue/cmd/testdata/script/issue217.txt
new file mode 100644
index 0000000..ae3322b
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/issue217.txt
@@ -0,0 +1,30 @@
+cue eval
+cmp stdout eval-stdout
+
+cue def
+cmp stdout def-stdout
+
+-- schema.cue --
+package tst
+
+x: {
+	a: A
+	b: A
+}
+
+A :: string | [A]
+
+-- def-stdout --
+package tst
+
+x: {
+    a: A
+    b: A
+}
+A :: string | [A]
+-- eval-stdout --
+x: {
+    a: A
+    b: A
+}
+A :: string | [A]
diff --git a/cue/export.go b/cue/export.go
index f4e7133..885a101 100644
--- a/cue/export.go
+++ b/cue/export.go
@@ -359,7 +359,7 @@
 		if v.kind()&structKind == 0 {
 			return p.expr(e)
 		}
-		if optional {
+		if optional || isDisjunction(e) {
 			// Break cycles: final and resolveReferences really should not be
 			// used with optional.
 			p.mode.resolveReferences = false
diff --git a/cue/export_test.go b/cue/export_test.go
index 47ebfbe..f1f8ad0 100644
--- a/cue/export_test.go
+++ b/cue/export_test.go
@@ -1029,6 +1029,27 @@
 				baz: "barParent2"
 			}
 		}`),
+	}, {
+		eval: true,
+		opts: []Option{Final(), Definitions(true)},
+		in: `
+		package tst
+
+		x: {
+			a: A
+			b: A
+		}
+		A :: string | [A]
+
+		`,
+		out: unindent(`
+		{
+			x: {
+				a: A
+				b: A
+			}
+			A :: string | [A]
+		}`),
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {