diff --git a/cue/testdata/cycle/builtins.txtar b/cue/testdata/cycle/builtins.txtar index f0c429955..7b494f211 100644 --- a/cue/testdata/cycle/builtins.txtar +++ b/cue/testdata/cycle/builtins.txtar @@ -134,8 +134,6 @@ issue3633: final: { #s: matchN(1, [matchN(1, [{a!: _}])]) } -- cycle.cue -- -import "encoding/yaml" - noCycle: t1: { _s _s: { @@ -169,6 +167,9 @@ issue3649: cycle: t1: { a: matchN(1, [#c]) } } +-- yamlcycle.cue -- +import "encoding/yaml" + yamlNoCycle: { // the validator is invoked recursively and also unifies with a concrete // value. This should nonetheless not result in a cycle error. @@ -189,34 +190,60 @@ selfCycle: t2: { c: matchN(1, [{d: c}]) c: {} } -// TODO: fix hang -// selfCycle: yamlVal: t1: { -// x: y: yaml.Validate(x) -// x: y: "{}" -// } -// selfCycle: yamlVal: t1: { -// x: y: yaml.Validate(x) -// x: y: "{}" -// } -// selfCycle: yamlFun: t1:{ -// x: y?: yaml.Validate("{}", x) -// } -// selfCycle: yamlFun: t2: { -// z: x & __no_sharing -// z: y: "{}" -// x: y: yaml.Validate("{}", x) -// } +selfCycle: yamlVal: t1: { + x: y: yaml.Validate(x) + x: y: "{}" +} +selfCycle: yamlVal: t2: { + // Duplicating validators can cause some tricky code paths, like finalizing + // a node while still in the middle of validation. + x: y: yaml.Validate(x) + x: y: "{}" + x: y: yaml.Validate(x) + x: y: "{}" +} +selfCycle: yamlFun: t1:{ + x: y?: yaml.Validate("{}", x) +} +selfCycle: yamlFun: t2: { + z: x & __no_sharing + z: y: "{}" + x: y: yaml.Validate("{}", x) +} +selfCycle: yamlValidatePartial: { + x: y: yaml.ValidatePartial(x) + x: y: "{}" +} +-- jsoncycle.cue -- +import "encoding/json" + +jsonCycle: t1: { + x: y: json.Validate(x) + x: y: "{}" +} +-- listmatchncycle.cue -- +import "list" + +listMatchN: structCycle: { + x: y: list.MatchN(1, x) + x: y: [{}] +} +listMatchN: ok: { + x: y?: list.MatchN(1, x) + z: x + z: y: [{}] +} -- todo/p1 -- issue3443.noCycle: fix hang -- out/evalalpha/stats -- -Leaks: 351 +Leaks: 410 Freed: 17 Reused: 17 -Allocs: 351 +Allocs: 410 Retain: 0 -Unifications: 310 -Conjuncts: 1216 +Unifications: 368 +Conjuncts: 1497 Disjuncts: 28 -- diff/-out/evalalpha/stats<==>+out/eval/stats -- diff old new @@ -224,66 +251,57 @@ diff old new +++ new @@ -1,9 +1,9 @@ -Leaks: 23 --Freed: 357 --Reused: 345 +-Freed: 414 +-Reused: 402 -Allocs: 35 --Retain: 94 -+Leaks: 351 +-Retain: 95 ++Leaks: 410 +Freed: 17 +Reused: 17 -+Allocs: 351 ++Allocs: 410 +Retain: 0 --Unifications: 352 --Conjuncts: 625 --Disjuncts: 441 -+Unifications: 310 -+Conjuncts: 1216 +-Unifications: 409 +-Conjuncts: 764 +-Disjuncts: 501 ++Unifications: 368 ++Conjuncts: 1497 +Disjuncts: 28 -- out/eval/stats -- Leaks: 23 -Freed: 357 -Reused: 345 +Freed: 414 +Reused: 402 Allocs: 35 -Retain: 94 +Retain: 95 -Unifications: 352 -Conjuncts: 625 -Disjuncts: 441 +Unifications: 409 +Conjuncts: 764 +Disjuncts: 501 -- out/evalalpha -- Errors: noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 noCycle.t1.#x.#x: structural cycle: - ./cycle.cue:6:7 + ./cycle.cue:4:7 noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:33:6 - ./cycle.cue:30:11 - ./cycle.cue:33:13 + ./cycle.cue:31:6 + ./cycle.cue:28:11 + ./cycle.cue:31:13 issue3649.cycle.t1.data.a.a: structural cycle: - ./cycle.cue:33:6 -selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:48:5 -selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:47:20 - ./cycle.cue:48:8 -selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:47:20 - ./cycle.cue:48:8 -selfCycle.t1.c.d.d.d: structural cycle: - ./cycle.cue:47:5 + ./cycle.cue:31:6 +jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle: + ./jsoncycle.cue:4:8 + ./jsoncycle.cue:5:8 +listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1: + ./listmatchncycle.cue:4:8 + ./listmatchncycle.cue:4:20 + ./listmatchncycle.cue:5:8 issue3443.matchIf.#S: cannot call non-function matchIf (type struct): ./matchn.cue:16:7 issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1: @@ -314,6 +332,37 @@ issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matc ./matchn.cue:55:43 issue3443.cycle2.fail.#S.n.n.n: structural cycle: ./matchn.cue:55:13 +selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:15:5 +selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:14:20 + ./yamlcycle.cue:15:8 +selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:14:20 + ./yamlcycle.cue:15:8 +selfCycle.t1.c.d.d.d: structural cycle: + ./yamlcycle.cue:14:5 +selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: + ./yamlcycle.cue:24:8 + ./yamlcycle.cue:25:8 +selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: + ./yamlcycle.cue:30:8 + ./yamlcycle.cue:31:8 + ./yamlcycle.cue:32:8 + ./yamlcycle.cue:33:8 +selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle: + ./yamlcycle.cue:41:8 +selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle: + ./yamlcycle.cue:41:8 +selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle: + ./yamlcycle.cue:44:8 + ./yamlcycle.cue:45:8 Result: (_|_){ @@ -326,18 +375,18 @@ Result: // [eval] #x: (_|_){ // [eval] noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 } } #x: (_|_){ // [eval] noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 // noCycle.t1.#x.#x: structural cycle: - // ./cycle.cue:6:7 + // ./cycle.cue:4:7 } } } @@ -391,11 +440,11 @@ Result: // [eval] a: (_|_){ // [eval] issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:33:6 - // ./cycle.cue:30:11 - // ./cycle.cue:33:13 + // ./cycle.cue:31:6 + // ./cycle.cue:28:11 + // ./cycle.cue:31:13 // issue3649.cycle.t1.data.a.a: structural cycle: - // ./cycle.cue:33:6 + // ./cycle.cue:31:6 b: (string){ "foo" } } b: (string){ string } @@ -410,46 +459,6 @@ Result: } } } - yamlNoCycle: (struct){ - #c: (#struct){ - b?: (string){ string } - a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } - } - data: (#struct){ - a: (string){ "{a: \"b: foo\"}" } - b?: (string){ string } - } - } - selfCycle: (_|_){ - // [eval] - t1: (_|_){ - // [eval] - c: (_|_){ - // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:48:5 - // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:47:20 - // ./cycle.cue:48:8 - // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:47:20 - // ./cycle.cue:48:8 - // selfCycle.t1.c.d.d.d: structural cycle: - // ./cycle.cue:47:5 - d: (struct){ - } - } - } - t2: (struct){ - c: (struct){ - } - } - } builtinCyclePerm0: (struct){ X: (string){ "mod.test" } Y: (struct){ @@ -504,6 +513,48 @@ Result: host: (string){ "mod.test" } } } + jsonCycle: (_|_){ + // [structural cycle] + t1: (_|_){ + // [structural cycle] + x: (_|_){ + // [structural cycle] + y: (_|_){ + // [structural cycle] jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle: + // ./jsoncycle.cue:4:8 + // ./jsoncycle.cue:5:8 + } + } + } + } + listMatchN: (_|_){ + // [eval] + structCycle: (_|_){ + // [eval] + x: (_|_){ + // [eval] + y: (_|_){ + // [eval] listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1: + // ./listmatchncycle.cue:4:8 + // ./listmatchncycle.cue:4:20 + // ./listmatchncycle.cue:5:8 + 0: (struct){ + } + } + } + } + ok: (struct){ + x: (struct){ + y?: (list){ list.MatchN(1, listMatchN.ok.x) } + } + z: (struct){ + y: (#list){ + 0: (struct){ + } + } + } + } + } issue3410: (struct){ _s: (struct){ #x: (_){ matchN(1, (#list){ @@ -659,52 +710,149 @@ Result: }) } } } + yamlNoCycle: (struct){ + #c: (#struct){ + b?: (string){ string } + a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } + } + data: (#struct){ + a: (string){ "{a: \"b: foo\"}" } + b?: (string){ string } + } + } + selfCycle: (_|_){ + // [eval] + t1: (_|_){ + // [eval] + c: (_|_){ + // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:15:5 + // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:14:20 + // ./yamlcycle.cue:15:8 + // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:14:20 + // ./yamlcycle.cue:15:8 + // selfCycle.t1.c.d.d.d: structural cycle: + // ./yamlcycle.cue:14:5 + d: (struct){ + } + } + } + t2: (struct){ + c: (struct){ + } + } + yamlVal: (_|_){ + // [eval] + t1: (_|_){ + // [eval] + x: (_|_){ + // [eval] + y: (_|_){ + // [eval] selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: + // ./yamlcycle.cue:24:8 + // ./yamlcycle.cue:25:8 + } + } + } + t2: (_|_){ + // [eval] + x: (_|_){ + // [eval] + y: (_|_){ + // [eval] selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: + // ./yamlcycle.cue:30:8 + // ./yamlcycle.cue:31:8 + // ./yamlcycle.cue:32:8 + // ./yamlcycle.cue:33:8 + } + } + } + } + yamlFun: (_|_){ + // [eval] + t1: (struct){ + x: (struct){ + y?: (bool){ true } + } + } + t2: (_|_){ + // [eval] + z: (_|_){ + // [eval] + y: (_|_){ + // [eval] selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle: + // ./yamlcycle.cue:41:8 + } + } + x: (_|_){ + // [eval] + y: (_|_){ + // [eval] selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle: + // ./yamlcycle.cue:41:8 + } + } + } + } + yamlValidatePartial: (_|_){ + // [structural cycle] + x: (_|_){ + // [structural cycle] + y: (_|_){ + // [structural cycle] selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle: + // ./yamlcycle.cue:44:8 + // ./yamlcycle.cue:45:8 + } + } + } + } } -- diff/-out/evalalpha<==>+out/eval -- diff old new --- old +++ new -@@ -3,18 +3,18 @@ - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 +@@ -3,24 +3,39 @@ + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 -noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- ./cycle.cue:6:7 -- ./cycle.cue:6:14 -- ./cycle.cue:7:13 +- ./cycle.cue:4:7 +- ./cycle.cue:4:14 +- ./cycle.cue:5:13 +noCycle.t1.#x.#x: structural cycle: -+ ./cycle.cue:6:7 ++ ./cycle.cue:4:7 noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 -noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- ./cycle.cue:6:7 -- ./cycle.cue:6:14 -- ./cycle.cue:7:13 +- ./cycle.cue:4:7 +- ./cycle.cue:4:14 +- ./cycle.cue:5:13 +-jsonCycle.t1.x.y.y: structural cycle: +- ./jsoncycle.cue:4:22 +-listMatchN.structCycle.x.y.y: structural cycle: +- ./listmatchncycle.cue:4:23 +issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1: -+ ./cycle.cue:33:6 -+ ./cycle.cue:30:11 -+ ./cycle.cue:33:13 ++ ./cycle.cue:31:6 ++ ./cycle.cue:28:11 ++ ./cycle.cue:31:13 +issue3649.cycle.t1.data.a.a: structural cycle: -+ ./cycle.cue:33:6 - selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 -@@ -31,18 +31,20 @@ - ./cycle.cue:48:8 - selfCycle.t1.c.d.d.d: structural cycle: - ./cycle.cue:47:5 --selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- ./cycle.cue:53:5 -- ./cycle.cue:53:12 -- ./cycle.cue:54:5 --selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- ./cycle.cue:53:5 -- ./cycle.cue:53:12 -- ./cycle.cue:53:20 --selfCycle.t2.c.d.d: structural cycle: -- ./cycle.cue:53:5 ++ ./cycle.cue:31:6 ++jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle: ++ ./jsoncycle.cue:4:8 ++ ./jsoncycle.cue:5:8 ++listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1: ++ ./listmatchncycle.cue:4:8 ++ ./listmatchncycle.cue:4:20 ++ ./listmatchncycle.cue:5:8 issue3443.matchIf.#S: cannot call non-function matchIf (type struct): ./matchn.cue:16:7 +issue3443.cycle1.cycle.s: invalid value {n:{n:_}} (does not satisfy matchN): 0 matched, expected 1: @@ -722,25 +870,67 @@ diff old new issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1: ./matchn.cue:55:13 ./matchn.cue:55:20 -@@ -74,10 +76,6 @@ - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 +@@ -53,26 +68,21 @@ + ./yamlcycle.cue:15:8 + selfCycle.t1.c.d.d.d: structural cycle: + ./yamlcycle.cue:14:5 +-selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: +- ./yamlcycle.cue:20:5 +- ./yamlcycle.cue:20:12 +- ./yamlcycle.cue:21:5 +-selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: +- ./yamlcycle.cue:20:5 +- ./yamlcycle.cue:20:12 +- ./yamlcycle.cue:20:20 +-selfCycle.t2.c.d.d: structural cycle: +- ./yamlcycle.cue:20:5 +-selfCycle.yamlVal.t1.x.y.y: structural cycle: +- ./yamlcycle.cue:24:22 +-selfCycle.yamlVal.t2.x.y.y: structural cycle: +- ./yamlcycle.cue:32:22 +-selfCycle.yamlFun.t1.x.y.y: structural cycle: +- ./yamlcycle.cue:36:29 +-selfCycle.yamlFun.t2.x.y.y: structural cycle: +- ./yamlcycle.cue:41:28 +-selfCycle.yamlValidatePartial.x.y.y: structural cycle: +- ./yamlcycle.cue:44:29 ++selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: ++ ./yamlcycle.cue:24:8 ++ ./yamlcycle.cue:25:8 ++selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: ++ ./yamlcycle.cue:30:8 ++ ./yamlcycle.cue:31:8 ++ ./yamlcycle.cue:32:8 ++ ./yamlcycle.cue:33:8 ++selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle: ++ ./yamlcycle.cue:41:8 ++selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle: ++ ./yamlcycle.cue:41:8 ++selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle: ++ ./yamlcycle.cue:44:8 ++ ./yamlcycle.cue:45:8 + + Result: + (_|_){ +@@ -88,10 +98,6 @@ + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 - // noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- // ./cycle.cue:6:7 -- // ./cycle.cue:6:14 -- // ./cycle.cue:7:13 +- // ./cycle.cue:4:7 +- // ./cycle.cue:4:14 +- // ./cycle.cue:5:13 } } #x: (_|_){ -@@ -85,26 +83,25 @@ - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 +@@ -99,26 +105,25 @@ + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 - // noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- // ./cycle.cue:6:7 -- // ./cycle.cue:6:14 -- // ./cycle.cue:7:13 +- // ./cycle.cue:4:7 +- // ./cycle.cue:4:14 +- // ./cycle.cue:5:13 - } - } - } @@ -753,7 +943,7 @@ diff old new - b: (string){ "foo" } - } + // noCycle.t1.#x.#x: structural cycle: -+ // ./cycle.cue:6:7 ++ // ./cycle.cue:4:7 + } + } + } @@ -775,7 +965,7 @@ diff old new } }) } } -@@ -111,7 +108,6 @@ +@@ -125,7 +130,6 @@ } t2: (struct){ x: (struct){ @@ -783,7 +973,7 @@ diff old new y: (struct){ a: (struct){ d: (struct){ -@@ -119,14 +115,15 @@ +@@ -133,14 +137,15 @@ } } } @@ -801,7 +991,7 @@ diff old new } }) } } -@@ -133,18 +130,27 @@ +@@ -147,18 +152,27 @@ } } } @@ -820,11 +1010,11 @@ diff old new + // [eval] + a: (_|_){ + // [eval] issue3649.cycle.t1.data.a: invalid value {b:"foo"} (does not satisfy matchN): 0 matched, expected 1: -+ // ./cycle.cue:33:6 -+ // ./cycle.cue:30:11 -+ // ./cycle.cue:33:13 ++ // ./cycle.cue:31:6 ++ // ./cycle.cue:28:11 ++ // ./cycle.cue:31:13 + // issue3649.cycle.t1.data.a.a: structural cycle: -+ // ./cycle.cue:33:6 ++ // ./cycle.cue:31:6 + b: (string){ "foo" } + } + b: (string){ string } @@ -837,39 +1027,40 @@ diff old new } }) } } -@@ -157,8 +163,8 @@ - a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } - } - data: (#struct){ -- b?: (string){ string } - a: (string){ "{a: \"b: foo\"}" } -+ b?: (string){ string } - } - } - selfCycle: (_|_){ -@@ -186,19 +192,8 @@ - } +@@ -224,8 +238,12 @@ + t1: (_|_){ + // [structural cycle] + x: (_|_){ +- // [structural cycle] jsonCycle.t1.x.y.y: structural cycle: +- // ./jsoncycle.cue:4:22 ++ // [structural cycle] ++ y: (_|_){ ++ // [structural cycle] jsonCycle.t1.x.y: invalid value "{}" (does not satisfy encoding/json.Validate): error in call to encoding/json.Validate: structural cycle: ++ // ./jsoncycle.cue:4:8 ++ // ./jsoncycle.cue:5:8 ++ } } } -- t2: (_|_){ -- // [eval] -- c: (_|_){ -- // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- // ./cycle.cue:53:5 -- // ./cycle.cue:53:12 -- // ./cycle.cue:54:5 -- // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: -- // ./cycle.cue:53:5 -- // ./cycle.cue:53:12 -- // ./cycle.cue:53:20 -- // selfCycle.t2.c.d.d: structural cycle: -- // ./cycle.cue:53:5 -+ t2: (struct){ -+ c: (struct){ + } +@@ -234,8 +252,15 @@ + structCycle: (_|_){ + // [eval] + x: (_|_){ +- // [eval] listMatchN.structCycle.x.y.y: structural cycle: +- // ./listmatchncycle.cue:4:23 ++ // [eval] ++ y: (_|_){ ++ // [eval] listMatchN.structCycle.x.y: invalid value [{}] (does not satisfy list.MatchN): number of matched elements is 0: does not satisfy 1: ++ // ./listmatchncycle.cue:4:8 ++ // ./listmatchncycle.cue:4:20 ++ // ./listmatchncycle.cue:5:8 ++ 0: (struct){ ++ } ++ } } } - } -@@ -259,20 +254,20 @@ + ok: (struct){ +@@ -253,20 +278,20 @@ issue3410: (struct){ _s: (struct){ #x: (_){ matchN(1, (#list){ @@ -898,7 +1089,7 @@ diff old new } }) } } -@@ -279,9 +274,9 @@ +@@ -273,9 +298,9 @@ issue3420: (struct){ matches1: (struct){ #S: (_){ matchN(1, (#list){ @@ -911,7 +1102,7 @@ diff old new } }) } s: (int){ 2 } -@@ -298,13 +293,13 @@ +@@ -292,13 +317,13 @@ } noCycle: (struct){ #S: (_){ matchN(1, (#list){ @@ -928,7 +1119,7 @@ diff old new n: (struct){ n: (_){ _ } } -@@ -313,29 +308,43 @@ +@@ -307,29 +332,43 @@ } noCycle2: (struct){ #S: (_){ matchN(1, (#list){ @@ -985,7 +1176,7 @@ diff old new n: (struct){ n: (_){ _ } } -@@ -388,11 +397,11 @@ +@@ -382,11 +421,11 @@ // ./matchn.cue:63:24 } #s: (_){ matchN(1, (#list){ @@ -999,52 +1190,149 @@ diff old new } }) } } +@@ -397,8 +436,8 @@ + a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } + } + data: (#struct){ +- b?: (string){ string } + a: (string){ "{a: \"b: foo\"}" } ++ b?: (string){ string } + } + } + selfCycle: (_|_){ +@@ -426,19 +465,8 @@ + } + } + } +- t2: (_|_){ +- // [eval] +- c: (_|_){ +- // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: +- // ./yamlcycle.cue:20:5 +- // ./yamlcycle.cue:20:12 +- // ./yamlcycle.cue:21:5 +- // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: +- // ./yamlcycle.cue:20:5 +- // ./yamlcycle.cue:20:12 +- // ./yamlcycle.cue:20:20 +- // selfCycle.t2.c.d.d: structural cycle: +- // ./yamlcycle.cue:20:5 ++ t2: (struct){ ++ c: (struct){ + } + } + yamlVal: (_|_){ +@@ -446,25 +474,33 @@ + t1: (_|_){ + // [eval] + x: (_|_){ +- // [eval] selfCycle.yamlVal.t1.x.y.y: structural cycle: +- // ./yamlcycle.cue:24:22 +- } +- } +- t2: (_|_){ +- // [eval] +- x: (_|_){ +- // [eval] selfCycle.yamlVal.t2.x.y.y: structural cycle: +- // ./yamlcycle.cue:32:22 ++ // [eval] ++ y: (_|_){ ++ // [eval] selfCycle.yamlVal.t1.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: ++ // ./yamlcycle.cue:24:8 ++ // ./yamlcycle.cue:25:8 ++ } ++ } ++ } ++ t2: (_|_){ ++ // [eval] ++ x: (_|_){ ++ // [eval] ++ y: (_|_){ ++ // [eval] selfCycle.yamlVal.t2.x.y: invalid value "{}" (does not satisfy encoding/yaml.Validate): error in call to encoding/yaml.Validate: structural cycle: ++ // ./yamlcycle.cue:30:8 ++ // ./yamlcycle.cue:31:8 ++ // ./yamlcycle.cue:32:8 ++ // ./yamlcycle.cue:33:8 ++ } + } + } + } + yamlFun: (_|_){ + // [eval] +- t1: (_|_){ +- // [structural cycle] +- x: (_|_){ +- // [structural cycle] selfCycle.yamlFun.t1.x.y.y: structural cycle: +- // ./yamlcycle.cue:36:29 ++ t1: (struct){ ++ x: (struct){ ++ y?: (bool){ true } + } + } + t2: (_|_){ +@@ -472,13 +508,16 @@ + z: (_|_){ + // [eval] + y: (_|_){ +- // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle: +- // ./yamlcycle.cue:41:28 +- } +- } +- x: (_|_){ +- // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle: +- // ./yamlcycle.cue:41:28 ++ // [eval] selfCycle.yamlFun.t2.z.y: error in call to encoding/yaml.Validate: structural cycle: ++ // ./yamlcycle.cue:41:8 ++ } ++ } ++ x: (_|_){ ++ // [eval] ++ y: (_|_){ ++ // [eval] selfCycle.yamlFun.t2.x.y: error in call to encoding/yaml.Validate: structural cycle: ++ // ./yamlcycle.cue:41:8 ++ } + } + } + } +@@ -485,8 +524,12 @@ + yamlValidatePartial: (_|_){ + // [structural cycle] + x: (_|_){ +- // [structural cycle] selfCycle.yamlValidatePartial.x.y.y: structural cycle: +- // ./yamlcycle.cue:44:29 ++ // [structural cycle] ++ y: (_|_){ ++ // [structural cycle] selfCycle.yamlValidatePartial.x.y: invalid value "{}" (does not satisfy encoding/yaml.ValidatePartial): error in call to encoding/yaml.ValidatePartial: structural cycle: ++ // ./yamlcycle.cue:44:8 ++ // ./yamlcycle.cue:45:8 ++ } + } + } + } -- diff/todo/p2 -- issue3443: Sort out differences in reporting of cycles. -- out/eval -- Errors: noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:6:7 - ./cycle.cue:6:14 - ./cycle.cue:7:13 -selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:48:5 -selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:47:20 - ./cycle.cue:48:8 -selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:47:5 - ./cycle.cue:47:12 - ./cycle.cue:47:20 - ./cycle.cue:48:8 -selfCycle.t1.c.d.d.d: structural cycle: - ./cycle.cue:47:5 -selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:53:5 - ./cycle.cue:53:12 - ./cycle.cue:54:5 -selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - ./cycle.cue:53:5 - ./cycle.cue:53:12 - ./cycle.cue:53:20 -selfCycle.t2.c.d.d: structural cycle: - ./cycle.cue:53:5 + ./cycle.cue:4:7 + ./cycle.cue:4:14 + ./cycle.cue:5:13 +jsonCycle.t1.x.y.y: structural cycle: + ./jsoncycle.cue:4:22 +listMatchN.structCycle.x.y.y: structural cycle: + ./listmatchncycle.cue:4:23 issue3443.matchIf.#S: cannot call non-function matchIf (type struct): ./matchn.cue:16:7 issue3443.cycle2.fail.#S: invalid value {n:{n:{n:_}}} (does not satisfy matchN): 0 matched, expected 1: @@ -1063,6 +1351,42 @@ issue3443.cycle2.fail.#S.n.n: invalid value {n:{n:{n:_}}} (does not satisfy matc ./matchn.cue:55:43 issue3443.cycle2.fail.#S.n.n.n: structural cycle: ./matchn.cue:55:13 +selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:15:5 +selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:14:20 + ./yamlcycle.cue:15:8 +selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:14:5 + ./yamlcycle.cue:14:12 + ./yamlcycle.cue:14:20 + ./yamlcycle.cue:15:8 +selfCycle.t1.c.d.d.d: structural cycle: + ./yamlcycle.cue:14:5 +selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:20:5 + ./yamlcycle.cue:20:12 + ./yamlcycle.cue:21:5 +selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: + ./yamlcycle.cue:20:5 + ./yamlcycle.cue:20:12 + ./yamlcycle.cue:20:20 +selfCycle.t2.c.d.d: structural cycle: + ./yamlcycle.cue:20:5 +selfCycle.yamlVal.t1.x.y.y: structural cycle: + ./yamlcycle.cue:24:22 +selfCycle.yamlVal.t2.x.y.y: structural cycle: + ./yamlcycle.cue:32:22 +selfCycle.yamlFun.t1.x.y.y: structural cycle: + ./yamlcycle.cue:36:29 +selfCycle.yamlFun.t2.x.y.y: structural cycle: + ./yamlcycle.cue:41:28 +selfCycle.yamlValidatePartial.x.y.y: structural cycle: + ./yamlcycle.cue:44:29 Result: (_|_){ @@ -1075,24 +1399,24 @@ Result: // [eval] #x: (_|_){ // [eval] noCycle.t1._s.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 // noCycle.t1._s.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 } } #x: (_|_){ // [eval] noCycle.t1.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 // noCycle.t1.#x.#x: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:6:7 - // ./cycle.cue:6:14 - // ./cycle.cue:7:13 + // ./cycle.cue:4:7 + // ./cycle.cue:4:14 + // ./cycle.cue:5:13 } } } @@ -1155,57 +1479,6 @@ Result: } } } - yamlNoCycle: (struct){ - #c: (#struct){ - b?: (string){ string } - a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } - } - data: (#struct){ - b?: (string){ string } - a: (string){ "{a: \"b: foo\"}" } - } - } - selfCycle: (_|_){ - // [eval] - t1: (_|_){ - // [eval] - c: (_|_){ - // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:48:5 - // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:47:20 - // ./cycle.cue:48:8 - // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:47:5 - // ./cycle.cue:47:12 - // ./cycle.cue:47:20 - // ./cycle.cue:48:8 - // selfCycle.t1.c.d.d.d: structural cycle: - // ./cycle.cue:47:5 - d: (struct){ - } - } - } - t2: (_|_){ - // [eval] - c: (_|_){ - // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:53:5 - // ./cycle.cue:53:12 - // ./cycle.cue:54:5 - // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: - // ./cycle.cue:53:5 - // ./cycle.cue:53:12 - // ./cycle.cue:53:20 - // selfCycle.t2.c.d.d: structural cycle: - // ./cycle.cue:53:5 - } - } - } builtinCyclePerm0: (struct){ X: (string){ "mod.test" } Y: (struct){ @@ -1260,6 +1533,37 @@ Result: host: (string){ "mod.test" } } } + jsonCycle: (_|_){ + // [structural cycle] + t1: (_|_){ + // [structural cycle] + x: (_|_){ + // [structural cycle] jsonCycle.t1.x.y.y: structural cycle: + // ./jsoncycle.cue:4:22 + } + } + } + listMatchN: (_|_){ + // [eval] + structCycle: (_|_){ + // [eval] + x: (_|_){ + // [eval] listMatchN.structCycle.x.y.y: structural cycle: + // ./listmatchncycle.cue:4:23 + } + } + ok: (struct){ + x: (struct){ + y?: (list){ list.MatchN(1, listMatchN.ok.x) } + } + z: (struct){ + y: (#list){ + 0: (struct){ + } + } + } + } + } issue3410: (struct){ _s: (struct){ #x: (_){ matchN(1, (#list){ @@ -1401,6 +1705,105 @@ Result: }) } } } + yamlNoCycle: (struct){ + #c: (#struct){ + b?: (string){ string } + a?: ((string|bytes)){ "encoding/yaml".Validate(yamlNoCycle.#c) } + } + data: (#struct){ + b?: (string){ string } + a: (string){ "{a: \"b: foo\"}" } + } + } + selfCycle: (_|_){ + // [eval] + t1: (_|_){ + // [eval] + c: (_|_){ + // [eval] selfCycle.t1.c: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:15:5 + // selfCycle.t1.c.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:14:20 + // ./yamlcycle.cue:15:8 + // selfCycle.t1.c.d.d: invalid value {d:{}} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:14:5 + // ./yamlcycle.cue:14:12 + // ./yamlcycle.cue:14:20 + // ./yamlcycle.cue:15:8 + // selfCycle.t1.c.d.d.d: structural cycle: + // ./yamlcycle.cue:14:5 + d: (struct){ + } + } + } + t2: (_|_){ + // [eval] + c: (_|_){ + // [eval] selfCycle.t2.c: invalid value {} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:20:5 + // ./yamlcycle.cue:20:12 + // ./yamlcycle.cue:21:5 + // selfCycle.t2.c.d: invalid value {} (does not satisfy matchN): 0 matched, expected 1: + // ./yamlcycle.cue:20:5 + // ./yamlcycle.cue:20:12 + // ./yamlcycle.cue:20:20 + // selfCycle.t2.c.d.d: structural cycle: + // ./yamlcycle.cue:20:5 + } + } + yamlVal: (_|_){ + // [eval] + t1: (_|_){ + // [eval] + x: (_|_){ + // [eval] selfCycle.yamlVal.t1.x.y.y: structural cycle: + // ./yamlcycle.cue:24:22 + } + } + t2: (_|_){ + // [eval] + x: (_|_){ + // [eval] selfCycle.yamlVal.t2.x.y.y: structural cycle: + // ./yamlcycle.cue:32:22 + } + } + } + yamlFun: (_|_){ + // [eval] + t1: (_|_){ + // [structural cycle] + x: (_|_){ + // [structural cycle] selfCycle.yamlFun.t1.x.y.y: structural cycle: + // ./yamlcycle.cue:36:29 + } + } + t2: (_|_){ + // [eval] + z: (_|_){ + // [eval] + y: (_|_){ + // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle: + // ./yamlcycle.cue:41:28 + } + } + x: (_|_){ + // [eval] selfCycle.yamlFun.t2.x.y.y: structural cycle: + // ./yamlcycle.cue:41:28 + } + } + } + yamlValidatePartial: (_|_){ + // [structural cycle] + x: (_|_){ + // [structural cycle] selfCycle.yamlValidatePartial.x.y.y: structural cycle: + // ./yamlcycle.cue:44:29 + } + } + } } -- out/compile -- --- cycle.cue @@ -1478,38 +1881,6 @@ Result: } } } - yamlNoCycle: { - #c: { - b?: string - a?: 〈import;"encoding/yaml"〉.Validate(〈1;#c〉) - } - data: 〈0;#c〉 - data: { - a: "{a: \"b: foo\"}" - } - } - selfCycle: { - t1: { - c: matchN(1, [ - { - d: 〈2;c〉 - }, - ]) - c: { - d: {} - } - } - } - selfCycle: { - t2: { - c: matchN(1, [ - { - d: 〈2;c〉 - }, - ]) - c: {} - } - } } --- in.cue { @@ -1562,6 +1933,47 @@ Result: } } } +--- jsoncycle.cue +{ + jsonCycle: { + t1: { + x: { + y: 〈import;"encoding/json"〉.Validate(〈1;x〉) + } + x: { + y: "{}" + } + } + } +} +--- listmatchncycle.cue +{ + listMatchN: { + structCycle: { + x: { + y: 〈import;list〉.MatchN(1, 〈1;x〉) + } + x: { + y: [ + {}, + ] + } + } + } + listMatchN: { + ok: { + x: { + y?: 〈import;list〉.MatchN(1, 〈1;x〉) + } + z: 〈0;x〉 + z: { + y: [ + {}, + ] + } + } + } +} --- matchn.cue { issue3410: { @@ -1662,3 +2074,100 @@ Result: } } } +--- yamlcycle.cue +{ + yamlNoCycle: { + #c: { + b?: string + a?: 〈import;"encoding/yaml"〉.Validate(〈1;#c〉) + } + data: 〈0;#c〉 + data: { + a: "{a: \"b: foo\"}" + } + } + selfCycle: { + t1: { + c: matchN(1, [ + { + d: 〈2;c〉 + }, + ]) + c: { + d: {} + } + } + } + selfCycle: { + t2: { + c: matchN(1, [ + { + d: 〈2;c〉 + }, + ]) + c: {} + } + } + selfCycle: { + yamlVal: { + t1: { + x: { + y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉) + } + x: { + y: "{}" + } + } + } + } + selfCycle: { + yamlVal: { + t2: { + x: { + y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉) + } + x: { + y: "{}" + } + x: { + y: 〈import;"encoding/yaml"〉.Validate(〈1;x〉) + } + x: { + y: "{}" + } + } + } + } + selfCycle: { + yamlFun: { + t1: { + x: { + y?: 〈import;"encoding/yaml"〉.Validate("{}", 〈1;x〉) + } + } + } + } + selfCycle: { + yamlFun: { + t2: { + z: (〈0;x〉 & _|_(no sharing)) + z: { + y: "{}" + } + x: { + y: 〈import;"encoding/yaml"〉.Validate("{}", 〈1;x〉) + } + } + } + } + selfCycle: { + yamlValidatePartial: { + x: { + y: 〈import;"encoding/yaml"〉.ValidatePartial(〈1;x〉) + } + x: { + y: "{}" + } + } + } +} diff --git a/internal/core/adt/eval_test.go b/internal/core/adt/eval_test.go index 159a4009a..1bf1b6234 100644 --- a/internal/core/adt/eval_test.go +++ b/internal/core/adt/eval_test.go @@ -76,6 +76,7 @@ var needFix = map[string]string{ // counter errors. // TODO: These counters should all go to zero. var skipDebugDepErrors = map[string]int{ + "cycle/builtins": 3, "disjunctions/elimination": 4, "eval/notify": 3, } diff --git a/internal/pkg/context.go b/internal/pkg/context.go index 374903843..ff0315a92 100644 --- a/internal/pkg/context.go +++ b/internal/pkg/context.go @@ -51,8 +51,13 @@ func (c *CallCtxt) Do() bool { } // Schema returns the ith argument as is, without converting it to a cue.Value. +// +// TODO: Schema should use CallContext.Expr to capture cycle information. +// However, this only makes sense if functions also use the same OpContext for +// further evaluation. We should enforce as we port the old calls. func (c *CallCtxt) Schema(i int) Schema { - return value.Make(c.ctx, c.args[i]) + v := c.Expr(i) + return value.Make(c.ctx, v) } // Value returns a finalized cue.Value for the ith argument. diff --git a/pkg/encoding/json/manual.go b/pkg/encoding/json/manual.go index c33d4f0bc..54368c1f5 100644 --- a/pkg/encoding/json/manual.go +++ b/pkg/encoding/json/manual.go @@ -134,6 +134,11 @@ func Unmarshal(b []byte) (ast.Expr, error) { // specified by v. func Validate(b []byte, v pkg.Schema) (bool, error) { c := value.OpContext(v) + return validate(c, b, v) +} + +// validate is the actual implementation of Validate. +func validate(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { if !json.Valid(b) { return false, fmt.Errorf("json: invalid JSON") } diff --git a/pkg/encoding/json/pkg.go b/pkg/encoding/json/pkg.go index 189709db1..a8e6d1d3b 100644 --- a/pkg/encoding/json/pkg.go +++ b/pkg/encoding/json/pkg.go @@ -123,7 +123,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = Validate(b, v) + c.Ret, c.Err = validate(c.OpContext(), b, v) } }, }}, diff --git a/pkg/encoding/json/testdata/gen.txtar b/pkg/encoding/json/testdata/gen.txtar index fac2d77b0..aeba97a14 100644 --- a/pkg/encoding/json/testdata/gen.txtar +++ b/pkg/encoding/json/testdata/gen.txtar @@ -116,7 +116,7 @@ validate: { schema: { a: <3 } - result: _|_ // validate.t2.result: error in call to encoding/json.Validate: validate.t2.schema.a: invalid value 10 (out of bound <3) + result: _|_ // validate.t2.result: error in call to encoding/json.Validate: validate.t2.result.a: invalid value 10 (out of bound <3) } disjunctionRequired: { str: *"{\"a\":10}" | string diff --git a/pkg/encoding/yaml/manual.go b/pkg/encoding/yaml/manual.go index 71d0bd3ae..5bf3db396 100644 --- a/pkg/encoding/yaml/manual.go +++ b/pkg/encoding/yaml/manual.go @@ -20,6 +20,7 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/cue/ast" + "cuelang.org/go/internal/core/adt" cueyaml "cuelang.org/go/internal/encoding/yaml" "cuelang.org/go/internal/pkg" "cuelang.org/go/internal/value" @@ -87,15 +88,31 @@ func UnmarshalStream(data []byte) (ast.Expr, error) { // Validate validates YAML and confirms it is an instance of schema. // If the YAML source is a stream, every object must match v. func Validate(b []byte, v pkg.Schema) (bool, error) { + // This function is left for Go documentation. The package entry calls + // cueyaml.Validate directly, passing it the call context. + ctx := value.OpContext(v) return cueyaml.Validate(ctx, b, v) } +// validate is the actual implementation of Validate. +func validate(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { + return cueyaml.Validate(c, b, v) +} + // ValidatePartial validates YAML and confirms it matches the constraints // specified by v using unification. This means that b must be consistent with, // but does not have to be an instance of v. If the YAML source is a stream, // every object must match v. func ValidatePartial(b []byte, v pkg.Schema) (bool, error) { + // This function is left for Go documentation. The package entry calls + // cueyaml.ValidatePartial directly, passing it the call context. + ctx := value.OpContext(v) return cueyaml.ValidatePartial(ctx, b, v) } + +// validatePartial is the actual implementation of ValidatePartial. +func validatePartial(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { + return cueyaml.ValidatePartial(c, b, v) +} diff --git a/pkg/encoding/yaml/pkg.go b/pkg/encoding/yaml/pkg.go index d1a31f150..4c117d447 100644 --- a/pkg/encoding/yaml/pkg.go +++ b/pkg/encoding/yaml/pkg.go @@ -73,7 +73,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = Validate(b, v) + c.Ret, c.Err = validate(c.OpContext(), b, v) } }, }, { @@ -87,7 +87,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = ValidatePartial(b, v) + c.Ret, c.Err = validatePartial(c.OpContext(), b, v) } }, }}, diff --git a/pkg/encoding/yaml/testdata/gen.txtar b/pkg/encoding/yaml/testdata/gen.txtar index 1843ced0b..f5b1a551c 100644 --- a/pkg/encoding/yaml/testdata/gen.txtar +++ b/pkg/encoding/yaml/testdata/gen.txtar @@ -51,10 +51,10 @@ unmarshalTrailingInput.invalid: error in call to encoding/yaml.Unmarshal: expect ./in.cue:28:11 Result: -t1: _|_ // t1: error in call to encoding/yaml.Validate: a: invalid value 4 (out of bound <3) +t1: _|_ // t1: error in call to encoding/yaml.Validate: t1.a: invalid value 4 (out of bound <3) t2: true -t3: _|_ // t3: error in call to encoding/yaml.Validate: b: incomplete value int -t4: _|_ // t4: error in call to encoding/yaml.ValidatePartial: a: invalid value 4 (out of bound <3) +t3: _|_ // t3: error in call to encoding/yaml.Validate: t3.b: incomplete value int +t4: _|_ // t4: error in call to encoding/yaml.ValidatePartial: t4.a: invalid value 4 (out of bound <3) t5: true t6: true t7: """ diff --git a/pkg/encoding/yaml/testdata/validate.txtar b/pkg/encoding/yaml/testdata/validate.txtar index 918f42827..f21abd615 100644 --- a/pkg/encoding/yaml/testdata/validate.txtar +++ b/pkg/encoding/yaml/testdata/validate.txtar @@ -79,7 +79,7 @@ validate: { // TODO: fix this test: the second disjunct should be eliminated, so there // should not be a concreteness error. t1: { - ok1: _|_ // validate.t1.ok1: invalid value "a: 2" (does not satisfy encoding/yaml.Validate): validate.t1.ok1: error in call to encoding/yaml.Validate: incomplete value {a:2} | {a:2,b!:int} + ok1: _|_ // validate.t1.ok1: invalid value "a: 2" (does not satisfy encoding/yaml.Validate): validate.t1.ok1: error in call to encoding/yaml.Validate: validate.t1.ok1: incomplete value {a:2} | {a:2,b!:int} ok2: "a: 2" ok3: "a: 2" } diff --git a/pkg/gen.go b/pkg/gen.go index ff39d1fd3..d96acab98 100644 --- a/pkg/gen.go +++ b/pkg/gen.go @@ -338,12 +338,17 @@ func (g *generator) genFunc(fn *types.Func) { fmt.Fprintf(g.w, "Name: %q,\n", fn.Name()) + needCallContext := false args := []string{} vals := []string{} kind := []string{} for i := 0; i < params.Len(); i++ { param := params.At(i) - methodName := g.callCtxtGetter(param.Type()) + typ := param.Type() + if typ.String() == "cuelang.org/go/internal/pkg.Schema" { + needCallContext = true + } + methodName := g.callCtxtGetter(typ) argKind := g.adtKind(param.Type()) vals = append(vals, fmt.Sprintf("c.%s(%d)", methodName, len(args))) args = append(args, param.Name()) @@ -368,6 +373,17 @@ func (g *generator) genFunc(fn *types.Func) { init = fmt.Sprintf("%s := %s", argList, valList) } + name := fn.Name() + if needCallContext { + argList = "c.OpContext(), " + argList + + // Main function is used for Godoc documentation. Once we have proper + // CUE function signatures, we can remove these stubs. + // NOTE: this will not work for scripts that are not cased. But this + // is intended to be a temporary situation anyway. + name = strings.ToLower(name[:1]) + name[1:] + } + fmt.Fprintf(g.w, "Func: func(c *pkg.CallCtxt) {") defer fmt.Fprintln(g.w, "},") fmt.Fprintln(g.w) @@ -377,9 +393,9 @@ func (g *generator) genFunc(fn *types.Func) { fmt.Fprintln(g.w, "if c.Do() {") defer fmt.Fprintln(g.w, "}") if results.Len() == 1 { - fmt.Fprintf(g.w, "c.Ret = %s(%s)", fn.Name(), argList) + fmt.Fprintf(g.w, "c.Ret = %s(%s)", name, argList) } else { - fmt.Fprintf(g.w, "c.Ret, c.Err = %s(%s)", fn.Name(), argList) + fmt.Fprintf(g.w, "c.Ret, c.Err = %s(%s)", name, argList) } } diff --git a/pkg/list/list.go b/pkg/list/list.go index 8e7ee79d7..e42162feb 100644 --- a/pkg/list/list.go +++ b/pkg/list/list.go @@ -333,6 +333,11 @@ func Contains(a []cue.Value, v cue.Value) bool { // Likewise, "matchValue" will usually be a non-concrete value. func MatchN(list []cue.Value, n pkg.Schema, matchValue pkg.Schema) (bool, error) { c := value.OpContext(n) + return matchN(c, list, n, matchValue) +} + +// matchN is the actual implementation of MatchN. +func matchN(c *adt.OpContext, list []cue.Value, n pkg.Schema, matchValue pkg.Schema) (bool, error) { var nmatch int64 for _, w := range list { vx := adt.Unify(c, value.Vertex(matchValue), value.Vertex(w)) @@ -342,7 +347,7 @@ func MatchN(list []cue.Value, n pkg.Schema, matchValue pkg.Schema) (bool, error) } } - ctx := value.Context(n) + ctx := value.Context(c) if err := n.Unify(ctx.Encode(nmatch)).Err(); err != nil { return false, pkg.ValidationError{B: &adt.Bottom{ diff --git a/pkg/list/pkg.go b/pkg/list/pkg.go index b58dc3a48..0cc45bf8d 100644 --- a/pkg/list/pkg.go +++ b/pkg/list/pkg.go @@ -167,7 +167,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { list, n, matchValue := c.List(0), c.Schema(1), c.Schema(2) if c.Do() { - c.Ret, c.Err = MatchN(list, n, matchValue) + c.Ret, c.Err = matchN(c.OpContext(), list, n, matchValue) } }, }, {