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