Skip to content

Commit 5c06b58

Browse files
committed
internal/core/adt: ensure shared nodes are evaluated as per request
CL https://cuelang.org/cl/1211563 prevented values from finalizing when finalization was not requested. This prevented premature evaluation, but, as it turned out, it was too aggressive and could lead values to be less evaluated than was requested by the call to unify. This ensures evaluation is started for shared values. Issue #3835 Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: I59199e268cd2a3dd71d5ca5f915411050c9d3021 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1211930 TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Daniel Martí <[email protected]>
1 parent 5aea31b commit 5c06b58

File tree

2 files changed

+17
-21
lines changed

2 files changed

+17
-21
lines changed

cue/testdata/eval/sharing.txtar

+2-17
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,7 @@ Result:
412412
}
413413
issue3835: (struct){
414414
foo: (struct){
415-
out: (_|_){
416-
// [cycle] issue3835.foo.out: cycle with field: orgBotUser:
417-
// ./issue3835.cue:8:22
418-
}
415+
out: (string){ "prefix: global value" }
419416
}
420417
_global: (string){ "global value" }
421418
}
@@ -704,19 +701,7 @@ diff old new
704701
b: (struct){
705702
c: (int){ 1 }
706703
}
707-
@@ -283,7 +237,10 @@
708-
}
709-
issue3835: (struct){
710-
foo: (struct){
711-
- out: (string){ "prefix: global value" }
712-
+ out: (_|_){
713-
+ // [cycle] issue3835.foo.out: cycle with field: orgBotUser:
714-
+ // ./issue3835.cue:8:22
715-
+ }
716-
}
717-
_global: (string){ "global value" }
718-
}
719-
@@ -312,7 +269,7 @@
704+
@@ -312,7 +266,7 @@
720705
// [eval] shareCycle.t2.Y.x: conflicting values int and {x:(#X & Y)} (mismatched types int and struct):
721706
// ./sharecycle.cue:8:6
722707
// ./sharecycle.cue:9:5

internal/core/adt/unify.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -348,17 +348,23 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode, checkTypos b
348348

349349
n.finalizeDisjunctions()
350350

351-
if n.completed&(subFieldsProcessed) == 0 {
352-
return false
353-
}
354-
355351
w = v.DerefValue() // Dereference anything, including shared nodes.
356352
if w != v {
357353
// Clear value fields that are now referred to in the dereferenced
358354
// value (w).
359355
v.ChildErrors = nil
360356
v.Arcs = nil
361357

358+
if n.completed&(subFieldsProcessed) == 0 {
359+
// Ensure the shared node is processed to the requested level. This is
360+
// typically needed for scalar values.
361+
if w.status == unprocessed {
362+
w.unify(c, needs, mode, false)
363+
}
364+
365+
return n.meets(needs)
366+
}
367+
362368
// Set control fields that are referenced without dereferencing.
363369
if w.ClosedRecursive {
364370
v.ClosedRecursive = true
@@ -368,6 +374,7 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode, checkTypos b
368374
if w.HasEllipsis {
369375
v.HasEllipsis = true
370376
}
377+
371378
v.status = w.status
372379

373380
n.finalizeSharing()
@@ -386,6 +393,10 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode, checkTypos b
386393
return true
387394
}
388395

396+
if n.completed&(subFieldsProcessed) == 0 {
397+
return n.meets(needs)
398+
}
399+
389400
// TODO: adding this is wrong, but it should not cause the snippet below
390401
// to hang. Investigate.
391402
// v.Closed = v.cc.isClosed

0 commit comments

Comments
 (0)