Skip to content

Commit cbcb701

Browse files
committed
internal/core/adt: error message improvements
- add position to cycle errors - stop resolving selectors for failed nodes Issue #602 Change-Id: I813abe8db9d63c1fdb0913370bb942b8657b5f8d Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7885 Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent f62bfed commit cbcb701

11 files changed

+166
-22
lines changed

cue/testdata/basicrewrite/018_self-reference_cycles.txtar

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ c: [c[1], c[0]]
2626
-- out/eval --
2727
(struct){
2828
a: (_|_){
29-
// [cycle] cycle error
29+
// [cycle] cycle error:
30+
// ./in.cue:2:4
3031
}
3132
b: (_|_){
32-
// [cycle] cycle error
33+
// [cycle] cycle error:
34+
// ./in.cue:2:4
3335
}
3436
c: (#list){
3537
0: (_){ _ }

cue/testdata/cycle/023_reentrance.txtar

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ Result:
8989
fibRec: (struct){
9090
nn: (int){ int }
9191
out: (_|_){
92-
// [incomplete] fibRec.out: undefined field out:
93-
// ./in.cue:3:40
94-
// non-concrete value int in operand to >=:
92+
// [incomplete] non-concrete value int in operand to >=:
9593
// ./in.cue:7:5
9694
// non-concrete value int in operand to <:
9795
// ./in.cue:10:5

cue/testdata/cycle/051_resolved_self-reference_cycles_with_disjunction.txtar

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ Result:
177177
}
178178
xb3: (int){ |((int){ 6 }, (int){ 9 }) }
179179
xb4: (_|_){
180-
// [cycle] cycle error
180+
// [cycle] cycle error:
181+
// ./in.cue:20:6
181182
}
182183
xc1: (int){ |((int){ 8 }, (int){ 9 }) }
183184
xc2: (int){ 8 }
@@ -219,7 +220,8 @@ Result:
219220
}
220221
xf3: (int){ |((int){ 6 }, (int){ 9 }) }
221222
xf4: (_|_){
222-
// [cycle] cycle error
223+
// [cycle] cycle error:
224+
// ./in.cue:54:6
223225
}
224226
z1: (int){ |((int){ 11 }, (int){ 13 }) }
225227
z2: (int){ 10 }

cue/testdata/cycle/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ Result:
144144
xb2: (int){ 8 }
145145
xb3: (int){ 6 }
146146
xb4: (_|_){
147-
// [cycle] cycle error
147+
// [cycle] cycle error:
148+
// ./in.cue:14:6
148149
}
149150
xc1: (int){ |(*(int){ 8 }, (int){ 9 }) }
150151
xc2: (int){ 8 }

cue/testdata/eval/incomplete.txtar

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,27 @@ Result:
4242
// ./in.cue:3:5
4343
}
4444
e5: (_|_){
45-
// [cycle] cycle error
45+
// [cycle] cycle error:
46+
// ./in.cue:8:6
4647
}
4748
E: (struct){
4849
a: (_|_){
49-
// [cycle] cycle error
50+
// [cycle] cycle error:
51+
// ./in.cue:12:6
52+
// cycle error:
53+
// ./in.cue:13:6
5054
}
5155
b: (_|_){
52-
// [cycle] cycle error
56+
// [cycle] cycle error:
57+
// ./in.cue:12:6
58+
// cycle error:
59+
// ./in.cue:13:6
5360
}
5461
c: (_|_){
55-
// [cycle] cycle error
62+
// [cycle] cycle error:
63+
// ./in.cue:12:6
64+
// cycle error:
65+
// ./in.cue:13:6
5666
}
5767
}
5868
permanentlyIncompleteOperands: (_|_){

cue/testdata/fulleval/026_dont_convert_incomplete_errors_to_non-incomplete.txtar

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ s3: strings.ContainsAny(str, "dd")
4848
(struct){
4949
n1: (struct){
5050
min: (_|_){
51-
// [cycle] cycle error
51+
// [cycle] cycle error:
52+
// ./in.cue:3:23
5253
}
5354
max: (_|_){
54-
// [cycle] cycle error
55+
// [cycle] cycle error:
56+
// ./in.cue:3:23
5557
}
5658
}
5759
n2: (_|_){

cue/testdata/fulleval/046_non-structural_direct_cycles.txtar

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ c2: _|_ // conflicting values {bar: 1} and 1 (mismatched types struct and int)
2929
-- out/eval --
3030
(struct){
3131
c1: (_|_){
32-
// [incomplete] c1: undefined field bar:
33-
// ./in.cue:1:24
32+
// [cycle] cycle error:
33+
// ./in.cue:1:21
3434
bar: (struct){
3535
baz: (int){ 2 }
3636
}
3737
}
3838
c2: (_|_){
39-
// [incomplete] c2: undefined field bar:
40-
// ./in.cue:2:24
39+
// [cycle] cycle error:
40+
// ./in.cue:2:21
4141
bar: (int){ 1 }
4242
}
4343
}

cue/testdata/references/errors.txtar

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
-- references.cue --
2+
3+
missingField: {
4+
a: {}
5+
r: a.b
6+
}
7+
8+
missingFieldClosed: {
9+
#a: {}
10+
r: #a.b
11+
}
12+
13+
missingFieldNested: {
14+
a: {}
15+
// Must refer to `b` in error
16+
r: a.b.c
17+
}
18+
19+
missingFieldNestedClosed: {
20+
#a: {}
21+
// Must refer to `d` in error
22+
r: #a.d.c
23+
}
24+
25+
missingFieldNestedInInterpolation: {
26+
a: {}
27+
// Must refer to `b` in error
28+
r1: "\(a.b.c)"
29+
// Must refer to `d` in error: in case only one error is shown for a
30+
// a location, ensure it doesn't alphabetically sort and pick `c` instead.
31+
r2: "\(a.d.c)"
32+
}
33+
-- out/eval --
34+
Errors:
35+
missingFieldClosed.r: undefined field b:
36+
./references.cue:9:11
37+
missingFieldNestedClosed.r: undefined field d:
38+
./references.cue:21:11
39+
40+
Result:
41+
(_|_){
42+
// [eval]
43+
missingField: (struct){
44+
a: (struct){
45+
}
46+
r: (_|_){
47+
// [incomplete] missingField.r: undefined field b:
48+
// ./references.cue:4:10
49+
}
50+
}
51+
missingFieldClosed: (_|_){
52+
// [eval]
53+
#a: (#struct){
54+
}
55+
r: (_|_){
56+
// [eval] missingFieldClosed.r: undefined field b:
57+
// ./references.cue:9:11
58+
}
59+
}
60+
missingFieldNested: (struct){
61+
a: (struct){
62+
}
63+
r: (_|_){
64+
// [incomplete] missingFieldNested.r: undefined field b:
65+
// ./references.cue:15:10
66+
}
67+
}
68+
missingFieldNestedClosed: (_|_){
69+
// [eval]
70+
#a: (#struct){
71+
}
72+
r: (_|_){
73+
// [eval] missingFieldNestedClosed.r: undefined field d:
74+
// ./references.cue:21:11
75+
}
76+
}
77+
missingFieldNestedInInterpolation: (struct){
78+
a: (struct){
79+
}
80+
r1: (_|_){
81+
// [incomplete] missingFieldNestedInInterpolation.r1: invalid interpolation: undefined field b:
82+
// ./references.cue:27:9
83+
}
84+
r2: (_|_){
85+
// [incomplete] missingFieldNestedInInterpolation.r2: invalid interpolation: undefined field d:
86+
// ./references.cue:30:9
87+
}
88+
}
89+
}
90+
-- out/compile --
91+
--- references.cue
92+
{
93+
missingField: {
94+
a: {}
95+
r: 〈0;a〉.b
96+
}
97+
missingFieldClosed: {
98+
#a: {}
99+
r: 〈0;#a〉.b
100+
}
101+
missingFieldNested: {
102+
a: {}
103+
r: 〈0;a〉.b.c
104+
}
105+
missingFieldNestedClosed: {
106+
#a: {}
107+
r: 〈0;#a〉.d.c
108+
}
109+
missingFieldNestedInInterpolation: {
110+
a: {}
111+
r1: "\(〈0;a〉.b.c)"
112+
r2: "\(〈0;a〉.d.c)"
113+
}
114+
}

internal/core/adt/context.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func (c *OpContext) addErrf(code ErrorCode, pos token.Pos, msg string, args ...i
269269
}
270270

271271
func (c *OpContext) addErr(code ErrorCode, err errors.Error) {
272-
c.errs = CombineErrors(c.src, c.errs, &Bottom{Code: code, Err: err})
272+
c.AddBottom(&Bottom{Code: code, Err: err})
273273
}
274274

275275
// AddBottom records an error in OpContext.
@@ -280,7 +280,7 @@ func (c *OpContext) AddBottom(b *Bottom) {
280280
// AddErr records an error in OpContext. It returns errors collected so far.
281281
func (c *OpContext) AddErr(err errors.Error) *Bottom {
282282
if err != nil {
283-
c.errs = CombineErrors(c.src, c.errs, &Bottom{Err: err})
283+
c.AddBottom(&Bottom{Err: err})
284284
}
285285
return c.errs
286286
}
@@ -529,6 +529,15 @@ func (c *OpContext) evalState(v Expr, state VertexStatus) (result Value) {
529529

530530
defer func() {
531531
c.errs = CombineErrors(c.src, c.errs, err)
532+
// TODO: remove this when we handle errors more principally.
533+
if b, ok := result.(*Bottom); ok && c.src != nil &&
534+
b.Code == CycleError &&
535+
b.Err.Position() == token.NoPos &&
536+
len(b.Err.InputPositions()) == 0 {
537+
bb := *b
538+
bb.Err = errors.Wrapf(b.Err, c.src.Pos(), "")
539+
result = &bb
540+
}
532541
c.errs = CombineErrors(c.src, c.errs, result)
533542
if c.errs != nil {
534543
result = c.errs

internal/core/adt/expr.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ func (x *SelectorExpr) Source() ast.Node {
586586

587587
func (x *SelectorExpr) resolve(c *OpContext) *Vertex {
588588
n := c.node(x, x.X, x.Sel.IsRegular())
589+
if n == emptyNode {
590+
return n
591+
}
589592
return c.lookup(n, x.Src.Sel.Pos(), x.Sel)
590593
}
591594

@@ -610,6 +613,9 @@ func (x *IndexExpr) resolve(ctx *OpContext) *Vertex {
610613
// TODO: support byte index.
611614
n := ctx.node(x, x.X, true)
612615
i := ctx.value(x.Index)
616+
if n == emptyNode {
617+
return n
618+
}
613619
f := ctx.Label(x.Index, i)
614620
return ctx.lookup(n, x.Src.Index.Pos(), f)
615621
}

0 commit comments

Comments
 (0)