Skip to content

Commit 7922f9b

Browse files
committed
pkg/internal: compute combined error severity
Combine list of valueErrors into a single Bottom, rather than having a list of bottom values. This preserved the combined severity. Fixes #1095 Signed-off-by: Marcel van Lohuizen <mpvl@golang.org> Change-Id: Ib32786e0403b1965c407deaa6471ca1ec2c174ae Signed-off-by: Marcel van Lohuizen <mpvl@golang.org> Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/528059 Unity-Result: CUEcueckoo <cueckoo@cuelang.org> TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Reviewed-by: Paul Jolly <paul@myitcv.io>
1 parent c490d4c commit 7922f9b

File tree

3 files changed

+83
-34
lines changed

3 files changed

+83
-34
lines changed

cue/testdata/builtins/incomplete.txtar

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import (
33
"list"
44
"strings"
5+
"text/template"
56
)
67

78

@@ -87,15 +88,27 @@ badListError: {
8788
str: strings.Join(x, "")
8889
}
8990

91+
// Issue #1095
92+
// Preserve combined error severity for multiple errors.
93+
multipleErrors: {
94+
#T: {
95+
params: {
96+
x: string
97+
y: string
98+
}
99+
out: template.Execute("{{.x}} {{.y}}", params)
100+
}
101+
}
102+
90103
-- out/eval --
91104
Errors:
92105
badListType.decimal: cannot use 2 (type int) as list in argument 1 to list.Max:
93-
./in.cue:77:8
106+
./in.cue:78:8
94107
badListType.str: cannot use 2 (type int) as list in argument 1 to strings.Join:
95-
./in.cue:77:8
108+
./in.cue:78:8
96109
badListError.x: invalid operands 2 and "foo" to '+' (type int and string):
97-
./in.cue:83:8
98110
./in.cue:84:8
111+
./in.cue:85:8
99112

