cuelang.org/go@v0.13.0/internal/core/adt/expr.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  	"bytes"
    19  	"fmt"
    20  	"regexp"
    21  
    22  	"github.com/cockroachdb/apd/v3"
    23  
    24  	"cuelang.org/go/cue/ast"
    25  	"cuelang.org/go/cue/errors"
    26  	"cuelang.org/go/cue/token"
    27  )
    28  
    29  var _ Elem = &ConjunctGroup{}
    30  
    31  // A ConjunctGroup is an Elem that is used for internal grouping of Conjuncts
    32  // only.
    33  type ConjunctGroup []Conjunct
    34  
    35  func (g *ConjunctGroup) Source() ast.Node {
    36  	return nil
    37  }
    38  
    39  // A StructLit represents an unevaluated struct literal or file body.
    40  type StructLit struct {
    41  	Src   ast.Node // ast.File or ast.StructLit
    42  	Decls []Decl
    43  
    44  	// TODO: record the merge order somewhere.
    45  
    46  	// The below fields are redundant to Decls and are computed with Init.
    47  
    48  	// field marks the optional conjuncts of all explicit Fields.
    49  	// Required Fields are marked as empty
    50  	Fields []FieldInfo
    51  
    52  	Dynamic []*DynamicField
    53  
    54  	// excluded are all literal fields that already exist.
    55  	Bulk []*BulkOptionalField
    56  
    57  	Additional  []*Ellipsis
    58  	HasEmbed    bool
    59  	IsOpen      bool // has a ...
    60  	initialized bool
    61  
    62  	types OptionalType
    63  
    64  	// administrative fields like hasreferences.
    65  	// hasReferences bool
    66  }
    67  
    68  func (o *StructLit) IsFile() bool {
    69  	_, ok := o.Src.(*ast.File)
    70  	return ok
    71  }
    72  
    73  type FieldInfo struct {
    74  	Label Feature
    75  }
    76  
    77  func (x *StructLit) HasOptional() bool {
    78  	return x.types&(HasPattern|HasAdditional) != 0
    79  }
    80  
    81  func (x *StructLit) Source() ast.Node { return x.Src }
    82  
    83  func (x *StructLit) evaluate(c *OpContext, state combinedFlags) Value {
    84  	e := c.Env(0)
    85  	v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
    86  	// evaluate may not finalize a field, as the resulting value may be
    87  	// used in a context where more conjuncts are added. It may also lead
    88  	// to disjuncts being in a partially expanded state, leading to
    89  	// misaligned nodeContexts.
    90  
    91  	// TODO(evalv3): to be fully compatible correct, we should not always
    92  	// finalize the arcs here. This is a temporary fix. For now, we have to do
    93  	// this as we need a mechanism to set the arcTypeKnown bit without
    94  	// finalizing the arcs, as they may depend on the completion of sub fields.
    95  	// See, for instance:
    96  	//
    97  	// 		chainSuccess: a: {
    98  	// 			raises?: {}
    99  	// 			if raises == _|_ {
   100  	// 				ret: a: 1
   101  	// 			}
   102  	// 			ret?: {}
   103  	// 			if ret != _|_ {
   104  	// 				foo: a: 1
   105  	// 			}
   106  	// 		}
   107  	//
   108  	// This would also require changing the arcType process in ForClause.yield.
   109  	//
   110  	// v.completeArcs(c, state)
   111  
   112  	v.CompleteArcsOnly(c)
   113  	return v
   114  }
   115  
   116  // TODO: remove this method
   117  func (o *StructLit) MarkField(f Feature) {
   118  	o.Fields = append(o.Fields, FieldInfo{Label: f})
   119  }
   120  
   121  func (o *StructLit) Init(ctx *OpContext) {
   122  	if o.initialized {
   123  		return
   124  	}
   125  	o.initialized = true
   126  
   127  	if ctx.isDevVersion() {
   128  		return
   129  	}
   130  
   131  	for _, d := range o.Decls {
   132  		switch x := d.(type) {
   133  		case *Field:
   134  			if o.fieldIndex(x.Label) < 0 {
   135  				o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   136  			}
   137  			if x.ArcType > ArcMember {
   138  				o.types |= HasField
   139  			}
   140  
   141  		case *LetField:
   142  			if o.fieldIndex(x.Label) >= 0 {
   143  				panic("duplicate let identifier")
   144  			}
   145  			o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   146  
   147  		case *DynamicField:
   148  			o.Dynamic = append(o.Dynamic, x)
   149  			o.types |= HasDynamic
   150  
   151  		case Expr:
   152  			o.HasEmbed = true
   153  
   154  		case *Comprehension:
   155  			o.HasEmbed = true
   156  
   157  		case *LetClause:
   158  			o.HasEmbed = true
   159  
   160  		case *BulkOptionalField:
   161  			o.Bulk = append(o.Bulk, x)
   162  			o.types |= HasPattern
   163  			switch x.Filter.(type) {
   164  			case *BasicType, *Top:
   165  			default:
   166  				o.types |= HasComplexPattern
   167  			}
   168  
   169  		case *Ellipsis:
   170  			switch x.Value.(type) {
   171  			case nil, *Top:
   172  				o.IsOpen = true
   173  				o.types |= IsOpen
   174  
   175  			default:
   176  				// TODO: consider only adding for non-top.
   177  				o.types |= HasAdditional
   178  			}
   179  			o.Additional = append(o.Additional, x)
   180  
   181  		default:
   182  			panic("unreachable")
   183  		}
   184  	}
   185  }
   186  
   187  func (o *StructLit) fieldIndex(f Feature) int {
   188  	for i := range o.Fields {
   189  		if o.Fields[i].Label == f {
   190  			return i
   191  		}
   192  	}
   193  	return -1
   194  }
   195  
   196  func (o *StructLit) OptionalTypes() OptionalType {
   197  	return o.types
   198  }
   199  
   200  // FIELDS
   201  //
   202  // Fields can also be used as expressions whereby the value field is the
   203  // expression this allows retaining more context.
   204  
   205  // Field represents a regular field or field constraint with a fixed label.
   206  // The label can be a regular field, definition or hidden field.
   207  //
   208  //	foo: bar
   209  //	#foo: bar
   210  //	_foo: bar
   211  type Field struct {
   212  	Src *ast.Field
   213  
   214  	ArcType ArcType
   215  	Label   Feature
   216  	Value   Expr
   217  }
   218  
   219  func (x *Field) Source() ast.Node {
   220  	if x.Src == nil {
   221  		return nil
   222  	}
   223  	return x.Src
   224  }
   225  
   226  // A LetField represents a field that is only visible in the local scope.
   227  //
   228  //	let X = expr
   229  type LetField struct {
   230  	Src   *ast.LetClause
   231  	Label Feature
   232  	// IsMulti is true when this let field should be replicated for each
   233  	// incarnation. This is the case when its expression refers to the
   234  	// variables of a for comprehension embedded within a struct.
   235  	IsMulti bool
   236  	Value   Expr
   237  }
   238  
   239  func (x *LetField) Source() ast.Node {
   240  	if x.Src == nil {
   241  		return nil
   242  	}
   243  	return x.Src
   244  }
   245  
   246  // A BulkOptionalField represents a set of optional field.
   247  //
   248  //	[expr]: expr
   249  type BulkOptionalField struct {
   250  	Src    *ast.Field // Ellipsis or Field
   251  	Filter Expr
   252  	Value  Expr
   253  	Label  Feature // for reference and formatting
   254  }
   255  
   256  func (x *BulkOptionalField) Source() ast.Node {
   257  	if x.Src == nil {
   258  		return nil
   259  	}
   260  	return x.Src
   261  }
   262  
   263  // A Ellipsis represents a set of optional fields of a given type.
   264  //
   265  //	...T
   266  type Ellipsis struct {
   267  	Src   *ast.Ellipsis
   268  	Value Expr
   269  }
   270  
   271  func (x *Ellipsis) Source() ast.Node {
   272  	if x.Src == nil {
   273  		return nil
   274  	}
   275  	return x.Src
   276  }
   277  
   278  // A DynamicField represents a regular field for which the key is computed.
   279  //
   280  //	"\(expr)": expr
   281  //	(expr): expr
   282  type DynamicField struct {
   283  	Src *ast.Field
   284  
   285  	ArcType ArcType
   286  	Key     Expr
   287  	Value   Expr
   288  }
   289  
   290  func (x *DynamicField) Source() ast.Node {
   291  	if x.Src == nil {
   292  		return nil
   293  	}
   294  	return x.Src
   295  }
   296  
   297  // A ListLit represents an unevaluated list literal.
   298  //
   299  //	[a, for x in src { ... }, b, ...T]
   300  type ListLit struct {
   301  	Src *ast.ListLit
   302  
   303  	// scalars, comprehensions, ...T
   304  	Elems []Elem
   305  
   306  	info *StructLit // Shared closedness info.
   307  }
   308  
   309  func (x *ListLit) Source() ast.Node {
   310  	if x.Src == nil {
   311  		return nil
   312  	}
   313  	return x.Src
   314  }
   315  
   316  func (x *ListLit) evaluate(c *OpContext, state combinedFlags) Value {
   317  	e := c.Env(0)
   318  	// Pass conditions but at least set fieldSetKnown.
   319  	v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
   320  	v.CompleteArcsOnly(c)
   321  
   322  	// TODO(evalv3): evaluating more aggressively yields some improvements, but
   323  	// breaks other tests. Consider using this approach, though.
   324  	// mode := state.runMode()
   325  	// if mode == finalize {
   326  	// 	v.completeArcs(c, allKnown)
   327  	// } else {
   328  	// 	v.completeArcs(c, fieldSetKnown)
   329  	// }
   330  	return v
   331  }
   332  
   333  // Null represents null. It can be used as a Value and Expr.
   334  type Null struct {
   335  	Src ast.Node
   336  }
   337  
   338  func (x *Null) Source() ast.Node { return x.Src }
   339  func (x *Null) Kind() Kind       { return NullKind }
   340  
   341  // Bool is a boolean value. It can be used as a Value and Expr.
   342  type Bool struct {
   343  	Src ast.Node
   344  	B   bool
   345  }
   346  
   347  func (x *Bool) Source() ast.Node { return x.Src }
   348  func (x *Bool) Kind() Kind       { return BoolKind }
   349  
   350  // Num is a numeric value. It can be used as a Value and Expr.
   351  type Num struct {
   352  	Src ast.Node
   353  	K   Kind        // needed?
   354  	X   apd.Decimal // Is integer if the apd.Decimal is an integer.
   355  }
   356  
   357  // TODO: do we need this?
   358  // func NewNumFromString(src ast.Node, s string) Value {
   359  // 	n := &Num{Src: src, K: IntKind}
   360  // 	if strings.ContainsAny(s, "eE.") {
   361  // 		n.K = FloatKind
   362  // 	}
   363  // 	_, _, err := n.X.SetString(s)
   364  // 	if err != nil {
   365  // 		pos := token.NoPos
   366  // 		if src != nil {
   367  // 			pos = src.Pos()
   368  // 		}
   369  // 		return &Bottom{Err: errors.Newf(pos, "invalid number: %v", err)}
   370  // 	}
   371  // 	return n
   372  // }
   373  
   374  func (x *Num) Source() ast.Node { return x.Src }
   375  func (x *Num) Kind() Kind       { return x.K }
   376  
   377  // TODO: do we still need this?
   378  // func (x *Num) Specialize(k Kind) Value {
   379  // 	k = k & x.K
   380  // 	if k == x.K {
   381  // 		return x
   382  // 	}
   383  // 	y := *x
   384  // 	y.K = k
   385  // 	return &y
   386  // }
   387  
   388  // String is a string value. It can be used as a Value and Expr.
   389  type String struct {
   390  	Src ast.Node
   391  	Str string
   392  	RE  *regexp.Regexp // only set if needed
   393  }
   394  
   395  func (x *String) Source() ast.Node { return x.Src }
   396  func (x *String) Kind() Kind       { return StringKind }
   397  
   398  // Bytes is a bytes value. It can be used as a Value and Expr.
   399  type Bytes struct {
   400  	Src ast.Node
   401  	B   []byte
   402  	RE  *regexp.Regexp // only set if needed
   403  }
   404  
   405  func (x *Bytes) Source() ast.Node { return x.Src }
   406  func (x *Bytes) Kind() Kind       { return BytesKind }
   407  
   408  // Composites: the evaluated fields of a composite are recorded in the arc
   409  // vertices.
   410  
   411  type ListMarker struct {
   412  	Src    ast.Expr
   413  	IsOpen bool
   414  }
   415  
   416  func (x *ListMarker) Source() ast.Node { return x.Src }
   417  func (x *ListMarker) Kind() Kind       { return ListKind }
   418  func (x *ListMarker) node()            {}
   419  
   420  type StructMarker struct {
   421  	// NeedClose is used to signal that the evaluator should close this struct.
   422  	// It is only set by the close builtin.
   423  	// TODO(evalv3: remove this field. Once we removed this, and also introduced
   424  	// open by default lists, we can get rid of StructMarker and ListMarker
   425  	// in its entirety in favor of using type bit masks.
   426  	NeedClose bool
   427  }
   428  
   429  func (x *StructMarker) Source() ast.Node { return nil }
   430  func (x *StructMarker) Kind() Kind       { return StructKind }
   431  func (x *StructMarker) node()            {}
   432  
   433  // Top represents all possible values. It can be used as a Value and Expr.
   434  type Top struct{ Src *ast.Ident }
   435  
   436  func (x *Top) Source() ast.Node {
   437  	if x.Src == nil {
   438  		return nil
   439  	}
   440  	return x.Src
   441  }
   442  func (x *Top) Kind() Kind { return TopKind }
   443  
   444  // BasicType represents all values of a certain Kind. It can be used as a Value
   445  // and Expr.
   446  //
   447  //	string
   448  //	int
   449  //	num
   450  //	bool
   451  type BasicType struct {
   452  	Src ast.Node
   453  	K   Kind
   454  }
   455  
   456  func (x *BasicType) Source() ast.Node {
   457  	if x.Src == nil {
   458  		return nil
   459  	}
   460  	return x.Src
   461  }
   462  func (x *BasicType) Kind() Kind { return x.K }
   463  
   464  // TODO: do we still need this?
   465  // func (x *BasicType) Specialize(k Kind) Value {
   466  // 	k = x.K & k
   467  // 	if k == x.K {
   468  // 		return x
   469  // 	}
   470  // 	y := *x
   471  // 	y.K = k
   472  // 	return &y
   473  // }
   474  
   475  // TODO: should we use UnaryExpr for Bound now we have BoundValue?
   476  
   477  // BoundExpr represents an unresolved unary comparator.
   478  //
   479  //	<a
   480  //	=~MyPattern
   481  type BoundExpr struct {
   482  	Src  *ast.UnaryExpr
   483  	Op   Op
   484  	Expr Expr
   485  }
   486  
   487  func (x *BoundExpr) Source() ast.Node {
   488  	if x.Src == nil {
   489  		return nil
   490  	}
   491  	return x.Src
   492  }
   493  
   494  func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value {
   495  	// scalarKnown is used here to ensure we know the value. The result does
   496  	// not have to be concrete, though.
   497  	v := ctx.value(x.Expr, require(partial, scalarKnown))
   498  	if isError(v) {
   499  		return v
   500  	}
   501  
   502  	switch k := v.Kind(); k {
   503  	case IntKind, FloatKind, NumberKind, StringKind, BytesKind:
   504  	case NullKind:
   505  		if x.Op != NotEqualOp {
   506  			err := ctx.NewPosf(pos(x.Expr),
   507  				"cannot use null for bound %s", x.Op)
   508  			return &Bottom{
   509  				Err:  err,
   510  				Node: ctx.vertex,
   511  			}
   512  		}
   513  	default:
   514  		mask := IntKind | FloatKind | NumberKind | StringKind | BytesKind
   515  		if x.Op == NotEqualOp {
   516  			mask |= NullKind
   517  		}
   518  		if k&mask != 0 {
   519  			ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   520  				"non-concrete value %s for bound %s", x.Expr, x.Op)
   521  			return nil
   522  		}
   523  		err := ctx.NewPosf(pos(x.Expr),
   524  			"invalid value %s (type %s) for bound %s", v, k, x.Op)
   525  		return &Bottom{
   526  			Err:  err,
   527  			Node: ctx.vertex,
   528  		}
   529  	}
   530  
   531  	if v, ok := x.Expr.(Value); ok {
   532  		if v == nil || v.Concreteness() > Concrete {
   533  			return ctx.NewErrf("bound has fixed non-concrete value")
   534  		}
   535  		return &BoundValue{x.Src, x.Op, v}
   536  	}
   537  
   538  	// This simplifies boundary expressions. It is an alternative to an
   539  	// evaluation strategy that makes nodes increasingly more specific.
   540  	//
   541  	// For instance, a completely different implementation would be to allow
   542  	// the presence of a concrete value to ignore incomplete errors.
   543  	//
   544  	// TODO: consider an alternative approach.
   545  	switch y := v.(type) {
   546  	case *BoundValue:
   547  		switch {
   548  		case y.Op == NotEqualOp:
   549  			switch x.Op {
   550  			case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   551  				// <(!=3)  =>  number
   552  				// Smaller than an arbitrarily large number is any number.
   553  				return &BasicType{K: y.Kind()}
   554  			case NotEqualOp:
   555  				// !=(!=3) ==> 3
   556  				// Not a value that is anything but a given value is that
   557  				// given value.
   558  				return y.Value
   559  			}
   560  
   561  		case x.Op == NotEqualOp:
   562  			// Invert if applicable.
   563  			switch y.Op {
   564  			case LessEqualOp:
   565  				return &BoundValue{x.Src, GreaterThanOp, y.Value}
   566  			case LessThanOp:
   567  				return &BoundValue{x.Src, GreaterEqualOp, y.Value}
   568  			case GreaterEqualOp:
   569  				return &BoundValue{x.Src, LessThanOp, y.Value}
   570  			case GreaterThanOp:
   571  				return &BoundValue{x.Src, LessEqualOp, y.Value}
   572  			}
   573  
   574  		case (x.Op == LessThanOp || x.Op == LessEqualOp) &&
   575  			(y.Op == GreaterThanOp || y.Op == GreaterEqualOp),
   576  			(x.Op == GreaterThanOp || x.Op == GreaterEqualOp) &&
   577  				(y.Op == LessThanOp || y.Op == LessEqualOp):
   578  			// <(>=3)
   579  			// Something smaller than an arbitrarily large number is any number.
   580  			return &BasicType{K: y.Kind()}
   581  
   582  		case x.Op == LessThanOp &&
   583  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   584  			x.Op == GreaterThanOp &&
   585  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   586  			// <(<=x)  => <x
   587  			// <(<x)   => <x
   588  			// Less than something that is less or equal to x is less than x.
   589  			return &BoundValue{x.Src, x.Op, y.Value}
   590  
   591  		case x.Op == LessEqualOp &&
   592  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   593  			x.Op == GreaterEqualOp &&
   594  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   595  			// <=(<x)   => <x
   596  			// <=(<=x)  => <=x
   597  			// Less or equal than something that is less than x is less than x.
   598  			return y
   599  		}
   600  
   601  	case *BasicType:
   602  		switch x.Op {
   603  		case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   604  			// TODO: this does not seem correct and results in some weird
   605  			// behavior for bounds.
   606  			ctx.addErrf(IncompleteError, token.NoPos,
   607  				"non-concrete value %s for bound %s", x.Expr, x.Op)
   608  			return nil
   609  		}
   610  	}
   611  	if v.Concreteness() > Concrete {
   612  		// TODO(errors): analyze dependencies of x.Expr to get positions.
   613  		ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   614  			"non-concrete value %s for bound %s", x.Expr, x.Op)
   615  		return nil
   616  	}
   617  	return &BoundValue{x.Src, x.Op, v}
   618  }
   619  
   620  // A BoundValue is a fully evaluated unary comparator that can be used to
   621  // validate other values.
   622  //
   623  //	<5
   624  //	=~"Name$"
   625  type BoundValue struct {
   626  	Src   ast.Expr
   627  	Op    Op
   628  	Value Value
   629  }
   630  
   631  func (x *BoundValue) Source() ast.Node { return x.Src }
   632  func (x *BoundValue) Kind() Kind {
   633  	k := x.Value.Kind()
   634  	switch k {
   635  	case IntKind, FloatKind, NumberKind:
   636  		return NumberKind
   637  
   638  	case NullKind:
   639  		if x.Op == NotEqualOp {
   640  			return TopKind &^ NullKind
   641  		}
   642  	}
   643  	return k
   644  }
   645  
   646  func (x *BoundValue) validate(c *OpContext, y Value) *Bottom {
   647  	a := y // Can be list or struct.
   648  	b := c.scalar(x.Value)
   649  	if c.HasErr() {
   650  		return c.Err()
   651  	}
   652  
   653  	switch v := BinOp(c, x.Op, a, b).(type) {
   654  	case *Bottom:
   655  		return v
   656  
   657  	case *Bool:
   658  		if v.B {
   659  			return nil
   660  		}
   661  		// TODO(errors): use "invalid value %v (not an %s)" if x is a
   662  		// predeclared identifier such as `int`.
   663  		err := c.Newf("invalid value %v (out of bound %s)", y, x)
   664  		err.AddPosition(y)
   665  		return &Bottom{
   666  			Src:  c.src,
   667  			Err:  err,
   668  			Code: EvalError,
   669  			Node: c.vertex,
   670  		}
   671  
   672  	default:
   673  		panic(fmt.Sprintf("unsupported type %T", v))
   674  	}
   675  }
   676  
   677  func (x *BoundValue) validateStr(c *OpContext, a string) bool {
   678  	if str, ok := x.Value.(*String); ok {
   679  		b := str.Str
   680  		switch x.Op {
   681  		case LessEqualOp:
   682  			return a <= b
   683  		case LessThanOp:
   684  			return a < b
   685  		case GreaterEqualOp:
   686  			return a >= b
   687  		case GreaterThanOp:
   688  			return a > b
   689  		case EqualOp:
   690  			return a == b
   691  		case NotEqualOp:
   692  			return a != b
   693  		case MatchOp:
   694  			return c.regexp(x.Value).MatchString(a)
   695  		case NotMatchOp:
   696  			return !c.regexp(x.Value).MatchString(a)
   697  		}
   698  	}
   699  	return x.validate(c, &String{Str: a}) == nil
   700  }
   701  
   702  func (x *BoundValue) validateInt(c *OpContext, a int64) bool {
   703  	switch n := x.Value.(type) {
   704  	case *Num:
   705  		b, err := n.X.Int64()
   706  		if err != nil {
   707  			break
   708  		}
   709  		switch x.Op {
   710  		case LessEqualOp:
   711  			return a <= b
   712  		case LessThanOp:
   713  			return a < b
   714  		case GreaterEqualOp:
   715  			return a >= b
   716  		case GreaterThanOp:
   717  			return a > b
   718  		case EqualOp:
   719  			return a == b
   720  		case NotEqualOp:
   721  			return a != b
   722  		}
   723  	}
   724  	return x.validate(c, c.NewInt64(a)) == nil
   725  }
   726  
   727  // A NodeLink is used during computation to refer to an existing Vertex.
   728  // It is used to signal a potential cycle or reference.
   729  // Note that a NodeLink may be used as a value. This should be taken into
   730  // account.
   731  type NodeLink struct {
   732  	Node *Vertex
   733  }
   734  
   735  func (x *NodeLink) Kind() Kind {
   736  	return x.Node.Kind()
   737  }
   738  func (x *NodeLink) Source() ast.Node { return x.Node.Source() }
   739  
   740  func (x *NodeLink) resolve(c *OpContext, state combinedFlags) *Vertex {
   741  	return x.Node
   742  }
   743  
   744  // A FieldReference represents a lexical reference to a field.
   745  //
   746  //	a
   747  type FieldReference struct {
   748  	Src     *ast.Ident
   749  	UpCount int32
   750  	Label   Feature
   751  }
   752  
   753  func (x *FieldReference) Source() ast.Node {
   754  	if x.Src == nil {
   755  		return nil
   756  	}
   757  	return x.Src
   758  }
   759  
   760  func (x *FieldReference) resolve(c *OpContext, state combinedFlags) *Vertex {
   761  	n := c.relNode(x.UpCount)
   762  	pos := pos(x)
   763  	return c.lookup(n, pos, x.Label, state)
   764  }
   765  
   766  // A ValueReference represents a lexical reference to a value.
   767  //
   768  // Example: an X referring to
   769  //
   770  //	a: X=b
   771  type ValueReference struct {
   772  	Src     *ast.Ident
   773  	UpCount int32
   774  	Label   Feature // for informative purposes
   775  }
   776  
   777  func (x *ValueReference) Source() ast.Node {
   778  	if x.Src == nil {
   779  		return nil
   780  	}
   781  	return x.Src
   782  }
   783  
   784  func (x *ValueReference) resolve(c *OpContext, state combinedFlags) *Vertex {
   785  	if x.UpCount == 0 {
   786  		return c.vertex
   787  	}
   788  	n := c.relNode(x.UpCount - 1)
   789  	return n
   790  }
   791  
   792  // A LabelReference refers to the string or integer value of a label.
   793  //
   794  // Example: an X referring to
   795  //
   796  //	[X=Pattern]: b: a
   797  type LabelReference struct {
   798  	Src     *ast.Ident
   799  	UpCount int32
   800  }
   801  
   802  // TODO: should this implement resolver at all?
   803  
   804  func (x *LabelReference) Source() ast.Node {
   805  	if x.Src == nil {
   806  		return nil
   807  	}
   808  	return x.Src
   809  }
   810  
   811  func (x *LabelReference) evaluate(ctx *OpContext, state combinedFlags) Value {
   812  	label := ctx.relLabel(x.UpCount)
   813  	if label == 0 {
   814  		// There is no label. This may happen if a LabelReference is evaluated
   815  		// outside of the context of a parent node, for instance if an
   816  		// "additional" items or properties is evaluated in isolation.
   817  		//
   818  		// TODO: this should return the pattern of the label.
   819  		return &BasicType{K: StringKind}
   820  	}
   821  	return label.ToValue(ctx)
   822  }
   823  
   824  // A DynamicReference is like a FieldReference, but with a computed label.
   825  //
   826  // Example: an X referring to
   827  //
   828  //	X=(x): v
   829  //	X="\(x)": v
   830  //	X=[string]: v
   831  type DynamicReference struct {
   832  	Src     *ast.Ident
   833  	UpCount int32
   834  	Label   Expr
   835  
   836  	// TODO: only use aliases and store the actual expression only in the scope.
   837  	// The feature is unique for every instance. This will also allow dynamic
   838  	// fields to be ordered among normal fields.
   839  	//
   840  	// This could also be used to assign labels to embedded values, if they
   841  	// don't match a label.
   842  	Alias Feature
   843  }
   844  
   845  func (x *DynamicReference) Source() ast.Node {
   846  	if x.Src == nil {
   847  		return nil
   848  	}
   849  	return x.Src
   850  }
   851  
   852  func (x *DynamicReference) EvaluateLabel(ctx *OpContext, env *Environment) Feature {
   853  	env = env.up(ctx, x.UpCount)
   854  	frame := ctx.PushState(env, x.Src)
   855  	v := ctx.value(x.Label, require(partial, scalarKnown))
   856  	ctx.PopState(frame)
   857  	return ctx.Label(x, v)
   858  }
   859  
   860  func (x *DynamicReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   861  	e := ctx.Env(x.UpCount)
   862  	frame := ctx.PushState(e, x.Src)
   863  	v := ctx.value(x.Label, require(partial, scalarKnown))
   864  	ctx.PopState(frame)
   865  	f := ctx.Label(x.Label, v)
   866  	return ctx.lookup(e.Vertex, pos(x), f, state)
   867  }
   868  
   869  // An ImportReference refers to an imported package.
   870  //
   871  // Example: strings in
   872  //
   873  //	import "strings"
   874  //
   875  //	strings.ToLower("Upper")
   876  type ImportReference struct {
   877  	Src        *ast.Ident
   878  	ImportPath Feature
   879  	Label      Feature // for informative purposes
   880  }
   881  
   882  func (x *ImportReference) Source() ast.Node {
   883  	if x.Src == nil {
   884  		return nil
   885  	}
   886  	return x.Src
   887  }
   888  
   889  func (x *ImportReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   890  	path := x.ImportPath.StringValue(ctx)
   891  	v := ctx.Runtime.LoadImport(path)
   892  	if v == nil {
   893  		ctx.addErrf(EvalError, x.Src.Pos(), "cannot find package %q", path)
   894  	}
   895  	return v
   896  }
   897  
   898  // A LetReference evaluates a let expression in its original environment.
   899  //
   900  // Example: an X referring to
   901  //
   902  //	let X = x
   903  type LetReference struct {
   904  	Src     *ast.Ident
   905  	UpCount int32
   906  	Label   Feature // for informative purposes
   907  	X       Expr
   908  }
   909  
   910  func (x *LetReference) Source() ast.Node {
   911  	if x.Src == nil {
   912  		return nil
   913  	}
   914  	return x.Src
   915  }
   916  
   917  func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   918  	e := ctx.Env(x.UpCount)
   919  	n := e.Vertex
   920  
   921  	// No need to Unify n, as Let references can only result from evaluating
   922  	// an expression within n, in which case evaluation must already have
   923  	// started.
   924  	if n.status < evaluating && !ctx.isDevVersion() {
   925  		panic("unexpected node state < Evaluating")
   926  	}
   927  
   928  	arc := ctx.lookup(n, pos(x), x.Label, state)
   929  	if arc == nil {
   930  		return nil
   931  	}
   932  
   933  	// Using a let arc directly saves an allocation, but should not be done
   934  	// in the following circumstances:
   935  	// 1) multiple Environments to be resolved for a single let
   936  	// 2) in case of error: some errors, like structural cycles, may only
   937  	//    occur when an arc is resolved directly, but not when used in an
   938  	//    expression. Consider, for instance:
   939  	//
   940  	//        a: {
   941  	//            b: 1
   942  	//            let X = a  // structural cycle
   943  	//            c: X.b     // not a structural cycle
   944  	//        }
   945  	//
   946  	//     In other words, a Vertex is not necessarily erroneous when a let
   947  	//     field contained in that Vertex is erroneous.
   948  
   949  	// We should only partly finalize the result here as it is not safe to
   950  	// finalize any references made by the let.
   951  	if !ctx.isDevVersion() {
   952  		arc.Finalize(ctx)
   953  	}
   954  	b := arc.Bottom()
   955  	if !arc.MultiLet && b == nil && n.Rooted() {
   956  		return arc
   957  	}
   958  
   959  	// Not caching let expressions may lead to exponential behavior.
   960  	// The expr uses the expression of a Let field, which can never be used in
   961  	// any other context.
   962  	c := arc.ConjunctAt(0)
   963  	expr := c.Expr()
   964  
   965  	// A let field always has a single expression and thus ConjunctGroups
   966  	// should always have been eliminated. This is critical, as we must
   967  	// ensure that Comprehensions, which may be wrapped in ConjunctGroups,
   968  	// are eliminated.
   969  	_, isGroup := expr.(*ConjunctGroup)
   970  	ctx.Assertf(pos(expr), !isGroup, "unexpected number of expressions")
   971  
   972  	key := cacheKey{expr, arc}
   973  	v, ok := e.cache[key]
   974  	if !ok {
   975  		// Link in the right environment to ensure comprehension context is not
   976  		// lost. Use a Vertex to piggyback on cycle processing.
   977  		c.Env = e
   978  		c.x = expr
   979  
   980  		if e.cache == nil {
   981  			e.cache = map[cacheKey]Value{}
   982  		}
   983  		n := &Vertex{
   984  			Parent:    arc.Parent,
   985  			Label:     x.Label,
   986  			IsDynamic: b != nil && b.Code == StructuralCycleError,
   987  			Conjuncts: []Conjunct{c},
   988  		}
   989  		v = n
   990  		e.cache[key] = n
   991  		if ctx.isDevVersion() {
   992  			// TODO(mem): enable again once we implement memory management.
   993  			// nc := n.getState(ctx)
   994  			// TODO: unlike with the old evaluator, we do not allow the first
   995  			// cycle to be skipped. Doing so can lead to hanging evaluation.
   996  			// As the cycle detection works slightly differently in the new
   997  			// evaluator (and is not entirely completed), this can happen. We
   998  			// should revisit this once we have completed the structural cycle
   999  			// detection.
  1000  			// nc.hasNonCycle = true
  1001  			// Allow a first cycle to be skipped.
  1002  			// nc.free()
  1003  		} else {
  1004  			nc := n.getNodeContext(ctx, 0)
  1005  			nc.hasNonCycle = true // Allow a first cycle to be skipped.
  1006  		}
  1007  
  1008  		// Parents cannot add more conjuncts to a let expression, so set of
  1009  		// conjuncts is always complete.
  1010  		//
  1011  		// NOTE(let finalization): as this let expression is not recorded as
  1012  		// a subfield within its parent arc, setParentDone will not be called
  1013  		// as part of normal processing. The same is true for finalization.
  1014  		// The use of setParentDone has the additional effect that the arc
  1015  		// will be finalized where it is needed. See the namesake NOTE for the
  1016  		// location where this is triggered.
  1017  		n.setParentDone()
  1018  	}
  1019  	return v.(*Vertex)
  1020  }
  1021  
  1022  // A SelectorExpr looks up a fixed field in an expression.
  1023  //
  1024  //	a.sel
  1025  type SelectorExpr struct {
  1026  	Src *ast.SelectorExpr
  1027  	X   Expr
  1028  	Sel Feature
  1029  }
  1030  
  1031  func (x *SelectorExpr) Source() ast.Node {
  1032  	if x.Src == nil {
  1033  		return nil
  1034  	}
  1035  	return x.Src
  1036  }
  1037  
  1038  func (x *SelectorExpr) resolve(c *OpContext, state combinedFlags) *Vertex {
  1039  	n := c.node(x, x.X, x.Sel.IsRegular(), require(partial, needFieldSetKnown))
  1040  	if n == emptyNode {
  1041  		return n
  1042  	}
  1043  	if n.status == partial && !c.isDevVersion() {
  1044  		if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
  1045  			c.AddBottom(b)
  1046  			return n
  1047  		}
  1048  	}
  1049  	// TODO(eval): dynamic nodes should be fully evaluated here as the result
  1050  	// will otherwise be discarded and there will be no other chance to check
  1051  	// the struct is valid.
  1052  
  1053  	pos := x.Src.Sel.Pos()
  1054  	return c.lookup(n, pos, x.Sel, state)
  1055  }
  1056  
  1057  // IndexExpr is like a selector, but selects an index.
  1058  //
  1059  //	a[index]
  1060  type IndexExpr struct {
  1061  	Src   *ast.IndexExpr
  1062  	X     Expr
  1063  	Index Expr
  1064  }
  1065  
  1066  func (x *IndexExpr) Source() ast.Node {
  1067  	if x.Src == nil {
  1068  		return nil
  1069  	}
  1070  	return x.Src
  1071  }
  1072  
  1073  func (x *IndexExpr) resolve(ctx *OpContext, state combinedFlags) *Vertex {
  1074  	// TODO: support byte index.
  1075  	n := ctx.node(x, x.X, true, require(partial, needFieldSetKnown))
  1076  	i := ctx.value(x.Index, require(partial, scalarKnown))
  1077  	if n == emptyNode {
  1078  		return n
  1079  	}
  1080  	if n.status == partial && !ctx.isDevVersion() {
  1081  		if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
  1082  			ctx.AddBottom(b)
  1083  			return n
  1084  		}
  1085  	}
  1086  	// TODO(eval): dynamic nodes should be fully evaluated here as the result
  1087  	// will otherwise be discarded and there will be no other chance to check
  1088  	// the struct is valid.
  1089  
  1090  	f := ctx.Label(x.Index, i)
  1091  
  1092  	// Within lookup, errors collected in ctx may be associated with n. This is
  1093  	// correct if the error is generated within lookup, but not if it has
  1094  	// already been generated at this point. We therefore bail out early here if
  1095  	// we already have an error.
  1096  	// TODO: this code can probably go once we have cleaned up error generation.
  1097  	if ctx.errs != nil {
  1098  		return nil
  1099  	}
  1100  	pos := x.Src.Index.Pos()
  1101  	return ctx.lookup(n, pos, f, state)
  1102  }
  1103  
  1104  // A SliceExpr represents a slice operation. (Not currently in spec.)
  1105  //
  1106  //	X[Lo:Hi:Stride]
  1107  type SliceExpr struct {
  1108  	Src    *ast.SliceExpr
  1109  	X      Expr
  1110  	Lo     Expr
  1111  	Hi     Expr
  1112  	Stride Expr
  1113  }
  1114  
  1115  func (x *SliceExpr) Source() ast.Node {
  1116  	if x.Src == nil {
  1117  		return nil
  1118  	}
  1119  	return x.Src
  1120  }
  1121  
  1122  func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1123  	// TODO: strides
  1124  
  1125  	v := c.value(x.X, require(partial, fieldSetKnown))
  1126  	const as = "slice index"
  1127  
  1128  	switch v := v.(type) {
  1129  	case nil:
  1130  		c.addErrf(IncompleteError, c.pos(), "non-concrete slice subject %s", x.X)
  1131  		return nil
  1132  	case *Vertex:
  1133  		if !v.IsList() {
  1134  			break
  1135  		}
  1136  
  1137  		var (
  1138  			lo = uint64(0)
  1139  			hi = uint64(len(v.Arcs))
  1140  		)
  1141  		if x.Lo != nil {
  1142  			lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
  1143  		}
  1144  		if x.Hi != nil {
  1145  			hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
  1146  			if hi > uint64(len(v.Arcs)) {
  1147  				return c.NewErrf("index %d out of range", hi)
  1148  			}
  1149  		}
  1150  		if lo > hi {
  1151  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
  1152  		}
  1153  
  1154  		n := c.newList(c.src, v.Parent)
  1155  		for i, a := range v.Arcs[lo:hi] {
  1156  			label, err := MakeLabel(a.Source(), int64(i), IntLabel)
  1157  			if err != nil {
  1158  				c.AddBottom(&Bottom{
  1159  					Src:  a.Source(),
  1160  					Err:  err,
  1161  					Node: v,
  1162  				})
  1163  				return nil
  1164  			}
  1165  			if v.IsDynamic {
  1166  				// If the list is dynamic, there is no need to recompute the
  1167  				// arcs.
  1168  				a.Label = label
  1169  				n.Arcs = append(n.Arcs, a)
  1170  				continue
  1171  			}
  1172  			arc := *a
  1173  			arc.Parent = n
  1174  			arc.Label = label
  1175  			n.Arcs = append(n.Arcs, &arc)
  1176  		}
  1177  		n.status = finalized
  1178  		return n
  1179  
  1180  	case *Bytes:
  1181  		var (
  1182  			lo = uint64(0)
  1183  			hi = uint64(len(v.B))
  1184  		)
  1185  		if x.Lo != nil {
  1186  			lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
  1187  		}
  1188  		if x.Hi != nil {
  1189  			hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
  1190  			if hi > uint64(len(v.B)) {
  1191  				return c.NewErrf("index %d out of range", hi)
  1192  			}
  1193  		}
  1194  		if lo > hi {
  1195  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
  1196  		}
  1197  		return c.newBytes(v.B[lo:hi])
  1198  	}
  1199  
  1200  	if isError(v) {
  1201  		return v
  1202  	}
  1203  	return c.NewErrf("cannot slice %v (type %s)", v, v.Kind())
  1204  }
  1205  
  1206  // An Interpolation is a string interpolation.
  1207  //
  1208  //	"a \(b) c"
  1209  type Interpolation struct {
  1210  	Src   *ast.Interpolation
  1211  	K     Kind   // string or bytes
  1212  	Parts []Expr // odd: strings, even sources
  1213  }
  1214  
  1215  func (x *Interpolation) Source() ast.Node {
  1216  	if x.Src == nil {
  1217  		return nil
  1218  	}
  1219  	return x.Src
  1220  }
  1221  
  1222  func (x *Interpolation) evaluate(c *OpContext, state combinedFlags) Value {
  1223  	buf := bytes.Buffer{}
  1224  	for _, e := range x.Parts {
  1225  		v := c.value(e, require(partial, scalarKnown))
  1226  		if x.K == BytesKind {
  1227  			buf.Write(c.ToBytes(v))
  1228  		} else {
  1229  			buf.WriteString(c.ToString(v))
  1230  		}
  1231  	}
  1232  	if err := c.Err(); err != nil {
  1233  		err = &Bottom{
  1234  			Code: err.Code,
  1235  			Node: c.vertex,
  1236  			Err:  errors.Wrapf(err.Err, pos(x), "invalid interpolation"),
  1237  		}
  1238  		// c.AddBottom(err)
  1239  		// return nil
  1240  		return err
  1241  	}
  1242  	if x.K == BytesKind {
  1243  		return &Bytes{x.Src, buf.Bytes(), nil}
  1244  	}
  1245  	return &String{x.Src, buf.String(), nil}
  1246  }
  1247  
  1248  // UnaryExpr is a unary expression.
  1249  //
  1250  //	Op X
  1251  //	-X !X +X
  1252  type UnaryExpr struct {
  1253  	Src *ast.UnaryExpr
  1254  	Op  Op
  1255  	X   Expr
  1256  }
  1257  
  1258  func (x *UnaryExpr) Source() ast.Node {
  1259  	if x.Src == nil {
  1260  		return nil
  1261  	}
  1262  	return x.Src
  1263  }
  1264  
  1265  func (x *UnaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1266  	if !c.concreteIsPossible(x.Op, x.X) {
  1267  		return nil
  1268  	}
  1269  	v := c.value(x.X, require(partial, scalarKnown))
  1270  	if isError(v) {
  1271  		return v
  1272  	}
  1273  
  1274  	op := x.Op
  1275  	k := kind(v)
  1276  	expectedKind := k
  1277  	switch op {
  1278  	case SubtractOp:
  1279  		if v, ok := v.(*Num); ok {
  1280  			f := *v
  1281  			f.X.Neg(&v.X)
  1282  			f.Src = x.Src
  1283  			return &f
  1284  		}
  1285  		expectedKind = NumberKind
  1286  
  1287  	case AddOp:
  1288  		if v, ok := v.(*Num); ok {
  1289  			// TODO: wrap in thunk to save position of '+'?
  1290  			return v
  1291  		}
  1292  		expectedKind = NumberKind
  1293  
  1294  	case NotOp:
  1295  		if v, ok := v.(*Bool); ok {
  1296  			return &Bool{x.Src, !v.B}
  1297  		}
  1298  		expectedKind = BoolKind
  1299  	}
  1300  	if k&expectedKind != BottomKind {
  1301  		c.addErrf(IncompleteError, pos(x.X),
  1302  			"operand %s of '%s' not concrete (was %s)", x.X, op, k)
  1303  		return nil
  1304  	}
  1305  	return c.NewErrf("invalid operation %v (%s %s)", x, op, k)
  1306  }
  1307  
  1308  // BinaryExpr is a binary expression.
  1309  //
  1310  //	X + Y
  1311  //	X & Y
  1312  type BinaryExpr struct {
  1313  	Src *ast.BinaryExpr
  1314  	Op  Op
  1315  	X   Expr
  1316  	Y   Expr
  1317  }
  1318  
  1319  func (x *BinaryExpr) Source() ast.Node {
  1320  	if x.Src == nil {
  1321  		return nil
  1322  	}
  1323  	return x.Src
  1324  }
  1325  
  1326  func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1327  	env := c.Env(0)
  1328  	if x.Op == AndOp {
  1329  		v := c.newInlineVertex(nil, nil, makeAnonymousConjunct(env, x, c.ci.Refs))
  1330  
  1331  		// Do not fully evaluate the Vertex: if it is embedded within a
  1332  		// struct with arcs that are referenced from within this expression,
  1333  		// it will end up adding "locked" fields, resulting in an error.
  1334  		// It will be the responsibility of the "caller" to get the result
  1335  		// to the required state. If the struct is already dynamic, we will
  1336  		// evaluate the struct regardless to ensure that cycle reporting
  1337  		// keeps working.
  1338  		if env.Vertex.IsDynamic || c.inValidator > 0 {
  1339  			v.Finalize(c)
  1340  		} else {
  1341  			v.CompleteArcsOnly(c)
  1342  		}
  1343  
  1344  		return v
  1345  	}
  1346  
  1347  	if !c.concreteIsPossible(x.Op, x.X) || !c.concreteIsPossible(x.Op, x.Y) {
  1348  		return nil
  1349  	}
  1350  
  1351  	// TODO: allow comparing to a literal Bottom only. Find something more
  1352  	// principled perhaps. One should especially take care that two values
  1353  	// evaluating to Bottom don't evaluate to true. For now we check for
  1354  	// Bottom here and require that one of the values be a Bottom literal.
  1355  	if x.Op == EqualOp || x.Op == NotEqualOp {
  1356  		if isLiteralBottom(x.X) {
  1357  			return c.validate(env, x.Src, x.Y, x.Op, state)
  1358  		}
  1359  		if isLiteralBottom(x.Y) {
  1360  			return c.validate(env, x.Src, x.X, x.Op, state)
  1361  		}
  1362  	}
  1363  
  1364  	left, _ := c.concrete(env, x.X, x.Op)
  1365  	right, _ := c.concrete(env, x.Y, x.Op)
  1366  
  1367  	if err := CombineErrors(x.Src, left, right); err != nil {
  1368  		return err
  1369  	}
  1370  
  1371  	if err := c.Err(); err != nil {
  1372  		return err
  1373  	}
  1374  
  1375  	return BinOp(c, x.Op, left, right)
  1376  }
  1377  
  1378  func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flags combinedFlags) (r Value) {
  1379  	state := flags.vertexStatus()
  1380  
  1381  	s := c.PushState(env, src)
  1382  
  1383  	match := op != EqualOp // non-error case
  1384  
  1385  	c.inValidator++
  1386  	// Note that evalState may call yield, so we need to balance the counter
  1387  	// with a defer.
  1388  	defer func() { c.inValidator-- }()
  1389  	req := flags
  1390  	req = final(state, needTasksDone)
  1391  	v := c.evalState(x, req)
  1392  	u, _ := c.getDefault(v)
  1393  	u = Unwrap(u)
  1394  
  1395  	// If our final (unwrapped) value is potentially a recursive structure, we
  1396  	// still need to recursively check for errors. We do so by treating it
  1397  	// as the original value, which if it is a Vertex will be evaluated
  1398  	// recursively below.
  1399  	if u != nil && u.Kind().IsAnyOf(StructKind|ListKind) {
  1400  		u = v
  1401  	}
  1402  
  1403  	switch v := u.(type) {
  1404  	case nil:
  1405  	case *Bottom:
  1406  		switch v.Code {
  1407  		case CycleError:
  1408  			c.PopState(s)
  1409  			c.AddBottom(v)
  1410  			// TODO: add this. This erases some
  1411  			// c.verifyNonMonotonicResult(env, x, true)
  1412  			return nil
  1413  
  1414  		case IncompleteError:
  1415  			c.evalState(x, oldOnly(finalized))
  1416  
  1417  			// We have a nonmonotonic use of a failure. Referenced fields should
  1418  			// not be added anymore.
  1419  			c.verifyNonMonotonicResult(env, x, true)
  1420  		}
  1421  
  1422  		match = op == EqualOp
  1423  
  1424  	case *Vertex:
  1425  		// TODO(cycle): if EqualOp:
  1426  		// - ensure to pass special status to if clause or keep a track of "hot"
  1427  		//   paths.
  1428  		// - evaluate hypothetical struct
  1429  		// - walk over all fields and verify that fields are not contradicting
  1430  		//   previously marked fields.
  1431  		//
  1432  
  1433  		if c.hasDepthCycle(v) {
  1434  			// Eval V3 logic
  1435  			c.verifyNonMonotonicResult(env, x, true)
  1436  			match = op == EqualOp
  1437  			break
  1438  		}
  1439  		if v.status == evaluatingArcs {
  1440  			unreachableForDev(c) // Eval V2 logic
  1441  
  1442  			// We have a cycle, which may be an error. Cycle errors may occur
  1443  			// in chains that are themselves not a cycle. It suffices to check
  1444  			// for non-monotonic results at the end for this particular path.
  1445  			// TODO(perf): finding the right path through such comprehensions
  1446  			// may be expensive. Finding a path in a directed graph is O(n),
  1447  			// though, so we should ensure that the implementation conforms to
  1448  			// this.
  1449  			c.verifyNonMonotonicResult(env, x, true)
  1450  			match = op == EqualOp
  1451  			break
  1452  		}
  1453  		v.Finalize(c)
  1454  
  1455  		switch {
  1456  		case !v.IsDefined(c):
  1457  			c.verifyNonMonotonicResult(env, x, true) // TODO: remove?
  1458  
  1459  			// TODO: mimic comparison to bottom semantics. If it is a valid
  1460  			// value, check for concreteness that this level only. This
  1461  			// should ultimately be replaced with an exists and valid
  1462  			// builtin.
  1463  			match = op == EqualOp
  1464  
  1465  		case isFinalError(v):
  1466  			// Need to recursively check for errors, so we need to evaluate the
  1467  			// Vertex in case it hadn't been evaluated yet.
  1468  			match = op == EqualOp
  1469  		}
  1470  
  1471  	default:
  1472  		if v.Kind().IsAnyOf(CompositeKind) && v.Concreteness() > Concrete && state < conjuncts {
  1473  			c.PopState(s)
  1474  			c.AddBottom(cycle)
  1475  			return nil
  1476  		}
  1477  
  1478  		c.verifyNonMonotonicResult(env, x, false)
  1479  
  1480  		if v.Concreteness() > Concrete {
  1481  			// TODO: mimic comparison to bottom semantics. If it is a valid
  1482  			// value, check for concreteness that this level only. This
  1483  			// should ultimately be replaced with an exists and valid
  1484  			// builtin.
  1485  			match = op == EqualOp
  1486  		}
  1487  
  1488  		c.evalState(x, require(state, needTasksDone))
  1489  	}
  1490  
  1491  	c.PopState(s)
  1492  	return &Bool{src, match}
  1493  }
  1494  
  1495  func isFinalError(n *Vertex) bool {
  1496  	n = n.DerefValue()
  1497  	if b, ok := Unwrap(n).(*Bottom); ok && b.Code < IncompleteError {
  1498  		return true
  1499  	}
  1500  	return false
  1501  }
  1502  
  1503  // verifyNonMonotonicResult re-evaluates the given expression at a later point
  1504  // to ensure that the result has not changed. This is relevant when a function
  1505  // uses reflection, as in `if a != _|_`, where the result of an evaluation may
  1506  // change after the fact.
  1507  // expectError indicates whether the value should evaluate to an error or not.
  1508  func (c *OpContext) verifyNonMonotonicResult(env *Environment, x Expr, expectError bool) {
  1509  	if n := env.Vertex.state; n != nil {
  1510  		n.postChecks = append(n.postChecks, envCheck{
  1511  			env:         env,
  1512  			expr:        x,
  1513  			expectError: expectError,
  1514  		})
  1515  	}
  1516  }
  1517  
  1518  // A CallExpr represents a call to a builtin.
  1519  //
  1520  //	len(x)
  1521  //	strings.ToLower(x)
  1522  type CallExpr struct {
  1523  	Src  *ast.CallExpr
  1524  	Fun  Expr
  1525  	Args []Expr
  1526  }
  1527  
  1528  func (x *CallExpr) Source() ast.Node {
  1529  	if x.Src == nil {
  1530  		return nil
  1531  	}
  1532  	return x.Src
  1533  }
  1534  
  1535  func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1536  	call := &CallContext{
  1537  		ctx:  c,
  1538  		call: x,
  1539  	}
  1540  
  1541  	fun := c.value(x.Fun, require(partial, concreteKnown))
  1542  	switch f := fun.(type) {
  1543  	case *Builtin:
  1544  		call.builtin = f
  1545  		if f.RawFunc != nil {
  1546  			if !call.builtin.checkArgs(c, pos(x), len(x.Args)) {
  1547  				return nil
  1548  			}
  1549  			return f.RawFunc(call)
  1550  		}
  1551  
  1552  	case *BuiltinValidator:
  1553  		// We allow a validator that takes no arguments except the validated
  1554  		// value to be called with zero arguments.
  1555  		switch {
  1556  		case f.Src != nil:
  1557  			c.AddErrf("cannot call previously called validator %s", x.Fun)
  1558  
  1559  		case f.Builtin.IsValidator(len(x.Args)):
  1560  			v := *f
  1561  			v.Src = x
  1562  			return &v
  1563  
  1564  		default:
  1565  			call.builtin = f.Builtin
  1566  		}
  1567  
  1568  	default:
  1569  		c.AddErrf("cannot call non-function %s (type %s)", x.Fun, kind(fun))
  1570  		return nil
  1571  	}
  1572  
  1573  	// Arguments to functions are open. This mostly matters for NonConcrete
  1574  	// builtins.
  1575  	saved := c.ci
  1576  	c.ci.FromDef = false
  1577  	c.ci.FromEmbed = false
  1578  	defer func() {
  1579  		c.ci.FromDef = saved.FromDef
  1580  		c.ci.FromEmbed = saved.FromEmbed
  1581  	}()
  1582  
  1583  	args := []Value{}
  1584  	for i, a := range x.Args {
  1585  		saved := c.errs
  1586  		c.errs = nil
  1587  		// XXX: XXX: clear id.closeContext per argument and remove from runTask?
  1588  
  1589  		runMode := state.runMode()
  1590  		cond := state.conditions()
  1591  		var expr Value
  1592  		if call.builtin.NonConcrete {
  1593  			state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus())
  1594  			expr = c.evalState(a, state)
  1595  		} else {
  1596  			cond |= fieldSetKnown | concreteKnown
  1597  			// Be sure to process disjunctions at the very least when
  1598  			// finalizing. Requiring disjunctions earlier may lead to too eager
  1599  			// evaluation.
  1600  			//
  1601  			// TODO: Ideally we would always add this flag regardless of mode.
  1602  			if runMode == finalize {
  1603  				cond |= disjunctionTask
  1604  			}
  1605  			state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus())
  1606  			expr = c.value(a, state)
  1607  		}
  1608  
  1609  		switch v := expr.(type) {
  1610  		case nil:
  1611  			if c.errs == nil {
  1612  				// There SHOULD be an error in the context. If not, we generate
  1613  				// one.
  1614  				c.Assertf(pos(x.Fun), c.HasErr(),
  1615  					"argument %d to function %s is incomplete", i, x.Fun)
  1616  			}
  1617  
  1618  		case *Bottom:
  1619  			// TODO(errors): consider adding an argument index for this errors.
  1620  			c.errs = CombineErrors(a.Source(), c.errs, v)
  1621  
  1622  		default:
  1623  			args = append(args, expr)
  1624  		}
  1625  		c.errs = CombineErrors(a.Source(), saved, c.errs)
  1626  	}
  1627  	if c.HasErr() {
  1628  		return nil
  1629  	}
  1630  	if call.builtin.IsValidator(len(args)) {
  1631  		return &BuiltinValidator{x, call.builtin, args}
  1632  	}
  1633  	call.args = args
  1634  	result := call.builtin.call(call)
  1635  	if result == nil {
  1636  		return nil
  1637  	}
  1638  	v, ci := c.evalStateCI(result, state.withVertexStatus(partial))
  1639  	c.ci = ci
  1640  	return v
  1641  }
  1642  
  1643  // A Builtin is a value representing a native function call.
  1644  type Builtin struct {
  1645  	// TODO:  make these values for better type checking.
  1646  	Params []Param
  1647  	Result Kind
  1648  
  1649  	// NonConcrete should be set to true if a builtin supports non-concrete
  1650  	// arguments. By default, all arguments are checked to be concrete.
  1651  	NonConcrete bool
  1652  
  1653  	Func func(call *CallContext) Expr
  1654  
  1655  	// RawFunc gives low-level control to CUE's internals for builtins.
  1656  	// It should be used when fine control over the evaluation process is
  1657  	// needed. Note that RawFuncs are responsible for returning a Value. This
  1658  	// gives them fine control over how exactly such value gets evaluated.
  1659  	// A RawFunc may pass CycleInfo, errors and other information through
  1660  	// the Context.
  1661  	//
  1662  	// TODO: consider merging Func and RawFunc into a single field again.
  1663  	RawFunc func(call *CallContext) Value
  1664  
  1665  	Package Feature
  1666  	Name    string
  1667  }
  1668  
  1669  type Param struct {
  1670  	Name  Feature // name of the argument; mostly for documentation
  1671  	Value Value   // Could become Value later, using disjunctions for defaults.
  1672  }
  1673  
  1674  // Kind returns the kind mask of this parameter.
  1675  func (p Param) Kind() Kind {
  1676  	return p.Value.Kind()
  1677  }
  1678  
  1679  // Default reports the default value for this Param or nil if there is none.
  1680  func (p Param) Default() Value {
  1681  	d, ok := p.Value.(*Disjunction)
  1682  	if !ok || d.NumDefaults != 1 {
  1683  		return nil
  1684  	}
  1685  	return d.Values[0]
  1686  }
  1687  
  1688  func (x *Builtin) qualifiedName(c *OpContext) string {
  1689  	if x.Package != InvalidLabel {
  1690  		return x.Package.StringValue(c) + "." + x.Name
  1691  	}
  1692  	return x.Name
  1693  }
  1694  
  1695  // Kind here represents the case where Builtin is used as a Validator.
  1696  func (x *Builtin) Kind() Kind {
  1697  	return FuncKind
  1698  }
  1699  
  1700  func (x *Builtin) BareValidator() *BuiltinValidator {
  1701  	if len(x.Params) != 1 ||
  1702  		(x.Result != BoolKind && x.Result != BottomKind) {
  1703  		return nil
  1704  	}
  1705  	return &BuiltinValidator{Builtin: x}
  1706  }
  1707  
  1708  // IsValidator reports whether b should be interpreted as a Validator for the
  1709  // given number of arguments.
  1710  func (b *Builtin) IsValidator(numArgs int) bool {
  1711  	return numArgs == len(b.Params)-1 &&
  1712  		b.Result&^BoolKind == 0 &&
  1713  		b.Params[numArgs].Default() == nil
  1714  }
  1715  
  1716  func bottom(v Value) *Bottom {
  1717  	if x, ok := v.(*Vertex); ok {
  1718  		v = x.Value()
  1719  	}
  1720  	b, _ := v.(*Bottom)
  1721  	return b
  1722  }
  1723  
  1724  func (x *Builtin) checkArgs(c *OpContext, p token.Pos, numArgs int) bool {
  1725  	if numArgs > len(x.Params) {
  1726  		c.addErrf(0, p,
  1727  			"too many arguments in call to %v (have %d, want %d)",
  1728  			x, numArgs, len(x.Params))
  1729  		return false
  1730  	}
  1731  	if numArgs < len(x.Params) {
  1732  		// Assume that all subsequent params have a default as well.
  1733  		v := x.Params[numArgs].Default()
  1734  		if v == nil {
  1735  			c.addErrf(0, p,
  1736  				"not enough arguments in call to %v (have %d, want %d)",
  1737  				x, numArgs, len(x.Params))
  1738  			return false
  1739  		}
  1740  	}
  1741  	return true
  1742  }
  1743  
  1744  func (x *Builtin) call(call *CallContext) Expr {
  1745  	c := call.ctx
  1746  	p := call.Pos()
  1747  
  1748  	fun := x // right now always x.
  1749  	if !x.checkArgs(c, p, len(call.args)) {
  1750  		return nil
  1751  	}
  1752  	for i := len(call.args); i < len(x.Params); i++ {
  1753  		call.args = append(call.args, x.Params[i].Default())
  1754  	}
  1755  	for i, a := range call.args {
  1756  		if x.Params[i].Kind() == BottomKind {
  1757  			continue
  1758  		}
  1759  		if b := bottom(a); b != nil {
  1760  			return b
  1761  		}
  1762  		if k := kind(a); x.Params[i].Kind()&k == BottomKind {
  1763  			code := EvalError
  1764  			b, _ := call.args[i].(*Bottom)
  1765  			if b != nil {
  1766  				code = b.Code
  1767  			}
  1768  			c.addErrf(code, pos(a),
  1769  				"cannot use %s (type %s) as %s in argument %d to %v",
  1770  				a, k, x.Params[i].Kind(), i+1, fun)
  1771  			return nil
  1772  		}
  1773  		v := x.Params[i].Value
  1774  		if _, ok := v.(*BasicType); !ok {
  1775  			env := c.Env(0)
  1776  			x := &BinaryExpr{Op: AndOp, X: v, Y: a}
  1777  			n := c.newInlineVertex(nil, nil, Conjunct{env, x, c.ci})
  1778  			n.Finalize(c)
  1779  			if n.IsErr() {
  1780  				c.addErrf(0, pos(a),
  1781  					"cannot use %s as %s in argument %d to %v",
  1782  					a, v, i+1, fun)
  1783  				return nil
  1784  			}
  1785  			call.args[i] = n
  1786  		}
  1787  	}
  1788  
  1789  	// Arguments to functions are open. This mostly matters for NonConcrete
  1790  	// builtins.
  1791  	saved := c.IsValidator
  1792  	c.IsValidator = call.isValidator
  1793  	ci := c.ci
  1794  	c.ci.FromEmbed = false
  1795  	c.ci.FromDef = false
  1796  	defer func() {
  1797  		c.ci.FromDef = ci.FromDef
  1798  		c.ci.FromEmbed = ci.FromEmbed
  1799  		c.IsValidator = saved
  1800  	}()
  1801  
  1802  	return x.Func(call)
  1803  }
  1804  
  1805  func (x *Builtin) Source() ast.Node { return nil }
  1806  
  1807  // A BuiltinValidator is a Value that results from evaluation a partial call
  1808  // to a builtin (using CallExpr).
  1809  //
  1810  //	strings.MinRunes(4)
  1811  type BuiltinValidator struct {
  1812  	Src     *CallExpr
  1813  	Builtin *Builtin
  1814  	Args    []Value // any but the first value
  1815  }
  1816  
  1817  func (x *BuiltinValidator) Source() ast.Node {
  1818  	if x.Src == nil {
  1819  		return x.Builtin.Source()
  1820  	}
  1821  	return x.Src.Source()
  1822  }
  1823  
  1824  func (x *BuiltinValidator) Pos() token.Pos {
  1825  	if src := x.Source(); src != nil {
  1826  		return src.Pos()
  1827  	}
  1828  	return token.NoPos
  1829  }
  1830  
  1831  func (x *BuiltinValidator) Kind() Kind {
  1832  	return x.Builtin.Params[0].Kind()
  1833  }
  1834  
  1835  func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom {
  1836  	args := make([]Value, len(x.Args)+1)
  1837  	args[0] = v
  1838  	copy(args[1:], x.Args)
  1839  
  1840  	call := &CallContext{
  1841  		ctx:         c,
  1842  		call:        x.Src,
  1843  		builtin:     x.Builtin,
  1844  		args:        args,
  1845  		isValidator: true,
  1846  	}
  1847  
  1848  	return validateWithBuiltin(call)
  1849  }
  1850  
  1851  func validateWithBuiltin(call *CallContext) *Bottom {
  1852  	var severeness ErrorCode
  1853  	var err errors.Error
  1854  
  1855  	c := call.ctx
  1856  	b := call.builtin
  1857  	src := call.Pos()
  1858  	arg0 := call.Value(0)
  1859  
  1860  	res := call.builtin.call(call)
  1861  	switch v := res.(type) {
  1862  	case nil:
  1863  		return nil
  1864  
  1865  	case *Bottom:
  1866  		if v == nil {
  1867  			return nil // caught elsewhere, but be defensive.
  1868  		}
  1869  		severeness = v.Code
  1870  		err = v.Err
  1871  
  1872  	case *Bool:
  1873  		if v.B {
  1874  			return nil
  1875  		}
  1876  
  1877  	default:
  1878  		return c.NewErrf("invalid validator %s", b.qualifiedName(c))
  1879  	}
  1880  
  1881  	// If the validator returns an error and we already had an error, just
  1882  	// return the original error.
  1883  	if b, ok := Unwrap(call.Value(0)).(*Bottom); ok {
  1884  		return b
  1885  	}
  1886  	// failed:
  1887  	var buf bytes.Buffer
  1888  	buf.WriteString(b.qualifiedName(c))
  1889  
  1890  	// Note: when the builtin accepts non-concrete arguments, omit them because
  1891  	// they can easily be very large.
  1892  	if !b.NonConcrete && call.NumParams() > 1 { // use NumArgs instead
  1893  		buf.WriteString("(")
  1894  		// TODO: use accessor instead of call.arg
  1895  		for i, a := range call.args[1:] {
  1896  			if i > 0 {
  1897  				_, _ = buf.WriteString(", ")
  1898  			}
  1899  			buf.WriteString(c.Str(a))
  1900  		}
  1901  		buf.WriteString(")")
  1902  	}
  1903  
  1904  	vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", arg0, buf.String())
  1905  
  1906  	call.AddPositions(vErr)
  1907  
  1908  	return &Bottom{
  1909  		Code: severeness,
  1910  		Err:  errors.Wrap(vErr, err),
  1911  		Node: c.vertex,
  1912  	}
  1913  }
  1914  
  1915  // A Disjunction represents a disjunction, where each disjunct may or may not
  1916  // be marked as a default.
  1917  type DisjunctionExpr struct {
  1918  	Src    *ast.BinaryExpr
  1919  	Values []Disjunct
  1920  
  1921  	HasDefaults bool
  1922  }
  1923  
  1924  // A Disjunct is used in Disjunction.
  1925  type Disjunct struct {
  1926  	Val     Expr
  1927  	Default bool
  1928  }
  1929  
  1930  func (x *DisjunctionExpr) Source() ast.Node {
  1931  	if x.Src == nil {
  1932  		return nil
  1933  	}
  1934  	return x.Src
  1935  }
  1936  
  1937  func (x *DisjunctionExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1938  	e := c.Env(0)
  1939  	v := c.newInlineVertex(nil, nil, Conjunct{e, x, c.ci})
  1940  	v.Finalize(c) // TODO: also partial okay?
  1941  	// TODO: if the disjunction result originated from a literal value, we may
  1942  	// consider the result closed to create more permanent errors.
  1943  	return v
  1944  }
  1945  
  1946  // A Conjunction is a conjunction of values that cannot be represented as a
  1947  // single value. It is the result of unification.
  1948  type Conjunction struct {
  1949  	Src    ast.Expr
  1950  	Values []Value
  1951  }
  1952  
  1953  func (x *Conjunction) Source() ast.Node { return x.Src }
  1954  func (x *Conjunction) Kind() Kind {
  1955  	k := TopKind
  1956  	for _, v := range x.Values {
  1957  		k &= v.Kind()
  1958  	}
  1959  	return k
  1960  }
  1961  
  1962  // A disjunction is a disjunction of values. It is the result of expanding
  1963  // a DisjunctionExpr if the expression cannot be represented as a single value.
  1964  type Disjunction struct {
  1965  	Src ast.Expr
  1966  
  1967  	// Values are the non-error disjuncts of this expression. The first
  1968  	// NumDefaults values are default values.
  1969  	Values []Value
  1970  
  1971  	Errors *Bottom // []bottom
  1972  
  1973  	// NumDefaults indicates the number of default values.
  1974  	NumDefaults int
  1975  	HasDefaults bool
  1976  }
  1977  
  1978  func (x *Disjunction) Source() ast.Node { return x.Src }
  1979  func (x *Disjunction) Kind() Kind {
  1980  	k := BottomKind
  1981  	for _, v := range x.Values {
  1982  		k |= v.Kind()
  1983  	}
  1984  	return k
  1985  }
  1986  
  1987  type Comprehension struct {
  1988  	Syntax ast.Node
  1989  
  1990  	// Clauses is the list of for, if, and other clauses of a comprehension,
  1991  	// not including the yielded value (in curly braces).
  1992  	Clauses []Yielder
  1993  
  1994  	// Value can be either a StructLit if this is a compiled expression or
  1995  	// a Field if this is a computed Comprehension. Value holds a Field,
  1996  	// rather than an Expr, in the latter case to preserve as much position
  1997  	// information as possible.
  1998  	Value Node
  1999  
  2000  	// The type of field as which the comprehension is added.
  2001  	arcType ArcType
  2002  
  2003  	// Kind indicates the possible kind of Value.
  2004  	kind Kind
  2005  
  2006  	// Only used for partial comprehensions.
  2007  	comp   *envComprehension
  2008  	parent *Comprehension // comprehension from which this one was derived, if any
  2009  	arc    *Vertex        // arc to which this comprehension was added.
  2010  }
  2011  
  2012  // Nest returns the nesting level of void arcs of this comprehension.
  2013  func (c *Comprehension) Nest() int {
  2014  	count := 0
  2015  	for ; c.parent != nil; c = c.parent {
  2016  		count++
  2017  	}
  2018  	return count
  2019  }
  2020  
  2021  // Envs returns all Environments yielded from an evaluated comprehension.
  2022  // Together with the Comprehension value, each Environment represents a
  2023  // result value of the comprehension.
  2024  func (c *Comprehension) Envs() []*Environment {
  2025  	if c.comp == nil {
  2026  		return nil
  2027  	}
  2028  	return c.comp.envs
  2029  }
  2030  
  2031  // DidResolve reports whether a comprehension was processed and resulted in at
  2032  // least one yielded value.
  2033  func (x *Comprehension) DidResolve() bool {
  2034  	return x.comp.done && len(x.comp.envs) > 0
  2035  }
  2036  
  2037  func (x *Comprehension) Source() ast.Node {
  2038  	if x.Syntax == nil {
  2039  		return nil
  2040  	}
  2041  	return x.Syntax
  2042  }
  2043  
  2044  // A ForClause represents a for clause of a comprehension. It can be used
  2045  // as a struct or list element.
  2046  //
  2047  //	for k, v in src {}
  2048  type ForClause struct {
  2049  	Syntax *ast.ForClause
  2050  	Key    Feature
  2051  	Value  Feature
  2052  	Src    Expr
  2053  }
  2054  
  2055  func (x *ForClause) Source() ast.Node {
  2056  	if x.Syntax == nil {
  2057  		return nil
  2058  	}
  2059  	return x.Syntax
  2060  }
  2061  
  2062  func (c *OpContext) forSource(x Expr) *Vertex {
  2063  	state := attempt(conjuncts, needFieldSetKnown)
  2064  
  2065  	// TODO: always get the vertex. This allows a whole bunch of trickery
  2066  	// down the line.
  2067  	c.inDetached++
  2068  	v := c.unifyNode(x, state)
  2069  	c.inDetached--
  2070  
  2071  	node, ok := v.(*Vertex)
  2072  	if ok && c.isDevVersion() {
  2073  		// We do not request to "yield" here, but rather rely on the
  2074  		// call-by-need behavior in combination with the freezing mechanism.
  2075  		// TODO: this seems a bit fragile. At some point we need to make this
  2076  		// more robust by moving to a pure call-by-need mechanism, for instance.
  2077  		// TODO: using attemptOnly here will remove the cyclic reference error
  2078  		// of comprehension.t1.ok (which also errors in V2),
  2079  		node.unify(c, state.conditions(), finalize, true)
  2080  	}
  2081  
  2082  	v, ok = c.getDefault(v)
  2083  
  2084  	if !ok {
  2085  		// Error already generated by getDefault.
  2086  		return emptyNode
  2087  	}
  2088  
  2089  	// TODO: skip in new evaluator? Check once we introduce disjunctions.
  2090  	if w := Unwrap(v); !isCyclePlaceholder(w) {
  2091  		v = w
  2092  	}
  2093  	node, ok = v.(*Vertex)
  2094  	if ok && !isCyclePlaceholder(node.BaseValue) {
  2095  		v = node.Value()
  2096  	}
  2097  
  2098  	switch nv := v.(type) {
  2099  	case nil:
  2100  		c.addErrf(IncompleteError, pos(x),
  2101  			"cannot range over %s (incomplete)", x)
  2102  		return emptyNode
  2103  
  2104  	case *Bottom:
  2105  		// TODO: this is a bit messy. In some cases errors are already added
  2106  		// and in some cases not. Not a huge deal, as errors will be uniqued
  2107  		// down the line, but could be better.
  2108  		c.AddBottom(nv)
  2109  		return emptyNode
  2110  
  2111  	case *Vertex:
  2112  		if node == nil {
  2113  			panic("unexpected markers with nil node")
  2114  		}
  2115  
  2116  	default:
  2117  		if kind := v.Kind(); kind&(StructKind|ListKind) != 0 {
  2118  			c.addErrf(IncompleteError, pos(x),
  2119  				"cannot range over %s (incomplete type %s)", x, kind)
  2120  			return emptyNode
  2121  
  2122  		} else if !ok {
  2123  			c.addErrf(0, pos(x), // TODO(error): better message.
  2124  				"cannot range over %s (found %s, want list or struct)",
  2125  				x.Source(), v.Kind())
  2126  			return emptyNode
  2127  		}
  2128  	}
  2129  	if c.isDevVersion() {
  2130  		kind := v.Kind()
  2131  		// At this point it is possible that the Vertex represents an incomplete
  2132  		// struct or list, which is the case if it may be struct or list, but
  2133  		// is also at least some other type, such as is the case with top.
  2134  		if kind&(StructKind|ListKind) != 0 && kind != StructKind && kind != ListKind {
  2135  			c.addErrf(IncompleteError, pos(x),
  2136  				"cannot range over %s (incomplete type %s)", x, kind)
  2137  			return emptyNode
  2138  		}
  2139  	}
  2140  
  2141  	return node
  2142  }
  2143  
  2144  func (x *ForClause) yield(s *compState) {
  2145  	c := s.ctx
  2146  	n := c.forSource(x.Src)
  2147  
  2148  	if c.isDevVersion() {
  2149  		if s := n.getState(c); s != nil {
  2150  			s.freeze(fieldSetKnown)
  2151  		}
  2152  	} else {
  2153  		if n.status == evaluating && !n.LockArcs {
  2154  			c.AddBottom(&Bottom{
  2155  				Code:     CycleError,
  2156  				ForCycle: true,
  2157  				Value:    n,
  2158  				Node:     n,
  2159  				Err:      errors.Newf(pos(x.Src), "comprehension source references itself"),
  2160  			})
  2161  			return
  2162  		}
  2163  		if c.HasErr() {
  2164  			return
  2165  		}
  2166  		n.LockArcs = true
  2167  	}
  2168  
  2169  	for _, a := range n.Arcs {
  2170  		if !a.Label.IsRegular() {
  2171  			continue
  2172  		}
  2173  
  2174  		if c.isDevVersion() {
  2175  			// TODO(evalv3): See comment in StructLit.evaluate.
  2176  			if state := a.getState(c); state != nil {
  2177  				state.process(arcTypeKnown, attemptOnly)
  2178  			}
  2179  		} else {
  2180  			if !a.isDefined() {
  2181  				a.Finalize(c)
  2182  			}
  2183  			if !a.definitelyExists() {
  2184  				continue
  2185  			}
  2186  		}
  2187  
  2188  		switch a.ArcType {
  2189  		case ArcMember:
  2190  		case ArcRequired:
  2191  			c.AddBottom(newRequiredFieldInComprehensionError(c, x, a))
  2192  			continue
  2193  		default:
  2194  			continue
  2195  		}
  2196  
  2197  		n := &Vertex{
  2198  			Parent: c.Env(0).Vertex,
  2199  
  2200  			// Using Finalized here ensures that no nodeContext is allocated,
  2201  			// preventing a leak, as this "helper" struct bypasses normal
  2202  			// processing, eluding the deallocation step.
  2203  			status:    finalized,
  2204  			IsDynamic: true,
  2205  			anonymous: true,
  2206  			ArcType:   ArcMember,
  2207  		}
  2208  
  2209  		if x.Value != InvalidLabel {
  2210  			b := &Vertex{
  2211  				Label:     x.Value,
  2212  				BaseValue: a,
  2213  				IsDynamic: true,
  2214  				anonymous: true,
  2215  				ArcType:   ArcPending,
  2216  			}
  2217  			n.Arcs = append(n.Arcs, b)
  2218  		}
  2219  
  2220  		if x.Key != InvalidLabel {
  2221  			v := &Vertex{
  2222  				Label:     x.Key,
  2223  				IsDynamic: true,
  2224  				anonymous: true,
  2225  			}
  2226  			key := a.Label.ToValue(c)
  2227  			v.AddConjunct(MakeRootConjunct(c.Env(0), key))
  2228  			v.SetValue(c, key)
  2229  			n.Arcs = append(n.Arcs, v)
  2230  		}
  2231  
  2232  		sub := c.spawn(n)
  2233  		if !s.yield(sub) {
  2234  			break
  2235  		}
  2236  	}
  2237  }
  2238  
  2239  // An IfClause represents an if clause of a comprehension. It can be used
  2240  // as a struct or list element.
  2241  //
  2242  //	if cond {}
  2243  type IfClause struct {
  2244  	Src       *ast.IfClause
  2245  	Condition Expr
  2246  }
  2247  
  2248  func (x *IfClause) Source() ast.Node {
  2249  	if x.Src == nil {
  2250  		return nil
  2251  	}
  2252  	return x.Src
  2253  }
  2254  
  2255  func (x *IfClause) yield(s *compState) {
  2256  	ctx := s.ctx
  2257  	if ctx.BoolValue(ctx.value(x.Condition, require(s.state, scalarKnown))) {
  2258  		s.yield(ctx.e)
  2259  	}
  2260  }
  2261  
  2262  // A LetClause represents a let clause in a comprehension.
  2263  //
  2264  //	let x = y
  2265  type LetClause struct {
  2266  	Src   *ast.LetClause
  2267  	Label Feature
  2268  	Expr  Expr
  2269  }
  2270  
  2271  func (x *LetClause) Source() ast.Node {
  2272  	if x.Src == nil {
  2273  		return nil
  2274  	}
  2275  	return x.Src
  2276  }
  2277  
  2278  func (x *LetClause) yield(s *compState) {
  2279  	c := s.ctx
  2280  	n := &Vertex{Arcs: []*Vertex{
  2281  		{
  2282  			Label:     x.Label,
  2283  			IsDynamic: true,
  2284  			anonymous: true,
  2285  			Conjuncts: []Conjunct{{c.Env(0), x.Expr, c.ci}},
  2286  		},
  2287  	}}
  2288  
  2289  	s.yield(c.spawn(n))
  2290  }