diff --git a/internal/core/adt/call.go b/internal/core/adt/call.go index fbadf99d4..403b290a5 100644 --- a/internal/core/adt/call.go +++ b/internal/core/adt/call.go @@ -75,7 +75,7 @@ func (c *CallContext) Args() []Value { // // This method of getting an argument should be used when the argument is used // as a schema and may contain cycles. -func (c *CallContext) Expr(i int) Expr { +func (c *CallContext) Expr(i int) Value { // If the call context represents a validator call, the argument will be // offset by 1. if c.isValidator { @@ -85,7 +85,10 @@ func (c *CallContext) Expr(i int) Expr { } i-- } - return c.call.Args[i] + x := c.call.Args[i] + + // Evaluated while keeping any cycle information in the context. + return c.ctx.EvaluateKeepState(x) } func (c *CallContext) Errf(format string, args ...interface{}) *Bottom { diff --git a/internal/core/adt/context.go b/internal/core/adt/context.go index 50d61e86b..41f3991c5 100644 --- a/internal/core/adt/context.go +++ b/internal/core/adt/context.go @@ -563,7 +563,7 @@ func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete b return val, true } -// EvaluateKeepState does an evaluate, but leaves any errors an cycle info +// EvaluateKeepState does an evaluate, but leaves any errors and cycle info // within the context. func (c *OpContext) EvaluateKeepState(x Expr) (result Value) { src := c.src diff --git a/internal/core/compile/builtin.go b/internal/core/compile/builtin.go index 59cc56899..22a87bb7e 100644 --- a/internal/core/compile/builtin.go +++ b/internal/core/compile/builtin.go @@ -120,9 +120,7 @@ var andBuiltin = &adt.Builtin{ c := call.OpContext() arg := call.Expr(0) - // Pass through the cycle information from evaluating the first argument. - v := c.EvaluateKeepState(arg) - list := c.RawElems(v) + list := c.RawElems(arg) if len(list) == 0 { return &adt.Top{} }