Skip to content

Commit 665f697

Browse files
committed
internal/core/adt: fix error gobbling of internal nodes
In some cases, errors in erroneous nodes would not be carried over. This is because CUE assumes that if a reference requires a scalar, it is okay to proceed when a scalar is found as the value can only be changed to an error, which is then assumed to be reported at the site where the error occurred. This is not the case for "non-addressable" nodes, though, as they will not be output. In such cases, the error is lost. We now detect such cases during evaluation and require all task nodes to be completed, thereby forcing the error if there is any. This can only be done for non-addressable nodes to avoid getting into spurious cycles. Fixes #3977 Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: Ia51f4586ce9b0b142ab11d73c67a480039b276fb Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1217228 TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Daniel Martí <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent 996e8b0 commit 665f697

File tree

2 files changed

+110
-12
lines changed

2 files changed

+110
-12
lines changed

cue/testdata/eval/nonrooted.txtar

Lines changed: 106 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,21 @@ Conjuncts: 87
5858
Disjuncts: 68
5959
-- out/evalalpha --
6060
Errors:
61+
issue3977.inlineLet.p.x: conflicting values 1 and 2:
62+
./in.cue:38:14
63+
./in.cue:43:6
64+
x: conflicting values 1 and 2:
65+
./in.cue:2:14
66+
./in.cue:8:18
6167
x: conflicting values 2 and 1:
6268
./in.cue:20:14
6369
./in.cue:26:19
6470
x: conflicting values 4 and 1:
6571
./in.cue:20:14
6672
./in.cue:26:23
73+
x: invalid interpolation: 3 errors in empty disjunction::
74+
./in.cue:14:8
75+
./in.cue:14:17
6776
x: 2 errors in empty disjunction::
6877
./in.cue:23:8
6978

