From e97c624887e55bd3016494e3afc5d10c8780a4bd Mon Sep 17 00:00:00 2001 From: Marcel van Lohuizen Date: Tue, 3 Sep 2024 13:31:02 +0200 Subject: [PATCH] internal/core/adt: ensure pattern is evaluated The old evaluator handled patterns differently. Ensure patterns are evaluated before used. This also fixes a case where a nil pointer was referenced when computing an error position. Fixes #3412 Signed-off-by: Marcel van Lohuizen Change-Id: I13e89de6a1fe25ad4161c61a0e450360981f2f0e Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1200588 TryBot-Result: CUEcueckoo Reviewed-by: Matthew Sackman Unity-Result: CUE porcuepine --- cue/testdata/builtins/all.txtar | 52 +++++++++++++++++++++++++++----- internal/core/adt/composite.go | 6 +++- internal/core/adt/constraints.go | 3 ++ 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/cue/testdata/builtins/all.txtar b/cue/testdata/builtins/all.txtar index 72fc7d88a58..63a9e13c1ef 100644 --- a/cue/testdata/builtins/all.txtar +++ b/cue/testdata/builtins/all.txtar @@ -16,16 +16,24 @@ okIncompleteChild: { b: {} x: and([{a: b.c}, {b: 1}]) } +-- issue3412.cue -- +andInPattern: { + out: { + [and(#constraints)]: _ + someKey: {} + } + #constraints: [=~"^.*$"] +} -- out/eval/stats -- Leaks: 2 -Freed: 12 -Reused: 8 -Allocs: 6 -Retain: 2 +Freed: 18 +Reused: 12 +Allocs: 8 +Retain: 3 -Unifications: 14 -Conjuncts: 17 -Disjuncts: 14 +Unifications: 20 +Conjuncts: 27 +Disjuncts: 21 -- out/evalalpha -- Errors: fatalArg.x: invalid operands "eee" and 'eee' to '+' (type string and bytes): @@ -65,6 +73,15 @@ Result: b: (int){ 1 } } } + andInPattern: (struct){ + out: (struct){ + someKey: (struct){ + } + } + #constraints: (#list){ + 0: (string){ =~"^.*$" } + } + } } -- diff/-out/evalalpha<==>+out/eval -- diff old new @@ -137,6 +154,15 @@ Result: b: (int){ 1 } } } + andInPattern: (struct){ + out: (struct){ + someKey: (struct){ + } + } + #constraints: (#list){ + 0: (string){ =~"^.*$" } + } + } } -- out/compile -- --- in.cue @@ -164,3 +190,15 @@ Result: ]) } } +--- issue3412.cue +{ + andInPattern: { + out: { + [and(〈1;#constraints〉)]: _ + someKey: {} + } + #constraints: [ + =~"^.*$", + ] + } +} diff --git a/internal/core/adt/composite.go b/internal/core/adt/composite.go index a49435651e4..b7db4fd1ff8 100644 --- a/internal/core/adt/composite.go +++ b/internal/core/adt/composite.go @@ -328,8 +328,12 @@ func (v *Vertex) updateArcType(t ArcType) { if (s != nil || v.isFinal()) && s.ctx.isDevVersion() { c := s.ctx if s.scheduler.frozen.meets(arcTypeKnown) { + p := token.NoPos + if src := c.Source(); src != nil { + p = src.Pos() + } parent := v.Parent - parent.reportFieldCycleError(c, c.Source().Pos(), v.Label) + parent.reportFieldCycleError(c, p, v.Label) return } } diff --git a/internal/core/adt/constraints.go b/internal/core/adt/constraints.go index 9425c2f5212..84e9f6035b7 100644 --- a/internal/core/adt/constraints.go +++ b/internal/core/adt/constraints.go @@ -134,6 +134,9 @@ func matchPattern(ctx *OpContext, pattern Value, f Feature) bool { // This is an optimization an intended to be faster than regular CUE evaluation // for the majority of cases where pattern constraints are used. func matchPatternValue(ctx *OpContext, pattern Value, f Feature, label Value) (result bool) { + if v, ok := pattern.(*Vertex); ok { + v.unify(ctx, scalarKnown, finalize) + } pattern = Unwrap(pattern) label = Unwrap(label)