cuelang.org/go@v0.13.0/internal/core/adt/eval.go (about)

     1  // Copyright 2021 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 eval contains the high level CUE evaluation strategy.
    16  //
    17  // CUE allows for a significant amount of freedom in order of evaluation due to
    18  // the commutativity of the unification operation. This package implements one
    19  // of the possible strategies.
    20  package adt
    21  
    22  // TODO:
    23  //   - result should be nodeContext: this allows optionals info to be extracted
    24  //     and computed.
    25  //
    26  
    27  import (
    28  	"fmt"
    29  
    30  	"cuelang.org/go/cue/ast"
    31  	"cuelang.org/go/cue/errors"
    32  	"cuelang.org/go/cue/stats"
    33  	"cuelang.org/go/cue/token"
    34  )
    35  
    36  // TODO TODO TODO TODO TODO TODO  TODO TODO TODO  TODO TODO TODO  TODO TODO TODO
    37  //
    38  // - Reuse work from previous cycles. For instance, if we can guarantee that a
    39  //   value is always correct for partial results, we can just process the arcs
    40  //   going from Partial to Finalized, without having to reevaluate the value.
    41  //
    42  // - Test closedness far more thoroughly.
    43  //
    44  
    45  func (c *OpContext) Stats() *stats.Counts {
    46  	return &c.stats
    47  }
    48  
    49  // TODO: Note: NewContext takes essentially a cue.Value. By making this
    50  // type more central, we can perhaps avoid context creation.
    51  
    52  // func NewContext(r Runtime, v *Vertex) *OpContext {
    53  // 	e := NewUnifier(r)
    54  // 	return e.NewContext(v)
    55  // }
    56  
    57  var incompleteSentinel = &Bottom{
    58  	Code: IncompleteError,
    59  	Err:  errors.Newf(token.NoPos, "incomplete"),
    60  }
    61  
    62  // evaluate returns the evaluated value associated with v. It may return a
    63  // partial result. That is, if v was not yet unified, it may return a
    64  // concrete value that must be the result assuming the configuration has no
    65  // errors.
    66  //
    67  // This semantics allows CUE to break reference cycles in a straightforward
    68  // manner.
    69  //
    70  // Vertex v must still be evaluated at some point to catch the underlying
    71  // error.
    72  //
    73  // TODO: return *Vertex
    74  func (c *OpContext) evaluate(v *Vertex, r Resolver, state combinedFlags) Value {
    75  	if v.isUndefined() {
    76  		// Use node itself to allow for cycle detection.
    77  		c.unify(v, state)
    78  
    79  		if v.ArcType == ArcPending {
    80  			if v.status == evaluating {
    81  				for ; v.Parent != nil && v.ArcType == ArcPending; v = v.Parent {
    82  				}
    83  				err := c.Newf("cycle with field %v", r)
    84  				b := &Bottom{
    85  					Code: CycleError,
    86  					Err:  err,
    87  					Node: v,
    88  				}
    89  				v.setValue(c, v.status, b)
    90  				return b
    91  				// TODO: use this instead, as is usual for incomplete errors,
    92  				// and also move this block one scope up to also apply to
    93  				// defined arcs. In both cases, though, doing so results in
    94  				// some errors to be misclassified as evaluation error.
    95  				// c.AddBottom(b)
    96  				// return nil
    97  			}
    98  			c.undefinedFieldError(v, IncompleteError)
    99  			return nil
   100  		}
   101  	}
   102  
   103  	if n := v.state; n != nil {
   104  		n.assertInitialized()
   105  
   106  		if n.errs != nil && !n.errs.IsIncomplete() {
   107  			return n.errs
   108  		}
   109  		if n.scalar != nil && isCyclePlaceholder(v.BaseValue) {
   110  			return n.scalar
   111  		}
   112  	}
   113  
   114  	switch x := v.BaseValue.(type) {
   115  	case *Bottom:
   116  		if x.IsIncomplete() {
   117  			c.AddBottom(x)
   118  			return nil
   119  		}
   120  		return x
   121  
   122  	case nil:
   123  		if v.state != nil {
   124  			switch x := v.state.getValidators(finalized).(type) {
   125  			case Value:
   126  				return x
   127  			default:
   128  				w := *v
   129  				w.BaseValue = x
   130  				return &w
   131  			}
   132  		}
   133  		// This may happen if the evaluator is invoked outside of regular
   134  		// evaluation, such as in dependency analysis.
   135  		return nil
   136  	}
   137  
   138  	if v.status < finalized && v.state != nil && !c.isDevVersion() {
   139  		// TODO: errors are slightly better if we always add addNotify, but
   140  		// in this case it is less likely to cause a performance penalty.
   141  		// See https://cuelang.org/issue/661. It may be possible to
   142  		// relax this again once we have proper tests to prevent regressions of
   143  		// that issue.
   144  		if !v.state.done() || v.state.errs != nil {
   145  			v.state.addNotify(c.vertex)
   146  		}
   147  	}
   148  
   149  	return v
   150  }
   151  
   152  // unify unifies values of a Vertex to and stores the result in the Vertex. If
   153  // unify was called on v before it returns the cached results.
   154  // state can be used to indicate to which extent processing should continue.
   155  // state == finalized means it is evaluated to completion. See vertexStatus
   156  // for more details.
   157  func (c *OpContext) unify(v *Vertex, flags combinedFlags) {
   158  	if c.isDevVersion() {
   159  		requires, mode := flags.conditions(), flags.runMode()
   160  		v.unify(c, requires, mode, true)
   161  		return
   162  	}
   163  
   164  	// defer c.PopVertex(c.PushVertex(v))
   165  	if c.LogEval > 0 {
   166  		c.nest++
   167  		c.Logf(v, "Unify")
   168  		defer func() {
   169  			c.Logf(v, "END Unify")
   170  			c.nest--
   171  		}()
   172  	}
   173  
   174  	// Ensure a node will always have a nodeContext after calling Unify if it is
   175  	// not yet Finalized.
   176  	n := v.getNodeContext(c, 1)
   177  	defer v.freeNode(n)
   178  
   179  	state := flags.vertexStatus()
   180  
   181  	// TODO(cycle): verify this happens in all cases when we need it.
   182  	if n != nil && v.Parent != nil && v.Parent.state != nil {
   183  		n.depth = v.Parent.state.depth + 1
   184  	}
   185  
   186  	if state <= v.Status() &&
   187  		state == partial &&
   188  		v.isDefined() &&
   189  		n != nil && n.scalar != nil {
   190  		return
   191  	}
   192  
   193  	switch v.Status() {
   194  	case evaluating:
   195  		n.insertConjuncts(state)
   196  		return
   197  
   198  	case evaluatingArcs:
   199  		Assertf(c, v.status > unprocessed, "unexpected status %d", v.status)
   200  		return
   201  
   202  	case 0:
   203  		if v.Label.IsDef() {
   204  			v.ClosedRecursive = true
   205  		}
   206  
   207  		if v.Parent != nil {
   208  			if v.Parent.ClosedRecursive {
   209  				v.ClosedRecursive = true
   210  			}
   211  		}
   212  
   213  		defer c.PopArc(c.PushArc(v))
   214  
   215  		v.updateStatus(evaluating)
   216  
   217  		if p := v.Parent; p != nil && p.state != nil && v.Label.IsString() {
   218  			for _, s := range p.state.node.Structs {
   219  				if s.Disable {
   220  					continue
   221  				}
   222  				s.MatchAndInsert(n.ctx, v)
   223  			}
   224  		}
   225  
   226  		c.stats.Unifications++
   227  
   228  		// Set the cache to a cycle error to ensure a cyclic reference will result
   229  		// in an error if applicable. A cyclic error may be ignored for
   230  		// non-expression references. The cycle error may also be removed as soon
   231  		// as there is evidence what a correct value must be, but before all
   232  		// validation has taken place.
   233  		//
   234  		// TODO(cycle): having a more recursive algorithm would make this
   235  		// special cycle handling unnecessary.
   236  		v.BaseValue = cycle
   237  
   238  		if c.HasErr() {
   239  			n.addBottom(c.errs)
   240  		}
   241  
   242  		// NOTE: safeguard against accidentally entering the 'unprocessed' state
   243  		// twice.
   244  		n.conjuncts = n.conjuncts[:0]
   245  
   246  		for i, c := range v.Conjuncts {
   247  			n.addConjunction(c, i)
   248  		}
   249  		if n.insertConjuncts(state) {
   250  			n.maybeSetCache()
   251  			v.updateStatus(partial)
   252  			return
   253  		}
   254  
   255  		fallthrough
   256  
   257  	case partial, conjuncts:
   258  		// TODO: remove this optimization or make it correct.
   259  		// No need to do further processing when we have errors and all values
   260  		// have been considered.
   261  		// TODO: is checkClosed really still necessary here?
   262  		if v.status == conjuncts && (n.hasErr() || !n.checkClosed(state)) {
   263  			if err := n.getErr(); err != nil {
   264  				b, _ := v.BaseValue.(*Bottom)
   265  				v.BaseValue = CombineErrors(nil, b, err)
   266  			}
   267  			break
   268  		}
   269  
   270  		defer c.PopArc(c.PushArc(v))
   271  
   272  		n.insertConjuncts(state)
   273  
   274  		v.status = evaluating
   275  
   276  		// Use maybeSetCache for cycle breaking
   277  		for n.maybeSetCache(); n.expandOne(partial); n.maybeSetCache() {
   278  		}
   279  
   280  		n.doNotify()
   281  
   282  		if !n.done() {
   283  			switch {
   284  			case state < conjuncts:
   285  				n.node.updateStatus(partial)
   286  				return
   287  
   288  			case state == conjuncts:
   289  				if err := n.incompleteErrors(true); err != nil && err.Code < CycleError {
   290  					n.node.AddErr(c, err)
   291  				} else {
   292  					n.node.updateStatus(partial)
   293  				}
   294  				return
   295  			}
   296  		}
   297  
   298  		// Disjunctions should always be finalized. If there are nested
   299  		// disjunctions the last one should be finalized.
   300  		disState := state
   301  		if len(n.disjunctions) > 0 && disState != finalized {
   302  			disState = finalized
   303  		}
   304  		n.expandDisjuncts(disState, n, maybeDefault, false, true)
   305  
   306  		n.finalizeDisjuncts()
   307  
   308  		switch len(n.disjuncts) {
   309  		case 0:
   310  		case 1:
   311  			x := n.disjuncts[0].result
   312  			x.state = nil
   313  			x.cyclicReferences = n.node.cyclicReferences
   314  			*v = x
   315  
   316  		default:
   317  			d := n.createDisjunct()
   318  			v.BaseValue = d
   319  			// The conjuncts will have too much information. Better have no
   320  			// information than incorrect information.
   321  			for _, d := range d.Values {
   322  				d, ok := d.(*Vertex)
   323  				if !ok {
   324  					continue
   325  				}
   326  				// We clear the conjuncts for now. As these disjuncts are for API
   327  				// use only, we will fill them out when necessary (using Defaults).
   328  				d.Conjuncts = nil
   329  
   330  				// TODO: use a more principled form of dereferencing. For instance,
   331  				// disjuncts could already be assumed to be the given Vertex, and
   332  				// the main vertex could be dereferenced during evaluation.
   333  				for _, a := range d.Arcs {
   334  					for _, x := range a.Conjuncts {
   335  						// All the environments for embedded structs need to be
   336  						// dereferenced.
   337  						for env := x.Env; env != nil && env.Vertex == v; env = env.Up {
   338  							env.Vertex = d
   339  						}
   340  					}
   341  				}
   342  			}
   343  			v.Arcs = nil
   344  			v.ChildErrors = nil
   345  			// v.Structs = nil // TODO: should we keep or discard the Structs?
   346  			// TODO: how to represent closedness information? Do we need it?
   347  		}
   348  
   349  		// If the state has changed, it is because a disjunct has been run, or
   350  		// because a single disjunct has replaced it. Restore the old state as
   351  		// to not confuse memory management.
   352  		v.state = n
   353  
   354  		// We don't do this in postDisjuncts, as it should only be done after
   355  		// completing all disjunctions.
   356  		if !n.done() {
   357  			if err := n.incompleteErrors(true); err != nil {
   358  				b := n.node.Bottom()
   359  				if b != err {
   360  					err = CombineErrors(n.ctx.src, b, err)
   361  				}
   362  				n.node.BaseValue = err
   363  			}
   364  		}
   365  
   366  		assertStructuralCycle(n)
   367  
   368  		if state != finalized {
   369  			return
   370  		}
   371  
   372  		if v.BaseValue == nil {
   373  			v.BaseValue = n.getValidators(finalized)
   374  		}
   375  
   376  		// Free memory here?
   377  		v.updateStatus(finalized)
   378  
   379  	case finalized:
   380  	}
   381  }
   382  
   383  // insertConjuncts inserts conjuncts previously not inserted.
   384  func (n *nodeContext) insertConjuncts(state vertexStatus) bool {
   385  	unreachableForDev(n.ctx)
   386  
   387  	// Exit early if we have a concrete value and only need partial results.
   388  	if state == partial {
   389  		for n.conjunctsPartialPos < len(n.conjuncts) {
   390  			c := &n.conjuncts[n.conjunctsPartialPos]
   391  			n.conjunctsPartialPos++
   392  			if c.done {
   393  				continue
   394  			}
   395  			if v, ok := c.C.Elem().(Value); ok && IsConcrete(v) {
   396  				c.done = true
   397  				n.addValueConjunct(c.C.Env, v, c.C.CloseInfo)
   398  			}
   399  		}
   400  		if n.scalar != nil && n.node.isDefined() {
   401  			return true
   402  		}
   403  	}
   404  	for n.conjunctsPos < len(n.conjuncts) {
   405  		nInfos := len(n.node.Structs)
   406  		p := &n.conjuncts[n.conjunctsPos]
   407  		n.conjunctsPos++
   408  		if p.done {
   409  			continue
   410  		}
   411  
   412  		// Initially request a Partial state to allow cyclic references to
   413  		// resolve more naturally first. This results in better error messages
   414  		// and less operations.
   415  		n.addExprConjunct(p.C, partial)
   416  		p.done = true
   417  
   418  		// Record the OptionalTypes for all structs that were inferred by this
   419  		// Conjunct. This information can be used by algorithms such as trim.
   420  		for i := nInfos; i < len(n.node.Structs); i++ {
   421  			n.node.Conjuncts[p.index].CloseInfo.FieldTypes |= n.node.Structs[i].types
   422  		}
   423  	}
   424  	return false
   425  }
   426  
   427  // finalizeDisjuncts: incomplete errors are kept around and not removed early.
   428  // This call filters the incomplete errors and removes them
   429  //
   430  // This also collects all errors of empty disjunctions. These cannot be
   431  // collected during the finalization state of individual disjuncts. Care should
   432  // be taken to only call this after all disjuncts have been finalized.
   433  func (n *nodeContext) finalizeDisjuncts() {
   434  	a := n.disjuncts
   435  	if len(a) == 0 {
   436  		return
   437  	}
   438  	k := 0
   439  	for i, d := range a {
   440  		switch d.finalDone() {
   441  		case true:
   442  			a[k], a[i] = d, a[k]
   443  			k++
   444  		default:
   445  			if err := d.incompleteErrors(true); err != nil {
   446  				n.disjunctErrs = append(n.disjunctErrs, err)
   447  			}
   448  		}
   449  		d.free()
   450  	}
   451  	if k == 0 {
   452  		n.makeError()
   453  	}
   454  	n.disjuncts = a[:k]
   455  }
   456  
   457  func (n *nodeContext) doNotify() {
   458  	if n.errs == nil || len(n.notify) == 0 {
   459  		return
   460  	}
   461  	for _, rec := range n.notify {
   462  		v := rec.v
   463  		if v.state == nil {
   464  			if b := v.Bottom(); b != nil {
   465  				v.BaseValue = CombineErrors(nil, b, n.errs)
   466  			} else {
   467  				v.BaseValue = n.errs
   468  			}
   469  		} else {
   470  			v.state.addBottom(n.errs)
   471  		}
   472  	}
   473  	n.notify = n.notify[:0]
   474  }
   475  
   476  func (n *nodeContext) postDisjunct(state vertexStatus) {
   477  	ctx := n.ctx
   478  	unreachableForDev(ctx)
   479  
   480  	for {
   481  		// Use maybeSetCache for cycle breaking
   482  		for n.maybeSetCache(); n.expandOne(state); n.maybeSetCache() {
   483  		}
   484  
   485  		if !n.addLists(oldOnly(state)) {
   486  			break
   487  		}
   488  	}
   489  
   490  	if n.aStruct != nil {
   491  		n.updateNodeType(StructKind, n.aStruct, n.aStructID)
   492  	}
   493  
   494  	if len(n.selfComprehensions) > 0 {
   495  		// Up to here all comprehensions with sources other than this node will
   496  		// have had a chance to run. We can now run self-referencing
   497  		// comprehensions with the restriction that they cannot add new arcs.
   498  		//
   499  		// Note: we should only set this in case of self-referential
   500  		// comprehensions. A comprehension in a parent node may still add
   501  		// arcs to this node, even if it has reached AllConjunctsDone status,
   502  		// as long as any evaluation did not rely on its specific set of arcs.
   503  		// Example:
   504  		//
   505  		//	a: {
   506  		//		b: _env: c: 1
   507  		//
   508  		//		// Using dynamic field ("b") prevents the evaluation of the
   509  		//		// comprehension to be pushed down to env: and instead evaluates
   510  		//		// it before b is completed. Even though b needs to reach state
   511  		//		// AllConjunctsDone before evaluating b._env, it is still okay
   512  		//		// to add arcs to b after this evaluation: only the set of arcs
   513  		//		// in b._env needs to be frozen after that.
   514  		//		for k2, v2 in b._env {
   515  		//			("b"): env: (k2): v2
   516  		//		}
   517  		//	}
   518  		n.node.LockArcs = true
   519  
   520  		n.injectSelfComprehensions(state)
   521  	}
   522  
   523  	for n.expandOne(state) {
   524  	}
   525  
   526  	switch err := n.getErr(); {
   527  	case err != nil:
   528  		if err.Code < IncompleteError && n.node.ArcType == ArcPending {
   529  			n.node.ArcType = ArcMember
   530  		}
   531  		n.node.BaseValue = err
   532  		n.errs = nil
   533  
   534  	default:
   535  		if isCyclePlaceholder(n.node.BaseValue) {
   536  			if !n.done() {
   537  				n.node.BaseValue = n.incompleteErrors(true)
   538  			} else {
   539  				n.node.BaseValue = nil
   540  			}
   541  		}
   542  		// TODO: this ideally should be done here. However, doing so causes
   543  		// a somewhat more aggressive cutoff in disjunction cycles, which cause
   544  		// some incompatibilities. Fix in another CL.
   545  		//
   546  		// else if !n.done() {
   547  		// 	n.expandOne()
   548  		// 	if err := n.incompleteErrors(); err != nil {
   549  		// 		n.node.BaseValue = err
   550  		// 	}
   551  		// }
   552  
   553  		// We are no longer evaluating.
   554  
   555  		n.validateValue(state)
   556  
   557  		v := n.node.Value()
   558  
   559  		// TODO(perf): only delay processing of actual non-monotonic checks.
   560  		skip := n.skipNonMonotonicChecks()
   561  		if v != nil && IsConcrete(v) && !skip {
   562  			for _, v := range n.checks {
   563  				// TODO(errors): make Validate return bottom and generate
   564  				// optimized conflict message. Also track and inject IDs
   565  				// to determine origin location.s
   566  				if b := ctx.Validate(v, n.node); b != nil {
   567  					n.addBottom(b)
   568  				}
   569  			}
   570  		}
   571  
   572  		if v == nil {
   573  			break
   574  		}
   575  
   576  		switch {
   577  		case v.Kind() == ListKind:
   578  			for _, a := range n.node.Arcs {
   579  				if a.Label.Typ() == StringLabel && a.IsDefined(ctx) {
   580  					n.addErr(ctx.Newf("list may not have regular fields"))
   581  					// TODO(errors): add positions for list and arc definitions.
   582  
   583  				}
   584  			}
   585  
   586  			// case !isStruct(n.node) && v.Kind() != BottomKind:
   587  			// 	for _, a := range n.node.Arcs {
   588  			// 		if a.Label.IsRegular() {
   589  			// 			n.addErr(errors.Newf(token.NoPos,
   590  			// 				// TODO(errors): add positions of non-struct values and arcs.
   591  			// 				"cannot combine scalar values with arcs"))
   592  			// 		}
   593  			// 	}
   594  		}
   595  	}
   596  
   597  	n.completeArcs(state)
   598  }
   599  
   600  // validateValue checks collected bound validators and checks them against
   601  // the current value. If there is no value, it sets the current value
   602  // to these validators itself.
   603  //
   604  // Before it does this, it also checks whether n is of another incompatible
   605  // type, like struct. This prevents validators from being inadvertently set.
   606  // TODO(evalv3): optimize this function for new implementation.
   607  func (n *nodeContext) validateValue(state vertexStatus) {
   608  	ctx := n.ctx
   609  
   610  	// Either set to Conjunction or error.
   611  	// TODO: verify and simplify the below code to determine whether
   612  	// something is a struct.
   613  	markStruct := false
   614  	if n.aStruct != nil {
   615  		markStruct = true
   616  	} else if len(n.node.Structs) > 0 {
   617  		// TODO: do something more principled here.
   618  		// Here we collect evidence that a value is a struct. If a struct has
   619  		// an embedding, it may evaluate to an embedded scalar value, in which
   620  		// case it is not a struct. Right now this is tracked at the node level,
   621  		// but it really should be at the struct level. For instance:
   622  		//
   623  		// 		A: matchN(1, [>10])
   624  		// 		A: {
   625  		// 			if true {c: 1}
   626  		// 		}
   627  		//
   628  		// Here A is marked as Top by matchN. The other struct also has an
   629  		// embedding (the comprehension), and thus does not force it either.
   630  		// So the resulting kind is top, not struct.
   631  		// As an approximation, we at least mark the node as a struct if it has
   632  		// any regular fields.
   633  		markStruct = n.kind&StructKind != 0 && !n.hasTop
   634  		for _, a := range n.node.Arcs {
   635  			// TODO(spec): we generally allow optional fields alongside embedded
   636  			// scalars. We probably should not. Either way this is not entirely
   637  			// accurate, as a Pending arc may still be optional. We should
   638  			// collect the arcType noted in adt.Comprehension in a nodeContext
   639  			// as well so that we know what the potential arc of this node may
   640  			// be.
   641  			//
   642  			// TODO(evalv3): even better would be to ensure that all
   643  			// comprehensions are done before calling this.
   644  			if a.Label.IsRegular() && a.ArcType != ArcOptional {
   645  				markStruct = true
   646  				break
   647  			}
   648  		}
   649  	}
   650  	v := n.node.DerefValue().Value()
   651  	if n.node.BaseValue == nil && markStruct {
   652  		n.node.BaseValue = &StructMarker{}
   653  		v = n.node
   654  	}
   655  	if v != nil && IsConcrete(v) {
   656  		// Also check when we already have errors as we may find more
   657  		// serious errors and would like to know about all errors anyway.
   658  
   659  		if n.lowerBound != nil {
   660  			c := MakeRootConjunct(nil, n.lowerBound)
   661  			if b := ctx.Validate(c, v); b != nil {
   662  				// TODO(errors): make Validate return boolean and generate
   663  				// optimized conflict message. Also track and inject IDs
   664  				// to determine origin location.s
   665  				if e, _ := b.Err.(*ValueError); e != nil {
   666  					e.AddPosition(n.lowerBound)
   667  					e.AddPosition(v)
   668  				}
   669  				n.addBottom(b)
   670  			}
   671  		}
   672  		if n.upperBound != nil {
   673  			c := MakeRootConjunct(nil, n.upperBound)
   674  			if b := ctx.Validate(c, v); b != nil {
   675  				// TODO(errors): make Validate return boolean and generate
   676  				// optimized conflict message. Also track and inject IDs
   677  				// to determine origin location.s
   678  				if e, _ := b.Err.(*ValueError); e != nil {
   679  					e.AddPosition(n.upperBound)
   680  					e.AddPosition(v)
   681  				}
   682  				n.addBottom(b)
   683  			}
   684  		}
   685  
   686  	} else if state == finalized {
   687  		n.node.BaseValue = n.getValidators(finalized)
   688  	}
   689  }
   690  
   691  // incompleteErrors reports all errors from uncompleted conjuncts.
   692  // If final is true, errors are permanent and reported to parents.
   693  func (n *nodeContext) incompleteErrors(final bool) *Bottom {
   694  	unreachableForDev(n.ctx)
   695  
   696  	// collect incomplete errors.
   697  	var err *Bottom // n.incomplete
   698  	for _, d := range n.dynamicFields {
   699  		err = CombineErrors(nil, err, d.err)
   700  	}
   701  	for _, c := range n.comprehensions {
   702  		if c.err == nil {
   703  			continue
   704  		}
   705  		err = CombineErrors(nil, err, c.err)
   706  
   707  		// TODO: use this code once possible.
   708  		//
   709  		// Add comprehension to ensure incomplete error is inserted. This
   710  		// ensures that the error is reported in the Vertex where the
   711  		// comprehension was defined, and not just in the node below. This, in
   712  		// turn, is necessary to support certain logic, like export, that
   713  		// expects to be able to detect an "incomplete" error at the first level
   714  		// where it is necessary.
   715  		// if c.node.status != Finalized {
   716  		// 	n := c.node.getNodeContext(n.ctx)
   717  		// 	n.comprehensions = append(n.comprehensions, c)
   718  		// } else {
   719  		// 	n.node.AddErr(n.ctx, err)
   720  		// }
   721  		// n := d.node.getNodeContext(ctx)
   722  		// n.addBottom(err)
   723  		if final && c.vertex != nil && c.vertex.status != finalized {
   724  			c.vertex.state.assertInitialized()
   725  			c.vertex.state.addBottom(err)
   726  			c.vertex = nil
   727  		}
   728  	}
   729  	for _, c := range n.selfComprehensions {
   730  		if c.err == nil {
   731  			continue
   732  		}
   733  
   734  		err = CombineErrors(nil, err, c.err)
   735  
   736  		// TODO: use this code once possible.
   737  		//
   738  		// Add comprehension to ensure incomplete error is inserted. This
   739  		// ensures that the error is reported in the Vertex where the
   740  		// comprehension was defined, and not just in the node below. This, in
   741  		// turn, is necessary to support certain logic, like export, that
   742  		// expects to be able to detect an "incomplete" error at the first level
   743  		// where it is necessary.
   744  		// if c.node.status != Finalized {
   745  		// 	n := c.node.getNodeContext(n.ctx)
   746  		// 	n.comprehensions = append(n.comprehensions, c)
   747  		// } else {
   748  		// 	n.node.AddErr(n.ctx, err)
   749  		// }
   750  		// n := d.node.getNodeContext(ctx)
   751  		// n.addBottom(err)
   752  		if c.vertex != nil && c.vertex.status != finalized {
   753  			c.vertex.state.addBottom(err)
   754  			c.vertex = nil
   755  		}
   756  	}
   757  	for _, x := range n.exprs {
   758  		err = CombineErrors(nil, err, x.err)
   759  	}
   760  	if err == nil {
   761  		// safeguard.
   762  		err = incompleteSentinel
   763  	}
   764  	if err.Code < IncompleteError {
   765  		n.node.ArcType = ArcMember
   766  	}
   767  	return err
   768  }
   769  
   770  // TODO(perf): ideally we should always perform a closedness check if
   771  // state is Finalized. This is currently not possible when computing a
   772  // partial disjunction as the closedness information is not yet
   773  // complete, possibly leading to a disjunct to be rejected prematurely.
   774  // It is probably possible to fix this if we could add StructInfo
   775  // structures demarked per conjunct.
   776  //
   777  // In practice this should not be a problem: when disjuncts originate
   778  // from the same disjunct, they will have the same StructInfos, and thus
   779  // Equal is able to equate them even in the presence of optional field.
   780  // In general, combining any limited set of disjuncts will soon reach
   781  // a fixed point where duplicate elements can be eliminated this way.
   782  //
   783  // Note that not checking closedness is irrelevant for disjunctions of
   784  // scalars. This means it also doesn't hurt performance where structs
   785  // have a discriminator field (e.g. Kubernetes). We should take care,
   786  // though, that any potential performance issues are eliminated for
   787  // Protobuf-like oneOf fields.
   788  func (n *nodeContext) checkClosed(state vertexStatus) bool {
   789  	unreachableForDev(n.ctx)
   790  
   791  	ignore := state != finalized || n.skipNonMonotonicChecks()
   792  
   793  	v := n.node
   794  	if !v.Label.IsInt() && v.Parent != nil && !ignore && v.ArcType <= ArcRequired {
   795  		ctx := n.ctx
   796  		// Visit arcs recursively to validate and compute error.
   797  		if _, err := verifyArc2(ctx, v.Label, v, v.ClosedRecursive); err != nil {
   798  			// Record error in child node to allow recording multiple
   799  			// conflicts at the appropriate place, to allow valid fields to
   800  			// be represented normally and, most importantly, to avoid
   801  			// recursive processing of a disallowed field.
   802  			v.SetValue(ctx, err)
   803  			return false
   804  		}
   805  	}
   806  	return true
   807  }
   808  
   809  func (n *nodeContext) completeArcs(state vertexStatus) {
   810  	unreachableForDev(n.ctx)
   811  
   812  	if n.node.hasAllConjuncts || n.node.Parent == nil {
   813  		n.node.setParentDone()
   814  	}
   815  
   816  	// At this point, if this arc is of type arcVoid, it means that the value
   817  	// may still be modified by child arcs. So in this case we must now process
   818  	// all arcs to be sure we get the correct result.
   819  	// For other cases we terminate early as this results in considerably
   820  	// better error messages.
   821  	if state <= conjuncts &&
   822  		// Is allowed to go one step back. See Vertex.UpdateStatus.
   823  		n.node.status <= state+1 &&
   824  		(!n.node.hasPendingArc || n.node.ArcType == ArcMember) {
   825  
   826  		n.node.updateStatus(conjuncts)
   827  		return
   828  	}
   829  
   830  	n.node.updateStatus(evaluatingArcs)
   831  
   832  	ctx := n.ctx
   833  
   834  	if !assertStructuralCycle(n) {
   835  		k := 0
   836  		// Visit arcs recursively to validate and compute error.
   837  		for _, a := range n.node.Arcs {
   838  			// Call UpdateStatus here to be absolutely sure the status is set
   839  			// correctly and that we are not regressing.
   840  			n.node.updateStatus(evaluatingArcs)
   841  
   842  			wasVoid := a.ArcType == ArcPending
   843  
   844  			ctx.unify(a, oldOnly(finalized))
   845  
   846  			if a.ArcType == ArcPending {
   847  				continue
   848  			}
   849  
   850  			// Errors are allowed in let fields. Handle errors and failure to
   851  			// complete accordingly.
   852  			if !a.Label.IsLet() && a.ArcType <= ArcRequired {
   853  				// Don't set the state to Finalized if the child arcs are not done.
   854  				if state == finalized && a.status < finalized {
   855  					state = conjuncts
   856  				}
   857  
   858  				if err := a.Bottom(); err != nil {
   859  					n.AddChildError(err)
   860  				}
   861  			}
   862  
   863  			// If a structural cycle is detected, Arcs is cleared to avoid
   864  			// going into an infinite loop. If this is the case, we can bail
   865  			// from this loop.
   866  			if len(n.node.Arcs) == 0 {
   867  				goto postChecks
   868  			}
   869  			n.node.Arcs[k] = a
   870  			k++
   871  
   872  			switch {
   873  			case a.ArcType > ArcRequired, !a.Label.IsString():
   874  			case n.kind&StructKind == 0:
   875  				if !n.node.IsErr() {
   876  					n.reportFieldMismatch(pos(a.Value()), nil, a.Label, n.node.Value())
   877  				}
   878  			case !wasVoid:
   879  			case n.kind == TopKind:
   880  				// Theoretically it may be possible that a "void" arc references
   881  				// this top value where it really should have been a struct. One
   882  				// way to solve this is to have two passes over the arcs, where
   883  				// the first pass additionally analyzes whether comprehensions
   884  				// will yield values and "un-voids" an arc ahead of the rest.
   885  				//
   886  				// At this moment, though, I fail to see a possibility to create
   887  				// faulty CUE using this mechanism, though. At most error
   888  				// messages are a bit unintuitive. This may change once we have
   889  				// functionality to reflect on types.
   890  				if !n.node.IsErr() {
   891  					n.node.BaseValue = &StructMarker{}
   892  					n.kind = StructKind
   893  				}
   894  			}
   895  		}
   896  		n.node.Arcs = n.node.Arcs[:k]
   897  
   898  	postChecks:
   899  		for _, c := range n.postChecks {
   900  			f := ctx.PushState(c.env, c.expr.Source())
   901  
   902  			// TODO(errors): make Validate return bottom and generate
   903  			// optimized conflict message. Also track and inject IDs
   904  			// to determine origin location.s
   905  			v := ctx.evalState(c.expr, oldOnly(finalized))
   906  			v, _ = ctx.getDefault(v)
   907  			v = Unwrap(v)
   908  
   909  			switch _, isError := v.(*Bottom); {
   910  			case isError == c.expectError:
   911  			default:
   912  				n.node.AddErr(ctx, &Bottom{
   913  					Src:  c.expr.Source(),
   914  					Code: CycleError,
   915  					Node: n.node,
   916  					Err: ctx.NewPosf(pos(c.expr),
   917  						"circular dependency in evaluation of conditionals: %v changed after evaluation",
   918  						ctx.Str(c.expr)),
   919  				})
   920  			}
   921  
   922  			ctx.PopState(f)
   923  		}
   924  	}
   925  
   926  	if err := n.getErr(); err != nil {
   927  		n.errs = nil
   928  		if b, _ := n.node.BaseValue.(*Bottom); b != nil {
   929  			err = CombineErrors(nil, b, err)
   930  		}
   931  		n.node.BaseValue = err
   932  	}
   933  
   934  	b, hasErr := n.node.BaseValue.(*Bottom)
   935  	if !hasErr && b != cycle {
   936  		n.checkClosed(state)
   937  	}
   938  
   939  	// Strip struct literals that were not initialized and are not part
   940  	// of the output.
   941  	//
   942  	// TODO(perf): we could keep track if any such structs exist and only
   943  	// do this removal if there is a change of shrinking the list.
   944  	k := 0
   945  	for _, s := range n.node.Structs {
   946  		if s.initialized {
   947  			n.node.Structs[k] = s
   948  			k++
   949  		}
   950  	}
   951  	n.node.Structs = n.node.Structs[:k]
   952  
   953  	n.node.updateStatus(finalized)
   954  }
   955  
   956  // TODO: this is now a sentinel. Use a user-facing error that traces where
   957  // the cycle originates.
   958  var cycle = &Bottom{
   959  	Err:  errors.Newf(token.NoPos, "cycle error"),
   960  	Code: CycleError,
   961  }
   962  
   963  func isCyclePlaceholder(v BaseValue) bool {
   964  	// TODO: do not mark cycle in BaseValue.
   965  	if a, _ := v.(*Vertex); a != nil {
   966  		v = a.DerefValue().BaseValue
   967  	}
   968  	return v == cycle
   969  }
   970  
   971  func (n *nodeContext) createDisjunct() *Disjunction {
   972  	a := make([]Value, len(n.disjuncts))
   973  	p := 0
   974  	hasDefaults := false
   975  	for i, x := range n.disjuncts {
   976  		v := new(Vertex)
   977  		*v = x.result
   978  		v.state = nil
   979  		switch x.defaultMode {
   980  		case isDefault:
   981  			a[i] = a[p]
   982  			a[p] = v
   983  			p++
   984  			hasDefaults = true
   985  
   986  		case notDefault:
   987  			hasDefaults = true
   988  			fallthrough
   989  		case maybeDefault:
   990  			a[i] = v
   991  		}
   992  	}
   993  	// TODO: disambiguate based on concrete values.
   994  	// TODO: consider not storing defaults.
   995  	// if p > 0 {
   996  	// 	a = a[:p]
   997  	// }
   998  	return &Disjunction{
   999  		Values:      a,
  1000  		NumDefaults: p,
  1001  		HasDefaults: hasDefaults,
  1002  	}
  1003  }
  1004  
  1005  type arcKey struct {
  1006  	arc *Vertex
  1007  	id  CloseInfo
  1008  }
  1009  
  1010  // A nodeContext is used to collate all conjuncts of a value to facilitate
  1011  // unification. Conceptually order of unification does not matter. However,
  1012  // order has relevance when performing checks of non-monotic properties. Such
  1013  // checks should only be performed once the full value is known.
  1014  type nodeContext struct {
  1015  	nextFree *nodeContext
  1016  	refCount int
  1017  
  1018  	// Keep node out of the nodeContextState to make them more accessible
  1019  	// for source-level debuggers.
  1020  	node *Vertex
  1021  
  1022  	// parent keeps track of the parent Vertex in which a Vertex is being
  1023  	// evaluated. This is to keep track of the full path in error messages.
  1024  	parent *Vertex
  1025  
  1026  	// underlying is the original Vertex that this node overlays. It should be
  1027  	// set for all Vertex values that were cloned.
  1028  	underlying *Vertex
  1029  
  1030  	nodeContextState
  1031  
  1032  	scheduler
  1033  
  1034  	// Below are slices that need to be managed when cloning and reclaiming
  1035  	// nodeContexts for reuse. We want to ensure that, instead of setting
  1036  	// slices to nil, we truncate the existing buffers so that they do not
  1037  	// need to be reallocated upon reuse of the nodeContext.
  1038  
  1039  	arcMap []arcKey // not copied for cloning
  1040  
  1041  	// vertexMap is used to map vertices in disjunctions.
  1042  	vertexMap vertexMap
  1043  
  1044  	// notify is used to communicate errors in cyclic dependencies.
  1045  	// TODO: also use this to communicate increasingly more concrete values.
  1046  	notify []receiver
  1047  
  1048  	// sharedIDs contains all the CloseInfos that are involved in a shared node.
  1049  	// There can be more than one if the same Vertex is shared multiple times.
  1050  	// It is important to keep track of each instance as we need to insert each
  1051  	// of them separately in case a Vertex is "unshared" to ensure that
  1052  	// closedness information is correctly computed in such cases.
  1053  	sharedIDs []CloseInfo
  1054  
  1055  	// Conjuncts holds a reference to the Vertex Arcs that still need
  1056  	// processing. It does NOT need to be copied.
  1057  	conjuncts       []conjunct
  1058  	cyclicConjuncts []cyclicConjunct
  1059  
  1060  	dynamicFields      []envDynamic
  1061  	comprehensions     []envYield
  1062  	selfComprehensions []envYield // comprehensions iterating over own struct.
  1063  
  1064  	// Expression conjuncts
  1065  	lists  []envList
  1066  	vLists []*Vertex
  1067  	exprs  []envExpr
  1068  
  1069  	// These fields are used to track type checking.
  1070  	reqDefIDs    []refInfo
  1071  	replaceIDs   []replaceID
  1072  	conjunctInfo []conjunctInfo
  1073  	reqSets      reqSets
  1074  
  1075  	// Checks is a list of conjuncts, as we need to preserve the context in
  1076  	// which it was evaluated. The conjunct is always a validator (and thus
  1077  	// a Value). We need to keep track of the CloseInfo, however, to be able
  1078  	// to catch cycles when evaluating BuiltinValidators.
  1079  	// TODO: introduce ValueConjunct to get better compile time type checking.
  1080  	checks []Conjunct
  1081  
  1082  	postChecks []envCheck // Check non-monotonic constraints, among other things.
  1083  
  1084  	// Disjunction handling
  1085  	disjunctions []envDisjunct
  1086  
  1087  	// usedDefault indicates the for each of possibly multiple parent
  1088  	// disjunctions whether it is unified with a default disjunct or not.
  1089  	// This is then later used to determine whether a disjunction should
  1090  	// be treated as a marked disjunction.
  1091  	usedDefault []defaultInfo
  1092  
  1093  	// disjuncts holds disjuncts that evaluated to a non-bottom value.
  1094  	// TODO: come up with a better name.
  1095  	disjuncts    []*nodeContext
  1096  	buffer       []*nodeContext
  1097  	disjunctErrs []*Bottom
  1098  
  1099  	// hasDisjunction marks wither any disjunct was added. It is listed here
  1100  	// instead of in nodeContextState as it should be cleared when a disjunction
  1101  	// is split off. TODO: find something more principled.
  1102  	hasDisjunction bool
  1103  
  1104  	// snapshot holds the last value of the vertex before calling postDisjunct.
  1105  	snapshot Vertex
  1106  
  1107  	// Result holds the last evaluated value of the vertex after calling
  1108  	// postDisjunct.
  1109  	result Vertex
  1110  }
  1111  
  1112  type conjunct struct {
  1113  	C Conjunct
  1114  
  1115  	// done marks that this conjunct has been inserted. This prevents a
  1116  	// conjunct from being processed more than once, for instance, when
  1117  	// insertConjuncts is called more than once for the same node.
  1118  	done  bool
  1119  	index int // index of the original conjunct in Vertex.Conjuncts
  1120  }
  1121  
  1122  type nodeContextState struct {
  1123  	// isInitialized indicates whether conjuncts have been inserted in the node.
  1124  	// Use node.isInitialized() to more generally check whether conjuncts have
  1125  	// been processed.
  1126  	isInitialized bool
  1127  
  1128  	// toComplete marks whether completeNodeTasks needs to be called on this
  1129  	// node after a corresponding task has been completed.
  1130  	toComplete bool
  1131  
  1132  	// isCompleting > 0 indicates whether a call to completeNodeTasks is in
  1133  	// progress.
  1134  	isCompleting int
  1135  
  1136  	// runMode keeps track of what runMode a disjunct should run as. This is
  1137  	// relevant for nested disjunctions, like the 2|3 in (1 | (2|3)) & (1 | 2),
  1138  	// where the nested disjunction should _not_ be considered as final, as
  1139  	// there is still a disjunction at a higher level to be processed.
  1140  	runMode runMode
  1141  
  1142  	// evalDept is a number that is assigned when evaluating arcs and is set to
  1143  	// detect structural cycles. This value may be temporarily altered when a
  1144  	// node descends into evaluating a value that may be an error (pattern
  1145  	// constraints, optional fields, etc.). A non-zero value always indicates
  1146  	// that there are cyclic references, though.
  1147  	evalDepth int
  1148  
  1149  	// State info
  1150  
  1151  	hasTop               bool
  1152  	hasAnyCyclicConjunct bool // has conjunct with structural cycle
  1153  	hasAncestorCycle     bool // has conjunct with structural cycle to an ancestor
  1154  	hasNonCycle          bool // has material conjuncts without structural cycle
  1155  	hasNonCyclic         bool // has non-cyclic conjuncts at start of field processing
  1156  
  1157  	// These simulate the old closeContext logic. TODO: perhaps remove.
  1158  	hasStruct        bool // this node has a struct conjunct
  1159  	hasOpenValidator bool // this node has an open validator
  1160  	isDef            bool // this node is a definition
  1161  
  1162  	dropParentRequirements bool // used for typo checking
  1163  	computedCloseInfo      bool // used for typo checking
  1164  
  1165  	isShared         bool       // set if we are currently structure sharing
  1166  	noSharing        bool       // set if structure sharing is not allowed
  1167  	shared           Conjunct   // the original conjunct that led to sharing
  1168  	shareCycleType   CyclicType // keeps track of the cycle type of shared nodes
  1169  	origBaseValue    BaseValue  // the BaseValue that structure sharing replaces
  1170  	shareDecremented bool       // counters of sharedIDs have been decremented
  1171  
  1172  	depth           int32
  1173  	defaultMode     defaultMode // cumulative default mode
  1174  	origDefaultMode defaultMode // default mode of the original disjunct
  1175  
  1176  	// has a value filled out before the node splits into a disjunction. Aside
  1177  	// from detecting a self-reference cycle when there is otherwise just an
  1178  	// other error, this field is not needed. It greatly helps, however, to
  1179  	// improve the error messages.
  1180  	hasFieldValue bool
  1181  
  1182  	// defaultAttemptInCycle indicates that a value relies on the default value
  1183  	// and that it will be an error to remove the default value from the
  1184  	// disjunction. It is set to the referring Vertex. Consider for instance:
  1185  	//
  1186  	//      a: 1 - b
  1187  	//      b: 1 - a
  1188  	//      a: *0 | 1
  1189  	//      b: *0 | 1
  1190  	//
  1191  	// versus
  1192  	//
  1193  	//      a: 1 - b
  1194  	//      b: 1 - a
  1195  	//      a: *1 | 0
  1196  	//      b: *0 | 1
  1197  	//
  1198  	// In both cases there are multiple solutions to the configuration. In the
  1199  	// first case there is an ambiguity: if we start with evaluating 'a' and
  1200  	// pick the default for 'b', we end up with a value of '1' for 'a'. If,
  1201  	// conversely, we start evaluating 'b' and pick the default for 'a', we end
  1202  	// up with {a: 0, b: 0}. In the seconds case, however, we do _will_ get the
  1203  	// same answer regardless of order.
  1204  	//
  1205  	// In general, we will allow expressions on cyclic paths to be resolved if
  1206  	// in all cases the default value is taken. In order to do that, we do not
  1207  	// allow a default value to be removed from a disjunction if such value is
  1208  	// depended on.
  1209  	//
  1210  	// For completeness, note that CUE will NOT solve a solution, even if there
  1211  	// is only one solution. Consider for instance:
  1212  	//
  1213  	//      a: 0 | 1
  1214  	//      a: b + 1
  1215  	//      b: c - 1
  1216  	//      c: a - 1
  1217  	//      c: 1 | 2
  1218  	//
  1219  	// There the only consistent solution is {a: 1, b: 0, c: 1}. CUE, however,
  1220  	// will not attempt this solve this as, in general, such solving would be NP
  1221  	// complete.
  1222  	//
  1223  	// NOTE(evalv4): note that this would be easier if we got rid of default
  1224  	// values and had pre-selected overridable values instead.
  1225  	defaultAttemptInCycle *Vertex
  1226  
  1227  	// Value info
  1228  
  1229  	kind     Kind
  1230  	kindExpr Expr      // expr that adjust last value (for error reporting)
  1231  	kindID   CloseInfo // for error tracing
  1232  
  1233  	// Current value (may be under construction)
  1234  	scalar   Value // TODO: use Value in node.
  1235  	scalarID CloseInfo
  1236  
  1237  	aStruct   Expr
  1238  	aStructID CloseInfo
  1239  
  1240  	// List fields
  1241  	listIsClosed bool
  1242  	maxListLen   int
  1243  	maxNode      Expr
  1244  
  1245  	lowerBound *BoundValue // > or >=
  1246  	upperBound *BoundValue // < or <=
  1247  	errs       *Bottom
  1248  
  1249  	// Slice positions
  1250  
  1251  	// conjunctsPos is an index into conjuncts indicating the next conjunct
  1252  	// to process. This is used to avoids processing a conjunct twice in some
  1253  	// cases where there is an evaluation cycle.
  1254  	conjunctsPos int
  1255  	// conjunctsPartialPos is like conjunctsPos, but for the 'partial' phase
  1256  	// of processing where conjuncts are only processed as concrete scalars.
  1257  	conjunctsPartialPos int
  1258  }
  1259  
  1260  // A receiver receives notifications.
  1261  // cc is used for V3 and is nil in V2.
  1262  // v is equal to cc.src._cc in V3.
  1263  type receiver struct {
  1264  	v *Vertex
  1265  }
  1266  
  1267  // Logf substitutes args in format. Arguments of type Feature, Value, and Expr
  1268  // are printed in human-friendly formats. The printed string is prefixed and
  1269  // indented with the path associated with the current nodeContext.
  1270  func (n *nodeContext) Logf(format string, args ...interface{}) {
  1271  	n.ctx.Logf(n.node, format, args...)
  1272  }
  1273  
  1274  type defaultInfo struct {
  1275  	// parentMode indicates whether this values was used as a default value,
  1276  	// based on the parent mode.
  1277  	parentMode defaultMode
  1278  
  1279  	// The result of default evaluation for a nested disjunction.
  1280  	nestedMode defaultMode
  1281  
  1282  	origMode defaultMode
  1283  }
  1284  
  1285  func (n *nodeContext) addNotify(v *Vertex) {
  1286  	unreachableForDev(n.ctx)
  1287  
  1288  	if v != nil && !n.node.hasAllConjuncts {
  1289  		n.notify = append(n.notify, receiver{v})
  1290  	}
  1291  }
  1292  
  1293  func (n *nodeContext) clone() *nodeContext {
  1294  	d := n.ctx.newNodeContext(n.node)
  1295  
  1296  	d.refCount++
  1297  
  1298  	d.ctx = n.ctx
  1299  	d.node = n.node
  1300  
  1301  	d.nodeContextState = n.nodeContextState
  1302  
  1303  	d.arcMap = append(d.arcMap, n.arcMap...)
  1304  	d.notify = append(d.notify, n.notify...)
  1305  	d.sharedIDs = append(d.sharedIDs, n.sharedIDs...)
  1306  
  1307  	n.scheduler.cloneInto(&d.scheduler)
  1308  
  1309  	d.conjuncts = append(d.conjuncts, n.conjuncts...)
  1310  	d.cyclicConjuncts = append(d.cyclicConjuncts, n.cyclicConjuncts...)
  1311  	d.dynamicFields = append(d.dynamicFields, n.dynamicFields...)
  1312  	d.comprehensions = append(d.comprehensions, n.comprehensions...)
  1313  	d.selfComprehensions = append(d.selfComprehensions, n.selfComprehensions...)
  1314  	d.lists = append(d.lists, n.lists...)
  1315  	d.vLists = append(d.vLists, n.vLists...)
  1316  	d.exprs = append(d.exprs, n.exprs...)
  1317  
  1318  	d.reqDefIDs = append(d.reqDefIDs, n.reqDefIDs...)
  1319  	d.replaceIDs = append(d.replaceIDs, n.replaceIDs...)
  1320  	d.conjunctInfo = append(d.conjunctInfo, n.conjunctInfo...)
  1321  	d.reqSets = append(d.reqSets, n.reqSets...)
  1322  
  1323  	d.checks = append(d.checks, n.checks...)
  1324  	d.postChecks = append(d.postChecks, n.postChecks...)
  1325  
  1326  	d.usedDefault = append(d.usedDefault, n.usedDefault...)
  1327  
  1328  	// Do not clone other disjunction-related slices, like disjuncts and buffer:
  1329  	// disjunction slices are managed by disjunction processing directly.
  1330  
  1331  	return d
  1332  }
  1333  
  1334  func (c *OpContext) newNodeContext(node *Vertex) *nodeContext {
  1335  	if n := c.freeListNode; n != nil {
  1336  		c.stats.Reused++
  1337  		c.freeListNode = n.nextFree
  1338  
  1339  		*n = nodeContext{
  1340  			scheduler: scheduler{ctx: c},
  1341  			node:      node,
  1342  			nodeContextState: nodeContextState{
  1343  				kind: TopKind,
  1344  			},
  1345  			arcMap:             n.arcMap[:0],
  1346  			conjuncts:          n.conjuncts[:0],
  1347  			cyclicConjuncts:    n.cyclicConjuncts[:0],
  1348  			notify:             n.notify[:0],
  1349  			sharedIDs:          n.sharedIDs[:0],
  1350  			checks:             n.checks[:0],
  1351  			postChecks:         n.postChecks[:0],
  1352  			dynamicFields:      n.dynamicFields[:0],
  1353  			comprehensions:     n.comprehensions[:0],
  1354  			selfComprehensions: n.selfComprehensions[:0],
  1355  			lists:              n.lists[:0],
  1356  			vLists:             n.vLists[:0],
  1357  			exprs:              n.exprs[:0],
  1358  			reqDefIDs:          n.reqDefIDs[:0],
  1359  			replaceIDs:         n.replaceIDs[:0],
  1360  			conjunctInfo:       n.conjunctInfo[:0],
  1361  			reqSets:            n.reqSets[:0],
  1362  			disjunctions:       n.disjunctions[:0],
  1363  			usedDefault:        n.usedDefault[:0],
  1364  			disjunctErrs:       n.disjunctErrs[:0],
  1365  			disjuncts:          n.disjuncts[:0],
  1366  			buffer:             n.buffer[:0],
  1367  		}
  1368  		n.scheduler.clear()
  1369  		n.scheduler.node = n
  1370  		n.underlying = node
  1371  
  1372  		return n
  1373  	}
  1374  	c.stats.Allocs++
  1375  
  1376  	n := &nodeContext{
  1377  		scheduler: scheduler{
  1378  			ctx: c,
  1379  		},
  1380  		node: node,
  1381  
  1382  		nodeContextState: nodeContextState{kind: TopKind},
  1383  	}
  1384  	n.scheduler.node = n
  1385  	n.underlying = node
  1386  	return n
  1387  }
  1388  
  1389  func (v *Vertex) getNodeContext(c *OpContext, ref int) *nodeContext {
  1390  	unreachableForDev(c)
  1391  
  1392  	if v.state == nil {
  1393  		if v.status == finalized {
  1394  			return nil
  1395  		}
  1396  		v.state = c.newNodeContext(v)
  1397  	} else if v.state.node != v {
  1398  		panic("getNodeContext: nodeContext out of sync")
  1399  	}
  1400  	v.state.refCount += ref
  1401  	return v.state
  1402  }
  1403  
  1404  func (v *Vertex) freeNode(n *nodeContext) {
  1405  	if n == nil {
  1406  		return
  1407  	}
  1408  	if n.node != v {
  1409  		panic("freeNode: unpaired free")
  1410  	}
  1411  	if v.state != nil && v.state != n {
  1412  		panic("freeNode: nodeContext out of sync")
  1413  	}
  1414  	if n.refCount--; n.refCount == 0 {
  1415  		if v.status == finalized {
  1416  			v.freeNodeState()
  1417  		} else {
  1418  			n.ctx.stats.Retained++
  1419  		}
  1420  	}
  1421  }
  1422  
  1423  func (v *Vertex) freeNodeState() {
  1424  	if v.state == nil {
  1425  		return
  1426  	}
  1427  	state := v.state
  1428  	v.state = nil
  1429  
  1430  	state.ctx.freeNodeContext(state)
  1431  }
  1432  
  1433  func (n *nodeContext) free() {
  1434  	if n.refCount--; n.refCount == 0 {
  1435  		n.ctx.freeNodeContext(n)
  1436  	}
  1437  }
  1438  
  1439  func (c *OpContext) freeNodeContext(n *nodeContext) {
  1440  	c.stats.Freed++
  1441  	n.nextFree = c.freeListNode
  1442  	c.freeListNode = n
  1443  	n.node = nil
  1444  	n.refCount = 0
  1445  	n.scheduler.clear()
  1446  }
  1447  
  1448  // TODO(perf): return a dedicated ConflictError that can track original
  1449  // positions on demand.
  1450  func (n *nodeContext) reportConflict(
  1451  	v1, v2 Node,
  1452  	k1, k2 Kind,
  1453  	ids ...CloseInfo) {
  1454  
  1455  	ctx := n.ctx
  1456  
  1457  	var err *ValueError
  1458  	if k1 == k2 {
  1459  		err = ctx.NewPosf(token.NoPos, "conflicting values %s and %s", v1, v2)
  1460  	} else {
  1461  		err = ctx.NewPosf(token.NoPos,
  1462  			"conflicting values %s and %s (mismatched types %s and %s)",
  1463  			v1, v2, k1, k2)
  1464  	}
  1465  
  1466  	err.AddPosition(v1)
  1467  	err.AddPosition(v2)
  1468  	for _, id := range ids {
  1469  		err.AddClosedPositions(id)
  1470  	}
  1471  
  1472  	n.addErr(err)
  1473  }
  1474  
  1475  // reportFieldMismatch reports the mixture of regular fields with non-struct
  1476  // values. Either s or f needs to be given.
  1477  func (n *nodeContext) reportFieldMismatch(
  1478  	p token.Pos,
  1479  	s *StructLit,
  1480  	f Feature,
  1481  	scalar Expr,
  1482  	id ...CloseInfo) {
  1483  
  1484  	ctx := n.ctx
  1485  
  1486  	if f == InvalidLabel {
  1487  		for _, a := range s.Decls {
  1488  			if x, ok := a.(*Field); ok && x.Label.IsRegular() {
  1489  				f = x.Label
  1490  				p = pos(x)
  1491  				break
  1492  			}
  1493  		}
  1494  		if f == InvalidLabel {
  1495  			n.reportConflict(scalar, s, n.kind, StructKind, id...)
  1496  			return
  1497  		}
  1498  	}
  1499  
  1500  	err := ctx.NewPosf(p, "cannot combine regular field %q with %v", f, scalar)
  1501  
  1502  	if s != nil {
  1503  		err.AddPosition(s)
  1504  	}
  1505  
  1506  	for _, ci := range id {
  1507  		err.AddClosedPositions(ci)
  1508  	}
  1509  
  1510  	n.addErr(err)
  1511  }
  1512  
  1513  func (n *nodeContext) updateNodeType(k Kind, v Expr, id CloseInfo) bool {
  1514  	n.updateConjunctInfo(k, id, 0)
  1515  
  1516  	ctx := n.ctx
  1517  	kind := n.kind & k
  1518  
  1519  	switch {
  1520  	case n.kind == BottomKind,
  1521  		k == BottomKind:
  1522  		return false
  1523  
  1524  	case kind != BottomKind:
  1525  
  1526  	// TODO: we could consider changing the reporting for structs, but this
  1527  	// makes only sense in case they are for embeddings. Otherwise the type
  1528  	// of a struct is more relevant for the failure.
  1529  	// case k == StructKind:
  1530  	// 	s, _ := v.(*StructLit)
  1531  	// 	n.reportFieldMismatch(token.NoPos, s, 0, n.kindExpr, id, n.kindID)
  1532  
  1533  	case n.kindExpr != nil:
  1534  		n.reportConflict(n.kindExpr, v, n.kind, k, n.kindID, id)
  1535  
  1536  	default:
  1537  		n.addErr(ctx.Newf(
  1538  			"conflicting value %s (mismatched types %s and %s)",
  1539  			v, n.kind, k))
  1540  	}
  1541  
  1542  	if n.kind != kind || n.kindExpr == nil {
  1543  		n.kindExpr = v
  1544  	}
  1545  	n.kind = kind
  1546  	return kind != BottomKind
  1547  }
  1548  
  1549  func (n *nodeContext) done() bool {
  1550  	// TODO(v0.7): verify that done() is checking for the right conditions in
  1551  	// the new evaluator implementation.
  1552  	return len(n.dynamicFields) == 0 &&
  1553  		len(n.comprehensions) == 0 &&
  1554  		len(n.exprs) == 0
  1555  }
  1556  
  1557  // finalDone is like done, but allows for cycle errors, which can be ignored
  1558  // as they essentially indicate a = a & _.
  1559  func (n *nodeContext) finalDone() bool {
  1560  	// TODO(v0.7): update for new evaluator?
  1561  	for _, x := range n.exprs {
  1562  		if x.err.Code != CycleError {
  1563  			return false
  1564  		}
  1565  	}
  1566  	return len(n.dynamicFields) == 0 &&
  1567  		len(n.comprehensions) == 0 &&
  1568  		len(n.selfComprehensions) == 0
  1569  }
  1570  
  1571  // hasErr is used to determine if an evaluation path, for instance a single
  1572  // path after expanding all disjunctions, has an error.
  1573  func (n *nodeContext) hasErr() bool {
  1574  	n.assertInitialized()
  1575  
  1576  	if n.node.ChildErrors != nil {
  1577  		return true
  1578  	}
  1579  	if n.node.Status() > evaluating && n.node.IsErr() {
  1580  		return true
  1581  	}
  1582  	return n.ctx.HasErr() || n.errs != nil
  1583  }
  1584  
  1585  func (n *nodeContext) getErr() *Bottom {
  1586  	n.assertInitialized()
  1587  
  1588  	n.errs = CombineErrors(nil, n.errs, n.ctx.Err())
  1589  	return n.errs
  1590  }
  1591  
  1592  // getValidators sets the vertex' Value in case there was no concrete value.
  1593  func (n *nodeContext) getValidators(state vertexStatus) BaseValue {
  1594  	n.assertInitialized()
  1595  
  1596  	ctx := n.ctx
  1597  
  1598  	a := []Value{}
  1599  	// if n.node.Value != nil {
  1600  	// 	a = append(a, n.node.Value)
  1601  	// }
  1602  	kind := TopKind
  1603  	if n.lowerBound != nil {
  1604  		a = append(a, n.lowerBound)
  1605  		kind &= n.lowerBound.Kind()
  1606  	}
  1607  	if n.upperBound != nil {
  1608  		a = append(a, n.upperBound)
  1609  		kind &= n.upperBound.Kind()
  1610  	}
  1611  	for _, c := range n.checks {
  1612  		// Drop !=x if x is out of bounds with another bound.
  1613  		if b, _ := c.x.(*BoundValue); b != nil && b.Op == NotEqualOp {
  1614  			if n.upperBound != nil &&
  1615  				SimplifyBounds(ctx, n.kind, n.upperBound, b) != nil {
  1616  				continue
  1617  			}
  1618  			if n.lowerBound != nil &&
  1619  				SimplifyBounds(ctx, n.kind, n.lowerBound, b) != nil {
  1620  				continue
  1621  			}
  1622  		}
  1623  		v := c.x.(Value)
  1624  		a = append(a, v)
  1625  		kind &= v.Kind()
  1626  	}
  1627  
  1628  	if kind&^n.kind != 0 {
  1629  		a = append(a, &BasicType{
  1630  			Src: n.kindExpr.Source(), // TODO:Is this always a BasicType?
  1631  			K:   n.kind,
  1632  		})
  1633  	}
  1634  
  1635  	var v BaseValue
  1636  	switch len(a) {
  1637  	case 0:
  1638  		// Src is the combined input.
  1639  		if state >= conjuncts || n.kind&^CompositeKind == 0 {
  1640  			v = &BasicType{K: n.kind}
  1641  		}
  1642  
  1643  	case 1:
  1644  		v = a[0]
  1645  
  1646  	default:
  1647  		v = &Conjunction{Values: a}
  1648  	}
  1649  
  1650  	return v
  1651  }
  1652  
  1653  // TODO: this function can probably go as this is now handled in the nodeContext.
  1654  func (n *nodeContext) maybeSetCache() {
  1655  	// Set BaseValue to scalar, but only if it was not set before. Most notably,
  1656  	// errors should not be discarded.
  1657  	_, isErr := n.node.BaseValue.(*Bottom)
  1658  	if n.scalar != nil && (!isErr || isCyclePlaceholder(n.node.BaseValue)) {
  1659  		n.node.BaseValue = n.scalar
  1660  	}
  1661  	// NOTE: this is now handled by associating the nodeContext
  1662  	// if n.errs != nil {
  1663  	// 	n.node.SetValue(n.ctx, Partial, n.errs)
  1664  	// }
  1665  }
  1666  
  1667  type envExpr struct {
  1668  	c   Conjunct
  1669  	err *Bottom
  1670  }
  1671  
  1672  type envDynamic struct {
  1673  	env   *Environment
  1674  	field *DynamicField
  1675  	id    CloseInfo
  1676  	err   *Bottom
  1677  }
  1678  
  1679  type envList struct {
  1680  	env     *Environment
  1681  	list    *ListLit
  1682  	n       int64 // recorded length after evaluator
  1683  	elipsis *Ellipsis
  1684  	id      CloseInfo
  1685  	ignore  bool // has a self-referencing comprehension and is postponed
  1686  	self    bool // was added as a postponed self-referencing comprehension
  1687  }
  1688  
  1689  type envCheck struct {
  1690  	env         *Environment
  1691  	expr        Expr
  1692  	expectError bool
  1693  }
  1694  
  1695  func (n *nodeContext) addBottom(b *Bottom) {
  1696  	n.assertInitialized()
  1697  
  1698  	n.errs = CombineErrors(nil, n.errs, b)
  1699  	// TODO(errors): consider doing this
  1700  	// n.kindExpr = n.errs
  1701  	// n.kind = 0
  1702  }
  1703  
  1704  func (n *nodeContext) addErr(err errors.Error) {
  1705  	n.assertInitialized()
  1706  
  1707  	if err != nil {
  1708  		n.addBottom(&Bottom{
  1709  			Err:  err,
  1710  			Node: n.node,
  1711  		})
  1712  	}
  1713  }
  1714  
  1715  // addExprConjuncts will attempt to evaluate an Expr and insert the value
  1716  // into the nodeContext if successful or queue it for later evaluation if it is
  1717  // incomplete or is not value.
  1718  func (n *nodeContext) addExprConjunct(v Conjunct, state vertexStatus) {
  1719  	unreachableForDev(n.ctx)
  1720  
  1721  	env := v.Env
  1722  	id := v.CloseInfo
  1723  
  1724  	switch x := v.Elem().(type) {
  1725  	case *Vertex:
  1726  		if x.IsData() {
  1727  			n.addValueConjunct(env, x, id)
  1728  		} else {
  1729  			n.addVertexConjuncts(v, x, true)
  1730  		}
  1731  
  1732  	case Value:
  1733  		n.addValueConjunct(env, x, id)
  1734  
  1735  	case *BinaryExpr:
  1736  		if x.Op == AndOp {
  1737  			n.addExprConjunct(MakeConjunct(env, x.X, id), state)
  1738  			n.addExprConjunct(MakeConjunct(env, x.Y, id), state)
  1739  			return
  1740  		} else {
  1741  			n.evalExpr(v, state)
  1742  		}
  1743  
  1744  	case *StructLit:
  1745  		n.addStruct(env, x, id)
  1746  
  1747  	case *ListLit:
  1748  		childEnv := &Environment{
  1749  			Up:     env,
  1750  			Vertex: n.node,
  1751  		}
  1752  		n.lists = append(n.lists, envList{env: childEnv, list: x, id: id})
  1753  
  1754  	case *DisjunctionExpr:
  1755  		n.addDisjunction(env, x, id)
  1756  
  1757  	case *Comprehension:
  1758  		// always a partial comprehension.
  1759  		n.insertComprehension(env, x, id)
  1760  		return
  1761  
  1762  	default:
  1763  		// Must be Resolver or Evaluator.
  1764  		n.evalExpr(v, state)
  1765  	}
  1766  	n.ctx.stats.Conjuncts++
  1767  }
  1768  
  1769  // evalExpr is only called by addExprConjunct. If an error occurs, it records
  1770  // the error in n and returns nil.
  1771  func (n *nodeContext) evalExpr(v Conjunct, state vertexStatus) {
  1772  	unreachableForDev(n.ctx)
  1773  
  1774  	// Require an Environment.
  1775  	ctx := n.ctx
  1776  
  1777  	closeID := v.CloseInfo
  1778  
  1779  	switch x := v.Expr().(type) {
  1780  	case Resolver:
  1781  		// We elevate a field evaluated to the Conjuncts state to Finalized
  1782  		// later. For now we allow partial evaluation so that we can break
  1783  		// cycles and postpone incomplete evaluations until more information is
  1784  		// available down the line.
  1785  		if state == finalized {
  1786  			state = conjuncts
  1787  		}
  1788  		arc, err := ctx.resolveState(v, x, oldOnly(state))
  1789  		if err != nil && (!err.IsIncomplete() || err.Permanent) {
  1790  			n.addBottom(err)
  1791  			break
  1792  		}
  1793  		if arc == nil {
  1794  			n.exprs = append(n.exprs, envExpr{v, err})
  1795  			break
  1796  		}
  1797  
  1798  		// We complete the evaluation. Some optimizations will only work when an
  1799  		// arc is already finalized. So this ensures that such optimizations get
  1800  		// triggered more often.
  1801  		//
  1802  		// NOTE(let finalization): aside from being an optimization, this also
  1803  		// ensures that let arcs that are not contained as fields of arcs, but
  1804  		// rather are held in the cash, are finalized. This, in turn, is
  1805  		// necessary to trigger the notification mechanism, where appropriate.
  1806  		//
  1807  		// A node should not Finalize itself as it may erase the state object
  1808  		// which is still assumed to be present down the line
  1809  		// (see https://cuelang.org/issues/2171).
  1810  		if arc.status == conjuncts && arc != n.node && arc.hasAllConjuncts {
  1811  			arc.Finalize(ctx)
  1812  		}
  1813  
  1814  		ci, skip := n.markCycle(arc, v.Env, x, v.CloseInfo)
  1815  		if skip {
  1816  			return
  1817  		}
  1818  		v.CloseInfo = ci
  1819  
  1820  		n.addVertexConjuncts(v, arc, false)
  1821  
  1822  	case Evaluator:
  1823  		// Interpolation, UnaryExpr, BinaryExpr, CallExpr
  1824  		// Could be unify?
  1825  		val := ctx.evaluateRec(v, oldOnly(partial))
  1826  		if b, ok := val.(*Bottom); ok &&
  1827  			b.IsIncomplete() {
  1828  			n.exprs = append(n.exprs, envExpr{v, b})
  1829  			break
  1830  		}
  1831  
  1832  		if v, ok := val.(*Vertex); ok {
  1833  			// Handle generated disjunctions (as in the 'or' builtin).
  1834  			// These come as a Vertex, but should not be added as a value.
  1835  			b, ok := v.BaseValue.(*Bottom)
  1836  			if ok && b.IsIncomplete() && len(v.Conjuncts) > 0 {
  1837  				for _, c := range v.Conjuncts {
  1838  					c.CloseInfo = closeID
  1839  					n.addExprConjunct(c, state)
  1840  				}
  1841  				break
  1842  			}
  1843  		}
  1844  
  1845  		// TODO: also to through normal Vertex handling here. At the moment
  1846  		// addValueConjunct handles StructMarker.NeedsClose, as this is always
  1847  		// only needed when evaluation an Evaluator, and not a Resolver.
  1848  		// The two code paths should ideally be merged once this separate
  1849  		// mechanism is eliminated.
  1850  		//
  1851  		// if arc, ok := val.(*Vertex); ok && !arc.IsData() {
  1852  		// 	n.addVertexConjuncts(v.Env, closeID, v.Expr(), arc)
  1853  		// 	break
  1854  		// }
  1855  
  1856  		// TODO: insert in vertex as well
  1857  		n.addValueConjunct(v.Env, val, closeID)
  1858  
  1859  	default:
  1860  		panic(fmt.Sprintf("unknown expression of type %T", x))
  1861  	}
  1862  }
  1863  
  1864  func (n *nodeContext) addVertexConjuncts(c Conjunct, arc *Vertex, inline bool) {
  1865  	unreachableForDev(n.ctx)
  1866  
  1867  	closeInfo := c.CloseInfo
  1868  
  1869  	// We need to ensure that each arc is only unified once (or at least) a
  1870  	// bounded time, witch each conjunct. Comprehensions, for instance, may
  1871  	// distribute a value across many values that get unified back into the
  1872  	// same value. If such a value is a disjunction, than a disjunction of N
  1873  	// disjuncts will result in a factor N more unifications for each
  1874  	// occurrence of such value, resulting in exponential running time. This
  1875  	// is especially common values that are used as a type.
  1876  	//
  1877  	// However, unification is idempotent, so each such conjunct only needs
  1878  	// to be unified once. This cache checks for this and prevents an
  1879  	// exponential blowup in such case.
  1880  	//
  1881  	// TODO(perf): this cache ensures the conjuncts of an arc at most once
  1882  	// per ID. However, we really need to add the conjuncts of an arc only
  1883  	// once total, and then add the close information once per close ID
  1884  	// (pointer can probably be shared). Aside from being more performant,
  1885  	// this is probably the best way to guarantee that conjunctions are
  1886  	// linear in this case.
  1887  
  1888  	ckey := closeInfo
  1889  	ckey.Refs = nil
  1890  	ckey.Inline = false
  1891  	key := arcKey{arc, ckey}
  1892  	for _, k := range n.arcMap {
  1893  		if key == k {
  1894  			return
  1895  		}
  1896  	}
  1897  	n.arcMap = append(n.arcMap, key)
  1898  
  1899  	status := arc.status
  1900  
  1901  	switch status {
  1902  	case evaluating:
  1903  		// Reference cycle detected. We have reached a fixed point and
  1904  		// adding conjuncts at this point will not change the value. Also,
  1905  		// continuing to pursue this value will result in an infinite loop.
  1906  
  1907  		// TODO: add a mechanism so that the computation will only have to
  1908  		// be done once?
  1909  
  1910  		if arc == n.node {
  1911  			// TODO: we could use node sharing here. This may avoid an
  1912  			// exponential blowup during evaluation, like is possible with
  1913  			// YAML.
  1914  			return
  1915  		}
  1916  
  1917  	case evaluatingArcs:
  1918  		// There is a structural cycle, but values may be processed nonetheless
  1919  		// if there is a non-cyclic conjunct. See cycle.go.
  1920  	}
  1921  
  1922  	// Performance: the following if check filters cases that are not strictly
  1923  	// necessary for correct functioning. Not updating the closeInfo may cause
  1924  	// some position information to be lost for top-level positions of merges
  1925  	// resulting form APIs. These tend to be fairly uninteresting.
  1926  	// At the same time, this optimization may prevent considerable slowdown
  1927  	// in case an API does many calls to Unify.
  1928  	x := c.Expr()
  1929  	if !inline || arc.IsClosedStruct() || arc.IsClosedList() {
  1930  		isDef, _ := IsDef(x)
  1931  		closeInfo = closeInfo.SpawnRef(arc, isDef, x)
  1932  	}
  1933  
  1934  	if arc.status == unprocessed && !inline {
  1935  		// This is a rare condition, but can happen in certain
  1936  		// evaluation orders. Unfortunately, adding this breaks
  1937  		// resolution of cyclic mutually referring disjunctions. But it
  1938  		// is necessary to prevent lookups in unevaluated structs.
  1939  		// TODO(cycles): this can probably most easily be fixed with a
  1940  		// having a more recursive implementation.
  1941  		n.ctx.unify(arc, oldOnly(partial))
  1942  	}
  1943  
  1944  	// Don't add conjuncts if a node is referring to itself.
  1945  	if n.node == arc {
  1946  		return
  1947  	}
  1948  
  1949  	if arc.state != nil {
  1950  		arc.state.addNotify(n.node)
  1951  	}
  1952  
  1953  	for _, c := range arc.Conjuncts {
  1954  		// Note that we are resetting the tree here. We hereby assume that
  1955  		// closedness conflicts resulting from unifying the referenced arc were
  1956  		// already caught there and that we can ignore further errors here.
  1957  		c.CloseInfo = closeInfo
  1958  		n.addExprConjunct(c, partial)
  1959  	}
  1960  }
  1961  
  1962  func (n *nodeContext) addValueConjunct(env *Environment, v Value, id CloseInfo) {
  1963  	n.updateCyclicStatus(id)
  1964  
  1965  	ctx := n.ctx
  1966  
  1967  	if x, ok := v.(*Vertex); ok {
  1968  		if m, ok := x.BaseValue.(*StructMarker); ok {
  1969  			n.aStruct = x
  1970  			n.aStructID = id
  1971  			if m.NeedClose {
  1972  				id.IsClosed = true
  1973  			}
  1974  		}
  1975  
  1976  		if !x.IsData() {
  1977  			// TODO: this really shouldn't happen anymore.
  1978  			if isComplexStruct(ctx, x) {
  1979  				// This really shouldn't happen, but just in case.
  1980  				n.addVertexConjuncts(MakeConjunct(env, x, id), x, true)
  1981  				return
  1982  			}
  1983  
  1984  			for _, c := range x.Conjuncts {
  1985  				c.CloseInfo = id
  1986  				n.addExprConjunct(c, partial) // TODO: Pass from eval
  1987  			}
  1988  			return
  1989  		}
  1990  
  1991  		// TODO: evaluate value?
  1992  		switch v := x.BaseValue.(type) {
  1993  		default:
  1994  			panic(fmt.Sprintf("invalid type %T", x.BaseValue))
  1995  
  1996  		case *ListMarker:
  1997  			n.vLists = append(n.vLists, x)
  1998  			return
  1999  
  2000  		case *StructMarker:
  2001  
  2002  		case Value:
  2003  			n.addValueConjunct(env, v, id)
  2004  		}
  2005  
  2006  		if len(x.Arcs) == 0 {
  2007  			return
  2008  		}
  2009  
  2010  		s := &StructLit{}
  2011  
  2012  		// Keep ordering of Go struct for topological sort.
  2013  		n.node.AddStruct(s, env, id)
  2014  		n.node.Structs = append(n.node.Structs, x.Structs...)
  2015  
  2016  		for _, a := range x.Arcs {
  2017  			if !a.definitelyExists() {
  2018  				continue
  2019  			}
  2020  			// TODO(errors): report error when this is a regular field.
  2021  			c := MakeConjunct(nil, a, id)
  2022  			n.insertField(a.Label, a.ArcType, c)
  2023  			s.MarkField(a.Label)
  2024  		}
  2025  		return
  2026  	}
  2027  
  2028  	switch b := v.(type) {
  2029  	case *Bottom:
  2030  		if b == NoShareSentinel {
  2031  			return
  2032  		}
  2033  		n.addBottom(b)
  2034  		return
  2035  	case *Builtin:
  2036  		if v := b.BareValidator(); v != nil {
  2037  			n.addValueConjunct(env, v, id)
  2038  			return
  2039  		}
  2040  	}
  2041  
  2042  	if !n.updateNodeType(v.Kind(), v, id) {
  2043  		return
  2044  	}
  2045  
  2046  	switch x := v.(type) {
  2047  	case *Disjunction:
  2048  		n.addDisjunctionValue(env, x, id)
  2049  
  2050  	case *Conjunction:
  2051  		for _, x := range x.Values {
  2052  			n.addValueConjunct(env, x, id)
  2053  		}
  2054  
  2055  	case *Top:
  2056  		n.hasTop = true
  2057  
  2058  	case *BasicType:
  2059  		// handled above
  2060  
  2061  	case *BoundValue:
  2062  		switch x.Op {
  2063  		case LessThanOp, LessEqualOp:
  2064  			if y := n.upperBound; y != nil {
  2065  				v := SimplifyBounds(ctx, n.kind, x, y)
  2066  				if err := valueError(v); err != nil {
  2067  					err.AddPosition(v)
  2068  					err.AddPosition(n.upperBound)
  2069  					err.AddClosedPositions(id)
  2070  				}
  2071  				n.upperBound = nil
  2072  				n.addValueConjunct(env, v, id)
  2073  				return
  2074  			}
  2075  			n.upperBound = x
  2076  
  2077  		case GreaterThanOp, GreaterEqualOp:
  2078  			if y := n.lowerBound; y != nil {
  2079  				v := SimplifyBounds(ctx, n.kind, x, y)
  2080  				if err := valueError(v); err != nil {
  2081  					err.AddPosition(v)
  2082  					err.AddPosition(n.lowerBound)
  2083  					err.AddClosedPositions(id)
  2084  				}
  2085  				n.lowerBound = nil
  2086  				n.addValueConjunct(env, v, id)
  2087  				return
  2088  			}
  2089  			n.lowerBound = x
  2090  
  2091  		case EqualOp, NotEqualOp, MatchOp, NotMatchOp:
  2092  			// This check serves as simplifier, but also to remove duplicates.
  2093  			k := 0
  2094  			match := false
  2095  			cx := MakeConjunct(env, x, id)
  2096  			for _, c := range n.checks {
  2097  				if y, ok := c.x.(*BoundValue); ok {
  2098  					switch z := SimplifyBounds(ctx, n.kind, x, y); {
  2099  					case z == y:
  2100  						match = true
  2101  					case z == x:
  2102  						continue
  2103  					}
  2104  				}
  2105  				n.checks[k] = c
  2106  				k++
  2107  			}
  2108  			n.checks = n.checks[:k]
  2109  			if !match {
  2110  				n.checks = append(n.checks, cx)
  2111  			}
  2112  			return
  2113  		}
  2114  
  2115  	case Validator:
  2116  		// This check serves as simplifier, but also to remove duplicates.
  2117  		cx := MakeConjunct(env, x, id)
  2118  		for i, y := range n.checks {
  2119  			if b, ok := SimplifyValidator(ctx, cx, y); ok {
  2120  				n.checks[i] = b
  2121  				return
  2122  			}
  2123  		}
  2124  		n.updateNodeType(x.Kind(), x, id)
  2125  		n.checks = append(n.checks, cx)
  2126  		// TODO(validatorType): see namesake TODO in conjunct.go.
  2127  		k := x.Kind()
  2128  		if k == TopKind {
  2129  			n.hasTop = true
  2130  		}
  2131  		n.updateNodeType(k, x, id)
  2132  
  2133  	case *Vertex:
  2134  	// handled above.
  2135  
  2136  	case Value: // *NullLit, *BoolLit, *NumLit, *StringLit, *BytesLit, *Builtin
  2137  		if y := n.scalar; y != nil {
  2138  			if b, ok := BinOp(ctx, EqualOp, x, y).(*Bool); !ok || !b.B {
  2139  				n.reportConflict(x, y, x.Kind(), y.Kind(), n.scalarID, id)
  2140  			}
  2141  			// TODO: do we need to explicitly add again?
  2142  			// n.scalar = nil
  2143  			// n.addValueConjunct(c, BinOp(c, EqualOp, x, y))
  2144  			break
  2145  		}
  2146  		n.scalar = x
  2147  		n.scalarID = id
  2148  		if n.node.status >= conjuncts {
  2149  			n.node.BaseValue = x
  2150  		}
  2151  
  2152  	default:
  2153  		panic(fmt.Sprintf("unknown value type %T", x))
  2154  	}
  2155  
  2156  	if n.lowerBound != nil && n.upperBound != nil {
  2157  		if u := SimplifyBounds(ctx, n.kind, n.lowerBound, n.upperBound); u != nil {
  2158  			if err := valueError(u); err != nil {
  2159  				err.AddPosition(n.lowerBound)
  2160  				err.AddPosition(n.upperBound)
  2161  				err.AddClosedPositions(id)
  2162  			}
  2163  			n.lowerBound = nil
  2164  			n.upperBound = nil
  2165  			n.addValueConjunct(env, u, id)
  2166  		}
  2167  	}
  2168  }
  2169  
  2170  func valueError(v Value) *ValueError {
  2171  	if v == nil {
  2172  		return nil
  2173  	}
  2174  	b, _ := v.(*Bottom)
  2175  	if b == nil {
  2176  		return nil
  2177  	}
  2178  	err, _ := b.Err.(*ValueError)
  2179  	if err == nil {
  2180  		return nil
  2181  	}
  2182  	return err
  2183  }
  2184  
  2185  // addStruct collates the declarations of a struct.
  2186  //
  2187  // addStruct fulfills two additional pivotal functions:
  2188  //  1. Implement vertex unification (this happens through De Bruijn indices
  2189  //     combined with proper set up of Environments).
  2190  //  2. Implied closedness for definitions.
  2191  func (n *nodeContext) addStruct(
  2192  	env *Environment,
  2193  	s *StructLit,
  2194  	closeInfo CloseInfo) {
  2195  
  2196  	n.updateCyclicStatus(closeInfo)
  2197  
  2198  	// NOTE: This is a crucial point in the code:
  2199  	// Unification dereferencing happens here. The child nodes are set to
  2200  	// an Environment linked to the current node. Together with the De Bruijn
  2201  	// indices, this determines to which Vertex a reference resolves.
  2202  
  2203  	childEnv := &Environment{
  2204  		Up:     env,
  2205  		Vertex: n.node,
  2206  	}
  2207  
  2208  	s.Init(n.ctx)
  2209  
  2210  	if s.HasEmbed && !s.IsFile() {
  2211  		closeInfo = closeInfo.SpawnGroup(nil)
  2212  	}
  2213  
  2214  	parent := n.node.AddStruct(s, childEnv, closeInfo)
  2215  	closeInfo.IsClosed = false
  2216  
  2217  	parent.Disable = true // disable until processing is done.
  2218  
  2219  	for _, d := range s.Decls {
  2220  		switch x := d.(type) {
  2221  		case *Field:
  2222  			if x.Label.IsString() && x.ArcType == ArcMember {
  2223  				n.aStruct = s
  2224  				n.aStructID = closeInfo
  2225  			}
  2226  			n.insertField(x.Label, x.ArcType, MakeConjunct(childEnv, x, closeInfo))
  2227  
  2228  		case *LetField:
  2229  			arc := n.insertField(x.Label, ArcMember, MakeConjunct(childEnv, x, closeInfo))
  2230  			if x.IsMulti {
  2231  				arc.MultiLet = x.IsMulti
  2232  			}
  2233  
  2234  		case *DynamicField:
  2235  			n.aStruct = s
  2236  			n.aStructID = closeInfo
  2237  			n.dynamicFields = append(n.dynamicFields, envDynamic{childEnv, x, closeInfo, nil})
  2238  
  2239  		case *Comprehension:
  2240  			n.insertComprehension(childEnv, x, closeInfo)
  2241  
  2242  		case Expr:
  2243  			// add embedding to optional
  2244  
  2245  			// TODO(perf): only do this if addExprConjunct below will result in
  2246  			// a fieldSet. Otherwise the entry will just be removed next.
  2247  			id := closeInfo.SpawnEmbed(x)
  2248  
  2249  			c := MakeConjunct(childEnv, x, id)
  2250  			n.addExprConjunct(c, partial)
  2251  
  2252  		case *BulkOptionalField, *Ellipsis:
  2253  			// Nothing to do here. Note that the presence of these fields do not
  2254  			// excluded embedded scalars: only when they match actual fields
  2255  			// does it exclude those.
  2256  
  2257  		default:
  2258  			panic("unreachable")
  2259  		}
  2260  	}
  2261  
  2262  	if !s.HasEmbed {
  2263  		n.aStruct = s
  2264  		n.aStructID = closeInfo
  2265  	}
  2266  
  2267  	parent.Disable = false
  2268  
  2269  }
  2270  
  2271  // TODO(perf): if an arc is the only arc with that label added to a Vertex, and
  2272  // if there are no conjuncts of optional fields to be added, then the arc could
  2273  // be added as is until any of these conditions change. This would allow
  2274  // structure sharing in many cases. One should be careful, however, to
  2275  // recursively track arcs of previously unified evaluated vertices ot make this
  2276  // optimization meaningful.
  2277  //
  2278  // An alternative approach to avoid evaluating optional arcs (if we take that
  2279  // route) is to not recursively evaluate those arcs, even for Finalize. This is
  2280  // possible as it is not necessary to evaluate optional arcs to evaluate
  2281  // disjunctions.
  2282  func (n *nodeContext) insertField(f Feature, mode ArcType, x Conjunct) *Vertex {
  2283  	ctx := n.ctx
  2284  	if ctx.isDevVersion() {
  2285  		return n.insertArc(f, mode, x, x.CloseInfo, true)
  2286  	}
  2287  
  2288  	arc, isNew := n.node.GetArc(ctx, f, mode)
  2289  	if f.IsLet() && !isNew {
  2290  		arc.MultiLet = true
  2291  		return arc
  2292  	}
  2293  	if arc.hasConjunct(x) {
  2294  		return arc
  2295  	}
  2296  
  2297  	switch {
  2298  	case arc.state != nil:
  2299  		arc.state.addConjunctDynamic(x)
  2300  
  2301  	case arc.IsUnprocessed() || arc.status != finalized:
  2302  		arc.addConjunctUnchecked(x)
  2303  
  2304  	default:
  2305  		n.addBottom(&Bottom{
  2306  			Code: IncompleteError,
  2307  			Node: n.node,
  2308  			Err: ctx.NewPosf(pos(x.Field()),
  2309  				"cannot add field %s: was already used",
  2310  				f.SelectorString(ctx)),
  2311  		})
  2312  	}
  2313  	return arc
  2314  }
  2315  
  2316  func (n *nodeContext) insertFieldUnchecked(f Feature, mode ArcType, x Conjunct) *Vertex {
  2317  	ctx := n.ctx
  2318  	if ctx.isDevVersion() {
  2319  		return n.insertArc(f, mode, x, x.CloseInfo, false)
  2320  	}
  2321  
  2322  	arc, isNew := n.node.GetArc(ctx, f, mode)
  2323  	if f.IsLet() && !isNew {
  2324  		arc.MultiLet = true
  2325  		return arc
  2326  	}
  2327  	arc.addConjunctUnchecked(x)
  2328  	return arc
  2329  }
  2330  
  2331  // expandOne adds dynamic fields to a node until a fixed point is reached.
  2332  // On each iteration, dynamic fields that cannot resolve due to incomplete
  2333  // values are skipped. They will be retried on the next iteration until no
  2334  // progress can be made. Note that a dynamic field may add more dynamic fields.
  2335  //
  2336  // forClauses are processed after all other clauses. A struct may be referenced
  2337  // before it is complete, meaning that fields added by other forms of injection
  2338  // may influence the result of a for clause _after_ it has already been
  2339  // processed. We could instead detect such insertion and feed it to the
  2340  // ForClause to generate another entry or have the for clause be recomputed.
  2341  // This seems to be too complicated and lead to iffy edge cases.
  2342  // TODO(errors): detect when a field is added to a struct that is already used
  2343  // in a for clause.
  2344  func (n *nodeContext) expandOne(state vertexStatus) (done bool) {
  2345  	unreachableForDev(n.ctx)
  2346  
  2347  	// Don't expand incomplete expressions if we detected a cycle.
  2348  	if n.done() || (n.hasAnyCyclicConjunct && !n.hasNonCycle) {
  2349  		return false
  2350  	}
  2351  
  2352  	var progress bool
  2353  
  2354  	if progress = n.injectDynamic(); progress {
  2355  		return true
  2356  	}
  2357  
  2358  	if progress = n.injectComprehensions(state); progress {
  2359  		return true
  2360  	}
  2361  
  2362  	// Do expressions after comprehensions, as comprehensions can never
  2363  	// refer to embedded scalars, whereas expressions may refer to generated
  2364  	// fields if we were to allow attributes to be defined alongside
  2365  	// scalars.
  2366  	exprs := n.exprs
  2367  	n.exprs = n.exprs[:0]
  2368  	for _, x := range exprs {
  2369  		n.addExprConjunct(x.c, state)
  2370  
  2371  		// collect and or
  2372  	}
  2373  	if len(n.exprs) < len(exprs) {
  2374  		return true
  2375  	}
  2376  
  2377  	// No progress, report error later if needed: unification with
  2378  	// disjuncts may resolve this later on.
  2379  	return false
  2380  }
  2381  
  2382  // injectDynamic evaluates and inserts dynamic declarations.
  2383  func (n *nodeContext) injectDynamic() (progress bool) {
  2384  	unreachableForDev(n.ctx)
  2385  
  2386  	ctx := n.ctx
  2387  	k := 0
  2388  
  2389  	a := n.dynamicFields
  2390  	for _, d := range n.dynamicFields {
  2391  		var f Feature
  2392  		x := d.field.Key
  2393  		// Push state to capture and remove errors.
  2394  		s := ctx.PushState(d.env, x.Source())
  2395  		v := ctx.evalState(x, oldOnly(finalized))
  2396  		b := ctx.PopState(s)
  2397  
  2398  		if b != nil && b.IsIncomplete() {
  2399  			d.err, _ = v.(*Bottom)
  2400  			a[k] = d
  2401  			k++
  2402  			continue
  2403  		}
  2404  		if b, _ := v.(*Bottom); b != nil {
  2405  			n.addValueConjunct(nil, b, d.id)
  2406  			continue
  2407  		}
  2408  		f = ctx.Label(d.field.Key, v)
  2409  		if f.IsInt() {
  2410  			n.addErr(ctx.NewPosf(pos(d.field.Key), "integer fields not supported"))
  2411  		}
  2412  		n.insertField(f, d.field.ArcType, MakeConjunct(d.env, d.field, d.id))
  2413  	}
  2414  
  2415  	progress = k < len(n.dynamicFields)
  2416  
  2417  	n.dynamicFields = a[:k]
  2418  
  2419  	return progress
  2420  }
  2421  
  2422  // addLists evaluates the queued list conjuncts and inserts its arcs into the
  2423  // Vertex.
  2424  //
  2425  // TODO: association arrays:
  2426  // If an association array marker was present in a struct, create a struct node
  2427  // instead of a list node. In either case, a node may only have list fields
  2428  // or struct fields and not both.
  2429  //
  2430  // addLists should be run after the fixpoint expansion:
  2431  //   - it enforces that comprehensions may not refer to the list itself
  2432  //   - there may be no other fields within the list.
  2433  //
  2434  // TODO(embeddedScalars): for embedded scalars, there should be another pass
  2435  // of evaluation expressions after expanding lists.
  2436  func (n *nodeContext) addLists(state combinedFlags) (progress bool) {
  2437  	if len(n.lists) == 0 && len(n.vLists) == 0 {
  2438  		return false
  2439  	}
  2440  
  2441  	var oneOfTheLists Expr
  2442  	var anID CloseInfo
  2443  
  2444  	isOpen := true
  2445  	max := 0
  2446  	var maxNode Expr
  2447  
  2448  	if m, ok := n.node.BaseValue.(*ListMarker); ok {
  2449  		isOpen = m.IsOpen
  2450  		max = len(n.node.Arcs)
  2451  	}
  2452  
  2453  	c := n.ctx
  2454  
  2455  	for _, l := range n.vLists {
  2456  		// XXX: set hasNonCycle if appropriate.
  2457  
  2458  		oneOfTheLists = l
  2459  
  2460  		elems := l.Elems()
  2461  		isClosed := l.IsClosedList()
  2462  
  2463  		switch {
  2464  		case len(elems) < max:
  2465  			if isClosed {
  2466  				n.invalidListLength(len(elems), max, l, maxNode)
  2467  				continue
  2468  			}
  2469  
  2470  		case len(elems) > max:
  2471  			if !isOpen {
  2472  				n.invalidListLength(max, len(elems), maxNode, l)
  2473  				continue
  2474  			}
  2475  			isOpen = !isClosed
  2476  			max = len(elems)
  2477  			maxNode = l
  2478  
  2479  		case isClosed:
  2480  			isOpen = false
  2481  			maxNode = l
  2482  		}
  2483  
  2484  		for _, a := range elems {
  2485  			if a.Conjuncts == nil {
  2486  				n.insertField(a.Label, ArcMember, MakeRootConjunct(nil, a))
  2487  				continue
  2488  			}
  2489  			for _, c := range a.Conjuncts {
  2490  				n.insertField(a.Label, ArcMember, c)
  2491  			}
  2492  		}
  2493  	}
  2494  
  2495  outer:
  2496  	// updateCyclicStatus may grow the list of values, so we cannot use range.
  2497  	for i := 0; i < len(n.lists); i++ {
  2498  		l := n.lists[i]
  2499  
  2500  		n.updateCyclicStatus(l.id)
  2501  
  2502  		if l.self {
  2503  			n.node.LockArcs = true
  2504  		}
  2505  
  2506  		index := int64(0)
  2507  		hasComprehension := false
  2508  		for j, elem := range l.list.Elems {
  2509  			switch x := elem.(type) {
  2510  			case *Comprehension:
  2511  				err := c.yield(nil, l.env, x, state, func(e *Environment) {
  2512  					label, err := MakeLabel(x.Source(), index, IntLabel)
  2513  					n.addErr(err)
  2514  					index++
  2515  					c := MakeConjunct(e, x.Value, l.id)
  2516  					n.insertField(label, ArcMember, c)
  2517  				})
  2518  				hasComprehension = true
  2519  				if err != nil {
  2520  					if err.ForCycle && !l.self {
  2521  						// The list has a comprehension that refers to the list
  2522  						// itself. This means we should postpone evaluating this
  2523  						// list until all other lists have been evaluated.
  2524  						n.lists[i].ignore = true
  2525  						l.self = true
  2526  						n.lists = append(n.lists, l)
  2527  					} else {
  2528  						n.addBottom(err)
  2529  					}
  2530  					continue outer
  2531  				}
  2532  
  2533  			case *Ellipsis:
  2534  				if j != len(l.list.Elems)-1 {
  2535  					n.addErr(c.Newf("ellipsis must be last element in list"))
  2536  				}
  2537  
  2538  				n.lists[i].elipsis = x
  2539  
  2540  			default:
  2541  				label, err := MakeLabel(x.Source(), index, IntLabel)
  2542  				n.addErr(err)
  2543  				index++ // TODO: don't use insertField.
  2544  				n.insertField(label, ArcMember, MakeConjunct(l.env, x, l.id))
  2545  			}
  2546  
  2547  			// Terminate early in case of runaway comprehension.
  2548  			if !isOpen && int(index) > max {
  2549  				n.invalidListLength(max, len(l.list.Elems), maxNode, l.list)
  2550  				continue outer
  2551  			}
  2552  		}
  2553  
  2554  		oneOfTheLists = l.list
  2555  		anID = l.id
  2556  
  2557  		switch closed := n.lists[i].elipsis == nil; {
  2558  		case int(index) < max:
  2559  			if closed {
  2560  				n.invalidListLength(int(index), max, l.list, maxNode)
  2561  				continue
  2562  			}
  2563  
  2564  		case int(index) > max,
  2565  			closed && isOpen,
  2566  			(!closed == isOpen) && !hasComprehension:
  2567  			max = int(index)
  2568  			maxNode = l.list
  2569  			isOpen = !closed
  2570  		}
  2571  
  2572  		n.lists[i].n = index
  2573  	}
  2574  
  2575  	// add additionalItem values to list and construct optionals.
  2576  	elems := n.node.Elems()
  2577  	for _, l := range n.vLists {
  2578  		if !l.IsClosedList() {
  2579  			continue
  2580  		}
  2581  
  2582  		newElems := l.Elems()
  2583  		if len(newElems) >= len(elems) {
  2584  			continue // error generated earlier, if applicable.
  2585  		}
  2586  
  2587  		for _, arc := range elems[len(newElems):] {
  2588  			l.MatchAndInsert(c, arc)
  2589  		}
  2590  	}
  2591  
  2592  	for _, l := range n.lists {
  2593  		if l.elipsis == nil || l.ignore {
  2594  			continue
  2595  		}
  2596  
  2597  		s := l.list.info
  2598  		if s == nil {
  2599  			s = &StructLit{Decls: []Decl{l.elipsis}}
  2600  			s.Init(n.ctx)
  2601  			l.list.info = s
  2602  		}
  2603  		info := n.node.AddStruct(s, l.env, l.id)
  2604  
  2605  		for _, arc := range elems[l.n:] {
  2606  			info.MatchAndInsert(c, arc)
  2607  		}
  2608  	}
  2609  
  2610  	sources := []ast.Expr{}
  2611  	// Add conjuncts for additional items.
  2612  	for _, l := range n.lists {
  2613  		if l.elipsis == nil || l.ignore {
  2614  			continue
  2615  		}
  2616  		if src, _ := l.elipsis.Source().(ast.Expr); src != nil {
  2617  			sources = append(sources, src)
  2618  		}
  2619  	}
  2620  
  2621  	if m, ok := n.node.BaseValue.(*ListMarker); !ok {
  2622  		n.node.setValue(c, partial, &ListMarker{
  2623  			Src:    ast.NewBinExpr(token.AND, sources...),
  2624  			IsOpen: isOpen,
  2625  		})
  2626  	} else {
  2627  		if m.Src != nil {
  2628  			sources = append(sources, m.Src)
  2629  		}
  2630  		m.Src = ast.NewBinExpr(token.AND, sources...)
  2631  		m.IsOpen = m.IsOpen && isOpen
  2632  	}
  2633  
  2634  	n.lists = n.lists[:0]
  2635  	n.vLists = n.vLists[:0]
  2636  
  2637  	n.updateNodeType(ListKind, oneOfTheLists, anID)
  2638  
  2639  	return true
  2640  }
  2641  
  2642  func (n *nodeContext) invalidListLength(na, nb int, a, b Expr) {
  2643  	n.addErr(n.ctx.Newf("incompatible list lengths (%d and %d)", na, nb))
  2644  }