cuelang.org/go@v0.10.1/cue/testdata/disjunctions/edge.txtar (about) 1 # This file mostly contains edge cases of disjunction semantics. 2 # We should ensure that all these cases can be derived from thee spec. 3 # 4 # Many of these cases were discovered as part of the development of the new 5 # evaluator that started at v0.7 and do not pass for that version. 6 -- in.cue -- 7 cyclicalInsertInDisjunction: { 8 // We do not allow lookups across unresolved disjunctions. As such, the 9 // references across disjunctions are not allowed to disambiguate a 10 // disjunction. 11 // 12 // Algorithmically, the distinction between allowing this or not is 13 // achieved by allowing dereferencing of the node in which a disjunction 14 // occurs to the disjunct under evaluation. Effectively this is what the 15 // v0.6 evaluator does. 16 17 ok1: { 18 // In this case, unifying the comprehension into the processing of the 19 // disjunctions would _not_ case the reference to cross disjunction 20 // boundaries. 21 c: {d: e, e: _} 22 c: {d: 1, e: 2} | {d : 2, e: 2} 23 } 24 maybe1: { 25 // In this case, the reference c.e crosses a disjunction boundary. 26 // However, since the reference starts from within a disjunction, this 27 // could be allowed, if we define it to be. 28 c: d: c.e 29 c: {d: 1, e: 2} | {d : 2, e: 2} 30 } 31 err1: { 32 // This should be an error: to resolve x in c.d, we need to first 33 // resolve x to a concrete value. As `x` is defined outside the 34 // disjunction, and the disjunction cannot be resolved without it, `x` 35 // cannot be evaluated to a concrete value, resulting in an error. 36 x: c.e 37 c: d: x 38 c: {d: 1, e: 2} | {d : 2, e: 2} 39 } 40 err2: { 41 // This is a more obviously erroneous variant of err1. The div in x 42 // requires a concrete value for c.e. However, the disjunction can only 43 // be disambiguated as a result of computing x. This means c.e cannot 44 // be concrete at the time of evaluation. 45 x: div(c.e, 2) 46 c: d: x 47 c: {d: 1, e: 2} | {d : 2, e: 3} 48 } 49 err3: { 50 // Here it is clear that d will not disambiguate the disjunction at c. 51 // So c.e. cannot be resolved. 52 x: c.e 53 c: d: 1 | 2 | x 54 c: {d: 1, e: 2} | {d : 2, e: 3} 55 } 56 } 57 58 preseveBottomSemantics: ok: { 59 // `a: a`, which just says that `a` is `a`, is logically equivalent to 60 // `a: _`. Consequently, the disjunction `a: a | X` is equivalent to 61 // `a: _ | X`. As we do not simplify disjunctions, the result is `a: _ | X`. 62 // However, we could consider simplifying in this case to `a: _` if we can 63 // come up with a good general mechanism for subsumption. 64 #x: { #x | {} } 65 } 66 67 eliminateOpenVariant: ok: { 68 // We have two structs in the disjunction that are identical in every way 69 // except openness. TODO: should we disambiguate those? 70 c: {a: 1} | #b 71 #b: {a: 1} 72 } 73 74 cyclicSelfElimination: ok: { 75 // This should resolve to {y: 1} (works for new evaluator) 76 y: 1 | {y: 1} 77 y 78 } 79 -- out/eval/stats -- 80 Leaks: 0 81 Freed: 73 82 Reused: 62 83 Allocs: 11 84 Retain: 11 85 86 Unifications: 49 87 Conjuncts: 105 88 Disjuncts: 74 89 -- out/eval -- 90 (struct){ 91 cyclicalInsertInDisjunction: (struct){ 92 ok1: (struct){ 93 c: (struct){ 94 d: (int){ 2 } 95 e: (int){ 2 } 96 } 97 } 98 maybe1: (struct){ 99 c: (struct){ 100 d: (int){ 2 } 101 e: (int){ 2 } 102 } 103 } 104 err1: (struct){ 105 x: (int){ 2 } 106 c: (struct){ 107 d: (int){ 2 } 108 e: (int){ 2 } 109 } 110 } 111 err2: (struct){ 112 x: (int){ 1 } 113 c: (struct){ 114 d: (int){ 1 } 115 e: (int){ 2 } 116 } 117 } 118 err3: (struct){ 119 x: (_|_){ 120 // [incomplete] cyclicalInsertInDisjunction.err3.x: unresolved disjunction {d:1,e:2} | {d:2,e:3} (type struct): 121 // ./in.cue:46:6 122 } 123 c: (struct){ |((struct){ 124 d: (int){ 1 } 125 e: (int){ 2 } 126 }, (struct){ 127 d: (int){ 2 } 128 e: (int){ 3 } 129 }) } 130 } 131 } 132 preseveBottomSemantics: (struct){ 133 ok: (struct){ 134 #x: (#struct){ 135 } 136 } 137 } 138 eliminateOpenVariant: (struct){ 139 ok: (struct){ 140 c: (#struct){ |((struct){ 141 a: (int){ 1 } 142 }, (#struct){ 143 a: (int){ 1 } 144 }) } 145 #b: (#struct){ 146 a: (int){ 1 } 147 } 148 } 149 } 150 cyclicSelfElimination: (struct){ 151 ok: (_|_){ 152 // [incomplete] cyclicSelfElimination.ok: 2 errors in empty disjunction: 153 // cyclicSelfElimination.ok: conflicting values 1 and {y:(1|{y:1}),y} (mismatched types int and struct): 154 // ./in.cue:68:28 155 // ./in.cue:70:5 156 // cyclicSelfElimination.ok: cannot add field y: was already used: 157 // ./in.cue:70:10 158 y: ((int|struct)){ |((int){ 1 }, (struct){ 159 y: (int){ 1 } 160 }) } 161 } 162 } 163 } 164 -- out/evalalpha -- 165 (struct){ 166 cyclicalInsertInDisjunction: (struct){ 167 ok1: (struct){ 168 c: (struct){ 169 d: (int){ 2 } 170 e: (int){ 2 } 171 } 172 } 173 maybe1: (struct){ 174 c: (struct){ 175 d: (int){ 2 } 176 e: (int){ 2 } 177 } 178 } 179 err1: (struct){ 180 x: (int){ 2 } 181 c: (struct){ 182 d: (int){ 2 } 183 e: (int){ 2 } 184 } 185 } 186 err2: (struct){ 187 x: (int){ 1 } 188 c: (struct){ 189 d: (int){ 1 } 190 e: (int){ 2 } 191 } 192 } 193 err3: (struct){ 194 x: (_|_){ 195 // [incomplete] cyclicalInsertInDisjunction.err3.x: undefined field: e: 196 // ./in.cue:46:8 197 } 198 c: (struct){ |((struct){ 199 d: (int){ 1 } 200 e: (int){ 2 } 201 }, (struct){ 202 d: (int){ 2 } 203 e: (int){ 3 } 204 }) } 205 } 206 } 207 preseveBottomSemantics: (struct){ 208 ok: (struct){ 209 #x: (#struct){ 210 } 211 } 212 } 213 eliminateOpenVariant: (struct){ 214 ok: (struct){ 215 c: (struct){ |((struct){ 216 a: (int){ 1 } 217 }, (#struct){ 218 a: (int){ 1 } 219 }) } 220 #b: (#struct){ 221 a: (int){ 1 } 222 } 223 } 224 } 225 cyclicSelfElimination: (struct){ 226 ok: (struct){ 227 y: (int){ 1 } 228 } 229 } 230 } 231 -- diff/-out/evalalpha<==>+out/eval -- 232 diff old new 233 --- old 234 +++ new 235 @@ -28,8 +28,8 @@ 236 } 237 err3: (struct){ 238 x: (_|_){ 239 - // [incomplete] cyclicalInsertInDisjunction.err3.x: unresolved disjunction {d:1,e:2} | {d:2,e:3} (type struct): 240 - // ./in.cue:46:6 241 + // [incomplete] cyclicalInsertInDisjunction.err3.x: undefined field: e: 242 + // ./in.cue:46:8 243 } 244 c: (struct){ |((struct){ 245 d: (int){ 1 } 246 @@ -48,7 +48,7 @@ 247 } 248 eliminateOpenVariant: (struct){ 249 ok: (struct){ 250 - c: (#struct){ |((struct){ 251 + c: (struct){ |((struct){ 252 a: (int){ 1 } 253 }, (#struct){ 254 a: (int){ 1 } 255 @@ -59,16 +59,8 @@ 256 } 257 } 258 cyclicSelfElimination: (struct){ 259 - ok: (_|_){ 260 - // [incomplete] cyclicSelfElimination.ok: 2 errors in empty disjunction: 261 - // cyclicSelfElimination.ok: conflicting values 1 and {y:(1|{y:1}),y} (mismatched types int and struct): 262 - // ./in.cue:68:28 263 - // ./in.cue:70:5 264 - // cyclicSelfElimination.ok: cannot add field y: was already used: 265 - // ./in.cue:70:10 266 - y: ((int|struct)){ |((int){ 1 }, (struct){ 267 - y: (int){ 1 } 268 - }) } 269 + ok: (struct){ 270 + y: (int){ 1 } 271 } 272 } 273 } 274 -- diff/todo/p2 -- 275 cyclicalInsertInDisjunction.maybe: discrepancy may be okay 276 cyclicalInsertInDisjunction.err1: should be an err for the old and new evaluator. 277 -- diff/todo/p3 -- 278 preseveBottomSemantics: both the old and new evaluator are incorrect here. 279 The result should be either _ or _|{}. 280 -- diff/explanation -- 281 cyclicalInsertInDisjunction.err2: The new evaluator handles this correctly. 282 eliminateOpenVariant.ok: closedness of c is different. Seems correct, or at 283 least okay. 284 cyclicSelfElimination.ok: The new evaluator handles this correctly. 285 -- out/compile -- 286 --- in.cue 287 { 288 cyclicalInsertInDisjunction: { 289 ok1: { 290 c: { 291 d: 〈0;e〉 292 e: _ 293 } 294 c: ({ 295 d: 1 296 e: 2 297 }|{ 298 d: 2 299 e: 2 300 }) 301 } 302 maybe1: { 303 c: { 304 d: 〈1;c〉.e 305 } 306 c: ({ 307 d: 1 308 e: 2 309 }|{ 310 d: 2 311 e: 2 312 }) 313 } 314 err1: { 315 x: 〈0;c〉.e 316 c: { 317 d: 〈1;x〉 318 } 319 c: ({ 320 d: 1 321 e: 2 322 }|{ 323 d: 2 324 e: 2 325 }) 326 } 327 err2: { 328 x: div(〈0;c〉.e, 2) 329 c: { 330 d: 〈1;x〉 331 } 332 c: ({ 333 d: 1 334 e: 2 335 }|{ 336 d: 2 337 e: 3 338 }) 339 } 340 err3: { 341 x: 〈0;c〉.e 342 c: { 343 d: (1|2|〈1;x〉) 344 } 345 c: ({ 346 d: 1 347 e: 2 348 }|{ 349 d: 2 350 e: 3 351 }) 352 } 353 } 354 preseveBottomSemantics: { 355 ok: { 356 #x: { 357 (〈1;#x〉|{}) 358 } 359 } 360 } 361 eliminateOpenVariant: { 362 ok: { 363 c: ({ 364 a: 1 365 }|〈0;#b〉) 366 #b: { 367 a: 1 368 } 369 } 370 } 371 cyclicSelfElimination: { 372 ok: { 373 y: (1|{ 374 y: 1 375 }) 376 〈0;y〉 377 } 378 } 379 }