Skip to content

Commit 148f67a

Browse files
committed
internal/core: fix incorrect error handling
1: don't double-wrap errors in BinOp. This could happen when a value is passed as a Vertex in API usage. 2: subsumption incorrectly used And op for BinOp. Together these Fixes #461 This also improves reporting of structural errors, although this is not complete and not the goal of this CL. Change-Id: Id021a0eb4fa5628f56167d2fccea7d99dbddf390 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7065 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent bc101b3 commit 148f67a

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cue cmd writefile
2+
3+
-- cue.mod/module.cue --
4+
module: "mod.com"
5+
-- expect-hello --
6+
Hello, world!
7+
-- x_tool.cue --
8+
package x
9+
10+
import (
11+
"strings"
12+
"tool/exec"
13+
"tool/file"
14+
)
15+
16+
command: writefile: {
17+
echo: exec.Run & {
18+
cmd: "echo hello.txt"
19+
stdout: string
20+
}
21+
22+
write: file.Create & {
23+
filename: strings.TrimSpace(echo.stdout)
24+
contents: "Hello, world!"
25+
}
26+
}

cue/testdata/cycle/structural.txtar

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ d2: {
8484
}
8585

8686
d3: {
87-
// TODO(errors): position reporting in structural cycle.
87+
// TODO(errors): correct position reporting in structural cycle.
8888
config: {
8989
a: b: c: indirect
9090
indirect: [a.b, null][i]
@@ -253,6 +253,8 @@ d2.a.b.c.d.t: structural cycle:
253253
./in.cue:79:8
254254
d2.r: structural cycle:
255255
./in.cue:79:8
256+
0: structural cycle:
257+
./in.cue:89:19
256258

257259
Result:
258260
(_|_){
@@ -507,12 +509,14 @@ Result:
507509
b: (_|_){
508510
// [structural cycle]
509511
c: (_|_){
510-
// [structural cycle]
512+
// [structural cycle] 0: structural cycle:
513+
// ./in.cue:89:19
511514
}
512515
}
513516
}
514517
indirect: (_|_){
515-
// [structural cycle]
518+
// [structural cycle] 0: structural cycle:
519+
// ./in.cue:89:19
516520
}
517521
i: (int){ 1 }
518522
}
@@ -523,12 +527,14 @@ Result:
523527
b: (_|_){
524528
// [structural cycle]
525529
c: (_|_){
526-
// [structural cycle]
530+
// [structural cycle] 0: structural cycle:
531+
// ./in.cue:89:19
527532
}
528533
}
529534
}
530535
indirect: (_|_){
531-
// [structural cycle]
536+
// [structural cycle] 0: structural cycle:
537+
// ./in.cue:89:19
532538
}
533539
i: (int){ 0 }
534540
}

internal/core/adt/binop.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,8 @@ func BinOp(c *OpContext, op Op, left, right Value) Value {
5151
}
5252
}
5353

54-
if a, ok := left.(*Bottom); ok {
55-
return CombineErrors(nil, a, right)
56-
}
57-
if b, ok := left.(*Bottom); ok {
58-
return b
54+
if err := CombineErrors(c.src, left, right); err != nil {
55+
return err
5956
}
6057

6158
switch op {

internal/core/adt/errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ func (v *Vertex) AddChildError(recursive *Bottom) {
171171

172172
// CombineErrors combines two errors that originate at the same Vertex.
173173
func CombineErrors(src ast.Node, x, y Value) *Bottom {
174-
a, _ := x.(*Bottom)
175-
b, _ := y.(*Bottom)
174+
a, _ := Unwrap(x).(*Bottom)
175+
b, _ := Unwrap(y).(*Bottom)
176176

177177
switch {
178178
case a != nil && b != nil:

internal/core/subsume/subsume.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,21 @@ func (s *subsumer) errf(msg string, args ...interface{}) {
103103
s.errs = errors.Append(s.errs, b.Err)
104104
}
105105

106+
func unifyValue(c *adt.OpContext, a, b adt.Value) adt.Value {
107+
v := &adt.Vertex{}
108+
v.AddConjunct(adt.MakeRootConjunct(c.Env(0), a))
109+
v.AddConjunct(adt.MakeRootConjunct(c.Env(0), b))
110+
return c.Unifier.Evaluate(c, v)
111+
}
112+
106113
func (s *subsumer) getError() (err errors.Error) {
107114
c := s.ctx
108115
// src := binSrc(token.NoPos, opUnify, gt, lt)
109116
if s.gt != nil && s.lt != nil {
110117
// src := binSrc(token.NoPos, opUnify, s.gt, s.lt)
111118
if s.missing != 0 {
112119
s.errf("missing field %q", s.missing.SelectorString(c))
113-
} else if b, ok := adt.BinOp(c, adt.AndOp, s.gt, s.lt).(*adt.Bottom); !ok {
120+
} else if b, ok := unifyValue(c, s.gt, s.lt).(*adt.Bottom); !ok {
114121
s.errf("value not an instance")
115122
} else {
116123
s.errs = errors.Append(s.errs, b.Err)

0 commit comments

Comments
 (0)