@@ -16,6 +16,7 @@ package cue
1616
1717import (
1818 "bytes"
19+ "fmt"
1920 "math/big"
2021 "regexp"
2122 "sort"
@@ -54,9 +55,27 @@ func binOp(ctx *context, src source, op op, left, right evaluated) (result evalu
5455
5556 leftKind := left .kind ()
5657 rightKind := right .kind ()
57- kind , invert := matchBinOpKind (op , leftKind , rightKind )
58+ kind , invert , msg := matchBinOpKind (op , leftKind , rightKind )
5859 if kind == bottomKind {
59- return ctx .mkIncompatible (src , op , left , right )
60+ simplify := func (v , orig value ) value {
61+ switch x := v .(type ) {
62+ case * disjunction :
63+ return orig
64+ case * binaryExpr :
65+ if x .op == opDisjunction {
66+ return orig
67+ }
68+ default :
69+ return x
70+ }
71+ return v
72+ }
73+ var l , r value = left , right
74+ if x , ok := src .(* binaryExpr ); ok {
75+ l = simplify (x .left , left )
76+ r = simplify (x .right , right )
77+ }
78+ return ctx .mkErr (src , msg , op , ctx .str (l ), ctx .str (r ), leftKind , rightKind )
6079 }
6180 if kind .hasReferences () {
6281 panic ("unexpected references in expression" )
@@ -274,14 +293,14 @@ func errOutOfBounds(ctx *context, pos token.Pos, r *bound, v evaluated) *bottom
274293 pos = r .Pos ()
275294 }
276295 e := mkBin (ctx , pos , opUnify , r , v )
277- msg := "%v not within bound %v"
296+ msg := "invalid value %v (out of bound %v) "
278297 switch r .op {
279298 case opNeq , opNMat :
280- msg = "%v excluded by %v"
299+ msg = "invalid value %v ( excluded by %v) "
281300 case opMat :
282- msg = "%v does not match %v"
301+ msg = "invalid value %v ( does not match %v) "
283302 }
284- return ctx .mkErr (e , msg , debugStr ( ctx , v ), debugStr ( ctx , r ))
303+ return ctx .mkErr (e , msg , ctx . str ( v ), ctx . str ( r ))
285304}
286305
287306func opInfo (op op ) (cmp op , norm int ) {
@@ -310,8 +329,9 @@ func (x *bound) binOp(ctx *context, src source, op op, other evaluated) evaluate
310329 newSrc := binSrc (src .Pos (), op , x , other )
311330 switch op {
312331 case opUnify :
313- k , _ := matchBinOpKind (opUnify , x .kind (), other .kind ())
332+ k , _ , msg := matchBinOpKind (opUnify , x .kind (), other .kind ())
314333 if k == bottomKind {
334+ return ctx .mkErr (src , msg , opUnify , ctx .str (x ), ctx .str (other ), x .kind (), other .kind ())
315335 break
316336 }
317337 switch y := other .(type ) {
@@ -433,8 +453,8 @@ func (x *bound) binOp(ctx *context, src source, op op, other evaluated) evaluate
433453 fallthrough
434454
435455 case d .Negative :
436- return ctx .mkErr (newSrc , "incompatible bounds %v and %v" ,
437- debugStr ( ctx , x ), debugStr ( ctx , y ))
456+ return ctx .mkErr (newSrc , "conflicting bounds %v and %v" ,
457+ ctx . str ( x ), ctx . str ( y ))
438458 }
439459
440460 case x .op == opNeq :
@@ -477,8 +497,9 @@ func (x *customValidator) binOp(ctx *context, src source, op op, other evaluated
477497 newSrc := binSrc (src .Pos (), op , x , other )
478498 switch op {
479499 case opUnify :
480- k , _ := matchBinOpKind (opUnify , x .kind (), other .kind ())
500+ k , _ , msg := matchBinOpKind (opUnify , x .kind (), other .kind ())
481501 if k == bottomKind {
502+ return ctx .mkErr (src , msg , op , ctx .str (x ), ctx .str (other ), x .kind (), other .kind ())
482503 break
483504 }
484505 switch y := other .(type ) {
@@ -513,7 +534,7 @@ func (x *customValidator) binOp(ctx *context, src source, op op, other evaluated
513534 return y
514535 }
515536 }
516- return ctx .mkIncompatible (src , op , x , other )
537+ return ctx .mkErr (src , "invalid operation %v and %v (operator not defined for custom validator)" )
517538}
518539
519540func (x * customValidator ) check (ctx * context , v evaluated ) evaluated {
@@ -531,13 +552,13 @@ func (x *customValidator) check(ctx *context, v evaluated) evaluated {
531552 return ctx .mkErr (x , "invalid custom validator" )
532553 } else if ! b .b {
533554 var buf bytes.Buffer
534- buf . WriteString ( x .call .Name )
555+ fmt . Fprintf ( & buf , "%s.%s" , ctx . labelStr ( x . call . pkg ), x .call .Name )
535556 buf .WriteString ("(" )
536557 for _ , a := range x .args {
537- buf .WriteString (debugStr ( ctx , a ))
558+ buf .WriteString (ctx . str ( a ))
538559 }
539560 buf .WriteString (")" )
540- return ctx .mkErr (x , "value %v not in %v " , debugStr ( ctx , v ), buf .String ())
561+ return ctx .mkErr (x , "invalid value %s (does not satisfy %s) " , ctx . str ( v ), buf .String ())
541562 }
542563 return nil
543564}
@@ -681,7 +702,7 @@ func (x *boolLit) binOp(ctx *context, src source, op op, other evaluated) evalua
681702 switch op {
682703 case opUnify :
683704 if x .b != y .b {
684- return ctx .mkErr (x , "conflicting values: %v != %v" , x .b , y .b )
705+ return ctx .mkErr (x , "conflicting values %v and %v" , x .b , y .b )
685706 }
686707 return x
687708 case opLand :
@@ -711,7 +732,8 @@ func (x *stringLit) binOp(ctx *context, src source, op op, other evaluated) eval
711732 str := other .strValue ()
712733 if x .str != str {
713734 src := mkBin (ctx , src .Pos (), op , x , other )
714- return ctx .mkErr (src , "conflicting values: %v != %v" , x .str , str )
735+ return ctx .mkErr (src , "conflicting values %v and %v" ,
736+ ctx .str (x ), ctx .str (y ))
715737 }
716738 return x
717739 case opLss , opLeq , opEql , opNeq , opGeq , opGtr :
@@ -762,7 +784,8 @@ func (x *bytesLit) binOp(ctx *context, src source, op op, other evaluated) evalu
762784 switch op {
763785 case opUnify :
764786 if ! bytes .Equal (x .b , b ) {
765- return ctx .mkErr (x , "conflicting values: %v != %v" , x .b , b )
787+ return ctx .mkErr (x , "conflicting values %v and %v" ,
788+ ctx .str (x ), ctx .str (y ))
766789 }
767790 return x
768791 case opLss , opLeq , opEql , opNeq , opGeq , opGtr :
@@ -867,7 +890,8 @@ func (x *numLit) binOp(ctx *context, src source, op op, other evaluated) evaluat
867890 case opUnify :
868891 if x .v .Cmp (& y .v ) != 0 {
869892 src = mkBin (ctx , src .Pos (), op , x , other )
870- return ctx .mkErr (src , "conflicting values: %v != %v" , x .strValue (), y .strValue ())
893+ return ctx .mkErr (src , "conflicting values %v and %v" ,
894+ ctx .str (x ), ctx .str (y ))
871895 }
872896 if k != x .k {
873897 n .v = x .v
@@ -1010,7 +1034,7 @@ func (x *list) binOp(ctx *context, src source, op op, other evaluated) evaluated
10101034 n := unify (ctx , src , x .len .(evaluated ), y .len .(evaluated ))
10111035 if isBottom (n ) {
10121036 src = mkBin (ctx , src .Pos (), op , x , other )
1013- return ctx .mkErr (src , "incompatible list lengths: %v" , n )
1037+ return ctx .mkErr (src , "conflicting list lengths: %v" , n )
10141038 }
10151039 sx := x .elem .arcs
10161040 xa := sx
@@ -1026,10 +1050,10 @@ func (x *list) binOp(ctx *context, src source, op op, other evaluated) evaluated
10261050 typ := x .typ
10271051 max , ok := n .(* numLit )
10281052 if ! ok || len (xa ) < max .intValue (ctx ) {
1053+ src := mkBin (ctx , src .Pos (), op , x .typ , y .typ )
10291054 typ = unify (ctx , src , x .typ .(evaluated ), y .typ .(evaluated ))
10301055 if isBottom (typ ) {
1031- src = mkBin (ctx , src .Pos (), op , x , other )
1032- return ctx .mkErr (src , "incompatible list types: %v: " , typ )
1056+ return ctx .mkErr (src , "conflicting list element types: %v" , typ )
10331057 }
10341058 }
10351059
0 commit comments