@@ -72,15 +81,21 @@ Result:
7281
// [eval]
7382
issue3977: (_|_){
7483
// [eval]
75-
inlineExpr: (struct){
84+
inlineExpr: (_|_){
85+
// [eval]
7686
#NetworkID: (int){ 1 }
7787
#fn: (#struct){
7888
x: (int){ 1 }
7989
out: (int){ 2 }
8090
}
81-
err: (int){ 3 }
91+
err: (_|_){
92+
// [eval] x: conflicting values 1 and 2:
93+
// ./in.cue:2:14
94+
// ./in.cue:8:18
95+
}
8296
}
83-
inlineDisj1: (struct){
97+
inlineDisj1: (_|_){
98+
// [eval]
8499
#NetworkID: (string){ |((string){ "2" }, (string){ "3" }, (string){ "4" }) }
85100
#fn: (#struct){
86101
x: (string){ |((string){ "2" }, (string){ "3" }, (string){ "4" }) }
@@ -89,7 +104,11 @@ Result:
89104
// ./in.cue:14:8
90105
}
91106
}
92-
err: (string){ "value=invalid" }
107+
err: (_|_){
108+
// [eval] x: invalid interpolation: 3 errors in empty disjunction::
109+
// ./in.cue:14:8
110+
// ./in.cue:14:17
111+
}
93112
}
94113
inlineDisj2: (_|_){
95114
// [eval]
@@ -117,7 +136,8 @@ Result:
117136
}
118137
err: (int){ 11 }
119138
}
120-
inlineLet: (struct){
139+
inlineLet: (_|_){
140+
// [eval]
121141
#NetworkID: (int){ 1 }
122142
let p#1 = (_|_){
123143
// [eval]
@@ -132,16 +152,26 @@ Result:
132152
// ./in.cue:43:6
133153
}
134154
}
135-
err: (int){ 12 }
155+
err: (_|_){
156+
// [eval] issue3977.inlineLet.p.x: conflicting values 1 and 2:
157+
// ./in.cue:38:14
158+
// ./in.cue:43:6
159+
}
136160
}
137161
}
138162
}
139163
-- diff/-out/evalalpha<==>+out/eval --
140164
diff old new
141165
--- old
142166
+++ new
143-
@@ -1,13 +1,9 @@
167+
@@ -1,14 +1,19 @@
144168
Errors:
169+
+issue3977.inlineLet.p.x: conflicting values 1 and 2:
170+
+ ./in.cue:38:14
171+
+ ./in.cue:43:6
172+
+x: conflicting values 1 and 2:
173+
+ ./in.cue:2:14
174+
+ ./in.cue:8:18
145175
x: conflicting values 2 and 1:
146176
./in.cue:20:14
147177
- ./in.cue:22:8
@@ -152,9 +182,52 @@ diff old new
152182
- ./in.cue:22:8
153183
- ./in.cue:26:8
154184
./in.cue:26:23
185+
+x: invalid interpolation: 3 errors in empty disjunction::
186+
+ ./in.cue:14:8
187+
+ ./in.cue:14:17
155188
x: 2 errors in empty disjunction::
156189
./in.cue:23:8
157-
@@ -46,13 +42,9 @@
190+
191+
@@ -17,15 +22,21 @@
192+
// [eval]
193+
issue3977: (_|_){
194+
// [eval]
195+
- inlineExpr: (struct){
196+
+ inlineExpr: (_|_){
197+
+ // [eval]
198+
#NetworkID: (int){ 1 }
199+
#fn: (#struct){
200+
x: (int){ 1 }
201+
out: (int){ 2 }
202+
}
203+
- err: (int){ 3 }
204+
- }
205+
- inlineDisj1: (struct){
206+
+ err: (_|_){
207+
+ // [eval] x: conflicting values 1 and 2:
208+
+ // ./in.cue:2:14
209+
+ // ./in.cue:8:18
210+
+ }
211+
+ }
212+
+ inlineDisj1: (_|_){
213+
+ // [eval]
214+
#NetworkID: (string){ |((string){ "2" }, (string){ "3" }, (string){ "4" }) }
215+
#fn: (#struct){
216+
x: (string){ |((string){ "2" }, (string){ "3" }, (string){ "4" }) }
217+
@@ -34,7 +45,11 @@
218+
// ./in.cue:14:8
219+
}
220+
}
221+
- err: (string){ "value=invalid" }
222+
+ err: (_|_){
223+
+ // [eval] x: invalid interpolation: 3 errors in empty disjunction::
224+
+ // ./in.cue:14:8
225+
+ // ./in.cue:14:17
226+
+ }
227+
}
228+
inlineDisj2: (_|_){
229+
// [eval]
230+
@@ -46,13 +61,9 @@
158231
err: (_|_){
159232
// [eval] x: conflicting values 2 and 1:
160233
// ./in.cue:20:14
@@ -168,7 +241,14 @@ diff old new
168241
// ./in.cue:26:23
169242
// x: 2 errors in empty disjunction::
170243
// ./in.cue:23:8
171-
@@ -71,15 +63,13 @@
244+
@@ -66,24 +77,27 @@
245+
}
246+
err: (int){ 11 }
247+
}
248+
- inlineLet: (struct){
249+
+ inlineLet: (_|_){
250+
+ // [eval]
251+
#NetworkID: (int){ 1 }
172252
let p#1 = (_|_){
173253
// [eval]
174254
x: (_|_){
@@ -181,16 +261,30 @@ diff old new
181261
- // [eval] issue3977.inlineLet.p.x: conflicting values 2 and 1:
182262
- // ./in.cue:38:14
183263
- // ./in.cue:40:8
264+
- // ./in.cue:43:6
265+
- }
266+
- }
267+
- err: (int){ 12 }
184268
+ // [eval] issue3977.inlineLet.p.x: conflicting values 1 and 2:
185269
+ // ./in.cue:38:14
186270
+ // ./in.cue:43:6
187271
+ }
188272
+ out: (_|_){
189273
+ // [eval] issue3977.inlineLet.p.x: conflicting values 1 and 2:
190274
+ // ./in.cue:38:14
191-
// ./in.cue:43:6
192-
}
193-
}
275+
+ // ./in.cue:43:6
276+
+ }
277+
+ }
278+
+ err: (_|_){
279+
+ // [eval] issue3977.inlineLet.p.x: conflicting values 1 and 2:
280+
+ // ./in.cue:38:14
281+
+ // ./in.cue:43:6
282+
+ }
283+
}
284+
}
285+
}
286+
-- diff/explanation --
287+
evalv3 correctly fails on all places marked with "err"
194288
-- out/eval --
195289
Errors:
196290
x: conflicting values 2 and 1:

internal/core/adt/context.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,10 @@ func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci C
706706
if arc == nil {
707707
return nil, c.ci
708708
}
709+
if arc.Internal() && c.isDevVersion() {
710+
mode := state.conditions()
711+
state = final(partial, mode|allTasksCompleted)
712+
}
709713
orig := arc
710714
// TODO(deref): what is the right level of dereferencing here?
711715
// DerefValue seems to work too.

0 commit comments

Comments
 (0)