cue: fix cycle issue

If evaluated in a certain order, cycles within
expressions were cached too early.

Fixes cuelang/cue#19.

Change-Id: I795f18d6767b3d474712fd550faa3a4d4994605a
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 18b5c6a..9700eba 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -443,6 +443,22 @@
 		`,
 		out: `<0>{a: 100, b: 200, c: _|_(cycle detected), s1: <1>{a: 1, b: 2, c: 3}, s2: <2>{a: 1, b: 2, c: 3}, s3: <3>{a: 1, b: 2, c: 3}}`,
 	}, {
+		desc: "resolved self-reference cycles: Issue 19",
+		in: `
+			// CUE knows how to resolve the following:
+			x: y + 100
+			y: x - 100
+			x: 200
+
+			z1: z2 + 1
+			z2: z3 + 2
+			z3: z1 - 3
+			z3: 8
+
+			// TODO: extensive tests with disjunctions.
+		`,
+		out: `<0>{x: 200, y: 100, z1: 11, z2: 10, z3: 8}`,
+	}, {
 		desc: "delayed constraint failure",
 		in: `
 			a: b - 100
diff --git a/cue/value.go b/cue/value.go
index 5c34b96..a986b10 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -628,7 +628,7 @@
 
 		v = x.applyTemplate(ctx, i, v)
 
-		if ctx.evalDepth > 0 && ctx.cycleErr {
+		if (ctx.evalDepth > 0 && ctx.cycleErr) || cycleError(v) != nil {
 			// Don't cache while we're in a evaluation cycle as it will cache
 			// partial results. Each field involved in the cycle will have to
 			// reevaluated the values from scratch. As the result will be
@@ -636,7 +636,8 @@
 			x.arcs[i].cache = nil
 			return v
 		}
-		// If there as a cycle error, we have by now evaluated full cycle and
+
+		// If there as a cycle error, we have by now evaluated a full cycle and
 		// it is safe to cache the result.
 		ctx.cycleErr = false