diff --git a/cue/types.go b/cue/types.go index 7a529033c90..2ef360f56a6 100644 --- a/cue/types.go +++ b/cue/types.go @@ -656,7 +656,7 @@ func Dereference(v Value) Value { } ctx := v.ctx() - n, b := ctx.Resolve(c.Env, r) + n, b := ctx.Resolve(c, r) if b != nil { return newErrValue(v, b) } diff --git a/internal/core/adt/adt.go b/internal/core/adt/adt.go index 1a286e75964..315726481fd 100644 --- a/internal/core/adt/adt.go +++ b/internal/core/adt/adt.go @@ -39,7 +39,7 @@ func Resolve(ctx *OpContext, c Conjunct) *Vertex { v = x case Resolver: - r, err := ctx.Resolve(env, x) + r, err := ctx.Resolve(c, x) if err != nil { v = err break diff --git a/internal/core/adt/context.go b/internal/core/adt/context.go index 351c46f9e51..51528bbbc72 100644 --- a/internal/core/adt/context.go +++ b/internal/core/adt/context.go @@ -216,6 +216,7 @@ type OpContext struct { freeListNode *nodeContext e *Environment + ci CloseInfo src ast.Node errs *Bottom positions []Node // keep track of error positions @@ -239,7 +240,7 @@ type OpContext struct { // inDisjunct indicates that non-monotonic checks should be skipped. // This is used if we want to do some extra work to eliminate disjunctions - // early. The result of unificantion should be thrown away if this check is + // early. The result of unification should be thrown away if this check is // used. // // TODO: replace this with a mechanism to determine the correct set (per @@ -392,12 +393,14 @@ type frame struct { env *Environment err *Bottom src ast.Node + ci CloseInfo } func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) { saved.env = c.e saved.err = c.errs saved.src = c.src + saved.ci = c.ci c.errs = nil if src != nil { @@ -408,11 +411,30 @@ func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) { return saved } +func (c *OpContext) PushConjunct(x Conjunct) (saved frame) { + src := x.Expr().Source() + + saved.env = c.e + saved.err = c.errs + saved.src = c.src + saved.ci = c.ci + + c.errs = nil + if src != nil { + c.src = src + } + c.e = x.Env + c.ci = x.CloseInfo + + return saved +} + func (c *OpContext) PopState(s frame) *Bottom { err := c.errs c.e = s.env c.errs = s.err c.src = s.src + c.ci = s.ci return err } @@ -433,8 +455,8 @@ func (c *OpContext) PopArc(saved *Vertex) { // // Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts // and error. -func (c *OpContext) Resolve(env *Environment, r Resolver) (*Vertex, *Bottom) { - s := c.PushState(env, r.Source()) +func (c *OpContext) Resolve(x Conjunct, r Resolver) (*Vertex, *Bottom) { + s := c.PushConjunct(x) arc := r.resolve(c, Partial) @@ -580,8 +602,9 @@ func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete b return val, true } -func (c *OpContext) evaluateRec(env *Environment, x Expr, state VertexStatus) Value { - s := c.PushState(env, x.Source()) +func (c *OpContext) evaluateRec(v Conjunct, state VertexStatus) Value { + x := v.Expr() + s := c.PushConjunct(v) val := c.evalState(x, state) if val == nil { diff --git a/internal/core/adt/eval.go b/internal/core/adt/eval.go index cb92f91f55e..8a3e593390a 100644 --- a/internal/core/adt/eval.go +++ b/internal/core/adt/eval.go @@ -1437,7 +1437,7 @@ func (n *nodeContext) evalExpr(v Conjunct) { switch x := v.Expr().(type) { case Resolver: - arc, err := ctx.Resolve(v.Env, x) + arc, err := ctx.Resolve(v, x) if err != nil && !err.IsIncomplete() { n.addBottom(err) break @@ -1452,7 +1452,7 @@ func (n *nodeContext) evalExpr(v Conjunct) { case Evaluator: // Interpolation, UnaryExpr, BinaryExpr, CallExpr // Could be unify? - val := ctx.evaluateRec(v.Env, v.Expr(), Partial) + val := ctx.evaluateRec(v, Partial) if b, ok := val.(*Bottom); ok && b.IsIncomplete() { n.exprs = append(n.exprs, envExpr{v, b}) break diff --git a/internal/core/dep/dep.go b/internal/core/dep/dep.go index 583b4378820..b4058a8fb03 100644 --- a/internal/core/dep/dep.go +++ b/internal/core/dep/dep.go @@ -228,7 +228,7 @@ func (c *visitor) markResolver(env *adt.Environment, r adt.Resolver) { return } - if ref, _ := c.ctxt.Resolve(env, r); ref != nil { + if ref, _ := c.ctxt.Resolve(adt.MakeConjunct(env, r, adt.CloseInfo{}), r); ref != nil { if ref != c.node && ref != empty { d := Dependency{ Node: ref, diff --git a/tools/trim/trim.go b/tools/trim/trim.go index 8d973507c49..323b762929b 100644 --- a/tools/trim/trim.go +++ b/tools/trim/trim.go @@ -237,7 +237,7 @@ func (t *trimmer) addDominators(d, v *adt.Vertex, hasDisjunction bool) (doms *ad doms.AddConjunct(c) default: if r, ok := c.Elem().(adt.Resolver); ok { - x, _ := t.ctx.Resolve(c.Env, r) + x, _ := t.ctx.Resolve(c, r) // Even if this is not a dominator now, descendants will be. if x != nil && x.Label.IsDef() { for _, c := range x.Conjuncts {