OLD | NEW |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file implements typechecking of expressions. | 5 // This file implements typechecking of expressions. |
6 | 6 |
7 package types | 7 package types |
8 | 8 |
9 import ( | 9 import ( |
10 "go/ast" | 10 "go/ast" |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 // their type after each constant operation. | 442 // their type after each constant operation. |
443 check.isRepresentable(x, underlying(x.typ).(*Basic)) | 443 check.isRepresentable(x, underlying(x.typ).(*Basic)) |
444 return | 444 return |
445 } | 445 } |
446 | 446 |
447 x.mode = value | 447 x.mode = value |
448 // x.typ is unchanged | 448 // x.typ is unchanged |
449 } | 449 } |
450 | 450 |
451 // index checks an index expression for validity. If length >= 0, it is the uppe
r | 451 // index checks an index expression for validity. If length >= 0, it is the uppe
r |
452 // bound for the index. The result is a valid integer constant, or nil. | 452 // bound for the index. The result is a valid index >= 0, or a negative value. |
453 // | 453 // |
454 func (check *checker) index(index ast.Expr, length int64, iota int) interface{}
{ | 454 func (check *checker) index(index ast.Expr, length int64, iota int) int64 { |
455 var x operand | 455 var x operand |
456 | 456 |
457 check.expr(&x, index, nil, iota) | 457 check.expr(&x, index, nil, iota) |
458 if !x.isInteger() { | 458 if !x.isInteger() { |
459 check.errorf(x.pos(), "index %s must be integer", &x) | 459 check.errorf(x.pos(), "index %s must be integer", &x) |
460 » » return nil | 460 » » return -1 |
461 } | 461 } |
462 if x.mode != constant { | 462 if x.mode != constant { |
463 » » return nil // we cannot check more | 463 » » return -1 // we cannot check more |
464 } | 464 } |
465 » // x.mode == constant and the index value must be >= 0 | 465 » // The spec doesn't require int64 indices, but perhaps it should. |
466 » if isNegConst(x.val) { | 466 » i, ok := x.val.(int64) |
| 467 » if !ok { |
| 468 » » check.errorf(x.pos(), "stupid index %s", &x) |
| 469 » » return -1 |
| 470 » } |
| 471 » if i < 0 { |
467 check.errorf(x.pos(), "index %s must not be negative", &x) | 472 check.errorf(x.pos(), "index %s must not be negative", &x) |
468 » » return nil | 473 » » return -1 |
469 } | 474 } |
470 » // x.val >= 0 | 475 » if length >= 0 && i >= length { |
471 » if length >= 0 && compareConst(x.val, length, token.GEQ) { | |
472 check.errorf(x.pos(), "index %s is out of bounds (>= %d)", &x, l
ength) | 476 check.errorf(x.pos(), "index %s is out of bounds (>= %d)", &x, l
ength) |
473 » » return nil | 477 » » return -1 |
474 } | 478 } |
475 | 479 |
476 » return x.val | 480 » return i |
| 481 } |
| 482 |
| 483 // indexElts checks the elements (elts) of an array or slice composite literal |
| 484 // against the literals element type (typ), and the element indices against |
| 485 // the literal length if known (length >= 0). It returns the length of the |
| 486 // literal (maximum index value + 1). |
| 487 // |
| 488 func (check *checker) indexedElts(elts []ast.Expr, typ Type, length int64, iota
int) int64 { |
| 489 » visited := make(map[int64]bool, len(elts)) |
| 490 » var index, max int64 |
| 491 » for _, e := range elts { |
| 492 » » // determine and check index |
| 493 » » validIndex := false |
| 494 » » eval := e |
| 495 » » if kv, _ := e.(*ast.KeyValueExpr); kv != nil { |
| 496 » » » if i := check.index(kv.Key, length, iota); i >= 0 { |
| 497 » » » » index = i |
| 498 » » » » validIndex = true |
| 499 » » » } |
| 500 » » » eval = kv.Value |
| 501 » » } else if length >= 0 && index >= length { |
| 502 » » » check.errorf(e.Pos(), "index %d is out of bounds (>= %d)
", index, length) |
| 503 » » } else { |
| 504 » » » validIndex = true |
| 505 » » } |
| 506 |
| 507 » » // if we have a valid index, check for duplicate entries |
| 508 » » if validIndex { |
| 509 » » » if visited[index] { |
| 510 » » » » check.errorf(e.Pos(), "duplicate index %d in arr
ay or slice literal", index) |
| 511 » » » } |
| 512 » » » visited[index] = true |
| 513 » » } |
| 514 » » index++ |
| 515 » » if index > max { |
| 516 » » » max = index |
| 517 » » } |
| 518 |
| 519 » » // check element against composite literal element type |
| 520 » » var x operand |
| 521 » » check.expr(&x, eval, typ, iota) |
| 522 » » if !x.isAssignable(typ) { |
| 523 » » » check.errorf(x.pos(), "cannot use %s as %s value in arra
y or slice literal", &x, typ) |
| 524 » » } |
| 525 » } |
| 526 » return max |
477 } | 527 } |
478 | 528 |
479 func (check *checker) callRecord(x *operand) { | 529 func (check *checker) callRecord(x *operand) { |
480 if x.mode != invalid { | 530 if x.mode != invalid { |
481 check.mapf(x.expr, x.typ) | 531 check.mapf(x.expr, x.typ) |
482 } | 532 } |
483 } | 533 } |
484 | 534 |
485 // rawExpr typechecks expression e and initializes x with the expression | 535 // rawExpr typechecks expression e and initializes x with the expression |
486 // value or type. If an error occured, x.mode is set to invalid. | 536 // value or type. If an error occured, x.mode is set to invalid. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 case ast.Var: | 595 case ast.Var: |
546 x.mode = variable | 596 x.mode = variable |
547 case ast.Fun: | 597 case ast.Fun: |
548 x.mode = value | 598 x.mode = value |
549 default: | 599 default: |
550 unreachable() | 600 unreachable() |
551 } | 601 } |
552 x.typ = obj.Type.(Type) | 602 x.typ = obj.Type.(Type) |
553 | 603 |
554 case *ast.Ellipsis: | 604 case *ast.Ellipsis: |
555 » » unimplemented() | 605 » » // ellipses are handled explictly where they are legal |
| 606 » » // (array composite literals and parameter lists) |
| 607 » » check.errorf(e.Pos(), "invalid use of '...'") |
| 608 » » goto Error |
556 | 609 |
557 case *ast.BasicLit: | 610 case *ast.BasicLit: |
558 x.setConst(e.Kind, e.Value) | 611 x.setConst(e.Kind, e.Value) |
559 if x.mode == invalid { | 612 if x.mode == invalid { |
560 check.invalidAST(e.Pos(), "invalid literal %v", e.Value) | 613 check.invalidAST(e.Pos(), "invalid literal %v", e.Value) |
561 goto Error | 614 goto Error |
562 } | 615 } |
563 | 616 |
564 case *ast.FuncLit: | 617 case *ast.FuncLit: |
565 if typ, ok := check.typ(e.Type, false).(*Signature); ok { | 618 if typ, ok := check.typ(e.Type, false).(*Signature); ok { |
566 x.mode = value | 619 x.mode = value |
567 x.typ = typ | 620 x.typ = typ |
568 check.function(typ, e.Body) | 621 check.function(typ, e.Body) |
569 } else { | 622 } else { |
570 check.invalidAST(e.Pos(), "invalid function literal %s",
e) | 623 check.invalidAST(e.Pos(), "invalid function literal %s",
e) |
571 goto Error | 624 goto Error |
572 } | 625 } |
573 | 626 |
574 case *ast.CompositeLit: | 627 case *ast.CompositeLit: |
575 typ := hint | 628 typ := hint |
| 629 openArray := false |
576 if e.Type != nil { | 630 if e.Type != nil { |
577 » » » typ = check.typ(e.Type, false) | 631 » » » // [...]T array types may only appear with composite lit
erals. |
| 632 » » » // Check for them here so we don't have to handle ... in
general. |
| 633 » » » typ = nil |
| 634 » » » if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && at
yp.Len != nil { |
| 635 » » » » if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip !
= nil && ellip.Elt == nil { |
| 636 » » » » » // We have an "open" [...]T array type. |
| 637 » » » » » // Create a new ArrayType with unknown l
ength (-1) |
| 638 » » » » » // and finish setting it up after analyz
ing the literal. |
| 639 » » » » » typ = &Array{Len: -1, Elt: check.typ(aty
p.Elt, cycleOk)} |
| 640 » » » » » openArray = true |
| 641 » » » » } |
| 642 » » » } |
| 643 » » » if typ == nil { |
| 644 » » » » typ = check.typ(e.Type, false) |
| 645 » » » } |
578 } | 646 } |
579 if typ == nil { | 647 if typ == nil { |
580 check.errorf(e.Pos(), "missing type in composite literal
") | 648 check.errorf(e.Pos(), "missing type in composite literal
") |
581 goto Error | 649 goto Error |
582 } | 650 } |
583 | 651 |
584 // TODO(gri) try to factor code below better | |
585 | |
586 switch utyp := underlying(deref(typ)).(type) { | 652 switch utyp := underlying(deref(typ)).(type) { |
587 case *Struct: | 653 case *Struct: |
588 if len(e.Elts) == 0 { | 654 if len(e.Elts) == 0 { |
589 break | 655 break |
590 } | 656 } |
591 fields := utyp.Fields | 657 fields := utyp.Fields |
592 if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok { | 658 if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok { |
593 // all elements must have keys | 659 // all elements must have keys |
594 visited := make([]bool, len(fields)) | 660 visited := make([]bool, len(fields)) |
595 for _, e := range e.Elts { | 661 for _, e := range e.Elts { |
(...skipping 28 matching lines...) Expand all Loading... |
624 } else { | 690 } else { |
625 // no element must have a key | 691 // no element must have a key |
626 for i, e := range e.Elts { | 692 for i, e := range e.Elts { |
627 if kv, _ := e.(*ast.KeyValueExpr); kv !=
nil { | 693 if kv, _ := e.(*ast.KeyValueExpr); kv !=
nil { |
628 check.errorf(kv.Pos(), "mixture
of field:value and value elements in struct literal") | 694 check.errorf(kv.Pos(), "mixture
of field:value and value elements in struct literal") |
629 continue | 695 continue |
630 } | 696 } |
631 check.expr(x, e, nil, iota) | 697 check.expr(x, e, nil, iota) |
632 if i >= len(fields) { | 698 if i >= len(fields) { |
633 check.errorf(x.pos(), "too many
values in struct literal") | 699 check.errorf(x.pos(), "too many
values in struct literal") |
634 » » » » » » goto Error | 700 » » » » » » break // cannot continue |
635 } | 701 } |
| 702 // i < len(fields) |
636 etyp := fields[i].Type | 703 etyp := fields[i].Type |
637 if !x.isAssignable(etyp) { | 704 if !x.isAssignable(etyp) { |
638 check.errorf(x.pos(), "cannot us
e %s as an element of type %s in struct literal", x, etyp) | 705 check.errorf(x.pos(), "cannot us
e %s as an element of type %s in struct literal", x, etyp) |
639 continue | 706 continue |
640 } | 707 } |
641 } | 708 } |
642 if len(e.Elts) < len(fields) { | 709 if len(e.Elts) < len(fields) { |
643 check.errorf(e.Rbrace, "too few values i
n struct literal") | 710 check.errorf(e.Rbrace, "too few values i
n struct literal") |
644 » » » » » goto Error | 711 » » » » » // ok to continue |
645 } | 712 } |
646 } | 713 } |
647 | 714 |
648 case *Array: | 715 case *Array: |
649 » » » var index int64 | 716 » » » n := check.indexedElts(e.Elts, utyp.Elt, utyp.Len, iota) |
650 » » » for _, e := range e.Elts { | 717 » » » // if we have an "open" [...]T array, set the length now
that we know it |
651 » » » » eval := e | 718 » » » if openArray { |
652 » » » » if kv, _ := e.(*ast.KeyValueExpr); kv != nil { | 719 » » » » utyp.Len = n |
653 » » » » » check.index(kv.Key, -1, iota) | |
654 » » » » » eval = kv.Value | |
655 » » » » } | |
656 » » » » // TODO(gri) missing index range & duplicate che
ck | |
657 » » » » check.expr(x, eval, utyp.Elt, iota) | |
658 » » » » if !x.isAssignable(utyp.Elt) { | |
659 » » » » » check.errorf(x.pos(), "cannot use %s as
%s value in array literal", x, utyp.Elt) | |
660 » » » » } | |
661 » » » » index++ | |
662 } | 720 } |
663 | 721 |
664 case *Slice: | 722 case *Slice: |
665 » » » var index int64 | 723 » » » check.indexedElts(e.Elts, utyp.Elt, -1, iota) |
666 » » » for _, e := range e.Elts { | |
667 » » » » eval := e | |
668 » » » » if kv, _ := e.(*ast.KeyValueExpr); kv != nil { | |
669 » » » » » // TODO(gri) check key | |
670 » » » » » check.index(kv.Key, -1, iota) | |
671 » » » » » eval = kv.Value | |
672 » » » » } | |
673 » » » » // TODO(gri) missing index range & duplicate che
ck | |
674 » » » » check.expr(x, eval, utyp.Elt, iota) | |
675 » » » » if !x.isAssignable(utyp.Elt) { | |
676 » » » » » check.errorf(x.pos(), "cannot use %s as
%s value in slice literal", x, utyp.Elt) | |
677 » » » » } | |
678 » » » » index++ | |
679 » » » } | |
680 | 724 |
681 case *Map: | 725 case *Map: |
682 visited := make(map[interface{}]bool, len(e.Elts)) | 726 visited := make(map[interface{}]bool, len(e.Elts)) |
683 for _, e := range e.Elts { | 727 for _, e := range e.Elts { |
684 kv, _ := e.(*ast.KeyValueExpr) | 728 kv, _ := e.(*ast.KeyValueExpr) |
685 if kv == nil { | 729 if kv == nil { |
686 check.errorf(e.Pos(), "missing key in ma
p literal") | 730 check.errorf(e.Pos(), "missing key in ma
p literal") |
687 continue | 731 continue |
688 } | 732 } |
689 check.expr(x, kv.Key, nil, iota) | 733 check.expr(x, kv.Key, nil, iota) |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 length := int64(-1) // valid if >= 0 | 893 length := int64(-1) // valid if >= 0 |
850 switch typ := underlying(x.typ).(type) { | 894 switch typ := underlying(x.typ).(type) { |
851 case *Basic: | 895 case *Basic: |
852 if isString(typ) { | 896 if isString(typ) { |
853 valid = true | 897 valid = true |
854 if x.mode == constant { | 898 if x.mode == constant { |
855 length = int64(len(x.val.(string))) + 1
// +1 for slice | 899 length = int64(len(x.val.(string))) + 1
// +1 for slice |
856 } | 900 } |
857 // a sliced string always yields a string value | 901 // a sliced string always yields a string value |
858 // of the same type as the original string (not | 902 // of the same type as the original string (not |
859 » » » » // a constant) even if the string and the indexe
s | 903 » » » » // a constant) even if the string and the indice
s |
860 // are constant | 904 // are constant |
861 x.mode = value | 905 x.mode = value |
862 // x.typ doesn't change | 906 // x.typ doesn't change |
863 } | 907 } |
864 | 908 |
865 case *Array: | 909 case *Array: |
866 valid = true | 910 valid = true |
867 length = typ.Len + 1 // +1 for slice | 911 length = typ.Len + 1 // +1 for slice |
868 if x.mode != variable { | 912 if x.mode != variable { |
869 check.invalidOp(x.pos(), "cannot slice %s (value
not addressable)", x) | 913 check.invalidOp(x.pos(), "cannot slice %s (value
not addressable)", x) |
870 goto Error | 914 goto Error |
871 } | 915 } |
872 x.typ = &Slice{Elt: typ.Elt} | 916 x.typ = &Slice{Elt: typ.Elt} |
873 | 917 |
874 case *Slice: | 918 case *Slice: |
875 valid = true | 919 valid = true |
876 x.mode = variable | 920 x.mode = variable |
877 // x.typ doesn't change | 921 // x.typ doesn't change |
878 } | 922 } |
879 | 923 |
880 if !valid { | 924 if !valid { |
881 check.invalidOp(x.pos(), "cannot slice %s", x) | 925 check.invalidOp(x.pos(), "cannot slice %s", x) |
882 goto Error | 926 goto Error |
883 } | 927 } |
884 | 928 |
885 » » var lo interface{} = zeroConst | 929 » » lo := int64(0) |
886 if e.Low != nil { | 930 if e.Low != nil { |
887 lo = check.index(e.Low, length, iota) | 931 lo = check.index(e.Low, length, iota) |
888 } | 932 } |
889 | 933 |
890 » » var hi interface{} | 934 » » hi := int64(-1) |
891 if e.High != nil { | 935 if e.High != nil { |
892 hi = check.index(e.High, length, iota) | 936 hi = check.index(e.High, length, iota) |
893 } else if length >= 0 { | 937 } else if length >= 0 { |
894 hi = length | 938 hi = length |
895 } | 939 } |
896 | 940 |
897 » » if lo != nil && hi != nil && compareConst(lo, hi, token.GTR) { | 941 » » if lo >= 0 && hi >= 0 && lo > hi { |
898 » » » check.errorf(e.Low.Pos(), "inverted slice range: %v > %v
", lo, hi) | 942 » » » check.errorf(e.Low.Pos(), "inverted slice range: %d > %d
", lo, hi) |
899 // ok to continue | 943 // ok to continue |
900 } | 944 } |
901 | 945 |
902 case *ast.TypeAssertExpr: | 946 case *ast.TypeAssertExpr: |
903 check.expr(x, e.X, hint, iota) | 947 check.expr(x, e.X, hint, iota) |
904 if _, ok := underlying(x.typ).(*Interface); !ok { | 948 if _, ok := underlying(x.typ).(*Interface); !ok { |
905 check.invalidOp(e.X.Pos(), "non-interface type %s in typ
e assertion", x.typ) | 949 check.invalidOp(e.X.Pos(), "non-interface type %s in typ
e assertion", x.typ) |
906 // ok to continue | 950 // ok to continue |
907 } | 951 } |
908 // TODO(gri) some type asserts are compile-time decidable | 952 // TODO(gri) some type asserts are compile-time decidable |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 check.expr(&y, e.Y, hint, iota) | 1028 check.expr(&y, e.Y, hint, iota) |
985 check.binary(x, &y, e.Op, hint) | 1029 check.binary(x, &y, e.Op, hint) |
986 | 1030 |
987 case *ast.KeyValueExpr: | 1031 case *ast.KeyValueExpr: |
988 // key:value expressions are handled in composite literals | 1032 // key:value expressions are handled in composite literals |
989 check.invalidAST(e.Pos(), "no key:value expected") | 1033 check.invalidAST(e.Pos(), "no key:value expected") |
990 goto Error | 1034 goto Error |
991 | 1035 |
992 case *ast.ArrayType: | 1036 case *ast.ArrayType: |
993 if e.Len != nil { | 1037 if e.Len != nil { |
994 » » » var n int64 = -1 | 1038 » » » check.expr(x, e.Len, nil, iota) |
995 » » » if ellip, ok := e.Len.(*ast.Ellipsis); ok { | 1039 » » » if x.mode == invalid { |
996 » » » » // TODO(gri) need to check somewhere that [...]T
types are only used with composite literals | 1040 » » » » goto Error |
997 » » » » if ellip.Elt != nil { | 1041 » » » } |
998 » » » » » check.invalidAST(ellip.Pos(), "ellipsis
only expected") | 1042 » » » if x.mode != constant { |
999 » » » » » // ok to continue | 1043 » » » » if x.mode != invalid { |
| 1044 » » » » » check.errorf(x.pos(), "array length %s m
ust be constant", x) |
1000 } | 1045 } |
1001 » » » } else { | 1046 » » » » goto Error |
1002 » » » » check.expr(x, e.Len, nil, 0) | 1047 » » » } |
1003 » » » » if x.mode == invalid { | 1048 » » » n, ok := x.val.(int64) |
1004 » » » » » goto Error | 1049 » » » if !ok || n < 0 { |
1005 » » » » } | 1050 » » » » check.errorf(x.pos(), "invalid array length %s",
x) |
1006 » » » » if x.mode == constant { | 1051 » » » » goto Error |
1007 » » » » » if i, ok := x.val.(int64); ok && i == in
t64(int(i)) { | |
1008 » » » » » » n = i | |
1009 » » » » » } | |
1010 » » » » } | |
1011 » » » » if n < 0 { | |
1012 » » » » » check.errorf(e.Len.Pos(), "invalid array
bound %s", e.Len) | |
1013 » » » » » // ok to continue | |
1014 » » » » » n = 0 | |
1015 » » » » } | |
1016 } | 1052 } |
1017 x.typ = &Array{Len: n, Elt: check.typ(e.Elt, cycleOk)} | 1053 x.typ = &Array{Len: n, Elt: check.typ(e.Elt, cycleOk)} |
1018 } else { | 1054 } else { |
1019 x.typ = &Slice{Elt: check.typ(e.Elt, true)} | 1055 x.typ = &Slice{Elt: check.typ(e.Elt, true)} |
1020 } | 1056 } |
1021 x.mode = typexpr | 1057 x.mode = typexpr |
1022 | 1058 |
1023 case *ast.StructType: | 1059 case *ast.StructType: |
1024 x.mode = typexpr | 1060 x.mode = typexpr |
1025 x.typ = &Struct{Fields: check.collectFields(e.Fields, cycleOk)} | 1061 x.typ = &Struct{Fields: check.collectFields(e.Fields, cycleOk)} |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 // ignore - error reported before | 1125 // ignore - error reported before |
1090 case novalue: | 1126 case novalue: |
1091 check.errorf(x.pos(), "%s used as type", &x) | 1127 check.errorf(x.pos(), "%s used as type", &x) |
1092 case typexpr: | 1128 case typexpr: |
1093 return x.typ | 1129 return x.typ |
1094 default: | 1130 default: |
1095 check.errorf(x.pos(), "%s is not a type", &x) | 1131 check.errorf(x.pos(), "%s is not a type", &x) |
1096 } | 1132 } |
1097 return Typ[Invalid] | 1133 return Typ[Invalid] |
1098 } | 1134 } |
OLD | NEW |