cuelang.org/go@v0.10.1/internal/core/adt/context.go (about)

     1  // Copyright 2020 CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package adt
    16  
    17  import (
    18  	"fmt"
    19  	"log"
    20  	"reflect"
    21  	"regexp"
    22  	"sort"
    23  	"strings"
    24  
    25  	"github.com/cockroachdb/apd/v3"
    26  	"golang.org/x/text/encoding/unicode"
    27  
    28  	"cuelang.org/go/cue/ast"
    29  	"cuelang.org/go/cue/errors"
    30  	"cuelang.org/go/cue/stats"
    31  	"cuelang.org/go/cue/token"
    32  	"cuelang.org/go/internal"
    33  	"cuelang.org/go/internal/cuedebug"
    34  )
    35  
    36  // DebugSort specifies that arcs be sorted consistently between implementations.
    37  //
    38  //	0: default
    39  //	1: sort by Feature: this should be consistent between implementations where
    40  //		   there is no change in the compiler and indexing code.
    41  //	2: alphabetical
    42  //
    43  // TODO: move to DebugFlags
    44  var DebugSort int
    45  
    46  func DebugSortArcs(c *OpContext, n *Vertex) {
    47  	if n.IsList() {
    48  		return
    49  	}
    50  	switch a := n.Arcs; DebugSort {
    51  	case 1:
    52  		sort.SliceStable(a, func(i, j int) bool {
    53  			return a[i].Label < a[j].Label
    54  		})
    55  	case 2:
    56  		sort.SliceStable(a, func(i, j int) bool {
    57  			return a[i].Label.SelectorString(c.Runtime) <
    58  				a[j].Label.SelectorString(c.Runtime)
    59  		})
    60  	}
    61  }
    62  
    63  func DebugSortFields(c *OpContext, a []Feature) {
    64  	switch DebugSort {
    65  	case 1:
    66  		sort.SliceStable(a, func(i, j int) bool {
    67  			return a[i] < a[j]
    68  		})
    69  	case 2:
    70  		sort.SliceStable(a, func(i, j int) bool {
    71  			return a[i].SelectorString(c.Runtime) <
    72  				a[j].SelectorString(c.Runtime)
    73  		})
    74  	}
    75  }
    76  
    77  // Assert panics if the condition is false. Assert can be used to check for
    78  // conditions that are considers to break an internal variant or unexpected
    79  // condition, but that nonetheless probably will be handled correctly down the
    80  // line. For instance, a faulty condition could lead to error being caught
    81  // down the road, but resulting in an inaccurate error message. In production
    82  // code it is better to deal with the bad error message than to panic.
    83  //
    84  // It is advisable for each use of Assert to document how the error is expected
    85  // to be handled down the line.
    86  func Assertf(c *OpContext, b bool, format string, args ...interface{}) {
    87  	if c.Strict && !b {
    88  		panic(fmt.Sprintf("assertion failed: "+format, args...))
    89  	}
    90  }
    91  
    92  // Assertf either panics or reports an error to c if the condition is not met.
    93  func (c *OpContext) Assertf(pos token.Pos, b bool, format string, args ...interface{}) {
    94  	if !b {
    95  		if c.Strict {
    96  			panic(fmt.Sprintf("assertion failed: "+format, args...))
    97  		}
    98  		c.addErrf(0, pos, format, args...)
    99  	}
   100  }
   101  
   102  func init() {
   103  	log.SetFlags(log.Lshortfile)
   104  }
   105  
   106  var pMap = map[*Vertex]int{}
   107  
   108  func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) {
   109  	if c.LogEval == 0 {
   110  		return
   111  	}
   112  	if v == nil {
   113  		s := fmt.Sprintf(strings.Repeat("..", c.nest)+format, args...)
   114  		_ = log.Output(2, s)
   115  		return
   116  	}
   117  	p := pMap[v]
   118  	if p == 0 {
   119  		p = len(pMap) + 1
   120  		pMap[v] = p
   121  	}
   122  	a := append([]interface{}{
   123  		strings.Repeat("..", c.nest),
   124  		p,
   125  		v.Label.SelectorString(c),
   126  		v.Path(),
   127  	}, args...)
   128  	for i := 2; i < len(a); i++ {
   129  		switch x := a[i].(type) {
   130  		case Node:
   131  			a[i] = c.Str(x)
   132  		case Feature:
   133  			a[i] = x.SelectorString(c)
   134  		}
   135  	}
   136  	s := fmt.Sprintf("%s [%d] %s/%v"+format, a...)
   137  	_ = log.Output(2, s)
   138  }
   139  
   140  // PathToString creates a pretty-printed path of the given list of features.
   141  func (c *OpContext) PathToString(path []Feature) string {
   142  	var b strings.Builder
   143  	for i, f := range path {
   144  		if i > 0 {
   145  			b.WriteByte('.')
   146  		}
   147  		b.WriteString(f.SelectorString(c))
   148  	}
   149  	return b.String()
   150  }
   151  
   152  // Runtime defines an interface for low-level representation conversion and
   153  // lookup.
   154  type Runtime interface {
   155  	// StringIndexer allows for converting string labels to and from a
   156  	// canonical numeric representation.
   157  	StringIndexer
   158  
   159  	// LoadImport loads a unique Vertex associated with a given import path. It
   160  	// returns nil if no import for this package could be found.
   161  	LoadImport(importPath string) *Vertex
   162  
   163  	// StoreType associates a CUE expression with a Go type.
   164  	StoreType(t reflect.Type, src ast.Expr, expr Expr)
   165  
   166  	// LoadType retrieves a previously stored CUE expression for a given Go
   167  	// type if available.
   168  	LoadType(t reflect.Type) (src ast.Expr, expr Expr, ok bool)
   169  
   170  	Settings() (internal.EvaluatorVersion, cuedebug.Config)
   171  }
   172  
   173  type Config struct {
   174  	Runtime
   175  	Format func(Runtime, Node) string
   176  }
   177  
   178  // New creates an operation context.
   179  func New(v *Vertex, cfg *Config) *OpContext {
   180  	if cfg.Runtime == nil {
   181  		panic("nil Runtime")
   182  	}
   183  	version, flags := cfg.Runtime.Settings()
   184  	ctx := &OpContext{
   185  		Runtime:     cfg.Runtime,
   186  		Format:      cfg.Format,
   187  		vertex:      v,
   188  		Version:     version,
   189  		Config:      flags,
   190  		taskContext: schedConfig,
   191  	}
   192  	if v != nil {
   193  		ctx.e = &Environment{Up: nil, Vertex: v}
   194  	}
   195  	return ctx
   196  }
   197  
   198  func (c *OpContext) isDevVersion() bool {
   199  	return c.Version == internal.DevVersion
   200  }
   201  
   202  // An OpContext implements CUE's unification operation. It only
   203  // operates on values that are created with the Runtime with which an OpContext
   204  // is associated. An OpContext is not goroutine safe and only one goroutine may
   205  // use an OpContext at a time.
   206  type OpContext struct {
   207  	Runtime
   208  	Format func(Runtime, Node) string
   209  
   210  	cuedebug.Config
   211  	Version internal.EvaluatorVersion // Copied from Runtime
   212  
   213  	taskContext
   214  
   215  	nest int
   216  
   217  	stats        stats.Counts
   218  	freeListNode *nodeContext
   219  
   220  	e         *Environment
   221  	ci        CloseInfo
   222  	src       ast.Node
   223  	errs      *Bottom
   224  	positions []Node // keep track of error positions
   225  
   226  	// vertex is used to determine the path location in case of error. Turning
   227  	// this into a stack could also allow determining the cyclic path for
   228  	// structural cycle errors.
   229  	vertex *Vertex
   230  
   231  	// These fields are used associate scratch fields for computing closedness
   232  	// of a Vertex. These fields could have been included in StructInfo (like
   233  	// Tomabechi's unification algorithm), but we opted for an indirection to
   234  	// allow concurrent unification.
   235  	//
   236  	// TODO(perf): have two generations: one for each pass of the closedness
   237  	// algorithm, so that the results of the first pass can be reused for all
   238  	// features of a node.
   239  	generation int
   240  	closed     map[*closeInfo]*closeStats
   241  	todo       *closeStats
   242  
   243  	// evalDepth indicates the current depth of evaluation. It is used to
   244  	// detect structural cycles and their severity.s
   245  	evalDepth int
   246  
   247  	// optionalMark indicates the evalDepth at which the last optional field,
   248  	// pattern constraint or other construct that may contain errors was
   249  	// encountered. A value of 0 indicates we are not within such field.
   250  	optionalMark int
   251  
   252  	// inDisjunct indicates that non-monotonic checks should be skipped.
   253  	// This is used if we want to do some extra work to eliminate disjunctions
   254  	// early. The result of unification should be thrown away if this check is
   255  	// used.
   256  	//
   257  	// TODO: replace this with a mechanism to determine the correct set (per
   258  	// conjunct) of StructInfos to include in closedness checking.
   259  	inDisjunct int
   260  
   261  	// inConstaint overrides inDisjunct as field matching should always be
   262  	// enabled.
   263  	inConstraint int
   264  
   265  	// inValidator defines whether full evaluation need to be enforced, for
   266  	// instance when comparing against bottom.
   267  	inValidator int
   268  
   269  	// The current call is a validator. A builtin may return a boolean false
   270  	// along with an error message describing a validation error. If the latter
   271  	// is wrapped in an internal.ValidationError, it will only be interpreted
   272  	// as an error if this is true.
   273  	// TODO: strictly separate validators and functions.
   274  	IsValidator bool
   275  
   276  	// ErrorGraphs contains an analysis, represented as a Mermaid graph, for
   277  	// each node that has an error.
   278  	ErrorGraphs map[string]string
   279  }
   280  
   281  func (c *OpContext) CloseInfo() CloseInfo { return c.ci }
   282  
   283  func (n *nodeContext) skipNonMonotonicChecks() bool {
   284  	if n.ctx.inConstraint > 0 {
   285  		return false
   286  	}
   287  	return n.ctx.inDisjunct > 0
   288  }
   289  
   290  // Impl is for internal use only. This will go.
   291  func (c *OpContext) Impl() Runtime {
   292  	return c.Runtime
   293  }
   294  
   295  func (c *OpContext) Pos() token.Pos {
   296  	if c.src == nil {
   297  		return token.NoPos
   298  	}
   299  	return c.src.Pos()
   300  }
   301  
   302  func (c *OpContext) Source() ast.Node {
   303  	return c.src
   304  }
   305  
   306  // NewContext creates an operation context.
   307  func NewContext(r Runtime, v *Vertex) *OpContext {
   308  	return New(v, &Config{Runtime: r})
   309  }
   310  
   311  func (c *OpContext) pos() token.Pos {
   312  	if c.src == nil {
   313  		return token.NoPos
   314  	}
   315  	return c.src.Pos()
   316  }
   317  
   318  func (c *OpContext) spawn(node *Vertex) *Environment {
   319  	return spawn(c.e, node)
   320  }
   321  
   322  func spawn(env *Environment, node *Vertex) *Environment {
   323  	return &Environment{
   324  		Up:     env,
   325  		Vertex: node,
   326  	}
   327  }
   328  
   329  func (c *OpContext) Env(upCount int32) *Environment {
   330  	return c.e.up(c, upCount)
   331  }
   332  
   333  func (c *OpContext) relNode(upCount int32) *Vertex {
   334  	e := c.e.up(c, upCount)
   335  	c.unify(e.Vertex, oldOnly(partial))
   336  	return e.Vertex
   337  }
   338  
   339  func (c *OpContext) relLabel(upCount int32) Feature {
   340  	// locate current label.
   341  	e := c.e.up(c, upCount)
   342  	return e.DynamicLabel
   343  }
   344  
   345  func (c *OpContext) concreteIsPossible(op Op, x Expr) bool {
   346  	if !AssertConcreteIsPossible(op, x) {
   347  		// No need to take position of expression.
   348  		c.AddErr(c.NewPosf(token.NoPos,
   349  			"invalid operand %s ('%s' requires concrete value)", x, op))
   350  		return false
   351  	}
   352  	return true
   353  }
   354  
   355  // Assert that the given expression can evaluate to a concrete value.
   356  func AssertConcreteIsPossible(op Op, x Expr) bool {
   357  	switch v := x.(type) {
   358  	case *Bottom:
   359  	case *BoundExpr:
   360  		return false
   361  	case Value:
   362  		return v.Concreteness() == Concrete
   363  	}
   364  	return true
   365  }
   366  
   367  // HasErr reports whether any error was reported, including whether value
   368  // was incomplete.
   369  func (c *OpContext) HasErr() bool {
   370  	return c.errs != nil
   371  }
   372  
   373  func (c *OpContext) Err() *Bottom {
   374  	b := c.errs
   375  	c.errs = nil
   376  	return b
   377  }
   378  
   379  func (c *OpContext) addErrf(code ErrorCode, pos token.Pos, msg string, args ...interface{}) {
   380  	err := c.NewPosf(pos, msg, args...)
   381  	c.addErr(code, err)
   382  }
   383  
   384  func (c *OpContext) addErr(code ErrorCode, err errors.Error) {
   385  	c.AddBottom(&Bottom{Code: code, Err: err})
   386  }
   387  
   388  // AddBottom records an error in OpContext.
   389  func (c *OpContext) AddBottom(b *Bottom) {
   390  	c.errs = CombineErrors(c.src, c.errs, b)
   391  }
   392  
   393  // AddErr records an error in OpContext. It returns errors collected so far.
   394  func (c *OpContext) AddErr(err errors.Error) *Bottom {
   395  	if err != nil {
   396  		c.AddBottom(&Bottom{Err: err})
   397  	}
   398  	return c.errs
   399  }
   400  
   401  // NewErrf creates a *Bottom value and returns it. The returned uses the
   402  // current source as the point of origin of the error.
   403  func (c *OpContext) NewErrf(format string, args ...interface{}) *Bottom {
   404  	// TODO: consider renaming ot NewBottomf: this is now confusing as we also
   405  	// have Newf.
   406  	err := c.Newf(format, args...)
   407  	return &Bottom{Src: c.src, Err: err, Code: EvalError}
   408  }
   409  
   410  // AddErrf records an error in OpContext. It returns errors collected so far.
   411  func (c *OpContext) AddErrf(format string, args ...interface{}) *Bottom {
   412  	return c.AddErr(c.Newf(format, args...))
   413  }
   414  
   415  type frame struct {
   416  	env *Environment
   417  	err *Bottom
   418  	src ast.Node
   419  	ci  CloseInfo
   420  }
   421  
   422  func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) {
   423  	saved.env = c.e
   424  	saved.err = c.errs
   425  	saved.src = c.src
   426  	saved.ci = c.ci
   427  
   428  	c.errs = nil
   429  	if src != nil {
   430  		c.src = src
   431  	}
   432  	c.e = env
   433  
   434  	return saved
   435  }
   436  
   437  func (c *OpContext) PushConjunct(x Conjunct) (saved frame) {
   438  	src := x.Expr().Source()
   439  
   440  	saved.env = c.e
   441  	saved.err = c.errs
   442  	saved.src = c.src
   443  	saved.ci = c.ci
   444  
   445  	c.errs = nil
   446  	if src != nil {
   447  		c.src = src
   448  	}
   449  	c.e = x.Env
   450  	c.ci = x.CloseInfo
   451  
   452  	return saved
   453  }
   454  
   455  func (c *OpContext) PopState(s frame) *Bottom {
   456  	err := c.errs
   457  	c.e = s.env
   458  	c.errs = s.err
   459  	c.src = s.src
   460  	c.ci = s.ci
   461  	return err
   462  }
   463  
   464  // PushArc signals c that arc v is currently being processed for the purpose
   465  // of error reporting. PopArc should be called with the returned value once
   466  // processing of v is completed.
   467  func (c *OpContext) PushArc(v *Vertex) (saved *Vertex) {
   468  	c.vertex, saved = v, c.vertex
   469  	return saved
   470  }
   471  
   472  // PopArc signals completion of processing the current arc.
   473  func (c *OpContext) PopArc(saved *Vertex) {
   474  	c.vertex = saved
   475  }
   476  
   477  // Resolve finds a node in the tree.
   478  //
   479  // Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts
   480  // and error.
   481  func (c *OpContext) Resolve(x Conjunct, r Resolver) (*Vertex, *Bottom) {
   482  	return c.resolveState(x, r, final(finalized, allKnown))
   483  }
   484  
   485  func (c *OpContext) resolveState(x Conjunct, r Resolver, state combinedFlags) (*Vertex, *Bottom) {
   486  	s := c.PushConjunct(x)
   487  
   488  	arc := r.resolve(c, state)
   489  
   490  	err := c.PopState(s)
   491  	if err != nil {
   492  		return nil, err
   493  	}
   494  
   495  	if arc.ChildErrors != nil && arc.ChildErrors.Code == StructuralCycleError {
   496  		return nil, arc.ChildErrors
   497  	}
   498  
   499  	// Dereference any vertices that do not contribute to more knownledge about
   500  	// the node.
   501  	arc = arc.DerefNonRooted()
   502  
   503  	return arc, err
   504  }
   505  
   506  // Lookup looks up r in env without further resolving the value.
   507  func (c *OpContext) Lookup(env *Environment, r Resolver) (*Vertex, *Bottom) {
   508  	s := c.PushState(env, r.Source())
   509  
   510  	arc := r.resolve(c, oldOnly(partial))
   511  
   512  	err := c.PopState(s)
   513  
   514  	if arc != nil && !c.isDevVersion() {
   515  		// TODO(deref): lookup should probably not use DerefValue, but
   516  		// rather only dereference disjunctions.
   517  		arc = arc.DerefValue()
   518  	}
   519  
   520  	return arc, err
   521  }
   522  
   523  // Validate calls validates value for the given validator.
   524  //
   525  // TODO(errors): return boolean instead: only the caller has enough information
   526  // to generate a proper error message.
   527  func (c *OpContext) Validate(check Validator, value Value) *Bottom {
   528  	// TODO: use a position stack to push both values.
   529  	saved := c.src
   530  	c.src = check.Source()
   531  
   532  	err := check.validate(c, value)
   533  
   534  	c.src = saved
   535  
   536  	return err
   537  }
   538  
   539  // concrete returns the concrete value of x after evaluating it.
   540  // msg is used to mention the context in which an error occurred, if any.
   541  func (c *OpContext) concrete(env *Environment, x Expr, msg interface{}) (result Value, complete bool) {
   542  	s := c.PushState(env, x.Source())
   543  
   544  	state := require(partial, concreteKnown)
   545  	w := c.evalState(x, state)
   546  	_ = c.PopState(s)
   547  
   548  	w, ok := c.getDefault(w)
   549  	if !ok {
   550  		return w, false
   551  	}
   552  	v := Unwrap(w)
   553  
   554  	complete = w != nil
   555  	if !IsConcrete(v) {
   556  		complete = false
   557  		b := c.NewErrf("non-concrete value %v in operand to %s", w, msg)
   558  		b.Code = IncompleteError
   559  		v = b
   560  	}
   561  
   562  	return v, complete
   563  }
   564  
   565  // getDefault resolves a disjunction to a single value. If there is no default
   566  // value, or if there is more than one default value, it reports an "incomplete"
   567  // error and return false. In all other cases it will return true, even if
   568  // v is already an error. v may be nil, in which case it will also return nil.
   569  func (c *OpContext) getDefault(v Value) (result Value, ok bool) {
   570  	var d *Disjunction
   571  	switch x := v.(type) {
   572  	default:
   573  		return v, true
   574  
   575  	case *Vertex:
   576  		// TODO: return vertex if not disjunction.
   577  		switch t := x.BaseValue.(type) {
   578  		case *Disjunction:
   579  			d = t
   580  
   581  		case *Vertex:
   582  			return c.getDefault(t)
   583  
   584  		default:
   585  			return x, true
   586  		}
   587  
   588  	case *Disjunction:
   589  		d = x
   590  	}
   591  
   592  	if d.NumDefaults != 1 {
   593  		c.addErrf(IncompleteError, c.pos(),
   594  			"unresolved disjunction %v (type %s)", d, d.Kind())
   595  		return nil, false
   596  	}
   597  	return c.getDefault(d.Values[0])
   598  }
   599  
   600  // Evaluate evaluates an expression within the given environment and indicates
   601  // whether the result is complete. It will always return a non-nil result.
   602  func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) {
   603  	s := c.PushState(env, x.Source())
   604  
   605  	val := c.evalState(x, final(partial, concreteKnown))
   606  
   607  	complete = true
   608  
   609  	if err, _ := val.(*Bottom); err != nil && err.IsIncomplete() {
   610  		complete = false
   611  	}
   612  	if val == nil {
   613  		complete = false
   614  		// TODO ENSURE THIS DOESN"T HAPPEN>
   615  		val = &Bottom{
   616  			Code: IncompleteError,
   617  			Err:  c.Newf("UNANTICIPATED ERROR"),
   618  		}
   619  
   620  	}
   621  
   622  	_ = c.PopState(s)
   623  
   624  	if !complete || val == nil {
   625  		return val, false
   626  	}
   627  
   628  	return val, true
   629  }
   630  
   631  func (c *OpContext) evaluateRec(v Conjunct, state combinedFlags) Value {
   632  	x := v.Expr()
   633  	s := c.PushConjunct(v)
   634  
   635  	val := c.evalState(x, state)
   636  	if val == nil {
   637  		// Be defensive: this never happens, but just in case.
   638  		Assertf(c, false, "nil return value: unspecified error")
   639  		val = &Bottom{
   640  			Code: IncompleteError,
   641  			Err:  c.Newf("UNANTICIPATED ERROR"),
   642  		}
   643  	}
   644  	_ = c.PopState(s)
   645  
   646  	return val
   647  }
   648  
   649  // value evaluates expression v within the current environment. The result may
   650  // be nil if the result is incomplete. value leaves errors untouched to that
   651  // they can be collected by the caller.
   652  func (c *OpContext) value(x Expr, state combinedFlags) (result Value) {
   653  	v := c.evalState(x, state)
   654  
   655  	v, _ = c.getDefault(v)
   656  	v = Unwrap(v)
   657  	return v
   658  }
   659  
   660  func (c *OpContext) evalState(v Expr, state combinedFlags) (result Value) {
   661  	savedSrc := c.src
   662  	c.src = v.Source()
   663  	err := c.errs
   664  	c.errs = nil
   665  
   666  	defer func() {
   667  		c.errs = CombineErrors(c.src, c.errs, err)
   668  
   669  		if v, ok := result.(*Vertex); ok {
   670  			if b := v.Bottom(); b != nil {
   671  				switch b.Code {
   672  				case IncompleteError:
   673  				case CycleError:
   674  					if state.vertexStatus() == partial || c.isDevVersion() {
   675  						break
   676  					}
   677  					fallthrough
   678  				default:
   679  					result = b
   680  				}
   681  			}
   682  		}
   683  
   684  		// TODO: remove this when we handle errors more principally.
   685  		if b, ok := result.(*Bottom); ok {
   686  			result = c.wrapCycleError(c.src, b)
   687  			if c.errs != result {
   688  				c.errs = CombineErrors(c.src, c.errs, result)
   689  			}
   690  		}
   691  		if c.errs != nil {
   692  			result = c.errs
   693  		}
   694  		c.src = savedSrc
   695  	}()
   696  
   697  	switch x := v.(type) {
   698  	case Value:
   699  		return x
   700  
   701  	case Evaluator:
   702  		v := x.evaluate(c, state)
   703  		return v
   704  
   705  	case Resolver:
   706  		arc := x.resolve(c, state)
   707  		if c.HasErr() {
   708  			return nil
   709  		}
   710  		if arc == nil {
   711  			return nil
   712  		}
   713  		// TODO(deref): what is the right level of dereferencing here?
   714  		// DerefValue seems to work too.
   715  		arc = arc.DerefNonShared()
   716  
   717  		// TODO: consider moving this after markCycle, depending on how we
   718  		// implement markCycle, or whether we need it at all.
   719  		// TODO: is this indirect necessary?
   720  		// arc = arc.Indirect()
   721  
   722  		// Save the old CloseInfo and restore after evaluate to avoid detecting
   723  		// spurious cycles.
   724  		saved := c.ci
   725  		n := arc.state
   726  		if c.isDevVersion() {
   727  			n = arc.getState(c)
   728  		}
   729  		if n != nil {
   730  			c.ci, _ = n.markCycle(arc, nil, x, c.ci)
   731  		}
   732  		c.ci.Inline = true
   733  
   734  		if c.isDevVersion() {
   735  			if s := arc.getState(c); s != nil {
   736  				needs := state.conditions()
   737  				runMode := state.runMode()
   738  
   739  				arc.unify(c, needs|arcTypeKnown, attemptOnly) // to set scalar
   740  
   741  				if runMode == finalize {
   742  					// arc.unify(c, needs, attemptOnly) // to set scalar
   743  					// Freeze node.
   744  					arc.state.freeze(needs)
   745  				} else {
   746  					arc.unify(c, needs, runMode)
   747  				}
   748  
   749  				v := arc
   750  				if v.ArcType == ArcPending {
   751  					if v.status == evaluating {
   752  						for ; v.Parent != nil && v.ArcType == ArcPending; v = v.Parent {
   753  						}
   754  						err := c.Newf("cycle with field %v", x)
   755  						b := &Bottom{Code: CycleError, Err: err}
   756  						v.setValue(c, v.status, b)
   757  						return b
   758  						// TODO: use this instead, as is usual for incomplete errors,
   759  						// and also move this block one scope up to also apply to
   760  						// defined arcs. In both cases, though, doing so results in
   761  						// some errors to be misclassified as evaluation error.
   762  						// c.AddBottom(b)
   763  						// return nil
   764  					}
   765  					c.undefinedFieldError(v, IncompleteError)
   766  					return nil
   767  				}
   768  			}
   769  		}
   770  		v := c.evaluate(arc, x, state)
   771  		c.ci = saved
   772  		return v
   773  
   774  	default:
   775  		// This can only happen, really, if v == nil, which is not allowed.
   776  		panic(fmt.Sprintf("unexpected Expr type %T", v))
   777  	}
   778  }
   779  
   780  // wrapCycleError converts the sentinel cycleError in a concrete one with
   781  // position information.
   782  func (c *OpContext) wrapCycleError(src ast.Node, b *Bottom) *Bottom {
   783  	if src != nil &&
   784  		b.Code == CycleError &&
   785  		len(errors.Positions(b.Err)) == 0 {
   786  		bb := *b
   787  		bb.Err = errors.Wrapf(b.Err, src.Pos(), "")
   788  		b = &bb
   789  	}
   790  	return b
   791  }
   792  
   793  // unifyNode returns a possibly partially evaluated node value.
   794  //
   795  // TODO: maybe return *Vertex, *Bottom
   796  func (c *OpContext) unifyNode(v Expr, state combinedFlags) (result Value) {
   797  	savedSrc := c.src
   798  	c.src = v.Source()
   799  	err := c.errs
   800  	c.errs = nil
   801  
   802  	defer func() {
   803  		c.errs = CombineErrors(c.src, c.errs, err)
   804  
   805  		if v, ok := result.(*Vertex); ok {
   806  			if b := v.Bottom(); b != nil && !b.IsIncomplete() {
   807  				result = b
   808  			}
   809  		}
   810  
   811  		// TODO: remove this when we handle errors more principally.
   812  		if b, ok := result.(*Bottom); ok {
   813  			if c.src != nil &&
   814  				b.Code == CycleError &&
   815  				b.Err.Position() == token.NoPos &&
   816  				len(b.Err.InputPositions()) == 0 {
   817  				bb := *b
   818  				bb.Err = errors.Wrapf(b.Err, c.src.Pos(), "")
   819  				result = &bb
   820  			}
   821  			c.errs = CombineErrors(c.src, c.errs, result)
   822  		}
   823  		if c.errs != nil {
   824  			result = c.errs
   825  		}
   826  		c.src = savedSrc
   827  	}()
   828  
   829  	switch x := v.(type) {
   830  	case Value:
   831  		return x
   832  
   833  	case Evaluator:
   834  		v := x.evaluate(c, state)
   835  		return v
   836  
   837  	case Resolver:
   838  		v := x.resolve(c, state)
   839  		if c.HasErr() {
   840  			return nil
   841  		}
   842  		if v == nil {
   843  			return nil
   844  		}
   845  		v = v.DerefValue()
   846  
   847  		// TODO: consider moving this after markCycle, depending on how we
   848  		// implement markCycle, or whether we need it at all.
   849  		// TODO: is this indirect necessary?
   850  		// v = v.Indirect()
   851  
   852  		if c.isDevVersion() {
   853  			if n := v.getState(c); n != nil {
   854  				// Always yield to not get spurious errors.
   855  				n.process(arcTypeKnown, yield)
   856  			}
   857  		} else {
   858  			if v.isUndefined() || state.vertexStatus() > v.status {
   859  				c.unify(v, state)
   860  			}
   861  		}
   862  
   863  		return v
   864  
   865  	default:
   866  		// This can only happen, really, if v == nil, which is not allowed.
   867  		panic(fmt.Sprintf("unexpected Expr type %T", v))
   868  	}
   869  }
   870  
   871  func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, flags combinedFlags) *Vertex {
   872  	if c.isDevVersion() {
   873  		return x.lookup(c, pos, l, flags)
   874  	}
   875  
   876  	state := flags.vertexStatus()
   877  
   878  	if l == InvalidLabel || x == nil {
   879  		// TODO: is it possible to have an invalid label here? Maybe through the
   880  		// API?
   881  		return &Vertex{}
   882  	}
   883  
   884  	// var kind Kind
   885  	// if x.BaseValue != nil {
   886  	// 	kind = x.BaseValue.Kind()
   887  	// }
   888  
   889  	switch x.BaseValue.(type) {
   890  	case *StructMarker:
   891  		if l.Typ() == IntLabel {
   892  			c.addErrf(0, pos, "invalid struct selector %v (type int)", l)
   893  			return nil
   894  		}
   895  
   896  	case *ListMarker:
   897  		switch {
   898  		case l.Typ() == IntLabel:
   899  			switch {
   900  			case l.Index() < 0:
   901  				c.addErrf(0, pos, "invalid list index %v (index must be non-negative)", l)
   902  				return nil
   903  			case l.Index() > len(x.Arcs):
   904  				c.addErrf(0, pos, "invalid list index %v (out of bounds)", l)
   905  				return nil
   906  			}
   907  
   908  		case l.IsDef(), l.IsHidden(), l.IsLet():
   909  
   910  		default:
   911  			c.addErrf(0, pos, "invalid list index %v (type string)", l)
   912  			return nil
   913  		}
   914  
   915  	case nil:
   916  		// c.addErrf(IncompleteError, pos, "incomplete value %s", x)
   917  		// return nil
   918  
   919  	case *Bottom:
   920  
   921  	default:
   922  		kind := x.BaseValue.Kind()
   923  		if kind&(ListKind|StructKind) != 0 {
   924  			// c.addErrf(IncompleteError, pos,
   925  			// 	"cannot look up %s in incomplete type %s (type %s)",
   926  			// 	l, x.Source(), kind)
   927  			// return nil
   928  		} else if !l.IsDef() && !l.IsHidden() && !l.IsLet() {
   929  			c.addErrf(0, pos,
   930  				"invalid selector %v for value of type %s", l, kind)
   931  			return nil
   932  		}
   933  	}
   934  
   935  	a := x.Lookup(l)
   936  
   937  	var hasCycle bool
   938  
   939  	if a != nil {
   940  		// Ensure that a's status is at least of the required level. Otherwise,
   941  		// ensure that any remaining unprocessed conjuncts are processed by
   942  		// calling c.Unify(a, Partial). The ensures that need to rely on
   943  		// hasAllConjuncts, but that are finalized too early, get conjuncts
   944  		// processed beforehand.
   945  		if state > a.status {
   946  			c.unify(a, deprecated(c, state))
   947  		} else if a.state != nil {
   948  			c.unify(a, deprecated(c, partial))
   949  		}
   950  
   951  		if a.IsConstraint() {
   952  			code := IncompleteError
   953  			if hasCycle {
   954  				code = CycleError
   955  			}
   956  			label := l.SelectorString(c.Runtime)
   957  			c.AddBottom(&Bottom{
   958  				Code:      code,
   959  				Permanent: x.status >= conjuncts,
   960  				Err: c.NewPosf(pos,
   961  					"cannot reference optional field: %s", label),
   962  			})
   963  		}
   964  	} else {
   965  		if x.state != nil {
   966  			x.state.assertInitialized()
   967  
   968  			for _, e := range x.state.exprs {
   969  				if isCyclePlaceholder(e.err) {
   970  					hasCycle = true
   971  				}
   972  			}
   973  		}
   974  		code := IncompleteError
   975  		// As long as we have incomplete information, we cannot mark the
   976  		// inability to look up a field as "final", as it may resolve down the
   977  		// line.
   978  		permanent := x.status >= conjuncts
   979  		if m, _ := x.BaseValue.(*ListMarker); m != nil && !m.IsOpen {
   980  			permanent = true
   981  		}
   982  		if (state > partial || permanent) && !x.Accept(c, l) {
   983  			code = 0
   984  		} else if hasCycle {
   985  			code = CycleError
   986  		}
   987  		// TODO: if the struct was a literal struct, we can also treat it as
   988  		// closed and make this a permanent error.
   989  		label := l.SelectorString(c.Runtime)
   990  
   991  		// TODO(errors): add path reference and make message
   992  		//       "undefined field %s in %s"
   993  		var err *ValueError
   994  		switch {
   995  		case isCyclePlaceholder(x.BaseValue):
   996  			err = c.NewPosf(pos, "cycle error referencing %s", label)
   997  			permanent = false
   998  		case l.IsInt():
   999  			err = c.NewPosf(pos, "index out of range [%d] with length %d",
  1000  				l.Index(), len(x.Elems()))
  1001  		default:
  1002  			err = c.NewPosf(pos, "undefined field: %s", label)
  1003  		}
  1004  		c.AddBottom(&Bottom{
  1005  			Code:      code,
  1006  			Permanent: permanent,
  1007  			Err:       err,
  1008  		})
  1009  	}
  1010  	return a
  1011  }
  1012  
  1013  func (c *OpContext) undefinedFieldError(v *Vertex, code ErrorCode) {
  1014  	label := v.Label.SelectorString(c)
  1015  	c.addErrf(code, c.pos(), "undefined field: %s", label)
  1016  }
  1017  
  1018  func (c *OpContext) Label(src Expr, x Value) Feature {
  1019  	return LabelFromValue(c, src, x)
  1020  }
  1021  
  1022  func (c *OpContext) typeError(v Value, k Kind) {
  1023  	if isError(v) {
  1024  		return
  1025  	}
  1026  	if !IsConcrete(v) && v.Kind()&k != 0 {
  1027  		c.addErrf(IncompleteError, pos(v), "incomplete %s: %s", k, v)
  1028  	} else {
  1029  		c.AddErrf("cannot use %s (type %s) as type %s", v, v.Kind(), k)
  1030  	}
  1031  }
  1032  
  1033  func (c *OpContext) typeErrorAs(v Value, k Kind, as interface{}) {
  1034  	if as == nil {
  1035  		c.typeError(v, k)
  1036  		return
  1037  	}
  1038  	if isError(v) {
  1039  		return
  1040  	}
  1041  	if !IsConcrete(v) && v.Kind()&k != 0 {
  1042  		c.addErrf(IncompleteError, pos(v),
  1043  			"incomplete %s in %v: %s", k, as, v)
  1044  	} else {
  1045  		c.AddErrf("cannot use %s (type %s) as type %s in %v", v, v.Kind(), k, as)
  1046  	}
  1047  }
  1048  
  1049  var emptyNode = &Vertex{}
  1050  
  1051  func pos(x Node) token.Pos {
  1052  	if x.Source() == nil {
  1053  		return token.NoPos
  1054  	}
  1055  	return x.Source().Pos()
  1056  }
  1057  
  1058  func (c *OpContext) node(orig Node, x Expr, scalar bool, state combinedFlags) *Vertex {
  1059  	// TODO: always get the vertex. This allows a whole bunch of trickery
  1060  	// down the line.
  1061  	v := c.unifyNode(x, state)
  1062  
  1063  	v, ok := c.getDefault(v)
  1064  	if !ok {
  1065  		// Error already generated by getDefault.
  1066  		return emptyNode
  1067  	}
  1068  
  1069  	// The two if blocks below are rather subtle. If we have an error of
  1070  	// the sentinel value cycle, we have earlier determined that the cycle is
  1071  	// allowed and that it can be ignored here. Any other CycleError is an
  1072  	// annotated cycle error that could be taken as is.
  1073  	// TODO: do something simpler.
  1074  	if scalar {
  1075  		if w := Unwrap(v); !isCyclePlaceholder(w) {
  1076  			v = w
  1077  		}
  1078  	}
  1079  
  1080  	node, ok := v.(*Vertex)
  1081  	if ok && !isCyclePlaceholder(node.BaseValue) {
  1082  		v = node.Value()
  1083  	}
  1084  
  1085  	switch nv := v.(type) {
  1086  	case nil:
  1087  		c.addErrf(IncompleteError, pos(x),
  1088  			"%s undefined (%s is incomplete)", orig, x)
  1089  		return emptyNode
  1090  
  1091  	case *Bottom:
  1092  		// TODO: this is a bit messy. In some cases errors are already added
  1093  		// and in some cases not. Not a huge deal, as errors will be uniqued
  1094  		// down the line, but could be better.
  1095  		c.AddBottom(nv)
  1096  		return emptyNode
  1097  
  1098  	case *Vertex:
  1099  		if node == nil {
  1100  			panic("unexpected markers with nil node")
  1101  		}
  1102  
  1103  	default:
  1104  		if kind := v.Kind(); kind&StructKind != 0 {
  1105  			c.addErrf(IncompleteError, pos(x),
  1106  				"%s undefined as %s is incomplete (type %s)", orig, x, kind)
  1107  			return emptyNode
  1108  
  1109  		} else if !ok {
  1110  			c.addErrf(0, pos(x), // TODO(error): better message.
  1111  				"invalid operand %s (found %s, want list or struct)",
  1112  				x.Source(), v.Kind())
  1113  			return emptyNode
  1114  		}
  1115  	}
  1116  
  1117  	return node
  1118  }
  1119  
  1120  // Elems returns the evaluated elements of a list.
  1121  func (c *OpContext) Elems(v Value) []*Vertex {
  1122  	list := c.list(v)
  1123  	list.Finalize(c)
  1124  	return list.Elems()
  1125  }
  1126  
  1127  // RawElems returns the elements of the list without evaluating them.
  1128  func (c *OpContext) RawElems(v Value) []*Vertex {
  1129  	list := c.list(v)
  1130  	return list.Elems()
  1131  }
  1132  
  1133  func (c *OpContext) list(v Value) *Vertex {
  1134  	x, ok := v.(*Vertex)
  1135  	if !ok || !x.IsList() {
  1136  		c.typeError(v, ListKind)
  1137  		return emptyNode
  1138  	}
  1139  	return x
  1140  }
  1141  
  1142  func (c *OpContext) scalar(v Value) Value {
  1143  	v = Unwrap(v)
  1144  	switch v.(type) {
  1145  	case *Null, *Bool, *Num, *String, *Bytes:
  1146  	default:
  1147  		c.typeError(v, ScalarKinds)
  1148  	}
  1149  	return v
  1150  }
  1151  
  1152  var zero = &Num{K: NumberKind}
  1153  
  1154  func (c *OpContext) Num(v Value, as interface{}) *Num {
  1155  	v = Unwrap(v)
  1156  	if isError(v) {
  1157  		return zero
  1158  	}
  1159  	x, ok := v.(*Num)
  1160  	if !ok {
  1161  		c.typeErrorAs(v, NumberKind, as)
  1162  		return zero
  1163  	}
  1164  	return x
  1165  }
  1166  
  1167  func (c *OpContext) Int64(v Value) int64 {
  1168  	v = Unwrap(v)
  1169  	if isError(v) {
  1170  		return 0
  1171  	}
  1172  	x, ok := v.(*Num)
  1173  	if !ok {
  1174  		c.typeError(v, IntKind)
  1175  		return 0
  1176  	}
  1177  	i, err := x.X.Int64()
  1178  	if err != nil {
  1179  		c.AddErrf("number is not an int64: %v", err)
  1180  		return 0
  1181  	}
  1182  	return i
  1183  }
  1184  
  1185  func (c *OpContext) uint64(v Value, as string) uint64 {
  1186  	v = Unwrap(v)
  1187  	if isError(v) {
  1188  		return 0
  1189  	}
  1190  	x, ok := v.(*Num)
  1191  	if !ok {
  1192  		c.typeErrorAs(v, IntKind, as)
  1193  		return 0
  1194  	}
  1195  	if x.X.Negative {
  1196  		// TODO: improve message
  1197  		c.AddErrf("cannot convert negative number to uint64")
  1198  		return 0
  1199  	}
  1200  	if !x.X.Coeff.IsUint64() {
  1201  		// TODO: improve message
  1202  		c.AddErrf("cannot convert number %s to uint64", &x.X)
  1203  		return 0
  1204  	}
  1205  	return x.X.Coeff.Uint64()
  1206  }
  1207  
  1208  func (c *OpContext) BoolValue(v Value) bool {
  1209  	return c.boolValue(v, nil)
  1210  }
  1211  
  1212  func (c *OpContext) boolValue(v Value, as interface{}) bool {
  1213  	v = Unwrap(v)
  1214  	if isError(v) {
  1215  		return false
  1216  	}
  1217  	x, ok := v.(*Bool)
  1218  	if !ok {
  1219  		c.typeErrorAs(v, BoolKind, as)
  1220  		return false
  1221  	}
  1222  	return x.B
  1223  }
  1224  
  1225  func (c *OpContext) StringValue(v Value) string {
  1226  	return c.stringValue(v, nil)
  1227  }
  1228  
  1229  // ToBytes returns the bytes value of a scalar value.
  1230  func (c *OpContext) ToBytes(v Value) []byte {
  1231  	if x, ok := v.(*Bytes); ok {
  1232  		return x.B
  1233  	}
  1234  	return []byte(c.ToString(v))
  1235  }
  1236  
  1237  // ToString returns the string value of a scalar value.
  1238  func (c *OpContext) ToString(v Value) string {
  1239  	return c.toStringValue(v, StringKind|NumberKind|BytesKind|BoolKind, nil)
  1240  
  1241  }
  1242  
  1243  func (c *OpContext) stringValue(v Value, as interface{}) string {
  1244  	return c.toStringValue(v, StringKind, as)
  1245  }
  1246  
  1247  func (c *OpContext) toStringValue(v Value, k Kind, as interface{}) string {
  1248  	v = Unwrap(v)
  1249  	if isError(v) {
  1250  		return ""
  1251  	}
  1252  	if v.Kind()&k == 0 {
  1253  		if as == nil {
  1254  			c.typeError(v, k)
  1255  		} else {
  1256  			c.typeErrorAs(v, k, as)
  1257  		}
  1258  		return ""
  1259  	}
  1260  	switch x := v.(type) {
  1261  	case *String:
  1262  		return x.Str
  1263  
  1264  	case *Bytes:
  1265  		return bytesToString(x.B)
  1266  
  1267  	case *Num:
  1268  		return x.X.String()
  1269  
  1270  	case *Bool:
  1271  		if x.B {
  1272  			return "true"
  1273  		}
  1274  		return "false"
  1275  
  1276  	default:
  1277  		c.addErrf(IncompleteError, c.pos(),
  1278  			"non-concrete value %s (type %s)", v, v.Kind())
  1279  	}
  1280  	return ""
  1281  }
  1282  
  1283  func bytesToString(b []byte) string {
  1284  	b, _ = unicode.UTF8.NewDecoder().Bytes(b)
  1285  	return string(b)
  1286  }
  1287  
  1288  func (c *OpContext) bytesValue(v Value, as interface{}) []byte {
  1289  	v = Unwrap(v)
  1290  	if isError(v) {
  1291  		return nil
  1292  	}
  1293  	x, ok := v.(*Bytes)
  1294  	if !ok {
  1295  		c.typeErrorAs(v, BytesKind, as)
  1296  		return nil
  1297  	}
  1298  	return x.B
  1299  }
  1300  
  1301  var matchNone = regexp.MustCompile("^$")
  1302  
  1303  func (c *OpContext) regexp(v Value) *regexp.Regexp {
  1304  	v = Unwrap(v)
  1305  	if isError(v) {
  1306  		return matchNone
  1307  	}
  1308  	switch x := v.(type) {
  1309  	case *String:
  1310  		if x.RE != nil {
  1311  			return x.RE
  1312  		}
  1313  		// TODO: synchronization
  1314  		p, err := regexp.Compile(x.Str)
  1315  		if err != nil {
  1316  			// FatalError? How to cache error
  1317  			c.AddErrf("invalid regexp: %s", err)
  1318  			x.RE = matchNone
  1319  		} else {
  1320  			x.RE = p
  1321  		}
  1322  		return x.RE
  1323  
  1324  	case *Bytes:
  1325  		if x.RE != nil {
  1326  			return x.RE
  1327  		}
  1328  		// TODO: synchronization
  1329  		p, err := regexp.Compile(string(x.B))
  1330  		if err != nil {
  1331  			c.AddErrf("invalid regexp: %s", err)
  1332  			x.RE = matchNone
  1333  		} else {
  1334  			x.RE = p
  1335  		}
  1336  		return x.RE
  1337  
  1338  	default:
  1339  		c.typeError(v, StringKind|BytesKind)
  1340  		return matchNone
  1341  	}
  1342  }
  1343  
  1344  // newNum creates a new number of the given kind. It reports an error value
  1345  // instead if any error occurred.
  1346  func (c *OpContext) newNum(d *apd.Decimal, k Kind, sources ...Node) Value {
  1347  	if c.HasErr() {
  1348  		return c.Err()
  1349  	}
  1350  	return &Num{Src: c.src, X: *d, K: k}
  1351  }
  1352  
  1353  func (c *OpContext) NewInt64(n int64, sources ...Node) Value {
  1354  	if c.HasErr() {
  1355  		return c.Err()
  1356  	}
  1357  	d := apd.New(n, 0)
  1358  	return &Num{Src: c.src, X: *d, K: IntKind}
  1359  }
  1360  
  1361  func (c *OpContext) NewString(s string) Value {
  1362  	if c.HasErr() {
  1363  		return c.Err()
  1364  	}
  1365  	return &String{Src: c.src, Str: s}
  1366  }
  1367  
  1368  func (c *OpContext) newBytes(b []byte) Value {
  1369  	if c.HasErr() {
  1370  		return c.Err()
  1371  	}
  1372  	return &Bytes{Src: c.src, B: b}
  1373  }
  1374  
  1375  func (c *OpContext) newBool(b bool) Value {
  1376  	if c.HasErr() {
  1377  		return c.Err()
  1378  	}
  1379  	return &Bool{Src: c.src, B: b}
  1380  }
  1381  
  1382  func (c *OpContext) newList(src ast.Node, parent *Vertex) *Vertex {
  1383  	return c.newInlineVertex(parent, &ListMarker{})
  1384  }
  1385  
  1386  // Str reports a debug string of x.
  1387  func (c *OpContext) Str(x Node) string {
  1388  	if c.Format == nil {
  1389  		return fmt.Sprintf("%T", x)
  1390  	}
  1391  	return c.Format(c.Runtime, x)
  1392  }
  1393  
  1394  // NewList returns a new list for the given values.
  1395  func (c *OpContext) NewList(values ...Value) *Vertex {
  1396  	// TODO: consider making this a literal list instead.
  1397  	list := &ListLit{}
  1398  	v := c.newInlineVertex(nil, nil, Conjunct{Env: nil, x: list})
  1399  
  1400  	for _, x := range values {
  1401  		list.Elems = append(list.Elems, x)
  1402  	}
  1403  	v.Finalize(c)
  1404  	return v
  1405  }