-- in.cue --
circularIf: {
	#list: {
		tail: #list | *null
		if tail != null {
		}
		@test(eq, {tail: null})
	}
}

circularFor: {
	#list: {
		tail: #list | *null
		for x in tail != null {
		}
		@test(err, code=eval,
			contains="cannot range over %s (found %s, want list or struct)",
			args=[tail != null, bool], pos=[2:12])
	}
}

// Print a bit more sensible error message than "empty disjunction" here.
// Issue #465
userError: {
	a: string | *_|_
	if a != "" {
	}
	@test(err, code=incomplete, contains="non-concrete value string", pos=[2:5, 1:5])
}

intField: {
	for i, _ in [1, 2] {
		(i): {
		}
	}
	@test(err, code=eval, contains="integer fields not supported", pos=[2:4])
}

// Issue #2403
conflictRangingOverSelf: {
	x: {
		name: string
		age:  int
	}

	x: {
		for k, _ in x {
			(k): k
		}
	}
	@test(err, code=eval, at=x.age,
		contains="conflicting values %s and %s (mismatched types %s and %s)",
		args=[int, "age", int, string],
		pos=[3:9, 6:5, 7:3, 8:9])
}
-- out/errors.txt --
[eval] circularFor.#list: cannot range over tail != null (found bool, want list or struct):
    ./in.cue:13:12
[incomplete] userError: non-concrete value string in operand to !=:
    ./in.cue:25:5
    ./in.cue:24:5
[eval] intField: integer fields not supported:
    ./in.cue:32:4
[eval] conflictRangingOverSelf.x.age: conflicting values int and "age" (mismatched types int and string):
    ./in.cue:42:9
    ./in.cue:45:5
    ./in.cue:46:3
    ./in.cue:47:9
-- out/todo.txt --
Missing error message.
circularIf.#list.tail: v2 shows a more specific disjunction type with the recursive #list;
v3 evaluates to the concrete null default.
intField: v2 shows integer index fields 0 and 1 in result; v3 does not.
conflictRangingOverSelf.x.age: v2 reports position ./in.cue:39:5 but v3 does not.
-- out/eval/stats --
Leaks:  3
Freed:  20
Reused: 11
Allocs: 12
Retain: 0

Unifications: 17
Conjuncts:    32
Disjuncts:    6

NumCloseIDs: 12