100113
Result:
101114
(_|_){
@@ -104,67 +117,67 @@ Result:
104117
Out1: (#list){
105118
0: (_|_){
106119
// [cycle] cycle error:
107-
// ./in.cue:16:23
120+
// ./in.cue:17:23
108121
}
109122
}
110123
Out2: (#list){
111124
0: (_|_){
112125
// [cycle] cycle error:
113-
// ./in.cue:16:23
126+
// ./in.cue:17:23
114127
}
115128
}
116129
Out3: (#list){
117130
0: (_|_){
118131
// [cycle] cycle error:
119-
// ./in.cue:16:23
132+
// ./in.cue:17:23
120133
}
121134
}
122135
Top: (#list){
123136
0: (_|_){
124137
// [cycle] cycle error:
125-
// ./in.cue:16:23
138+
// ./in.cue:17:23
126139
}
127140
}
128141
_Sub: (_|_){
129142
// [incomplete] list1._Sub: undefined field: b:
130-
// ./in.cue:19:13
143+
// ./in.cue:20:13
131144
}
132145
a: (struct){
133146
}
134147
}
135148
list2: (struct){
136149
Out1: (_|_){
137150
// [cycle] cycle error:
138-
// ./in.cue:30:21
151+
// ./in.cue:31:21
139152
}
140153
Out2: (_|_){
141154
// [cycle] cycle error:
142-
// ./in.cue:30:21
155+
// ./in.cue:31:21
143156
}
144157
Out3: (_|_){
145158
// [cycle] cycle error:
146-
// ./in.cue:30:21
159+
// ./in.cue:31:21
147160
}
148161
_Top: (_|_){
149162
// [cycle] cycle error:
150-
// ./in.cue:30:21
163+
// ./in.cue:31:21
151164
}
152165
#Sub: (_|_){
153166
// [incomplete] list2.#Sub: undefined field: b:
154-
// ./in.cue:33:13
167+
// ./in.cue:34:13
155168
}
156169
a: (struct){
157170
}
158171
}
159172
value1: (struct){
160173
a: (_|_){
161174
// [incomplete] value1.a: unresolved disjunction 'sf' | 'dd' (type bytes):
162-
// ./in.cue:38:8
175+
// ./in.cue:39:8
163176
}
164177
}
165178
value2: (_|_){
166179
// [incomplete] value2: unresolved disjunction 'sf' | 'dd' (type bytes):
167-
// ./in.cue:42:5
180+
// ./in.cue:43:5
168181
}
169182
incompleteArgDecimalList: (struct){
170183
a: (#struct){
@@ -176,11 +189,11 @@ Result:
176189
param: (int){ int }
177190
transformed: (_|_){
178191
// [incomplete] incompleteArgDecimalList.#a.transformed: operand param of '+' not concrete (was int):
179-
// ./in.cue:49:23
192+
// ./in.cue:50:23
180193
}
181194
max: (_|_){
182195
// [incomplete] 0: operand param of '+' not concrete (was int):
183-
// ./in.cue:49:23
196+
// ./in.cue:50:23
184197
}
185198
}
186199
}
@@ -194,74 +207,87 @@ Result:
194207
param: (string){ string }
195208
transformed: (_|_){
196209
// [incomplete] incompleteArgStringList.#a.transformed: non-concrete value string in operand to +:
197-
// ./in.cue:58:22
198-
// ./in.cue:57:9
210+
// ./in.cue:59:22
211+
// ./in.cue:58:9
199212
}
200213
joined: (_|_){
201214
// [incomplete] 0: non-concrete value string in operand to +:
202-
// ./in.cue:58:22
203-
// ./in.cue:57:9
215+
// ./in.cue:59:22
216+
// ./in.cue:58:9
204217
}
205218
}
206219
}
207220
incompleteList: (struct){
208221
x: (_){ _ }
209222
decimal: (_|_){
210223
// [incomplete] incompleteList.decimal: non-concrete list for argument 0:
211-
// ./in.cue:65:14
224+
// ./in.cue:66:14
212225
}
213226
str: (_|_){
214227
// [incomplete] incompleteList.str: non-concrete list for argument 0:
215-
// ./in.cue:66:14
228+
// ./in.cue:67:14
216229
}
217230
}
218231
incompleteListError: (struct){
219232
x: (_|_){
220233
// [incomplete] incompleteListError.x: non-concrete value _ in operand to +:
221-
// ./in.cue:70:8
222-
// ./in.cue:71:5
234+
// ./in.cue:71:8
235+
// ./in.cue:72:5
223236
}
224237
y: (_){ _ }
225238
decimal: (_|_){
226239
// [incomplete] incompleteListError.x: non-concrete value _ in operand to +:
227-
// ./in.cue:70:8
228-
// ./in.cue:71:5
240+
// ./in.cue:71:8
241+
// ./in.cue:72:5
229242
}
230243
str: (_|_){
231244
// [incomplete] incompleteListError.x: non-concrete value _ in operand to +:
232-
// ./in.cue:70:8
233-
// ./in.cue:71:5
245+
// ./in.cue:71:8
246+
// ./in.cue:72:5
234247
}
235248
}
236249
badListType: (_|_){
237250
// [eval]
238251
x: (int){ 2 }
239252
decimal: (_|_){
240253
// [eval] badListType.decimal: cannot use 2 (type int) as list in argument 1 to list.Max:
241-
// ./in.cue:77:8
254+
// ./in.cue:78:8
242255
}
243256
str: (_|_){
244257
// [eval] badListType.str: cannot use 2 (type int) as list in argument 1 to strings.Join:
245-
// ./in.cue:77:8
258+
// ./in.cue:78:8
246259
}
247260
}
248261
badListError: (_|_){
249262
// [eval]
250263
x: (_|_){
251264
// [eval] badListError.x: invalid operands 2 and "foo" to '+' (type int and string):
252-
// ./in.cue:83:8
253265
// ./in.cue:84:8
266+
// ./in.cue:85:8
254267
}
255268
y: (string){ "foo" }
256269
decimal: (_|_){
257270
// [eval] badListError.x: invalid operands 2 and "foo" to '+' (type int and string):
258-
// ./in.cue:83:8
259271
// ./in.cue:84:8
272+
// ./in.cue:85:8
260273
}
261274
str: (_|_){
262275
// [eval] badListError.x: invalid operands 2 and "foo" to '+' (type int and string):
263-
// ./in.cue:83:8
264276
// ./in.cue:84:8
277+
// ./in.cue:85:8
278+
}
279+
}
280+
multipleErrors: (struct){
281+
#T: (#struct){
282+
params: (#struct){
283+
x: (string){ string }
284+
y: (string){ string }
285+
}
286+
out: (_|_){
287+
// [incomplete] error in call to text/template.Execute: cannot convert non-concrete value string:
288+
// ./in.cue:98:12
289+
// ./in.cue:95:9
290+
}
265291
}
266292
}
267293
}
@@ -354,4 +380,13 @@ Result:
354380
decimal: 〈import;list〉.Max(〈0;x〉)
355381
str: 〈import;strings〉.Join(〈0;x〉, "")
356382
}
383+
multipleErrors: {
384+
#T: {
385+
params: {
386+
x: string
387+
y: string
388+
}
389+
out: 〈import;"text/template"〉.Execute("{{.x}} {{.y}}", 〈0;params〉)
390+
}
391+
}
357392
}

pkg/internal/builtin.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,21 @@ func processErr(call *CallCtxt, errVal interface{}, ret adt.Expr) adt.Expr {
206206
}
207207
case bottomer:
208208
ret = wrapCallErr(call, err.Bottom())
209+
209210
case errors.Error:
211+
// Convert lists of errors to a combined Bottom error.
212+
if list := errors.Errors(err); len(list) != 0 && list[0] != errVal {
213+
var errs *adt.Bottom
214+
for _, err := range list {
215+
if b, ok := processErr(call, err, nil).(*adt.Bottom); ok {
216+
errs = adt.CombineErrors(nil, errs, b)
217+
}
218+
}
219+
if errs != nil {
220+
return errs
221+
}
222+
}
223+
210224
ret = wrapCallErr(call, &adt.Bottom{Err: err})
211225
case error:
212226
if call.Err == internal.ErrIncomplete {

0 commit comments

Comments
 (0)