Skip to content

Commit

Permalink
internal/core/eval: handle disjunction failure more properly
Browse files Browse the repository at this point in the history
- a failed disjunction could be interpreted as
  a full error, rather than an incomplete error.

- vastly improved error messages

Fixes #589
Fixes #570
Fixes #516

Change-Id: Iab65b813feb2a49cebfeddee8a65d53b4c7b2978
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7721
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Nov 21, 2020
1 parent 187c734 commit 7980ec5
Show file tree
Hide file tree
Showing 16 changed files with 436 additions and 51 deletions.
4 changes: 4 additions & 0 deletions cmd/cue/cmd/testdata/script/eval_errs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ cmp stdout expect-stdout

-- expect-stdout --
-- expect-stderr --
bar: empty disjunction: 2 related errors:
bar.a: conflicting values "str" and int (mismatched types string and int):
./errs.cue:5:10
./errs.cue:6:16
bar.b: conflicting values 2 and string (mismatched types int and string):
./errs.cue:5:21
./errs.cue:6:26
Expand Down
14 changes: 13 additions & 1 deletion cue/testdata/benchmarks/dedupelem.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ foo: [{type: "float"}] & [...#Value]
foo: [{type: "float"}] & [...#Value]
-- out/eval --
Errors:
foo.0: empty disjunction: 2 related errors:
foo.0.type: conflicting values "int" and "float":
./in.cue:3:16
./in.cue:5:14
./in.cue:5:30
foo.0.type: conflicting values "string" and "float":
./in.cue:5:14
./in.cue:10:14
Expand All @@ -32,7 +37,14 @@ Result:
foo: (_|_){
// [eval]
0: (_|_){
// [eval]
// [eval] foo.0: empty disjunction: 2 related errors:
// foo.0.type: conflicting values "int" and "float":
// ./in.cue:3:16
// ./in.cue:5:14
// ./in.cue:5:30
// foo.0.type: conflicting values "string" and "float":
// ./in.cue:5:14
// ./in.cue:10:14
type: (_|_){
// [eval] foo.0.type: conflicting values "string" and "float":
// ./in.cue:5:14
Expand Down
11 changes: 8 additions & 3 deletions cue/testdata/cycle/issue429.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ er3: #nonEmptyRange & {

-- out/eval --
Errors:
er3.min: empty disjunction: 1 related errors:
es3.max: empty disjunction: 1 related errors:
es3.max: invalid value 5 (out of bound >10):
./in.cue:5:10
./in.cue:22:10
Expand Down Expand Up @@ -92,7 +94,8 @@ Result:
res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
min: (int){ 10 }
max: (_|_){
// [eval] es3.max: invalid value 5 (out of bound >10):
// [eval] es3.max: empty disjunction: 1 related errors:
// es3.max: invalid value 5 (out of bound >10):
// ./in.cue:5:10
// ./in.cue:22:10
}
Expand Down Expand Up @@ -120,12 +123,14 @@ Result:
er3: (_|_){
// [eval]
min: (_|_){
// [eval] er3.min: invalid value 5 (out of bound <5):
// [eval] er3.min: empty disjunction: 1 related errors:
// er3.min: invalid value 5 (out of bound <5):
// ./in.cue:29:10
// ./in.cue:44:10
}
max: (_|_){
// [eval] er3.min: invalid value 5 (out of bound <5):
// [eval] er3.min: empty disjunction: 1 related errors:
// er3.min: invalid value 5 (out of bound <5):
// ./in.cue:29:10
// ./in.cue:44:10
}
Expand Down
32 changes: 32 additions & 0 deletions cue/testdata/cycle/structural.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,25 @@ e3.b.c: structural cycle
e4.a.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:297:13
./in.cue:298:9
e4.a.0: empty disjunction: 4 related errors:
e4.a.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct):
./in.cue:298:9
./in.cue:298:10
e4.a.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:297:13
./in.cue:298:9
e4.a.0.0: empty disjunction: 2 related errors:
e4.b.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:300:9
./in.cue:301:13
e4.b.0: empty disjunction: 4 related errors:
e4.b.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct):
./in.cue:300:9
./in.cue:300:10
e4.b.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
./in.cue:300:9
./in.cue:301:13
e4.b.0.0: empty disjunction: 2 related errors:
p2.#T.a.b.link: structural cycle
p3.#U.#T.a.b.link: structural cycle
p5.#T.a.0.link: structural cycle
Expand Down Expand Up @@ -1185,6 +1201,14 @@ Result:
// [eval] e4.a.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:297:13
// ./in.cue:298:9
// e4.a.0: empty disjunction: 4 related errors:
// e4.a.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct):
// ./in.cue:298:9
// ./in.cue:298:10
// e4.a.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:297:13
// ./in.cue:298:9
// e4.a.0.0: empty disjunction: 2 related errors:
0: (struct){
c: (int){ 1 }
}
Expand All @@ -1196,6 +1220,14 @@ Result:
// [eval] e4.b.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:300:9
// ./in.cue:301:13
// e4.b.0: empty disjunction: 4 related errors:
// e4.b.0.0: conflicting values [{c:1}] and {c:1} (mismatched types list and struct):
// ./in.cue:300:9
// ./in.cue:300:10
// e4.b.0.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
// ./in.cue:300:9
// ./in.cue:301:13
// e4.b.0.0: empty disjunction: 2 related errors:
0: (struct){
c: (int){ 1 }
}
Expand Down
156 changes: 156 additions & 0 deletions cue/testdata/disjunctions/errors.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
-- in.cue --
issue570: {
results: #DecodeOutput
results: result: "hello"

#Output: {
result: _
} | {
error: string
}

#DecodeOutput: #Output & {
result?: [... string]
...
}
}

issue516: {
#Def: {
match: metrics: string: {}
} | {}

x: #Def
x: match: metrics: "foo": {}
}

-- out/eval --
Errors:
issue516.x: empty disjunction: 2 related errors:
issue516.x: field `match` not allowed:
./in.cue:20:9
./in.cue:22:8
./in.cue:23:8
issue516.x.match.metrics: field `foo` not allowed:
./in.cue:19:25
./in.cue:22:8
./in.cue:23:24
issue570.results: empty disjunction: 2 related errors:
issue570.results: field `result` not allowed:
./in.cue:2:14
./in.cue:3:14
./in.cue:7:9
./in.cue:11:20
./in.cue:12:9
issue570.results.result: conflicting values "hello" and [...string] (mismatched types string and list):
./in.cue:2:14
./in.cue:3:22
./in.cue:12:18

Result:
(_|_){
// [eval]
issue570: (_|_){
// [eval]
results: (_|_){
// [eval] issue570.results: empty disjunction: 2 related errors:
// issue570.results: field `result` not allowed:
// ./in.cue:2:14
// ./in.cue:3:14
// ./in.cue:7:9
// ./in.cue:11:20
// ./in.cue:12:9
// issue570.results.result: conflicting values "hello" and [...string] (mismatched types string and list):
// ./in.cue:2:14
// ./in.cue:3:22
// ./in.cue:12:18
result: (_|_){
// [eval] issue570.results: field `result` not allowed:
// ./in.cue:2:14
// ./in.cue:3:14
// ./in.cue:7:9
// ./in.cue:11:20
// ./in.cue:12:9
}
error: (string){ string }
}
#Output: (struct){ |((#struct){
result: (_){ _ }
}, (#struct){
error: (string){ string }
}) }
#DecodeOutput: (struct){ |((#struct){
result: (list){
}
}, (#struct){
error: (string){ string }
}) }
}
issue516: (_|_){
// [eval]
#Def: (struct){ |((#struct){
match: (#struct){
metrics: (#struct){
string: (#struct){
}
}
}
}, (#struct){
}) }
x: (_|_){
// [eval] issue516.x: empty disjunction: 2 related errors:
// issue516.x: field `match` not allowed:
// ./in.cue:20:9
// ./in.cue:22:8
// ./in.cue:23:8
// issue516.x.match.metrics: field `foo` not allowed:
// ./in.cue:19:25
// ./in.cue:22:8
// ./in.cue:23:24
match: (_|_){
// [eval] issue516.x: field `match` not allowed:
// ./in.cue:20:9
// ./in.cue:22:8
// ./in.cue:23:8
}
}
}
}
-- out/compile --
--- in.cue
{
issue570: {
results: 〈0;#DecodeOutput〉
results: {
result: "hello"
}
#Output: ({
result: _
}|{
error: string
})
#DecodeOutput: (〈0;#Output〉 & {
result?: [
...string,
]
...
})
}
issue516: {
#Def: ({
match: {
metrics: {
string: {}
}
}
}|{})
x: 〈0;#Def〉
x: {
match: {
metrics: {
foo: {}
}
}
}
}
}
19 changes: 16 additions & 3 deletions cue/testdata/eval/closed_disjunction.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ b: #A & {
}
-- out/eval --
Errors:
b: empty disjunction: 2 related errors:
b: field `c` not allowed:
./in.cue:1:5
./in.cue:3:5
./in.cue:3:35
./in.cue:3:6
./in.cue:11:4
./in.cue:12:5
b: field `d` not allowed:
./in.cue:1:5
./in.cue:3:5
./in.cue:3:35
./in.cue:3:11
./in.cue:11:4
./in.cue:13:5

