Skip to content

Commit cacb4b8

Browse files
committed
internal/core/adt: fix panic on reinserted pattern constraint conjunct
When insertConstraint finds that a conjunct was already added to a pattern constraint, it records a defID replacement. The existing conjunct may have been inserted under a previous OpContext, for instance when "cue eval -e" evaluates an expression against an already evaluated instance whose pattern constraints it re-triggers. Its defID then indexes the previous context's containments table and may be out of range for the current one, panicking in addReplacement. Skip the replacement unless both conjuncts got their defIDs from the current context, matching the other opID misalignment guards. Fixes #4449 Assisted-by: Claude Code (claude-fable-5) Signed-off-by: Daniel Martí <mvdan@mvdan.cc> Change-Id: I15b8775d0f56a85070a36183d3104a54517275d0 Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1244341 Reviewed-by: Marcel van Lohuizen <mpvl@gmail.com> TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
1 parent d57c348 commit cacb4b8

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Verify that eval of an expression does not panic when it re-inserts a
2+
# pattern constraint conjunct that was first inserted while evaluating the
3+
# instance under a different OpContext.
4+
# Issue #4449.
5+
6+
exec cue eval -e export.objects.p in.cue
7+
cmp stdout stdout.golden
8+
9+
-- in.cue --
10+
export: objects: ({
11+
in: _
12+
out: p: {
13+
for x in in.deployment {}
14+
}
15+
} & {in: export.objects}).out
16+
export: objects: [string]: _
17+
-- stdout.golden --
18+
_ &
19+
{
20+
for x in OBJECTS.deployment {}
21+
}
22+
23+
//cue:path: export.objects
24+
let OBJECTS = ({
25+
in: _
26+
out: p: {
27+
for x in OBJECTS.deployment {}
28+
}
29+
} & {in: OBJECTS}).out & {{[string]: _}}

internal/core/adt/constraints.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ func (n *nodeContext) insertConstraint(pattern Value, c Conjunct) bool {
100100
} else {
101101
for x := range constraint.LeafConjuncts() {
102102
if x.x == c.x && x.Env.Equal(ctx, c.Env) {
103-
if c.CloseInfo.opID == n.ctx.opID {
103+
// Both defIDs must stem from the current OpContext: x may
104+
// predate it, in which case its defID indexes another
105+
// context's containments table.
106+
if c.CloseInfo.opID == n.ctx.opID && x.CloseInfo.opID == n.ctx.opID {
104107
// TODO: do we need this replacement?
105108
src := x.CloseInfo.defID
106109
dst := c.CloseInfo.defID

0 commit comments

Comments
 (0)