-- in.cue --
import "struct"

minFields1: {
	[string]: struct.MinFields(1)

	incomplete1: {}
	optIncomplete: {a?: string}

	fail1: close({})
	optCloseIncomplete: close({a?: 1})
	failHidden1: close({_a: 1})

	ok4: {_a: 1, a: 1}
	ok1: {a: 1}
	ok2: close({a: 1})
	ok3: {a?: 1, a: 1}
	ok5: {#a: int, a: #a & 1}
}

minFields2: {
	[string]: struct.MinFields(2)

	incomplete1: close({a?: string, b: 1})
	incomplete2: close({a?: string, b?: int})
	incomplete3: close({a?: string, b?: int, c: 1})
	incomplete4: close({a?: string, b?: int, c?: int})

	fail: close({a?: string})
}

maxFields: {
	[string]: struct.MaxFields(1)

	ok1: {}
	ok2: {a: 1}
	ok3: close({a: 1})
	ok4: {a?: 1, b?: 2}
	ok5: {a: 1, _b: 2}
	ok6: {a: 1, #b: int}

	fail1: {a: 1, b: 2}
}

-- out/structs-v3 --
Errors:
minFields1.fail1: invalid value {} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1):
    ./in.cue:4:12
    ./in.cue:4:29
    ./in.cue:9:9
minFields1.failHidden1: invalid value {_a:1} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1):
    ./in.cue:4:12
    ./in.cue:4:29
    ./in.cue:11:15
minFields2.fail: invalid value {a?:string} (does not satisfy struct.MinFields(2)): len(fields) < MinFields(2) (0 < 2):
    ./in.cue:21:12
    ./in.cue:21:29
    ./in.cue:28:8
maxFields.fail1: invalid value {a:1,b:2} (does not satisfy struct.MaxFields(1)): len(fields) > MaxFields(1) (2 > 1):
    ./in.cue:32:12
    ./in.cue:32:29
    ./in.cue:41:9

Result:
import "struct"

minFields1: {
	incomplete1: struct.MinFields(1) & {}
	optIncomplete: struct.MinFields(1) & {
		a?: string
	}
	fail1: _|_ // minFields1.fail1: invalid value {} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1)
	optCloseIncomplete: struct.MinFields(1) & close({
		a?: 1
	})
	failHidden1: _|_ // minFields1.failHidden1: invalid value {_a:1} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1)
	ok4: {
		a: 1
	}
	ok1: {
		a: 1
	}
	ok2: {
		a: 1
	}
	ok3: {
		a: 1
	}
	ok5: {
		#a: int
		a:  1
	}
}
minFields2: {
	incomplete1: struct.MinFields(2) & close({
		a?: string
		b:  1
	})
	incomplete2: struct.MinFields(2) & close({
		a?: string
		b?: int
	})
	incomplete3: struct.MinFields(2) & close({
		a?: string
		b?: int
		c:  1
	})
	incomplete4: struct.MinFields(2) & close({
		a?: string
		b?: int
		c?: int
	})
	fail: _|_ // minFields2.fail: invalid value {a?:string} (does not satisfy struct.MinFields(2)): len(fields) < MinFields(2) (0 < 2)
}
maxFields: {
	ok1: {}
	ok2: {
		a: 1
	}
	ok3: {
		a: 1
	}
	ok4: {
		a?: 1
		b?: 2
	}
	ok5: {
		a: 1
	}
	ok6: {
		a:  1
		#b: int
	}
	fail1: _|_ // maxFields.fail1: invalid value {a:1,b:2} (does not satisfy struct.MaxFields(1)): len(fields) > MaxFields(1) (2 > 1)
}
-- diff/-out/structs-v3<==>+out/structs --
diff old new
--- old
+++ new
@@ -7,6 +7,10 @@
     ./in.cue:4:12
     ./in.cue:4:29
     ./in.cue:11:15
+minFields2.fail: invalid value {a?:string} (does not satisfy struct.MinFields(2)): len(fields) < MinFields(2) (0 < 2):
+    ./in.cue:21:12
+    ./in.cue:21:29
+    ./in.cue:28:8
 maxFields.fail1: invalid value {a:1,b:2} (does not satisfy struct.MaxFields(1)): len(fields) > MaxFields(1) (2 > 1):
     ./in.cue:32:12
     ./in.cue:32:29
@@ -61,9 +65,7 @@
 		b?: int
 		c?: int
 	})
-	fail: struct.MinFields(2) & close({
-		a?: string
-	})
+	fail: _|_ // minFields2.fail: invalid value {a?:string} (does not satisfy struct.MinFields(2)): len(fields) < MinFields(2) (0 < 2)
 }
 maxFields: {
 	ok1: {}
-- diff/todo/p2 --
Missing error positions.
-- diff/explanation --
minFields1.fail1: the new evaluator fails as expected. It is more precise than
the old evaluator.
-- out/structs --
Errors:
minFields1.fail1: invalid value {} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1):
    ./in.cue:4:12
    ./in.cue:4:29
    ./in.cue:9:9
minFields1.failHidden1: invalid value {_a:1} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1):
    ./in.cue:4:12
    ./in.cue:4:29
    ./in.cue:11:15
maxFields.fail1: invalid value {a:1,b:2} (does not satisfy struct.MaxFields(1)): len(fields) > MaxFields(1) (2 > 1):
    ./in.cue:32:12
    ./in.cue:32:29
    ./in.cue:41:9

Result:
import "struct"

minFields1: {
	incomplete1: struct.MinFields(1) & {}
	optIncomplete: struct.MinFields(1) & {
		a?: string
	}
	fail1: _|_ // minFields1.fail1: invalid value {} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1)
	optCloseIncomplete: struct.MinFields(1) & close({
		a?: 1
	})
	failHidden1: _|_ // minFields1.failHidden1: invalid value {_a:1} (does not satisfy struct.MinFields(1)): len(fields) < MinFields(1) (0 < 1)
	ok4: {
		a: 1
	}
	ok1: {
		a: 1
	}
	ok2: {
		a: 1
	}
	ok3: {
		a: 1
	}
	ok5: {
		#a: int
		a:  1
	}
}
minFields2: {
	incomplete1: struct.MinFields(2) & close({
		a?: string
		b:  1
	})
	incomplete2: struct.MinFields(2) & close({
		a?: string
		b?: int
	})
	incomplete3: struct.MinFields(2) & close({
		a?: string
		b?: int
		c:  1
	})
	incomplete4: struct.MinFields(2) & close({
		a?: string
		b?: int
		c?: int
	})
	fail: struct.MinFields(2) & close({
		a?: string
	})
}
maxFields: {
	ok1: {}
	ok2: {
		a: 1
	}
	ok3: {
		a: 1
	}
	ok4: {
		a?: 1
		b?: 2
	}
	ok5: {
		a: 1
	}
	ok6: {
		a:  1
		#b: int
	}
	fail1: _|_ // maxFields.fail1: invalid value {a:1,b:2} (does not satisfy struct.MaxFields(1)): len(fields) > MaxFields(1) (2 > 1)
}