Expand All @@ -38,7 +39,19 @@ Result:
c: (int){ 3 }
}
b: (_|_){
// [eval]
// [eval] b: empty disjunction: 2 related errors:
// b: field `c` not allowed:
// ./in.cue:1:5
// ./in.cue:3:5
// ./in.cue:3:6
// ./in.cue:11:4
// ./in.cue:12:5
// b: field `d` not allowed:
// ./in.cue:1:5
// ./in.cue:3:5
// ./in.cue:3:11
// ./in.cue:11:4
// ./in.cue:13:5
c: (_|_){
// [eval] b: field `c` not allowed:
// ./in.cue:1:5
Expand Down
12 changes: 11 additions & 1 deletion cue/testdata/eval/disjunctions.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ d100: {

-- out/eval --
Errors:
f: empty disjunction: 2 related errors:
f.name: conflicting values "int" and "str":
./in.cue:5:8
./in.cue:15:16
f.val: conflicting values 3 and string (mismatched types int and string):
./in.cue:9:7
./in.cue:15:28
Expand Down Expand Up @@ -90,7 +94,13 @@ Result:
name: (string){ "str" }
}
f: (_|_){
// [eval]
// [eval] f: empty disjunction: 2 related errors:
// f.name: conflicting values "int" and "str":
// ./in.cue:5:8
// ./in.cue:15:16
// f.val: conflicting values 3 and string (mismatched types int and string):
// ./in.cue:9:7
// ./in.cue:15:28
name: (string){ "str" }
val: (_|_){
// [eval] f.val: conflicting values 3 and string (mismatched types int and string):
Expand Down
12 changes: 11 additions & 1 deletion cue/testdata/fulleval/024_Issue_#23.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ y: _|_ // ; empty disjunction: conflicting values 2 and 3
}
-- out/eval --
Errors:
y: empty disjunction: 2 related errors:
y.a: conflicting values 1 and 3:
./in.cue:1:12
./in.cue:2:12
y.a: conflicting values 2 and 3:
./in.cue:1:21
./in.cue:2:12
Expand All @@ -41,7 +45,13 @@ Result:
a: (int){ 2 }
}) }
y: (_|_){
// [eval]
// [eval] y: empty disjunction: 2 related errors:
// y.a: conflicting values 1 and 3:
// ./in.cue:1:12
// ./in.cue:2:12
// y.a: conflicting values 2 and 3:
// ./in.cue:1:21
// ./in.cue:2:12
a: (_|_){
// [eval] y.a: conflicting values 2 and 3:
// ./in.cue:1:21
Expand Down

0 comments on commit 7980ec5

Please sign in to comment.