Skip to content

Commit 1888d65

Browse files
committed
internal/core/eval: fix bug in cycle handling
Basically, the dereference list was grown incorrectly. This was exposed when a cyclic structure is referenced from within a more than 1 deeply nested other cyclic structure. Fixes #555 Fixes #534 Change-Id: I8aa71a37eb19b5efc75fc3bd75c8e00d254d88d7 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7481 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 1d8c688 commit 1888d65

File tree

3 files changed

+170
-51
lines changed

3 files changed

+170
-51
lines changed

cue/testdata/cycle/structural.txtar

Lines changed: 152 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@ b7: {
6161
a: [a]
6262
}
6363

64+
// Issue #555
65+
b8: {
66+
x: a
67+
a: f: b
68+
b: a | string
69+
}
70+
71+
// Issue #555
72+
b9: {
73+
#a: string | #b | #ref
74+
#b: {
75+
c: [#a, #a, #a]
76+
}
77+
#ref: ref: string
78+
x: #b | #ref
79+
}
80+
81+
// Issue #534
82+
b10: {
83+
a: close({
84+
b: string | a | c
85+
})
86+
c: close({
87+
d: string | a
88+
})
89+
}
90+
6491
c1: {
6592
a: {
6693
b: {}
@@ -236,43 +263,43 @@ e1.b.c: structural cycle
236263
e2.a.c: structural cycle
237264
e2.b.c: structural cycle
238265
e3.a: conflicting values [a] and {c:a} (mismatched types list and struct):
239-
./in.cue:114:8
240-
./in.cue:115:8
266+
./in.cue:141:8
267+
./in.cue:142:8
241268
e3.a.0: conflicting values [a] and {c:a} (mismatched types list and struct):
242-
./in.cue:114:8
243-
./in.cue:115:8
269+
./in.cue:141:8
270+
./in.cue:142:8
244271
e3.a.0: structural cycle
245272
e3.a.c: conflicting values [a] and {c:a} (mismatched types list and struct):
246-
./in.cue:114:8
247-
./in.cue:115:8
273+
./in.cue:141:8
274+
./in.cue:142:8
248275
e3.a.c: structural cycle
249276
e3.b: conflicting values [b] and {c:b} (mismatched types list and struct):
250-
./in.cue:117:8
251-
./in.cue:118:8
277+
./in.cue:144:8
278+
./in.cue:145:8
252279
e3.b.0: conflicting values [b] and {c:b} (mismatched types list and struct):
253-
./in.cue:117:8
254-
./in.cue:118:8
280+
./in.cue:144:8
281+
./in.cue:145:8
255282
e3.b.0: structural cycle
256283
e3.b.c: conflicting values [b] and {c:b} (mismatched types list and struct):
257-
./in.cue:117:8
258-
./in.cue:118:8
284+
./in.cue:144:8
285+
./in.cue:145:8
259286
e3.b.c: structural cycle
260287
e4.a.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
261-
./in.cue:122:13
262-
./in.cue:123:9
288+
./in.cue:149:13
289+
./in.cue:150:9
263290
e4.b.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
264-
./in.cue:125:9
265-
./in.cue:126:13
291+
./in.cue:152:9
292+
./in.cue:153:13
266293
z1.z.f.h.h: structural cycle
267294
z1.z.g.h: structural cycle
268295
b4.x.y.0: structural cycle:
269296
./in.cue:41:8
270297
d2.a.b.c.d.t: structural cycle:
271-
./in.cue:79:8
298+
./in.cue:106:8
272299
d2.r: structural cycle:
273-
./in.cue:79:8
300+
./in.cue:106:8
274301
0: structural cycle:
275-
./in.cue:89:19
302+
./in.cue:116:19
276303

277304
Result:
278305
(_|_){
@@ -420,6 +447,61 @@ Result:
420447
}
421448
}
422449
}
450+
b8: (struct){
451+
x: (struct){
452+
f: (string){ string }
453+
}
454+
a: (struct){
455+
f: (string){ string }
456+
}
457+
b: (string){ string }
458+
}
459+
b9: (struct){
460+
#a: ((string|struct)){ |((string){ string }, (#struct){
461+
ref: (string){ string }
462+
}) }
463+
#b: (#struct){
464+
c: (#list){
465+
0: ((string|struct)){ |((string){ string }, (#struct){
466+
ref: (string){ string }
467+
}) }
468+
1: ((string|struct)){ |((string){ string }, (#struct){
469+
ref: (string){ string }
470+
}) }
471+
2: ((string|struct)){ |((string){ string }, (#struct){
472+
ref: (string){ string }
473+
}) }
474+
}
475+
}
476+
#ref: (#struct){
477+
ref: (string){ string }
478+
}
479+
x: (struct){ |((#struct){
480+
c: (#list){
481+
0: ((string|struct)){ |((string){ string }, (#struct){
482+
ref: (string){ string }
483+
}) }
484+
1: ((string|struct)){ |((string){ string }, (#struct){
485+
ref: (string){ string }
486+
}) }
487+
2: ((string|struct)){ |((string){ string }, (#struct){
488+
ref: (string){ string }
489+
}) }
490+
}
491+
}, (#struct){
492+
ref: (string){ string }
493+
}) }
494+
}
495+
b10: (struct){
496+
a: (#struct){
497+
b: ((string|struct)){ |((string){ string }, (#struct){
498+
d: (string){ string }
499+
}) }
500+
}
501+
c: (#struct){
502+
d: (string){ string }
503+
}
504+
}
423505
c1: (_|_){
424506
// [structural cycle]
425507
a: (_|_){
@@ -483,11 +565,11 @@ Result:
483565
// [structural cycle]
484566
x: (_|_){
485567
// [structural cycle] d2.a.b.c.d.t: structural cycle:
486-
// ./in.cue:79:8
568+
// ./in.cue:106:8
487569
}
488570
r: (_|_){
489571
// [structural cycle] d2.r: structural cycle:
490-
// ./in.cue:79:8
572+
// ./in.cue:106:8
491573
c: (_|_){// {
492574
// d: {
493575
// h: int
@@ -530,13 +612,13 @@ Result:
530612
// [structural cycle]
531613
c: (_|_){
532614
// [structural cycle] 0: structural cycle:
533-
// ./in.cue:89:19
615+
// ./in.cue:116:19
534616
}
535617
}
536618
}
537619
indirect: (_|_){
538620
// [structural cycle] 0: structural cycle:
539-
// ./in.cue:89:19
621+
// ./in.cue:116:19
540622
}
541623
i: (int){ 1 }
542624
}
@@ -548,13 +630,13 @@ Result:
548630
// [structural cycle]
549631
c: (_|_){
550632
// [structural cycle] 0: structural cycle:
551-
// ./in.cue:89:19
633+
// ./in.cue:116:19
552634
}
553635
}
554636
}
555637
indirect: (_|_){
556638
// [structural cycle] 0: structural cycle:
557-
// ./in.cue:89:19
639+
// ./in.cue:116:19
558640
}
559641
i: (int){ 0 }
560642
}
@@ -601,12 +683,12 @@ Result:
601683
// [eval]
602684
a: (_|_){
603685
// [eval] e3.a: conflicting values [a] and {c:a} (mismatched types list and struct):
604-
// ./in.cue:114:8
605-
// ./in.cue:115:8
686+
// ./in.cue:141:8
687+
// ./in.cue:142:8
606688
c: (_|_){
607689
// [eval] e3.a.c: conflicting values [a] and {c:a} (mismatched types list and struct):
608-
// ./in.cue:114:8
609-
// ./in.cue:115:8
690+
// ./in.cue:141:8
691+
// ./in.cue:142:8
610692
// e3.a.c: structural cycle
611693
c: (_|_){// 〈1;a〉
612694
}
@@ -615,8 +697,8 @@ Result:
615697
}
616698
0: (_|_){
617699
// [eval] e3.a.0: conflicting values [a] and {c:a} (mismatched types list and struct):
618-
// ./in.cue:114:8
619-
// ./in.cue:115:8
700+
// ./in.cue:141:8
701+
// ./in.cue:142:8
620702
// e3.a.0: structural cycle
621703
c: (_|_){// 〈1;a〉
622704
}
@@ -626,12 +708,12 @@ Result:
626708
}
627709
b: (_|_){
628710
// [eval] e3.b: conflicting values [b] and {c:b} (mismatched types list and struct):
629-
// ./in.cue:117:8
630-
// ./in.cue:118:8
711+
// ./in.cue:144:8
712+
// ./in.cue:145:8
631713
c: (_|_){
632714
// [eval] e3.b.c: conflicting values [b] and {c:b} (mismatched types list and struct):
633-
// ./in.cue:117:8
634-
// ./in.cue:118:8
715+
// ./in.cue:144:8
716+
// ./in.cue:145:8
635717
// e3.b.c: structural cycle
636718
c: (_|_){// 〈1;b〉
637719
}
@@ -640,8 +722,8 @@ Result:
640722
}
641723
0: (_|_){
642724
// [eval] e3.b.0: conflicting values [b] and {c:b} (mismatched types list and struct):
643-
// ./in.cue:117:8
644-
// ./in.cue:118:8
725+
// ./in.cue:144:8
726+
// ./in.cue:145:8
645727
// e3.b.0: structural cycle
646728
c: (_|_){// 〈1;b〉
647729
}
@@ -656,8 +738,8 @@ Result:
656738
// [eval]
657739
0: (_|_){
658740
// [eval] e4.a.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
659-
// ./in.cue:122:13
660-
// ./in.cue:123:9
741+
// ./in.cue:149:13
742+
// ./in.cue:150:9
661743
0: (struct){
662744
c: (int){ 1 }
663745
}
@@ -667,8 +749,8 @@ Result:
667749
// [eval]
668750
0: (_|_){
669751
// [eval] e4.b.0: conflicting values [{c:1}] and {} (mismatched types list and struct):
670-
// ./in.cue:125:9
671-
// ./in.cue:126:13
752+
// ./in.cue:152:9
753+
// ./in.cue:153:13
672754
0: (struct){
673755
c: (int){ 1 }
674756
}
@@ -779,8 +861,6 @@ Result:
779861
// [structural cycle]
780862
h: (_|_){
781863
// [structural cycle] z1.z.f.h.h: structural cycle
782-
h: (_|_){// 〈1;g〉
783-
}
784864
}
785865
}
786866
}
@@ -932,6 +1012,35 @@ Result:
9321012
〈0;a〉,
9331013
]
9341014
}
1015+
b8: {
1016+
x: 〈0;a〉
1017+
a: {
1018+
f: 〈1;b〉
1019+
}
1020+
b: (〈0;a〉|string)
1021+
}
1022+
b9: {
1023+
#a: (string|〈0;#b〉|〈0;#ref〉)
1024+
#b: {
1025+
c: [
1026+
〈1;#a〉,
1027+
〈1;#a〉,
1028+
〈1;#a〉,
1029+
]
1030+
}
1031+
#ref: {
1032+
ref: string
1033+
}
1034+
x: (〈0;#b〉|〈0;#ref〉)
1035+
}
1036+
b10: {
1037+
a: close({
1038+
b: (string|〈1;a〉|〈1;c〉)
1039+
})
1040+
c: close({
1041+
d: (string|〈1;a〉)
1042+
})
1043+
}
9351044
c1: {
9361045
a: {
9371046
b: {}

internal/core/eval/closed.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ func (c *acceptor) InsertSubtree(at adt.ID, n *nodeContext, v *adt.Vertex, cycli
374374

375375
if n != nil {
376376
for _, c := range v.Conjuncts {
377-
c = updateCyclic(c, cyclic, nil)
377+
c = updateCyclic(c, cyclic, nil, nil)
378378
c.CloseID += id
379379
n.addExprConjunct(c)
380380
}

0 commit comments

Comments
 (0)