diff --git a/cue/testdata/eval/issue3301.txtar b/cue/testdata/eval/issue3301.txtar new file mode 100644 index 00000000000..16948954083 --- /dev/null +++ b/cue/testdata/eval/issue3301.txtar @@ -0,0 +1,77 @@ +-- in.cue -- +object: #Leaf & {} + +#Base: { + extra?: {...} +} + +#Mid: { + #Base +} + +#Leaf: { + #Mid + extra?: {...} + more?: int + if extra.foo != _|_ { + if more != _|_ { + foo: "bar" + } + } +} +-- out/eval -- +(struct){ + object: (#struct){ + extra?: (#struct){ + } + more?: (int){ int } + } + #Base: (#struct){ + extra?: (#struct){ + } + } + #Mid: (#struct){ + extra?: (#struct){ + } + } + #Leaf: (#struct){ + extra?: (#struct){ + } + more?: (int){ int } + } +} +-- out/eval/stats -- +Leaks: 0 +Freed: 11 +Reused: 5 +Allocs: 6 +Retain: 7 + +Unifications: 11 +Conjuncts: 25 +Disjuncts: 18 +-- out/compile -- +--- in.cue +{ + object: (〈0;#Leaf〉 & {}) + #Base: { + extra?: { + ... + } + } + #Mid: { + 〈1;#Base〉 + } + #Leaf: { + 〈1;#Mid〉 + extra?: { + ... + } + more?: int + if (〈0;extra〉.foo != _|_(explicit error (_|_ literal) in source)) { + if (〈1;more〉 != _|_(explicit error (_|_ literal) in source)) { + foo: "bar" + } + } + } +} diff --git a/internal/core/adt/fields.go b/internal/core/adt/fields.go index ea40ec1cc83..08620a2fa2b 100644 --- a/internal/core/adt/fields.go +++ b/internal/core/adt/fields.go @@ -433,17 +433,28 @@ func (cc *closeContext) linkNotify(ctx *OpContext, dst *Vertex, key *closeContex func (cc *closeContext) assignConjunct(ctx *OpContext, root *closeContext, c Conjunct, mode ArcType, check, checkClosed bool) (arc *closeContext, pos int, added bool) { arc = cc.getKeyedCC(ctx, root, c.CloseInfo.CycleInfo, mode, checkClosed) - pos = len(*arc.group) - c.CloseInfo.cc = nil - added = !check || !hasConjunct(*arc.group, c) + + var group ConjunctGroup + if arc.group != nil { + group = *arc.group + } + pos = len(group) + + added = !check || !hasConjunct(group, c) if added { c.CloseInfo.cc = arc if c.CloseInfo.cc.src != arc.src { panic("Inconsistent src") } - *arc.group = append(*arc.group, c) + + group = append(group, c) + if arc.group == nil { + arc.group = &group + } else { + *arc.group = group + } } return arc, pos, added