Skip to content

Commit f2c38f8

Browse files
committed
internal/core/adt: propagate child errors
In V3, because closedness is computed out of band with the processing of an arc, it may be that an arc gets an error _after_ it has been processed. For this reasons, we propagate it in a separate loop after all other arcs have been processed. To avoid spurious errors, we now need to explicitly check for an arc error before calling reportFieldMismatch. Theoretically it is possible that there is still a spurious error. This only occurs, however, if the arc is already erroneous, so this is not a huge deal. Fixes #3576 Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: Idfec48db39be56155c3376b4284bd67a4e8bef20 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1206291 Reviewed-by: Daniel Martí <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent 2491cac commit f2c38f8

File tree

2 files changed

+27
-97
lines changed

2 files changed

+27
-97
lines changed

cue/testdata/disjunctions/errors.txtar

+14-86
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ issue3576: full: {
6666
optionsValue: options
6767
}
6868
}
69-
69+
7070
#Copy: {
7171
copy!: string
7272
options?: #Option | [#Option, ...]
@@ -78,7 +78,7 @@ issue3576: full: {
7878
#Option: {}
7979

8080
foo: #Run | #Copy
81-
foo: run: "make"
81+
foo: run: "make"
8282
}
8383
-- out/eval/stats --
8484
Leaks: 0
@@ -180,15 +180,9 @@ Result:
180180
}
181181
#B: (#struct){
182182
}
183-
foo: (struct){ |((#struct){
184-
a: (_|_){
185-
// [eval] issue3576.reduced.foo.a: field not allowed:
186-
// ./issue3576.cue:5:11
187-
// ./issue3576.cue:9:7
188-
}
189-
}, (#struct){
190-
a: (string){ "1" }
191-
}) }
183+
foo: (#struct){
184+
a: (string){ "1" }
185+
}
192186
}
193187
full: (struct){
194188
#Run: (#struct){
@@ -209,26 +203,14 @@ Result:
209203
}
210204
#Option: (#struct){
211205
}
212-
foo: (struct){ |((#struct){
213-
run: (string){ "make" }
214-
options?: ((list|struct)){ |((#struct){
215-
}, (list){
216-
0: (#struct){
217-
}
218-
}) }
219-
}, (#struct){
220-
run: (_|_){
221-
// [eval] issue3576.full.foo.run: field not allowed:
222-
// ./issue3576.cue:24:18
223-
// ./issue3576.cue:31:7
224-
}
225-
copy!: (string){ string }
226-
options?: ((list|struct)){ |((#struct){
227-
}, (list){
228-
0: (#struct){
229-
}
230-
}) }
231-
}) }
206+
foo: (#struct){
207+
run: (string){ "make" }
208+
options?: ((list|struct)){ |((#struct){
209+
}, (list){
210+
0: (#struct){
211+
}
212+
}) }
213+
}
232214
}
233215
}
234216
issue3581: (struct){
@@ -329,61 +311,7 @@ diff old new
329311
}
330312
issue3576: (struct){
331313
reduced: (struct){
332-
@@ -99,9 +87,15 @@
333-
}
334-
#B: (#struct){
335-
}
336-
- foo: (#struct){
337-
- a: (string){ "1" }
338-
- }
339-
+ foo: (struct){ |((#struct){
340-
+ a: (_|_){
341-
+ // [eval] issue3576.reduced.foo.a: field not allowed:
342-
+ // ./issue3576.cue:5:11
343-
+ // ./issue3576.cue:9:7
344-
+ }
345-
+ }, (#struct){
346-
+ a: (string){ "1" }
347-
+ }) }
348-
}
349-
full: (struct){
350-
#Run: (#struct){
351-
@@ -122,14 +116,26 @@
352-
}
353-
#Option: (#struct){
354-
}
355-
- foo: (#struct){
356-
- run: (string){ "make" }
357-
- options?: ((list|struct)){ |((#struct){
358-
- }, (list){
359-
- 0: (#struct){
360-
- }
361-
- }) }
362-
- }
363-
+ foo: (struct){ |((#struct){
364-
+ run: (string){ "make" }
365-
+ options?: ((list|struct)){ |((#struct){
366-
+ }, (list){
367-
+ 0: (#struct){
368-
+ }
369-
+ }) }
370-
+ }, (#struct){
371-
+ run: (_|_){
372-
+ // [eval] issue3576.full.foo.run: field not allowed:
373-
+ // ./issue3576.cue:24:18
374-
+ // ./issue3576.cue:31:7
375-
+ }
376-
+ copy!: (string){ string }
377-
+ options?: ((list|struct)){ |((#struct){
378-
+ }, (list){
379-
+ 0: (#struct){
380-
+ }
381-
+ }) }
382-
+ }) }
383-
}
384-
}
385-
issue3581: (struct){
386-
@@ -136,13 +142,11 @@
314+
@@ -136,13 +124,11 @@
387315
reduced: (struct){
388316
list: (_|_){
389317
// [incomplete] issue3581.reduced.list: 2 errors in empty disjunction:

internal/core/adt/unify.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -565,21 +565,11 @@ func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool {
565565
continue
566566
}
567567

568-
// Errors are allowed in let fields. Handle errors and failure to
569-
// complete accordingly.
570-
if !a.Label.IsLet() && a.ArcType <= ArcRequired {
571-
a := a.DerefValue()
572-
if err := a.Bottom(); err != nil {
573-
n.AddChildError(err)
574-
}
575-
success = true // other arcs are irrelevant
576-
}
577-
578568
// TODO: harmonize this error with "cannot combine"
579569
switch {
580570
case a.ArcType > ArcRequired, !a.Label.IsString():
581571
case n.kind&StructKind == 0:
582-
if !n.node.IsErr() {
572+
if !n.node.IsErr() && !a.IsErr() {
583573
n.reportFieldMismatch(pos(a.Value()), nil, a.Label, n.node.Value())
584574
}
585575
// case !wasVoid:
@@ -610,6 +600,18 @@ func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool {
610600
}
611601
n.node.Arcs = n.node.Arcs[:k]
612602

603+
for _, a := range n.node.Arcs {
604+
// Errors are allowed in let fields. Handle errors and failure to
605+
// complete accordingly.
606+
if !a.Label.IsLet() && a.ArcType <= ArcRequired {
607+
a := a.DerefValue()
608+
if err := a.Bottom(); err != nil {
609+
n.AddChildError(err)
610+
}
611+
success = true // other arcs are irrelevant
612+
}
613+
}
614+
613615
// TODO: perhaps this code can go once we have builtins for comparing to
614616
// bottom.
615617
for _, c := range n.postChecks {

0 commit comments

Comments
 (0)