@@ -178,7 +178,9 @@ func (c *context) binary(x *ast.BinaryExpr) (Value, error) {
178178 }
179179 return binop (x .Op , lf , rf )
180180 }
181- return nil , fmt .Errorf ("cannot perform addition on %s" , reflect .TypeOf (l ))
181+ return nil , c .error (x .Span (),
182+ fmt .Sprintf ("cannot perform addition on %s" ,
183+ c .reg .String (l .Type ())))
182184
183185 case token .APPEND :
184186 l , err := c .eval (x .Left )
@@ -199,7 +201,18 @@ func (c *context) binary(x *ast.BinaryExpr) (Value, error) {
199201 if err != nil {
200202 return nil , err
201203 }
202- return append (ls , r ), nil
204+ typ := c .reg .GetList (ls .typ )
205+ if r .Type () != typ {
206+ // Special-case empty lists, which have type never.
207+ if typ == types .NeverRef {
208+ typ = r .Type ()
209+ } else {
210+ return nil , c .error (x .Right .Span (),
211+ fmt .Sprintf ("cannot append %s to %s" ,
212+ c .reg .String (r .Type ()), c .reg .String (ls .typ )))
213+ }
214+ }
215+ return List {c .reg .List (typ ), append (ls .elements , r )}, nil
203216 }
204217
205218 return nil , fmt .Errorf ("cannot append to non-list %s" , reflect .TypeOf (l ))
@@ -223,7 +236,18 @@ func (c *context) binary(x *ast.BinaryExpr) (Value, error) {
223236 if err != nil {
224237 return nil , err
225238 }
226- return append (List {l }, ls ... ), nil
239+ typ := c .reg .GetList (ls .typ )
240+ if l .Type () != typ {
241+ // Special-case empty lists, which have type never.
242+ if typ == types .NeverRef {
243+ typ = r .Type ()
244+ } else {
245+ return nil , c .error (x .Left .Span (),
246+ fmt .Sprintf ("cannot prepend %s to %s" ,
247+ c .reg .String (l .Type ()), c .reg .String (ls .typ )))
248+ }
249+ }
250+ return List {c .reg .List (typ ), append ([]Value {l }, ls .elements ... )}, nil
227251 }
228252
229253 return nil , fmt .Errorf ("cannot prepend to non-list %s" , reflect .TypeOf (r ))
@@ -247,7 +271,17 @@ func (c *context) binary(x *ast.BinaryExpr) (Value, error) {
247271 if err != nil {
248272 return nil , err
249273 }
250- return append (ls , r ... ), nil
274+
275+ // Special-case empty lists.
276+ typ := ls .typ // a list type
277+ if typ != r .typ {
278+ if c .reg .GetList (typ ) == types .NeverRef {
279+ typ = r .typ
280+ } else if c .reg .GetList (r .typ ) != types .NeverRef {
281+ return nil , c .error (x .Left .Span (), fmt .Sprintf ("cannot concat %s to %s" , c .reg .String (ls .typ ), c .reg .String (r .typ )))
282+ }
283+ }
284+ return List {typ , append (ls .elements , r .elements ... )}, nil
251285 }
252286
253287 if tx , ok := l .(Text ); ok {
@@ -419,17 +453,27 @@ func (c *context) access(x *ast.AccessExpr) (Value, error) {
419453 return val , nil
420454}
421455
422- func (c * context ) listExpr (x * ast.ListExpr ) (List , error ) {
423- list := make (List , len (x .Elements ))
456+ func (c * context ) listExpr (x * ast.ListExpr ) (ls List , err error ) {
457+ elements := make ([]Value , len (x .Elements ))
458+ typ := types .NeverRef
424459 for i , x := range x .Elements {
425- val , err := c .eval (x )
460+ var val Value
461+ val , err = c .eval (x )
426462 if err != nil {
427- return nil , err
463+ return
428464 }
429465
430- list [i ] = val
466+ elements [i ] = val
467+ if val .Type () != typ {
468+ if typ == types .NeverRef {
469+ typ = val .Type ()
470+ } else {
471+ err = c .error (x .Span (), fmt .Sprintf ("list elements must all be of type %s, got %s" , c .reg .String (typ ), c .reg .String (val .Type ())))
472+ return
473+ }
474+ }
431475 }
432- return list , nil
476+ return List { c . reg . List ( typ ), elements } , nil
433477}
434478
435479func (c * context ) pick (pick * ast.BinaryExpr , x ast.Expr ) (Value , error ) {
@@ -447,7 +491,7 @@ func (c *context) pick(pick *ast.BinaryExpr, x ast.Expr) (Value, error) {
447491 if tagTyp , ok := enum [tag ]; ok {
448492 if tagTyp == types .NeverRef {
449493 if x == nil {
450- return Variant {Type ( ref ) , tag , nil }, nil
494+ return Variant {ref , tag , nil }, nil
451495 } else {
452496 return nil , c .error (x .Span (), fmt .Sprintf ("#%s does not take a value" , tag ))
453497 }
@@ -459,8 +503,12 @@ func (c *context) pick(pick *ast.BinaryExpr, x ast.Expr) (Value, error) {
459503 if err != nil {
460504 return nil , err
461505 }
462- // TODO verify type.
463- return Variant {Type (ref ), tag , val }, nil
506+ if val .Type () != tagTyp {
507+ return nil , c .error (pick .Right .Span (),
508+ fmt .Sprintf ("#%s requires a value of type %s, got %s" ,
509+ tag , c .reg .String (tagTyp ), c .reg .String (val .Type ())))
510+ }
511+ return Variant {ref , tag , val }, nil
464512 }
465513 }
466514 }
@@ -582,15 +630,17 @@ func (c *context) bytes(x ast.Node) (Bytes, error) {
582630 return nil , c .error (x .Span (), fmt .Sprintf ("non-bytes value %s" , val ))
583631}
584632
585- func (c * context ) list (x ast.Node ) (List , error ) {
586- val , err := c .eval (x )
633+ func (c * context ) list (x ast.Node ) (l List , err error ) {
634+ var val Value
635+ val , err = c .eval (x )
587636 if err != nil {
588- return nil , err
637+ return
589638 }
590639 if i , ok := val .(List ); ok {
591640 return i , nil
592641 }
593- return nil , c .error (x .Span (), fmt .Sprintf ("non-list value %s" , val ))
642+ err = c .error (x .Span (), fmt .Sprintf ("non-list value %s" , val ))
643+ return
594644}
595645
596646func (c * context ) record (x ast.Node ) (Record , error ) {
0 commit comments