-- in.cue -- self: { // This is an incomplete error, as it may succeed when the user // explicitly specifies a value for fail.a.b. fail: { a: { if a.b == _|_ { b: 1 } } } // This is an incomplete error, as it may succeed when the user // explicitly specifies a value for a.b. isConcreteFail: { a: { if a.b == _|_ { b: 1 } b: int } } // This is an incomplete error, as it may succeed when the user // explicitly specifies a value for a.b. // TODO: new builtin semantics. // if isconcrete(a.b) -->> cyclic error evaluating isconcrete. // if isdefined(a.b) -->> evaluate to true as a.b is int, result is 1 // if !isdefined(a.b) -->> evaluate to false, a.b remains int isNotConcrete: { a: { if a.b != _|_ { b: 1 } b: int } } } -- mutual.cue -- mutual: { noConflicts: { a: {if b.foo == _|_ {new: ""}} b: {if a.bar == _|_ {new: ""}} } mutualCycleFail: { b: {if a.bar == _|_ {foo: ""}} a: {if b.foo == _|_ {bar: ""}} } brokenCycleSuccess: { a: { if b.foo == _|_ { foo: "" } } b: { if a.bar == _|_ { bar: "" } } a: bar: "" } allowOneDirectionalDependency: { p1: { a: { if b.foo == _|_ { bar: "" } } // added b: { if a.bar == _|_ { new: "" } } // not added } p2: { a: { if b.foo == _|_ { new: "" } } b: { if a.bar == _|_ { foo: "" } } } } oneDirectionalBrokenConflictSuccess: p1: { b: foo: "" a: { if b.foo == _|_ { bar: "" } } b: { if a.bar == _|_ { new: "" } } } oneDirectionalBrokenConflictSuccess: p2: { a: { if b.foo == _|_ { bar: "" } } b: foo: "" b: { if a.bar == _|_ { new: "" } } } oneDirectionalBrokenConflictSuccess: p3: { a: { if b.foo == _|_ { bar: "" } } b: { if a.bar == _|_ { new: "" } } b: foo: "" } oneDirectionalBrokenConflictSuccess: p4: { b: foo: "" b: { if a.bar == _|_ { new: "" } } a: { if b.foo == _|_ { bar: "" } } } oneDirectionalBrokenConflictSuccess: p5: { b: { if a.bar == _|_ { new: "" } } b: foo: "" a: { if b.foo == _|_ { bar: "" } } } oneDirectionalBrokenConflictSuccess: p6: { b: { if a.bar == _|_ { new: "" } } a: { if b.foo == _|_ { bar: "" } } b: foo: "" } } -- mutualsamestruct.cue -- sameStruct: { chainSuccess: a: { raises?: {} if raises == _|_ { ret: a: 1 } ret?: {} if ret != _|_ { foo: a: 1 } } chainSuccess: b: { if ret != _|_ { foo: a: 1 } raises?: {} if raises == _|_ { ret: a: 1 } ret?: {} } cycleFail: t1: p1: { raises?: {} if raises == _|_ { ret: a: 1 } ret?: {} if ret != _|_ { raises: a: 1 } } cycleFail: t1: p2: { ret?: {} if ret != _|_ { raises: a: 1 } raises?: {} if raises == _|_ { ret: a: 1 } } // This test should fail with a cycle error. Even though raises and ret are // both known to be defined, comparison against bottom requires that the // structs be recursively checked for errors. We disallow that here, because // the structs mutually depend on each other. // TODO: consider allowing a specific postCheck for determining if an arc // is erroneous. cycleFail: t2: p1: { raises: {} if raises == _|_ { ret: a: 1 } ret: {} if ret != _|_ { raises: a: 1 } } // Same as above test, but different order. It may be that the specific // fields that are added are different for the two cases. This is fine as // long as the parent fails, as that error is ultimately what represents // the value as a whole. cycleFail: t2: p2: { ret: {} if ret != _|_ { raises: a: 1 } raises: {} if raises == _|_ { ret: a: 1 } } // This test should fail similarly to the above tests. The fields ret and // raises are not concrete, but may still become a struct and thus need // to be recursively checked. cycleFail: t3: p1: { raises: _ if raises == _|_ { ret: a: 1 } ret: _ if ret != _|_ { raises: a: 1 } } cycleFail: t3: p2: { ret: _ if ret != _|_ { raises: a: 1 } raises: _ if raises == _|_ { ret: a: 1 } } defCloseSuccess: { #Example: { raises?: { runtime?: string } if raises == _|_ { ret?: _ } } expr: #Example & { ret: 2 } } } -- nestedchain.cue -- // Issue nestedChain: { cycleFail: { if #E.x != _|_ { #E: y: true } if #E.y == _|_ { #E: x: true } #E: [_]: bool } brokenCycleSuccess: { if #E.x != _|_ { #E: y: true } if #E.y == _|_ { #E: x: true } #E: [_]: bool #E: x: true } doubleAddfail: { if #E.x == _|_ { #E: y: true } if #E.y == _|_ { #E: x: true } #E: [_]: bool } trippleSuccess: { if #E.x != _|_ { #E: y: true } if #E.y != _|_ { z: true } #E: x: true } } -- out/eval/stats -- Leaks: 3 Freed: 141 Reused: 132 Allocs: 12 Retain: 66 Unifications: 144 Conjuncts: 159 Disjuncts: 186 -- out/eval -- (struct){ self: (struct){ fail: (struct){ a: (_|_){ // [cycle] self.fail.a: cycle with field a.b: // ./in.cue:6:7 } } isConcreteFail: (struct){ a: (_|_){ // [cycle] cycle error b: (_|_){ // [cycle] cycle error } } } isNotConcrete: (struct){ a: (_|_){ // [cycle] cycle error b: (_|_){ // [cycle] cycle error } } } } mutual: (struct){ noConflicts: (struct){ a: (struct){ new: (string){ "" } } b: (struct){ new: (string){ "" } } } mutualCycleFail: (struct){ b: (_|_){ // [cycle] mutual.mutualCycleFail.a: cycle with field b.foo: // ./mutual.cue:9:10 foo: (string){ "" } } a: (struct){ bar: (_|_){ // [cycle] mutual.mutualCycleFail.a: cycle with field b.foo: // ./mutual.cue:9:10 } } } brokenCycleSuccess: (struct){ a: (struct){ foo: (string){ "" } bar: (string){ "" } } b: (struct){ } } allowOneDirectionalDependency: (struct){ p1: (struct){ a: (struct){ bar: (string){ "" } } b: (struct){ } } p2: (struct){ a: (struct){ } b: (struct){ foo: (string){ "" } } } } oneDirectionalBrokenConflictSuccess: (struct){ p1: (struct){ b: (struct){ foo: (string){ "" } new: (string){ "" } } a: (struct){ } } p2: (struct){ a: (struct){ } b: (struct){ foo: (string){ "" } new: (string){ "" } } } p3: (struct){ a: (struct){ } b: (struct){ new: (string){ "" } foo: (string){ "" } } } p4: (struct){ b: (struct){ foo: (string){ "" } new: (string){ "" } } a: (struct){ } } p5: (struct){ b: (struct){ new: (string){ "" } foo: (string){ "" } } a: (struct){ } } p6: (struct){ b: (struct){ new: (string){ "" } foo: (string){ "" } } a: (struct){ } } } } sameStruct: (struct){ chainSuccess: (struct){ a: (struct){ ret: (struct){ a: (int){ 1 } } foo: (struct){ a: (int){ 1 } } } b: (struct){ foo: (struct){ a: (int){ 1 } } ret: (struct){ a: (int){ 1 } } } } cycleFail: (struct){ t1: (struct){ p1: (_|_){ // [cycle] sameStruct.cycleFail.t1.p1: circular dependency in evaluation of conditionals: ret changed after evaluation: // ./mutualsamestruct.cue:30:6 ret: (struct){ a: (int){ 1 } } } p2: (_|_){ // [cycle] sameStruct.cycleFail.t1.p2: circular dependency in evaluation of conditionals: raises changed after evaluation: // ./mutualsamestruct.cue:41:6 raises: (struct){ a: (int){ 1 } } ret: (struct){ a: (int){ 1 } } } } t2: (struct){ p1: (_|_){ // [cycle] sameStruct.cycleFail.t2.p1: circular dependency in evaluation of conditionals: ret changed after evaluation: // ./mutualsamestruct.cue:58:6 ret: (struct){ } raises: (struct){ } } p2: (_|_){ // [cycle] sameStruct.cycleFail.t2.p2: circular dependency in evaluation of conditionals: raises changed after evaluation: // ./mutualsamestruct.cue:73:6 raises: (struct){ a: (int){ 1 } } ret: (struct){ a: (int){ 1 } } } } t3: (struct){ p1: (_|_){ // [cycle] sameStruct.cycleFail.t3.p1: circular dependency in evaluation of conditionals: ret changed after evaluation: // ./mutualsamestruct.cue:87:6 ret: (_){ _ } raises: (_){ _ } } p2: (_|_){ // [cycle] sameStruct.cycleFail.t3.p2: circular dependency in evaluation of conditionals: raises changed after evaluation: // ./mutualsamestruct.cue:98:6 raises: (struct){ a: (int){ 1 } } ret: (struct){ a: (int){ 1 } } } } } defCloseSuccess: (struct){ #Example: (#struct){ } expr: (#struct){ ret: (int){ 2 } } } } nestedChain: (struct){ cycleFail: (_|_){ // [cycle] nestedChain.cycleFail: cycle with field #E.y: // ./nestedchain.cue:7:6 #E: (_|_){ // [cycle] nestedChain.cycleFail: cycle with field #E.y: // ./nestedchain.cue:7:6 } } brokenCycleSuccess: (struct){ #E: (#struct){ y: (bool){ true } x: (bool){ true } } } doubleAddfail: (_|_){ // [cycle] nestedChain.doubleAddfail: cycle with field #E.y: // ./nestedchain.cue:28:6 #E: (_|_){ // [cycle] nestedChain.doubleAddfail: cycle with field #E.y: // ./nestedchain.cue:28:6 y: (bool){ true } } } trippleSuccess: (struct){ #E: (#struct){ y: (bool){ true } x: (bool){ true } } z: (bool){ true } } } } -- out/compile -- --- in.cue { self: { fail: { a: { if (〈1;a〉.b == _|_(explicit error (_|_ literal) in source)) { b: 1 } } } isConcreteFail: { a: { if (〈1;a〉.b == _|_(explicit error (_|_ literal) in source)) { b: 1 } b: int } } isNotConcrete: { a: { if (〈1;a〉.b != _|_(explicit error (_|_ literal) in source)) { b: 1 } b: int } } } } --- mutual.cue { mutual: { noConflicts: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { new: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } } mutualCycleFail: { b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { foo: "" } } a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } } brokenCycleSuccess: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { foo: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { bar: "" } } a: { bar: "" } } allowOneDirectionalDependency: { p1: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } } p2: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { new: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { foo: "" } } } } oneDirectionalBrokenConflictSuccess: { p1: { b: { foo: "" } a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } } } oneDirectionalBrokenConflictSuccess: { p2: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } b: { foo: "" } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } } } oneDirectionalBrokenConflictSuccess: { p3: { a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } b: { foo: "" } } } oneDirectionalBrokenConflictSuccess: { p4: { b: { foo: "" } b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } } } oneDirectionalBrokenConflictSuccess: { p5: { b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } b: { foo: "" } a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } } } oneDirectionalBrokenConflictSuccess: { p6: { b: { if (〈1;a〉.bar == _|_(explicit error (_|_ literal) in source)) { new: "" } } a: { if (〈1;b〉.foo == _|_(explicit error (_|_ literal) in source)) { bar: "" } } b: { foo: "" } } } } } --- mutualsamestruct.cue { sameStruct: { chainSuccess: { a: { raises?: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } ret?: {} if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { foo: { a: 1 } } } } chainSuccess: { b: { if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { foo: { a: 1 } } raises?: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } ret?: {} } } cycleFail: { t1: { p1: { raises?: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } ret?: {} if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } } } } cycleFail: { t1: { p2: { ret?: {} if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } raises?: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } } } } cycleFail: { t2: { p1: { raises: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } ret: {} if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } } } } cycleFail: { t2: { p2: { ret: {} if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } raises: {} if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } } } } cycleFail: { t3: { p1: { raises: _ if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } ret: _ if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } } } } cycleFail: { t3: { p2: { ret: _ if (〈0;ret〉 != _|_(explicit error (_|_ literal) in source)) { raises: { a: 1 } } raises: _ if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret: { a: 1 } } } } } defCloseSuccess: { #Example: { raises?: { runtime?: string } if (〈0;raises〉 == _|_(explicit error (_|_ literal) in source)) { ret?: _ } } expr: (〈0;#Example〉 & { ret: 2 }) } } } --- nestedchain.cue { nestedChain: { cycleFail: { if (〈0;#E〉.x != _|_(explicit error (_|_ literal) in source)) { #E: { y: true } } if (〈0;#E〉.y == _|_(explicit error (_|_ literal) in source)) { #E: { x: true } } #E: { [_]: bool } } brokenCycleSuccess: { if (〈0;#E〉.x != _|_(explicit error (_|_ literal) in source)) { #E: { y: true } } if (〈0;#E〉.y == _|_(explicit error (_|_ literal) in source)) { #E: { x: true } } #E: { [_]: bool } #E: { x: true } } doubleAddfail: { if (〈0;#E〉.x == _|_(explicit error (_|_ literal) in source)) { #E: { y: true } } if (〈0;#E〉.y == _|_(explicit error (_|_ literal) in source)) { #E: { x: true } } #E: { [_]: bool } } trippleSuccess: { if (〈0;#E〉.x != _|_(explicit error (_|_ literal) in source)) { #E: { y: true } } if (〈0;#E〉.y != _|_(explicit error (_|_ literal) in source)) { z: true } #E: { x: true } } } }