@@ -167,10 +167,9 @@ func (e *Unifier) evaluate(c *OpContext, v *Vertex, state VertexStatus) Value {
167
167
Conjuncts : v .Conjuncts ,
168
168
}
169
169
w .UpdateStatus (v .Status ())
170
- return w
170
+ v = w
171
171
}
172
172
}
173
- return x
174
173
175
174
case nil :
176
175
if v .state != nil {
@@ -186,6 +185,10 @@ func (e *Unifier) evaluate(c *OpContext, v *Vertex, state VertexStatus) Value {
186
185
panic ("nil value" )
187
186
}
188
187
188
+ if v .status < Finalized && v .state != nil {
189
+ v .state .addNotify (c .vertex )
190
+ }
191
+
189
192
return v
190
193
}
191
194
@@ -274,6 +277,8 @@ func (e *Unifier) Unify(c *OpContext, v *Vertex, state VertexStatus) {
274
277
for n .maybeSetCache (); n .expandOne (); n .maybeSetCache () {
275
278
}
276
279
280
+ n .doNotify ()
281
+
277
282
if ! n .done () {
278
283
if len (n .disjunctions ) > 0 && v .BaseValue == cycle {
279
284
// We disallow entering computations of disjunctions with
@@ -372,6 +377,23 @@ func (e *Unifier) Unify(c *OpContext, v *Vertex, state VertexStatus) {
372
377
}
373
378
}
374
379
380
+ func (n * nodeContext ) doNotify () {
381
+ if n .errs != nil && len (n .notify ) > 0 {
382
+ for _ , v := range n .notify {
383
+ if v .state == nil {
384
+ if b , ok := v .BaseValue .(* Bottom ); ok {
385
+ v .BaseValue = CombineErrors (nil , b , n .errs )
386
+ } else {
387
+ v .BaseValue = n .errs
388
+ }
389
+ } else {
390
+ v .state .addBottom (n .errs )
391
+ }
392
+ }
393
+ n .notify = n .notify [:0 ]
394
+ }
395
+ }
396
+
375
397
func isStruct (v * Vertex ) bool {
376
398
_ , ok := v .BaseValue .(* StructMarker )
377
399
return ok
@@ -647,6 +669,10 @@ type nodeContext struct {
647
669
checks []Validator // BuiltinValidator, other bound values.
648
670
errs * Bottom
649
671
672
+ // notify is used to communicate errors in cyclic dependencies.
673
+ // TODO: also use this to communicate increasingly more concrete values.
674
+ notify []* Vertex
675
+
650
676
// Struct information
651
677
dynamicFields []envDynamic
652
678
ifClauses []envYield
@@ -671,6 +697,12 @@ type nodeContext struct {
671
697
disjunctErrs []* Bottom
672
698
}
673
699
700
+ func (n * nodeContext ) addNotify (v * Vertex ) {
701
+ if v != nil {
702
+ n .notify = append (n .notify , v )
703
+ }
704
+ }
705
+
674
706
func (n * nodeContext ) clone () * nodeContext {
675
707
d := n .ctx .Unifier .newNodeContext (n .ctx , n .node )
676
708
@@ -696,6 +728,7 @@ func (n *nodeContext) clone() *nodeContext {
696
728
d .hasNonCycle = n .hasNonCycle
697
729
698
730
// d.arcMap = append(d.arcMap, n.arcMap...) // XXX add?
731
+ d .notify = append (d .notify , n .notify ... )
699
732
d .checks = append (d .checks , n .checks ... )
700
733
d .dynamicFields = append (d .dynamicFields , n .dynamicFields ... )
701
734
d .ifClauses = append (d .ifClauses , n .ifClauses ... )
0 commit comments