From f5f947e77ec6877e5664168a1e47696f2393b116 Mon Sep 17 00:00:00 2001 From: Marcel van Lohuizen Date: Fri, 4 Oct 2024 11:27:57 +0200 Subject: [PATCH] internal/core/adt: less special handling for non-rooted We know from the cycle algorithm that inline and non-rooted structs/lists should get the same treatment as regular fields. This is a first step in removing their discrepancies. To avoid some test breakages, we had to move where the unification of shared structures was done. This indeed seems to be a more sensible spot. Issue #3476 Issue #2850 Issue #2854 Fixes #3509 Signed-off-by: Marcel van Lohuizen Change-Id: Ic26cb31f207d7be0209d01bad5c6df3130251e2f Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1202269 Unity-Result: CUE porcuepine Reviewed-by: Matthew Sackman TryBot-Result: CUEcueckoo --- cue/testdata/builtins/056_issue314.txtar | 43 ++++++ cue/testdata/builtins/incomplete.txtar | 8 +- cue/testdata/builtins/matchn.txtar | 48 ++++--- cue/testdata/comprehensions/issue837.txtar | 100 ++++++------- cue/testdata/cycle/023_reentrance.txtar | 4 +- cue/testdata/cycle/builtins.txtar | 24 ++-- cue/testdata/cycle/chain.txtar | 20 +-- cue/testdata/cycle/comprehension.txtar | 16 +-- cue/testdata/cycle/constraints.txtar | 155 +++++++++++++++++---- cue/testdata/cycle/evaluate.txtar | 49 ++++--- cue/testdata/cycle/inline.txtar | 77 ++++++---- cue/testdata/cycle/structural.txtar | 12 +- cue/testdata/eval/conjuncts.txtar | 16 +-- cue/testdata/eval/letjoin.txtar | 74 +++++++--- internal/core/adt/eval_test.go | 2 +- internal/core/adt/share.go | 6 - internal/core/adt/tasks.go | 5 - internal/core/adt/unify.go | 15 +- 18 files changed, 443 insertions(+), 231 deletions(-) diff --git a/cue/testdata/builtins/056_issue314.txtar b/cue/testdata/builtins/056_issue314.txtar index 79898276a74..6fb88f05045 100644 --- a/cue/testdata/builtins/056_issue314.txtar +++ b/cue/testdata/builtins/056_issue314.txtar @@ -83,6 +83,49 @@ Retain: 17 Unifications: 45 Conjuncts: 77 Disjuncts: 62 +-- out/evalalpha -- +(struct){ + x: (#struct){ + s: (string){ "myname" } + out: (string){ "myname" } + } + #T: (#struct){ + s: (string){ string } + out: (_|_){ + // [incomplete] #T.out: error in call to text/template.Execute: cannot convert non-concrete value string: + // ./in.cue:14:7 + // ./in.cue:13:2 + } + } + #V: (#struct){ + s: (string){ string } + out: (_|_){ + // [incomplete] cannot convert incomplete value "string" to JSON: + // ./in.cue:20:7 + } + } + #U: (#struct){ + s: (string){ string } + out: (_|_){ + // [incomplete] #U.out: error in call to encoding/yaml.Marshal: incomplete value string: + // ./in.cue:26:7 + // ./in.cue:25:7 + } + } +} +-- diff/-out/evalalpha<==>+out/eval -- +diff old new +--- old ++++ new +@@ -8,7 +8,7 @@ + out: (_|_){ + // [incomplete] #T.out: error in call to text/template.Execute: cannot convert non-concrete value string: + // ./in.cue:14:7 +- // ./in.cue:15:3 ++ // ./in.cue:13:2 + } + } + #V: (#struct){ -- out/eval -- (struct){ x: (#struct){ diff --git a/cue/testdata/builtins/incomplete.txtar b/cue/testdata/builtins/incomplete.txtar index a4298af1895..bc944089857 100644 --- a/cue/testdata/builtins/incomplete.txtar +++ b/cue/testdata/builtins/incomplete.txtar @@ -202,7 +202,7 @@ Result: // ./in.cue:50:17 } max: (_|_){ - // [incomplete] 0: operand param of '+' not concrete (was int): + // [incomplete] incompleteArgDecimalList.#a.transformed: operand param of '+' not concrete (was int): // ./in.cue:50:17 } } @@ -221,7 +221,7 @@ Result: // ./in.cue:58:16 } joined: (_|_){ - // [incomplete] 0: non-concrete value string in operand to +: + // [incomplete] incompleteArgStringList.#a.transformed: non-concrete value string in operand to +: // ./in.cue:59:16 // ./in.cue:58:16 } @@ -307,7 +307,7 @@ diff old new } max: (_|_){ - // [incomplete] incompleteArgDecimalList.#a.0: operand param of '+' not concrete (was int): -+ // [incomplete] 0: operand param of '+' not concrete (was int): ++ // [incomplete] incompleteArgDecimalList.#a.transformed: operand param of '+' not concrete (was int): // ./in.cue:50:17 } } @@ -316,7 +316,7 @@ diff old new } joined: (_|_){ - // [incomplete] incompleteArgStringList.#a.0: non-concrete value string in operand to +: -+ // [incomplete] 0: non-concrete value string in operand to +: ++ // [incomplete] incompleteArgStringList.#a.transformed: non-concrete value string in operand to +: // ./in.cue:59:16 // ./in.cue:58:16 } diff --git a/cue/testdata/builtins/matchn.txtar b/cue/testdata/builtins/matchn.txtar index eed159b72b5..0892e5572d3 100644 --- a/cue/testdata/builtins/matchn.txtar +++ b/cue/testdata/builtins/matchn.txtar @@ -629,10 +629,10 @@ Result: } -- out/evalalpha -- Errors: -match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: ./in.cue:8:17 ./in.cue:8:24 -match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: ./in.cue:12:21 ./in.cue:12:28 match.defaults.pickNested1Err: invalid value {a:*3 | int} (does not satisfy matchN(1, [{a:2}])): 0 matched, expected 1: @@ -641,7 +641,7 @@ match.defaults.pickNested1Err: invalid value {a:*3 | int} (does not satisfy matc match.defaults.pickNested2Err: invalid value {a:*3 | int} (does not satisfy matchN(1, [{a:<=2}])): 0 matched, expected 1: ./in.cue:41:23 ./in.cue:41:30 -not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: +not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [~(#Foo)])): 1 matched, expected 0: ./in.cue:74:17 ./in.cue:74:24 not.doubleErr: invalid value {a:"foo"} (does not satisfy matchN(0, [matchN(0, [#Foo])])): 1 matched, expected 0: @@ -699,7 +699,7 @@ Result: a: (int){ 2 } } singleErr: (_|_){ - // [eval] match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: + // [eval] match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: // ./in.cue:8:17 // ./in.cue:8:24 a: (string){ "foo" } @@ -708,7 +708,7 @@ Result: a: (int){ int } } incompleteErr: (_|_){ - // [eval] match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: + // [eval] match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: // ./in.cue:12:21 // ./in.cue:12:28 a: (string){ string } @@ -782,7 +782,7 @@ Result: a: (string){ "foo" } } singleErr: (_|_){ - // [eval] not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: + // [eval] not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [~(#Foo)])): 1 matched, expected 0: // ./in.cue:74:17 // ./in.cue:74:24 a: (int){ 2 } @@ -1015,12 +1015,15 @@ Result: diff old new --- old +++ new -@@ -2,27 +2,21 @@ - match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +@@ -1,28 +1,22 @@ + Errors: +-match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: ++match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: ./in.cue:8:17 ./in.cue:8:24 - ./in.cue:10:13 - match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +-match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: ++match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: ./in.cue:12:21 ./in.cue:12:28 - ./in.cue:14:17 @@ -1032,7 +1035,8 @@ diff old new ./in.cue:41:23 ./in.cue:41:30 - ./in.cue:44:19 - not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: +-not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: ++not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [~(#Foo)])): 1 matched, expected 0: ./in.cue:74:17 ./in.cue:74:24 - ./in.cue:76:13 @@ -1067,16 +1071,24 @@ diff old new Result: (_|_){ -@@ -83,7 +72,6 @@ - // [eval] match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +@@ -80,10 +69,9 @@ + a: (int){ 2 } + } + singleErr: (_|_){ +- // [eval] match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: ++ // [eval] match.singleErr: invalid value {a:"foo"} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: // ./in.cue:8:17 // ./in.cue:8:24 - // ./in.cue:10:13 a: (string){ "foo" } } incompleteOK: (struct){ -@@ -93,7 +81,6 @@ - // [eval] match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: +@@ -90,10 +78,9 @@ + a: (int){ int } + } + incompleteErr: (_|_){ +- // [eval] match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [{a:int}])): 0 matched, expected 1: ++ // [eval] match.incompleteErr: invalid value {a:string} (does not satisfy matchN(1, [~(#Foo)])): 0 matched, expected 1: // ./in.cue:12:21 // ./in.cue:12:28 - // ./in.cue:14:17 @@ -1108,8 +1120,12 @@ diff old new a: (int){ |(*(int){ 3 }, (int){ int }) } } } -@@ -170,7 +155,6 @@ - // [eval] not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: +@@ -167,10 +152,9 @@ + a: (string){ "foo" } + } + singleErr: (_|_){ +- // [eval] not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [{a:int}])): 1 matched, expected 0: ++ // [eval] not.singleErr: invalid value {a:2} (does not satisfy matchN(0, [~(#Foo)])): 1 matched, expected 0: // ./in.cue:74:17 // ./in.cue:74:24 - // ./in.cue:76:13 diff --git a/cue/testdata/comprehensions/issue837.txtar b/cue/testdata/comprehensions/issue837.txtar index e97f0c19932..fa788ff611c 100644 --- a/cue/testdata/comprehensions/issue837.txtar +++ b/cue/testdata/comprehensions/issue837.txtar @@ -81,8 +81,6 @@ _params.hsize.$_instances: conflicting values 1 and {$_instances:(>=0|*1)} (mism _params.hsize.$_instances: conflicting values >=0 and {$_instances:(>=0|*1)} (mismatched types number and struct): ./in.cue:55:12 ./in.cue:56:15 -#DoDeploy.deployment.description.dep.service.description: undefined field: service: - ./in.cue:5:28 _params.hsize.$_instances.$_instances: field not allowed: ./in.cue:33:20 ./in.cue:56:2 @@ -133,26 +131,29 @@ Result: // [eval] description: (_|_){ // [eval] - let dep#1 = (_|_){ - // [eval] - service: (_|_){ - // [eval] - ref: (#struct){ - kind: (string){ "service" } - } - description: (_|_){ - // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: - // ./in.cue:5:28 - } - } + let dep#1 = (#struct){ + service: ~(#ServiceManifest) hsize: (_|_){ - // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: + // [incomplete] #ServiceManifest.description: undefined field: service: // ./in.cue:5:28 } } service: (_|_){ - // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: - // ./in.cue:5:28 + // [eval] _params.hsize.$_instances: conflicting values 1 and {$_instances:(>=0|*1)} (mismatched types int and struct): + // ./in.cue:55:12 + // ./in.cue:56:22 + // _params.hsize.$_instances: conflicting values >=0 and {$_instances:(>=0|*1)} (mismatched types number and struct): + // ./in.cue:55:12 + // ./in.cue:56:15 + // _params.hsize.$_instances.$_instances: field not allowed: + // ./in.cue:33:20 + // ./in.cue:56:2 + // _params.hsize.$_instances: invalid operands {$_instances:_|_(_params.hsize.$_instances.$_instances: field not allowed)} and 0 to '>=' (type _|_ and int): + // ./in.cue:56:15 + // ./in.cue:56:17 + // _params.hsize.$_instances.$_instances: field not allowed: + // ./in.cue:56:15 + // ./in.cue:56:2 } } } @@ -241,7 +242,7 @@ Result: diff old new --- old +++ new -@@ -1,10 +1,23 @@ +@@ -1,10 +1,21 @@ Errors: -#Configure.service.description.role: undefined field: role: - ./in.cue:40:19 @@ -253,8 +254,6 @@ diff old new +_params.hsize.$_instances: conflicting values >=0 and {$_instances:(>=0|*1)} (mismatched types number and struct): + ./in.cue:55:12 + ./in.cue:56:15 -+#DoDeploy.deployment.description.dep.service.description: undefined field: service: -+ ./in.cue:5:28 +_params.hsize.$_instances.$_instances: field not allowed: + ./in.cue:33:20 + ./in.cue:56:2 @@ -269,7 +268,7 @@ diff old new Result: (_|_){ -@@ -13,24 +26,10 @@ +@@ -13,24 +24,10 @@ ref: (#struct){ kind: (string){ "deployment" } } @@ -296,7 +295,7 @@ diff old new description: (_|_){ // [incomplete] #Manifest.description: unresolved disjunction "service" | "deployment" (type string): // ./in.cue:5:15 -@@ -42,16 +41,10 @@ +@@ -42,16 +39,10 @@ #KindsNames: (string){ |((string){ "service" }, (string){ "deployment" }) } #KumoriKinds: (#struct){ deployment: (#struct){ @@ -317,7 +316,7 @@ diff old new } } } -@@ -58,58 +51,32 @@ +@@ -58,24 +49,7 @@ #DoDeploy: (_|_){ // [eval] _params: (#struct){ @@ -343,9 +342,10 @@ diff old new } deployment: (_|_){ // [eval] +@@ -82,34 +56,28 @@ description: (_|_){ // [eval] -- let dep#1 = (#struct){ + let dep#1 = (#struct){ - service: (#struct){ - ref: (#struct){ - kind: (string){ "service" } @@ -356,15 +356,16 @@ diff old new - } - } - hsize: (#struct){ -- } -- } -- service: (_|_){ ++ service: ~(#ServiceManifest) ++ hsize: (_|_){ ++ // [incomplete] #ServiceManifest.description: undefined field: service: ++ // ./in.cue:5:28 + } + } + service: (_|_){ - // [eval] - description: (_|_){ -+ let dep#1 = (_|_){ -+ // [eval] -+ service: (_|_){ - // [eval] +- // [eval] - let configed#2 = (_|_){ - // [eval] - labstr: (_|_){ @@ -377,26 +378,25 @@ diff old new - // ./in.cue:40:19 - } - } -+ ref: (#struct){ -+ kind: (string){ "service" } -+ } -+ description: (_|_){ -+ // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: -+ // ./in.cue:5:28 -+ } -+ } -+ hsize: (_|_){ -+ // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: -+ // ./in.cue:5:28 -+ } -+ } -+ service: (_|_){ -+ // [eval] #DoDeploy.deployment.description.dep.service.description: undefined field: service: -+ // ./in.cue:5:28 ++ // [eval] _params.hsize.$_instances: conflicting values 1 and {$_instances:(>=0|*1)} (mismatched types int and struct): ++ // ./in.cue:55:12 ++ // ./in.cue:56:22 ++ // _params.hsize.$_instances: conflicting values >=0 and {$_instances:(>=0|*1)} (mismatched types number and struct): ++ // ./in.cue:55:12 ++ // ./in.cue:56:15 ++ // _params.hsize.$_instances.$_instances: field not allowed: ++ // ./in.cue:33:20 ++ // ./in.cue:56:2 ++ // _params.hsize.$_instances: invalid operands {$_instances:_|_(_params.hsize.$_instances.$_instances: field not allowed)} and 0 to '>=' (type _|_ and int): ++ // ./in.cue:56:15 ++ // ./in.cue:56:17 ++ // _params.hsize.$_instances.$_instances: field not allowed: ++ // ./in.cue:56:15 ++ // ./in.cue:56:2 } } } -@@ -125,15 +92,38 @@ +@@ -125,15 +93,38 @@ description: (_|_){ // [eval] let configed#2 = (_|_){ @@ -442,7 +442,7 @@ diff old new } } } -@@ -141,9 +131,7 @@ +@@ -141,9 +132,7 @@ #RelabelService: (_|_){ // [eval] _params: (#struct){ @@ -453,7 +453,7 @@ diff old new } out: (_|_){ // [eval] -@@ -157,16 +145,10 @@ +@@ -157,16 +146,10 @@ $_instances: (number){ |(*(int){ 1 }, (number){ >=0 }) } } #Deployment: (#struct){ diff --git a/cue/testdata/cycle/023_reentrance.txtar b/cue/testdata/cycle/023_reentrance.txtar index 5947824e56a..4398947cc7d 100644 --- a/cue/testdata/cycle/023_reentrance.txtar +++ b/cue/testdata/cycle/023_reentrance.txtar @@ -68,7 +68,7 @@ Allocs: 70 Retain: 0 Unifications: 62 -Conjuncts: 225 +Conjuncts: 212 Disjuncts: 0 -- out/evalalpha -- Errors: @@ -138,7 +138,7 @@ diff old new -Conjuncts: 464 -Disjuncts: 268 +Unifications: 62 -+Conjuncts: 225 ++Conjuncts: 212 +Disjuncts: 0 -- diff/-out/evalalpha<==>+out/eval -- diff old new diff --git a/cue/testdata/cycle/builtins.txtar b/cue/testdata/cycle/builtins.txtar index 3bb10839023..3ff553d5862 100644 --- a/cue/testdata/cycle/builtins.txtar +++ b/cue/testdata/cycle/builtins.txtar @@ -129,14 +129,14 @@ issue3443: { -- todo/p1 -- issue3443.noCycle: fix hang -- out/evalalpha/stats -- -Leaks: 222 +Leaks: 193 Freed: 17 Reused: 17 -Allocs: 222 +Allocs: 193 Retain: 0 -Unifications: 194 -Conjuncts: 760 +Unifications: 167 +Conjuncts: 644 Disjuncts: 28 -- diff/-out/evalalpha/stats<==>+out/eval/stats -- diff old new @@ -148,17 +148,17 @@ diff old new -Reused: 218 -Allocs: 29 -Retain: 65 -+Leaks: 222 ++Leaks: 193 +Freed: 17 +Reused: 17 -+Allocs: 222 ++Allocs: 193 +Retain: 0 -Unifications: 211 -Conjuncts: 389 -Disjuncts: 290 -+Unifications: 194 -+Conjuncts: 760 ++Unifications: 167 ++Conjuncts: 644 +Disjuncts: 28 -- out/eval/stats -- Leaks: 12 @@ -177,7 +177,7 @@ issue3443.matchIf.#S: cannot call non-function matchIf (type struct): issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN(1, [{n:matchN(1, [{n:#S}])}])): 0 matched, expected 1: ./matchn.cue:35:7 ./matchn.cue:35:14 -issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: structural cycle))): 0.n: 0 matched, expected 1))): 0.n: 0 matched, expected 1))): 0 matched, expected 1: +issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, [{n:~(issue3443.cycle2.fail.#S)}])): 0 matched, expected 1: ./matchn.cue:55:13 ./matchn.cue:55:20 @@ -334,7 +334,7 @@ Result: fail: (_|_){ // [eval] #S: (_|_){ - // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: structural cycle))): 0.n: 0 matched, expected 1))): 0.n: 0 matched, expected 1))): 0 matched, expected 1: + // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, [{n:~(issue3443.cycle2.fail.#S)}])): 0 matched, expected 1: // ./matchn.cue:55:13 // ./matchn.cue:55:20 n: (#struct){ @@ -359,7 +359,7 @@ diff old new +issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN(1, [{n:matchN(1, [{n:#S}])}])): 0 matched, expected 1: + ./matchn.cue:35:7 + ./matchn.cue:35:14 -+issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: structural cycle))): 0.n: 0 matched, expected 1))): 0.n: 0 matched, expected 1))): 0 matched, expected 1: ++issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, [{n:~(issue3443.cycle2.fail.#S)}])): 0 matched, expected 1: ./matchn.cue:55:13 ./matchn.cue:55:20 @@ -475,7 +475,7 @@ diff old new // [eval] #S: (_|_){ - // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(issue3443.cycle2.fail.0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(issue3443.cycle2.fail.0.n: structural cycle (and 1 more errors)))): issue3443.cycle2.fail.0.n: 0 matched, expected 1))): 0 matched, expected 1: -+ // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, _|_(0.n: structural cycle))): 0.n: 0 matched, expected 1))): 0.n: 0 matched, expected 1))): 0 matched, expected 1: ++ // [eval] issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN(1, [{n:~(issue3443.cycle2.fail.#S)}])): 0 matched, expected 1: // ./matchn.cue:55:13 // ./matchn.cue:55:20 n: (#struct){ diff --git a/cue/testdata/cycle/chain.txtar b/cue/testdata/cycle/chain.txtar index ef02d66b95a..ff981a6ced7 100644 --- a/cue/testdata/cycle/chain.txtar +++ b/cue/testdata/cycle/chain.txtar @@ -208,15 +208,15 @@ issue2052: full: { d: #Depth & {#in: tree} } -- out/evalalpha/stats -- -Leaks: 20362 +Leaks: 13628 Freed: 1534 Reused: 1533 -Allocs: 20363 +Allocs: 13629 Retain: 0 -Unifications: 7655 -Conjuncts: 109521 -Disjuncts: 13941 +Unifications: 5379 +Conjuncts: 72236 +Disjuncts: 9483 -- out/evalalpha -- Errors: issue2052.t1.#Depth: adding field #basic not allowed as field set was already referenced: @@ -725,18 +725,18 @@ diff old new -Reused: 1816 -Allocs: 70 -Retain: 169 -+Leaks: 20362 ++Leaks: 13628 +Freed: 1534 +Reused: 1533 -+Allocs: 20363 ++Allocs: 13629 +Retain: 0 -Unifications: 801 -Conjuncts: 3177 -Disjuncts: 1979 -+Unifications: 7655 -+Conjuncts: 109521 -+Disjuncts: 13941 ++Unifications: 5379 ++Conjuncts: 72236 ++Disjuncts: 9483 -- diff/-out/evalalpha<==>+out/eval -- diff old new --- old diff --git a/cue/testdata/cycle/comprehension.txtar b/cue/testdata/cycle/comprehension.txtar index 7fdfa17ef0d..e778039b39a 100644 --- a/cue/testdata/cycle/comprehension.txtar +++ b/cue/testdata/cycle/comprehension.txtar @@ -310,14 +310,14 @@ issue2367: { } -- out/evalalpha/stats -- -Leaks: 779 +Leaks: 775 Freed: 63 Reused: 63 -Allocs: 779 +Allocs: 775 Retain: 0 -Unifications: 499 -Conjuncts: 3361 +Unifications: 495 +Conjuncts: 3328 Disjuncts: 196 -- out/evalalpha -- Errors: @@ -913,17 +913,17 @@ diff old new -Reused: 1260 -Allocs: 60 -Retain: 145 -+Leaks: 779 ++Leaks: 775 +Freed: 63 +Reused: 63 -+Allocs: 779 ++Allocs: 775 +Retain: 0 -Unifications: 832 -Conjuncts: 2525 -Disjuncts: 1404 -+Unifications: 499 -+Conjuncts: 3361 ++Unifications: 495 ++Conjuncts: 3328 +Disjuncts: 196 -- out/eval/stats -- Leaks: 50 diff --git a/cue/testdata/cycle/constraints.txtar b/cue/testdata/cycle/constraints.txtar index 6412169f097..c24c5bea302 100644 --- a/cue/testdata/cycle/constraints.txtar +++ b/cue/testdata/cycle/constraints.txtar @@ -172,7 +172,27 @@ cyclicRing: t1: { D: a: T T: b: D } +-- issue3476.cue -- +issue3476: { + #a: (#b & {x: _}).x + #b: { + x?: #c + #c: [string]: #c + } +} +-- issue3509.cue -- +issue3509: { + out: #job.step & "foo" + + #job: (#Workflow & {job: _}).job + + #Workflow: { + job: step: string + #matrixConfig: [...#matrixConfig] | string + matrix?: [string]: [...#matrixConfig] + } +} -- out/compile -- --- in.cue { @@ -463,6 +483,42 @@ cyclicRing: t1: { } } } +--- issue3476.cue +{ + issue3476: { + #a: (〈0;#b〉 & { + x: _ + }).x + #b: { + x?: 〈0;#c〉 + #c: { + [string]: 〈1;#c〉 + } + } + } +} +--- issue3509.cue +{ + issue3509: { + out: (〈0;#job〉.step & "foo") + #job: (〈0;#Workflow〉 & { + job: _ + }).job + #Workflow: { + job: { + step: string + } + #matrixConfig: ([ + ...〈1;#matrixConfig〉, + ]|string) + matrix?: { + [string]: [ + ...〈2;#matrixConfig〉, + ] + } + } + } +} --- ring.cue { brokenRing: { @@ -521,15 +577,15 @@ cyclicRing: t1: { } } -- out/eval/stats -- -Leaks: 0 -Freed: 173 -Reused: 160 +Leaks: 2 +Freed: 193 +Reused: 182 Allocs: 13 -Retain: 8 +Retain: 20 -Unifications: 173 -Conjuncts: 360 -Disjuncts: 181 +Unifications: 193 +Conjuncts: 399 +Disjuncts: 213 -- out/evalalpha -- Errors: cyclicRing.t1.T.b: structural cycle @@ -854,6 +910,31 @@ Result: } } } + issue3476: (struct){ + #a: (#struct){ + } + #b: (#struct){ + x?: (#struct){ + } + #c: (#struct){ + } + } + } + issue3509: (struct){ + out: (string){ "foo" } + #job: (#struct){ + step: (string){ string } + } + #Workflow: (#struct){ + job: (#struct){ + step: (string){ string } + } + #matrixConfig: ((string|list)){ |((list){ + }, (string){ string }) } + matrix?: (#struct){ + } + } + } brokenRing: (struct){ t1: (struct){ p1: (struct){ @@ -1050,19 +1131,22 @@ diff old new } } } -@@ -336,43 +309,31 @@ +@@ -336,7 +309,10 @@ b: (_|_){ // [structural cycle] b: (_|_){ - // [structural cycle] mutuallyTriggeringCycle.t1.x.c.b.b.b.b: structural cycle -- } -- } -- } -- } -- } -- } -- } -- } ++ // [structural cycle] ++ b: (_|_){ ++ // [structural cycle] mutuallyTriggeringCycle.t1.x.c.b.b.b.b.b: structural cycle ++ } + } + } + } +@@ -370,34 +346,19 @@ + } + } + } - brokenRing: (_|_){ - // [structural cycle] - t1: (_|_){ @@ -1091,18 +1175,6 @@ diff old new - // [structural cycle] brokenRing.t1.p2.T.b.a: structural cycle - } - } -+ // [structural cycle] -+ b: (_|_){ -+ // [structural cycle] mutuallyTriggeringCycle.t1.x.c.b.b.b.b.b: structural cycle -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } + brokenRing: (struct){ + t1: (struct){ + p1: (struct){ @@ -1119,7 +1191,7 @@ diff old new } D: (struct){ a?: (_|_){ -@@ -406,12 +367,7 @@ +@@ -431,12 +392,7 @@ // [structural cycle] D: (_|_){ // [structural cycle] @@ -1485,6 +1557,31 @@ Result: } } } + issue3476: (struct){ + #a: (#struct){ + } + #b: (#struct){ + x?: (#struct){ + } + #c: (#struct){ + } + } + } + issue3509: (struct){ + out: (string){ "foo" } + #job: (#struct){ + step: (string){ string } + } + #Workflow: (#struct){ + job: (#struct){ + step: (string){ string } + } + #matrixConfig: ((string|list)){ |((list){ + }, (string){ string }) } + matrix?: (#struct){ + } + } + } brokenRing: (_|_){ // [structural cycle] t1: (_|_){ diff --git a/cue/testdata/cycle/evaluate.txtar b/cue/testdata/cycle/evaluate.txtar index 8d38644601c..6d8444aced6 100644 --- a/cue/testdata/cycle/evaluate.txtar +++ b/cue/testdata/cycle/evaluate.txtar @@ -137,13 +137,13 @@ disjunctionCycle.b: cannot use 1 (type int) as list in argument 1 to and: ./in.cue:56:9 b: structural cycle: ./in.cue:62:6 -d: structural cycle: +closeCycle.c: structural cycle: ./in.cue:73:11 structural cycle: ./in.cue:85:12 -0.0: structural cycle: +listAddCycle.c: structural cycle: ./in.cue:91:5 -0.a.b: structural cycle: +listMulCycle.c: structural cycle: ./in.cue:97:5 closeFail.x.b: field not allowed: ./in.cue:105:6 @@ -249,15 +249,15 @@ Result: closeCycle: (_|_){ // [structural cycle] a: (_|_){ - // [structural cycle] d: structural cycle: + // [structural cycle] closeCycle.c: structural cycle: // ./in.cue:73:11 } b: (_|_){ - // [structural cycle] d: structural cycle: + // [structural cycle] closeCycle.c: structural cycle: // ./in.cue:73:11 } c: (_|_){ - // [structural cycle] d: structural cycle: + // [structural cycle] closeCycle.c: structural cycle: // ./in.cue:73:11 } } @@ -292,30 +292,30 @@ Result: listAddCycle: (_|_){ // [structural cycle] a: (_|_){ - // [structural cycle] 0.0: structural cycle: + // [structural cycle] listAddCycle.c: structural cycle: // ./in.cue:91:5 } b: (_|_){ - // [structural cycle] 0.0: structural cycle: + // [structural cycle] listAddCycle.c: structural cycle: // ./in.cue:91:5 } c: (_|_){ - // [structural cycle] 0.0: structural cycle: + // [structural cycle] listAddCycle.c: structural cycle: // ./in.cue:91:5 } } listMulCycle: (_|_){ // [structural cycle] a: (_|_){ - // [structural cycle] 0.a.b: structural cycle: + // [structural cycle] listMulCycle.c: structural cycle: // ./in.cue:97:5 } b: (_|_){ - // [structural cycle] 0.a.b: structural cycle: + // [structural cycle] listMulCycle.c: structural cycle: // ./in.cue:97:5 } c: (_|_){ - // [structural cycle] 0.a.b: structural cycle: + // [structural cycle] listMulCycle.c: structural cycle: // ./in.cue:97:5 } } @@ -375,7 +375,7 @@ diff old new - ./in.cue:56:9 b: structural cycle: ./in.cue:62:6 --closeCycle.c: structural cycle: + closeCycle.c: structural cycle: - ./in.cue:73:15 -structCycle.c: structural cycle: - ./in.cue:79:14 @@ -383,13 +383,12 @@ diff old new - ./in.cue:85:11 -printCycle.a.X.X: structural cycle: - ./in.cue:113:6 -+d: structural cycle: + ./in.cue:73:11 +structural cycle: + ./in.cue:85:12 -+0.0: structural cycle: ++listAddCycle.c: structural cycle: + ./in.cue:91:5 -+0.a.b: structural cycle: ++listMulCycle.c: structural cycle: + ./in.cue:97:5 +closeFail.x.b: field not allowed: + ./in.cue:105:6 @@ -505,15 +504,15 @@ diff old new - c: (_|_){ - // [structural cycle] closeCycle.c: structural cycle: - // ./in.cue:73:15 -+ // [structural cycle] d: structural cycle: ++ // [structural cycle] closeCycle.c: structural cycle: + // ./in.cue:73:11 + } + b: (_|_){ -+ // [structural cycle] d: structural cycle: ++ // [structural cycle] closeCycle.c: structural cycle: + // ./in.cue:73:11 + } + c: (_|_){ -+ // [structural cycle] d: structural cycle: ++ // [structural cycle] closeCycle.c: structural cycle: + // ./in.cue:73:11 } } @@ -577,15 +576,15 @@ diff old new - } - c: (_|_){ - // [structural cycle] -+ // [structural cycle] 0.0: structural cycle: ++ // [structural cycle] listAddCycle.c: structural cycle: + // ./in.cue:91:5 + } + b: (_|_){ -+ // [structural cycle] 0.0: structural cycle: ++ // [structural cycle] listAddCycle.c: structural cycle: + // ./in.cue:91:5 + } + c: (_|_){ -+ // [structural cycle] 0.0: structural cycle: ++ // [structural cycle] listAddCycle.c: structural cycle: + // ./in.cue:91:5 } } @@ -599,15 +598,15 @@ diff old new - } - c: (_|_){ - // [structural cycle] -+ // [structural cycle] 0.a.b: structural cycle: ++ // [structural cycle] listMulCycle.c: structural cycle: + // ./in.cue:97:5 + } + b: (_|_){ -+ // [structural cycle] 0.a.b: structural cycle: ++ // [structural cycle] listMulCycle.c: structural cycle: + // ./in.cue:97:5 + } + c: (_|_){ -+ // [structural cycle] 0.a.b: structural cycle: ++ // [structural cycle] listMulCycle.c: structural cycle: + // ./in.cue:97:5 } } diff --git a/cue/testdata/cycle/inline.txtar b/cue/testdata/cycle/inline.txtar index 6d897eb79c7..cd0c4eaaff9 100644 --- a/cue/testdata/cycle/inline.txtar +++ b/cue/testdata/cycle/inline.txtar @@ -153,14 +153,14 @@ inline: acrossFields: ok1: { } } -- out/evalalpha/stats -- -Leaks: 92 +Leaks: 113 Freed: 0 Reused: 0 -Allocs: 92 +Allocs: 113 Retain: 0 -Unifications: 88 -Conjuncts: 409 +Unifications: 109 +Conjuncts: 588 Disjuncts: 0 -- diff/-out/evalalpha/stats<==>+out/eval/stats -- diff old new @@ -172,17 +172,17 @@ diff old new -Reused: 136 -Allocs: 252 -Retain: 834 -+Leaks: 92 ++Leaks: 113 +Freed: 0 +Reused: 0 -+Allocs: 92 ++Allocs: 113 +Retain: 0 -Unifications: 388 -Conjuncts: 1307 -Disjuncts: 707 -+Unifications: 88 -+Conjuncts: 409 ++Unifications: 109 ++Conjuncts: 588 +Disjuncts: 0 -- out/eval/stats -- Leaks: 247 @@ -295,6 +295,8 @@ Result: } -- out/evalalpha -- Errors: +inline.acrossFields.fail1.k10: conflicting values 4 and 1: + ./x.cue:30:8 structural cycle: ./x.cue:6:9 structural cycle: @@ -304,15 +306,15 @@ structural cycle: structural cycle: ./x.cue:20:9 in: structural cycle: - ./x.cue:34:17 + ./x.cue:35:17 in: structural cycle: ./x.cue:49:17 Result: (_|_){ - // [structural cycle] + // [eval] inline: (_|_){ - // [structural cycle] + // [eval] small: (_|_){ // [structural cycle] f: (_|_){ @@ -358,9 +360,9 @@ Result: } } acrossFields: (_|_){ - // [structural cycle] + // [eval] fail1: (_|_){ - // [structural cycle] + // [eval] f: (struct){ in: (number){ number } out: (_|_){ @@ -371,16 +373,16 @@ Result: } k00: (int){ 0 } k10: (_|_){ - // [structural cycle] in: structural cycle: - // ./x.cue:34:17 + // [eval] inline.acrossFields.fail1.k10: conflicting values 4 and 1: + // ./x.cue:30:8 } k20: (_|_){ // [structural cycle] in: structural cycle: - // ./x.cue:34:17 + // ./x.cue:35:17 } k30: (_|_){ // [structural cycle] in: structural cycle: - // ./x.cue:34:17 + // ./x.cue:35:17 } } ok1: (_|_){ @@ -410,7 +412,10 @@ Result: diff old new --- old +++ new -@@ -2,11 +2,15 @@ +@@ -1,18 +1,24 @@ + Errors: ++inline.acrossFields.fail1.k10: conflicting values 4 and 1: ++ ./x.cue:30:8 structural cycle: ./x.cue:6:9 structural cycle: @@ -421,13 +426,21 @@ diff old new ./x.cue:20:9 in: structural cycle: - ./x.cue:30:8 -+ ./x.cue:34:17 ++ ./x.cue:35:17 +in: structural cycle: + ./x.cue:49:17 Result: (_|_){ -@@ -28,7 +32,7 @@ +- // [structural cycle] ++ // [eval] + inline: (_|_){ +- // [structural cycle] ++ // [eval] + small: (_|_){ + // [structural cycle] + f: (_|_){ +@@ -28,7 +34,7 @@ // [structural cycle] f2: (_|_){ // [structural cycle] structural cycle: @@ -436,10 +449,23 @@ diff old new } fRec: (_|_){ // [structural cycle] -@@ -72,26 +76,36 @@ +@@ -58,9 +64,9 @@ + } + } + acrossFields: (_|_){ +- // [structural cycle] ++ // [eval] + fail1: (_|_){ +- // [structural cycle] ++ // [eval] + f: (struct){ + in: (number){ number } + out: (_|_){ +@@ -71,27 +77,37 @@ + } k00: (int){ 0 } k10: (_|_){ - // [structural cycle] in: structural cycle: +- // [structural cycle] in: structural cycle: - // ./x.cue:30:8 - } - k20: (_|_){ @@ -452,15 +478,16 @@ diff old new - } - } - ok1: (struct){ -+ // ./x.cue:34:17 ++ // [eval] inline.acrossFields.fail1.k10: conflicting values 4 and 1: ++ // ./x.cue:30:8 + } + k20: (_|_){ + // [structural cycle] in: structural cycle: -+ // ./x.cue:34:17 ++ // ./x.cue:35:17 + } + k30: (_|_){ + // [structural cycle] in: structural cycle: -+ // ./x.cue:34:17 ++ // ./x.cue:35:17 + } + } + ok1: (_|_){ diff --git a/cue/testdata/cycle/structural.txtar b/cue/testdata/cycle/structural.txtar index def5b4ec5b5..16cc0a120c4 100644 --- a/cue/testdata/cycle/structural.txtar +++ b/cue/testdata/cycle/structural.txtar @@ -621,7 +621,7 @@ b7.b.0.0: conflicting values 1 and [a] (mismatched types int and list): b7.b.0.0.0: structural cycle c1.a.c: structural cycle d1.r: structural cycle -d3.x.indirect: structural cycle +d3.x.0: structural cycle e1.a.c: structural cycle e1.b.c: structural cycle e2.a.c: structural cycle @@ -1261,12 +1261,12 @@ Result: b: (_|_){ // [structural cycle] c: (_|_){ - // [structural cycle] d3.x.indirect: structural cycle + // [structural cycle] d3.x.0: structural cycle } } } indirect: (_|_){ - // [structural cycle] d3.x.indirect: structural cycle + // [structural cycle] d3.x.0: structural cycle } } } @@ -1781,7 +1781,7 @@ diff old new +b7.b.0.0.0: structural cycle +c1.a.c: structural cycle +d1.r: structural cycle -+d3.x.indirect: structural cycle ++d3.x.0: structural cycle e1.a.c: structural cycle e1.b.c: structural cycle e2.a.c: structural cycle @@ -2143,7 +2143,7 @@ diff old new // [structural cycle] c: (_|_){ - // [structural cycle] d3.x.a.b.c: structural cycle -+ // [structural cycle] d3.x.indirect: structural cycle ++ // [structural cycle] d3.x.0: structural cycle } } } @@ -2152,7 +2152,7 @@ diff old new - // ./in.cue:316:12 - } - i: (int){ 0 } -+ // [structural cycle] d3.x.indirect: structural cycle ++ // [structural cycle] d3.x.0: structural cycle + } } } diff --git a/cue/testdata/eval/conjuncts.txtar b/cue/testdata/eval/conjuncts.txtar index 7709c1f3780..7d712502230 100644 --- a/cue/testdata/eval/conjuncts.txtar +++ b/cue/testdata/eval/conjuncts.txtar @@ -69,14 +69,14 @@ issue2355: { } -- out/evalalpha/stats -- -Leaks: 235 +Leaks: 234 Freed: 42 Reused: 42 -Allocs: 235 +Allocs: 234 Retain: 0 -Unifications: 47 -Conjuncts: 436 +Unifications: 46 +Conjuncts: 430 Disjuncts: 184 -- out/evalalpha -- Errors: @@ -163,17 +163,17 @@ diff old new -Reused: 59 -Allocs: 18 -Retain: 22 -+Leaks: 235 ++Leaks: 234 +Freed: 42 +Reused: 42 -+Allocs: 235 ++Allocs: 234 +Retain: 0 -Unifications: 45 -Conjuncts: 135 -Disjuncts: 86 -+Unifications: 47 -+Conjuncts: 436 ++Unifications: 46 ++Conjuncts: 430 +Disjuncts: 184 -- diff/-out/evalalpha<==>+out/eval -- diff old new diff --git a/cue/testdata/eval/letjoin.txtar b/cue/testdata/eval/letjoin.txtar index 4c65a3c14e2..82763ea37e7 100644 --- a/cue/testdata/eval/letjoin.txtar +++ b/cue/testdata/eval/letjoin.txtar @@ -113,9 +113,7 @@ Disjuncts: 69 } y: (struct){ let X#2 = (struct){ - b: (struct){ - q: (int){ 1 } - } + b: ~(t2.x1.a) c: (int){ 1 } } v: (int){ 1 } @@ -127,9 +125,7 @@ Disjuncts: 69 } y: (struct){ let X#2 = (struct){ - b: (struct){ - r: (int){ 2 } - } + b: ~(t2.x2.a) c: (int){ 1 } } v: (int){ 1 } @@ -142,10 +138,7 @@ Disjuncts: 69 } y: (struct){ let X#2 = (struct){ - b: (struct){ - q: (int){ 1 } - r: (int){ 2 } - } + b: ~(t2.xy.a) c: (int){ 1 } } v: (int){ 1 } @@ -157,18 +150,67 @@ Disjuncts: 69 diff old new --- old +++ new -@@ -85,9 +85,12 @@ - r: (int){ 2 } +@@ -57,37 +57,33 @@ } y: (struct){ + let X#2 = (struct){ +- b: (struct){ +- q: (int){ 1 } +- } +- c: (int){ 1 } +- } +- v: (int){ 1 } +- } +- } +- x2: (struct){ +- a: (struct){ +- r: (int){ 2 } +- } +- y: (struct){ +- let X#2 = (struct){ +- b: (struct){ +- r: (int){ 2 } +- } +- c: (int){ 1 } +- } +- v: (int){ 1 } +- } +- } +- xy: (struct){ +- a: (struct){ +- q: (int){ 1 } +- r: (int){ 2 } +- } +- y: (struct){ - let X#2multi = { - b: 〈2;a〉 - c: 1 ++ b: ~(t2.x1.a) ++ c: (int){ 1 } ++ } ++ v: (int){ 1 } ++ } ++ } ++ x2: (struct){ ++ a: (struct){ ++ r: (int){ 2 } ++ } ++ y: (struct){ ++ let X#2 = (struct){ ++ b: ~(t2.x2.a) ++ c: (int){ 1 } ++ } ++ v: (int){ 1 } ++ } ++ } ++ xy: (struct){ ++ a: (struct){ ++ q: (int){ 1 } ++ r: (int){ 2 } ++ } ++ y: (struct){ + let X#2 = (struct){ -+ b: (struct){ -+ q: (int){ 1 } -+ r: (int){ 2 } -+ } ++ b: ~(t2.xy.a) + c: (int){ 1 } } v: (int){ 1 } diff --git a/internal/core/adt/eval_test.go b/internal/core/adt/eval_test.go index d456e2e9292..9d9675562db 100644 --- a/internal/core/adt/eval_test.go +++ b/internal/core/adt/eval_test.go @@ -83,7 +83,7 @@ var skipDebugDepErrors = map[string]int{ "cycle/comprehension": 3, "cycle/disjunction": 4, "cycle/issue990": 2, - "cycle/structural": 18, + "cycle/structural": 17, "disjunctions/edge": 1, "disjunctions/elimination": 8, "disjunctions/embed": 6, diff --git a/internal/core/adt/share.go b/internal/core/adt/share.go index b8937751945..be17d3bf23c 100644 --- a/internal/core/adt/share.go +++ b/internal/core/adt/share.go @@ -144,12 +144,6 @@ func (n *nodeContext) shareIfPossible(c Conjunct, arc *Vertex, id CloseInfo) boo return false } - // If an arc is a computed intermediate result and not part of a CUE output, - // it should not be shared. - if n.node.nonRooted || arc.nonRooted { - return false - } - n.share(c, arc, id) return true } diff --git a/internal/core/adt/tasks.go b/internal/core/adt/tasks.go index 85433f6907a..6ba81cc0e6d 100644 --- a/internal/core/adt/tasks.go +++ b/internal/core/adt/tasks.go @@ -126,11 +126,6 @@ func processResolver(ctx *OpContext, t *task, mode runMode) { return } - if arc.nonRooted { - if arc.status == finalized { - ci.Refs = nil - } - } c := MakeConjunct(t.env, t.x, ci) t.node.scheduleVertexConjuncts(c, arc, ci) } diff --git a/internal/core/adt/unify.go b/internal/core/adt/unify.go index 4751a2ce354..1ad3ef050be 100644 --- a/internal/core/adt/unify.go +++ b/internal/core/adt/unify.go @@ -210,6 +210,12 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { } } + if v, ok := n.node.BaseValue.(*Vertex); ok && n.sharedID.CycleType == NoCycle { + // We unify here to proactively detect cycles. We do not need to, + // nor should we, if have have already found one. + v.unify(n.ctx, needs, mode) + } + // At this point, no more conjuncts will be added, so we could decrement // the notification counters. @@ -282,13 +288,6 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { v.ChildErrors = nil v.Arcs = nil - result := true - if n.isShared && n.sharedID.CycleType == NoCycle { - // We unify here to proactively detect cycles. We do not need to, - // nor should we, if have have already found one. - result = w.unify(c, needs, mode) - } - // Set control fields that are referenced without dereferencing. if w.Closed { v.Closed = true @@ -298,7 +297,7 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { } v.status = w.status - return result + return true } // TODO: adding this is wrong, but it should not cause the snippet below