...
1-- in.cue --
2// All these cases whose name end with cycle should fail with a structural
3// error. These are all uncommon code paths, triggered when container types
4// are evalated within a nested expression such as as an argument to a
5// function call.
6//
7// The builtins are typically used to trigger the uncommon path. The choice of
8// builtin is irrelevant, as long as they don't finalize args before processing.
9
10// This is a resolvable reference cycle, were b is equated to c.
11letCycleOK: t1: {
12 b: c
13 let X = b
14 c: X
15}
16
17// The let has structural cycle, but it is only used in a way that the
18// structural cycle is avoided.
19letCycleOK: t2: {
20 a: {
21 b: 1
22 let X = a
23 c: X.b
24 }
25}
26
27// Ensure that the cycle exemption algorithm does not bypass actual structural
28// cycles.
29letCycleFail: t1: {
30 a: {
31 b: 1
32 let X = a
33 c: X
34 }
35}
36
37// Cycles should also be detected in evaluation paths that descend into
38// recursion at non-field boundaries.
39letCycleFail: t2: {
40 a: {
41 let X = a
42 if X == _|_ { }
43 x: y: ""
44 }
45}
46
47listCycleOK: {
48 a: b
49 b: and([c])
50 c: a
51}
52
53disjunctionCycle: {
54 a: b
55 b: and(1 | c)
56 c: a
57}
58
59forCycle: {
60 #A: a: #B // TODO(errors): Correct error position.
61 #B: or([for x in #A { b: x }])
62}
63
64letCycleWithAnd: {
65 a: d: b
66 b: and([for x in a let y = x { y }])
67 c: a
68}
69
70closeCycle: {
71 a: b
72 b: close({d: c})
73 c: a
74}
75
76structCycle: {
77 a: b
78 b: and([{d: c}])
79 c: a
80}
81
82embedCycle: {
83 a: b
84 b: close({c})
85 c: a
86}
87
88listAddCycle: {
89 a: b
90 b: [c] + [c]
91 c: a
92}
93
94listMulCycle: {
95 a: b
96 b: 3 + [{a: b: c}]
97 c: a
98}
99
100// consult the correct closeness info in the face of it being passed down
101// from parent.
102closeFail: {
103 #T: [_]: _
104 #T: close({"a": string})
105 x: #T
106 x: b: "foo"
107}
108
109-- out/eval/stats --
110Leaks: 57
111Freed: 90
112Reused: 86
113Allocs: 61
114Retain: 126
115
116Unifications: 135
117Conjuncts: 269
118Disjuncts: 156
119-- out/eval --
120Errors:
121closeCycle.a: structural cycle
122closeCycle.b.d: structural cycle
123closeFail.x.b: field not allowed:
124 ./in.cue:102:6
125 ./in.cue:103:12
126 ./in.cue:104:6
127 ./in.cue:105:5
128letCycleFail.t1.a.c: structural cycle
129listAddCycle.a: structural cycle
130listAddCycle.b.0.0: structural cycle
131listAddCycle.b.0.1: structural cycle
132structCycle.a: structural cycle
133structCycle.b.d: structural cycle
134disjunctionCycle.a: cannot use 1 (type int) as list in argument 1 to and:
135 ./in.cue:54:9
136disjunctionCycle.b: cannot use 1 (type int) as list in argument 1 to and:
137 ./in.cue:54:9
138disjunctionCycle.c: cannot use 1 (type int) as list in argument 1 to and:
139 ./in.cue:54:9
140b: structural cycle:
141 ./in.cue:60:6
142closeCycle.c: structural cycle:
143 ./in.cue:71:15
144structCycle.c: structural cycle:
145 ./in.cue:77:14
146embedCycle: structural cycle:
147 ./in.cue:83:11
148listAddCycle.c: structural cycle:
149 ./in.cue:89:6
150listMulCycle.a: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
151 ./in.cue:95:5
152 ./in.cue:95:9
153listMulCycle.b: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
154 ./in.cue:95:5
155 ./in.cue:95:9
156listMulCycle.c: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
157 ./in.cue:95:5
158 ./in.cue:95:9
159
160Result:
161(_|_){
162 // [eval]
163 letCycleOK: (struct){
164 t1: (struct){
165 b: (_){ _ }
166 let X#1 = (_){ _ }
167 c: (_){ _ }
168 }
169 t2: (struct){
170 a: (struct){
171 b: (int){ 1 }
172 let X#2 = (_|_){
173 // [structural cycle] letCycleOK.t2.a.X: structural cycle
174 }
175 c: (int){ 1 }
176 }
177 }
178 }
179 letCycleFail: (_|_){
180 // [structural cycle]
181 t1: (_|_){
182 // [structural cycle]
183 a: (_|_){
184 // [structural cycle]
185 b: (int){ 1 }
186 let X#3 = (_|_){
187 // [structural cycle] letCycleFail.t1.a.X: structural cycle
188 }
189 c: (_|_){
190 // [structural cycle] letCycleFail.t1.a.c: structural cycle
191 }
192 }
193 }
194 t2: (struct){
195 a: (struct){
196 let X#4 = (struct){
197 let X#4 = (_|_){
198 // [structural cycle] letCycleFail.t2.a.X.X: structural cycle:
199 // ./in.cue:41:6
200 }
201 x: (struct){
202 y: (string){ "" }
203 }
204 }
205 x: (struct){
206 y: (string){ "" }
207 }
208 }
209 }
210 }
211 listCycleOK: (struct){
212 a: (_){ _ }
213 b: (_){ _ }
214 c: (_){ _ }
215 }
216 disjunctionCycle: (_|_){
217 // [eval]
218 a: (_|_){
219 // [eval] disjunctionCycle.a: cannot use 1 (type int) as list in argument 1 to and:
220 // ./in.cue:54:9
221 }
222 b: (_|_){
223 // [eval] disjunctionCycle.b: cannot use 1 (type int) as list in argument 1 to and:
224 // ./in.cue:54:9
225 }
226 c: (_|_){
227 // [eval] disjunctionCycle.c: cannot use 1 (type int) as list in argument 1 to and:
228 // ./in.cue:54:9
229 }
230 }
231 forCycle: (_|_){
232 // [structural cycle]
233 #A: (_|_){
234 // [structural cycle]
235 a: (_|_){
236 // [structural cycle] b: structural cycle:
237 // ./in.cue:60:6
238 }
239 }
240 #B: (_|_){
241 // [structural cycle] b: structural cycle:
242 // ./in.cue:60:6
243 }
244 }
245 letCycleWithAnd: (struct){
246 a: (struct){
247 d: (struct){
248 }
249 }
250 b: (struct){
251 }
252 c: (struct){
253 d: (struct){
254 }
255 }
256 }
257 closeCycle: (_|_){
258 // [structural cycle]
259 a: (_|_){
260 // [structural cycle] closeCycle.a: structural cycle
261 }
262 b: (_|_){
263 // [structural cycle]
264 d: (_|_){
265 // [structural cycle] closeCycle.b.d: structural cycle
266 }
267 }
268 c: (_|_){
269 // [structural cycle] closeCycle.c: structural cycle:
270 // ./in.cue:71:15
271 }
272 }
273 structCycle: (_|_){
274 // [structural cycle]
275 a: (_|_){
276 // [structural cycle] structCycle.a: structural cycle
277 }
278 b: (_|_){
279 // [structural cycle]
280 d: (_|_){
281 // [structural cycle] structCycle.b.d: structural cycle
282 }
283 }
284 c: (_|_){
285 // [structural cycle] structCycle.c: structural cycle:
286 // ./in.cue:77:14
287 }
288 }
289 embedCycle: (_|_){
290 // [structural cycle]
291 a: (_|_){
292 // [structural cycle] embedCycle: structural cycle:
293 // ./in.cue:83:11
294 }
295 b: (_|_){
296 // [structural cycle] embedCycle: structural cycle:
297 // ./in.cue:83:11
298 }
299 c: (_|_){
300 // [structural cycle] embedCycle: structural cycle:
301 // ./in.cue:83:11
302 }
303 }
304 listAddCycle: (_|_){
305 // [structural cycle]
306 a: (_|_){
307 // [structural cycle] listAddCycle.a: structural cycle
308 }
309 b: (_|_){
310 // [structural cycle]
311 0: (_|_){
312 // [structural cycle]
313 0: (_|_){
314 // [structural cycle] listAddCycle.b.0.0: structural cycle
315 }
316 1: (_|_){
317 // [structural cycle] listAddCycle.b.0.1: structural cycle
318 }
319 }
320 1: (_|_){
321 // [structural cycle]
322 }
323 }
324 c: (_|_){
325 // [structural cycle] listAddCycle.c: structural cycle:
326 // ./in.cue:89:6
327 }
328 }
329 listMulCycle: (_|_){
330 // [eval]
331 a: (_|_){
332 // [eval] listMulCycle.a: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
333 // ./in.cue:95:5
334 // ./in.cue:95:9
335 }
336 b: (_|_){
337 // [eval] listMulCycle.b: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
338 // ./in.cue:95:5
339 // ./in.cue:95:9
340 }
341 c: (_|_){
342 // [eval] listMulCycle.c: invalid operands 3 and [{a:{b:c}}] to '+' (type int and list):
343 // ./in.cue:95:5
344 // ./in.cue:95:9
345 }
346 }
347 closeFail: (_|_){
348 // [eval]
349 #T: (#struct){
350 a: (string){ string }
351 }
352 x: (_|_){
353 // [eval]
354 a: (string){ string }
355 b: (_|_){
356 // [eval] closeFail.x.b: field not allowed:
357 // ./in.cue:102:6
358 // ./in.cue:103:12
359 // ./in.cue:104:6
360 // ./in.cue:105:5
361 }
362 }
363 }
364}
365-- out/compile --
366--- in.cue
367{
368 letCycleOK: {
369 t1: {
370 b: 〈0;c〉
371 let X#1 = 〈0;b〉
372 c: 〈0;let X#1〉
373 }
374 }
375 letCycleOK: {
376 t2: {
377 a: {
378 b: 1
379 let X#2 = 〈1;a〉
380 c: 〈0;let X#2〉.b
381 }
382 }
383 }
384 letCycleFail: {
385 t1: {
386 a: {
387 b: 1
388 let X#3 = 〈1;a〉
389 c: 〈0;let X#3〉
390 }
391 }
392 }
393 letCycleFail: {
394 t2: {
395 a: {
396 let X#4 = 〈1;a〉
397 if (〈0;let X#4〉 == _|_(explicit error (_|_ literal) in source)) {}
398 x: {
399 y: ""
400 }
401 }
402 }
403 }
404 listCycleOK: {
405 a: 〈0;b〉
406 b: and([
407 〈1;c〉,
408 ])
409 c: 〈0;a〉
410 }
411 disjunctionCycle: {
412 a: 〈0;b〉
413 b: and((1|〈0;c〉))
414 c: 〈0;a〉
415 }
416 forCycle: {
417 #A: {
418 a: 〈1;#B〉
419 }
420 #B: or([
421 for _, x in 〈1;#A〉 {
422 b: 〈1;x〉
423 },
424 ])
425 }
426 letCycleWithAnd: {
427 a: {
428 d: 〈1;b〉
429 }
430 b: and([
431 for _, x in 〈1;a〉 let y = 〈0;x〉 {
432 〈1;y〉
433 },
434 ])
435 c: 〈0;a〉
436 }
437 closeCycle: {
438 a: 〈0;b〉
439 b: close({
440 d: 〈1;c〉
441 })
442 c: 〈0;a〉
443 }
444 structCycle: {
445 a: 〈0;b〉
446 b: and([
447 {
448 d: 〈2;c〉
449 },
450 ])
451 c: 〈0;a〉
452 }
453 embedCycle: {
454 a: 〈0;b〉
455 b: close({
456 〈1;c〉
457 })
458 c: 〈0;a〉
459 }
460 listAddCycle: {
461 a: 〈0;b〉
462 b: ([
463 〈1;c〉,
464 ] + [
465 〈1;c〉,
466 ])
467 c: 〈0;a〉
468 }
469 listMulCycle: {
470 a: 〈0;b〉
471 b: (3 + [
472 {
473 a: {
474 b: 〈3;c〉
475 }
476 },
477 ])
478 c: 〈0;a〉
479 }
480 closeFail: {
481 #T: {
482 [_]: _
483 }
484 #T: close({
485 a: string
486 })
487 x: 〈0;#T〉
488 x: {
489 b: "foo"
490 }
491 }
492}
View as plain text