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  }