Source file
src/go/types/expr.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "fmt"
11 "go/ast"
12 "go/constant"
13 "go/token"
14 . "internal/types/errors"
15 )
16
17
58
59 type opPredicates map[token.Token]func(Type) bool
60
61 var unaryOpPredicates opPredicates
62
63 func init() {
64
65 unaryOpPredicates = opPredicates{
66 token.ADD: allNumeric,
67 token.SUB: allNumeric,
68 token.XOR: allInteger,
69 token.NOT: allBoolean,
70 }
71 }
72
73 func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
74 if pred := m[op]; pred != nil {
75 if !pred(x.typ) {
76 check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
77 return false
78 }
79 } else {
80 check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
81 return false
82 }
83 return true
84 }
85
86
87
88 func opPos(x ast.Expr) token.Pos {
89 switch op := x.(type) {
90 case nil:
91 return nopos
92 case *ast.BinaryExpr:
93 return op.OpPos
94 default:
95 return x.Pos()
96 }
97 }
98
99
100
101 func opName(e ast.Expr) string {
102 switch e := e.(type) {
103 case *ast.BinaryExpr:
104 if int(e.Op) < len(op2str2) {
105 return op2str2[e.Op]
106 }
107 case *ast.UnaryExpr:
108 if int(e.Op) < len(op2str1) {
109 return op2str1[e.Op]
110 }
111 }
112 return ""
113 }
114
115 var op2str1 = [...]string{
116 token.XOR: "bitwise complement",
117 }
118
119
120 var op2str2 = [...]string{
121 token.ADD: "addition",
122 token.SUB: "subtraction",
123 token.XOR: "bitwise XOR",
124 token.MUL: "multiplication",
125 token.SHL: "shift",
126 }
127
128
129 func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
130 check.expr(nil, x, e.X)
131 if x.mode == invalid {
132 return
133 }
134
135 op := e.Op
136 switch op {
137 case token.AND:
138
139
140 if _, ok := ast.Unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
141 check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
142 x.mode = invalid
143 return
144 }
145 x.mode = value
146 x.typ = &Pointer{base: x.typ}
147 return
148
149 case token.ARROW:
150 if elem := check.chanElem(x, x, true); elem != nil {
151 x.mode = commaok
152 x.typ = elem
153 check.hasCallOrRecv = true
154 return
155 }
156 x.mode = invalid
157 return
158
159 case token.TILDE:
160
161 if !allInteger(x.typ) {
162 check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
163 x.mode = invalid
164 return
165 }
166 check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
167 op = token.XOR
168 }
169
170 if !check.op(unaryOpPredicates, x, op) {
171 x.mode = invalid
172 return
173 }
174
175 if x.mode == constant_ {
176 if x.val.Kind() == constant.Unknown {
177
178 return
179 }
180 var prec uint
181 if isUnsigned(x.typ) {
182 prec = uint(check.conf.sizeof(x.typ) * 8)
183 }
184 x.val = constant.UnaryOp(op, x.val, prec)
185 x.expr = e
186 check.overflow(x, opPos(x.expr))
187 return
188 }
189
190 x.mode = value
191
192 }
193
194
195
196
197 func (check *Checker) chanElem(pos positioner, x *operand, recv bool) Type {
198 u, err := commonUnder(x.typ, func(t, u Type) *typeError {
199 if u == nil {
200 return typeErrorf("no specific channel type")
201 }
202 ch, _ := u.(*Chan)
203 if ch == nil {
204 return typeErrorf("non-channel %s", t)
205 }
206 if recv && ch.dir == SendOnly {
207 return typeErrorf("send-only channel %s", t)
208 }
209 if !recv && ch.dir == RecvOnly {
210 return typeErrorf("receive-only channel %s", t)
211 }
212 return nil
213 })
214
215 if u != nil {
216 return u.(*Chan).elem
217 }
218
219 cause := err.format(check)
220 if recv {
221 if isTypeParam(x.typ) {
222 check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s: %s", x, cause)
223 } else {
224
225 check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s %s", cause, x)
226 }
227 } else {
228 if isTypeParam(x.typ) {
229 check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s: %s", x, cause)
230 } else {
231
232 check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s %s", cause, x)
233 }
234 }
235 return nil
236 }
237
238 func isShift(op token.Token) bool {
239 return op == token.SHL || op == token.SHR
240 }
241
242 func isComparison(op token.Token) bool {
243
244 switch op {
245 case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
246 return true
247 }
248 return false
249 }
250
251
252
253
254
255
256
257
258
259
260 func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
261 old, found := check.untyped[x]
262 if !found {
263 return
264 }
265
266
267 switch x := x.(type) {
268 case *ast.BadExpr,
269 *ast.FuncLit,
270 *ast.CompositeLit,
271 *ast.IndexExpr,
272 *ast.SliceExpr,
273 *ast.TypeAssertExpr,
274 *ast.StarExpr,
275 *ast.KeyValueExpr,
276 *ast.ArrayType,
277 *ast.StructType,
278 *ast.FuncType,
279 *ast.InterfaceType,
280 *ast.MapType,
281 *ast.ChanType:
282
283
284
285 if debug {
286 check.dump("%v: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ)
287 panic("unreachable")
288 }
289 return
290
291 case *ast.CallExpr:
292
293
294
295
296 case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr:
297
298
299
300
301 case *ast.ParenExpr:
302 check.updateExprType(x.X, typ, final)
303
304 case *ast.UnaryExpr:
305
306
307
308
309
310 if old.val != nil {
311 break
312 }
313 check.updateExprType(x.X, typ, final)
314
315 case *ast.BinaryExpr:
316 if old.val != nil {
317 break
318 }
319 if isComparison(x.Op) {
320
321
322 } else if isShift(x.Op) {
323
324
325 check.updateExprType(x.X, typ, final)
326 } else {
327
328 check.updateExprType(x.X, typ, final)
329 check.updateExprType(x.Y, typ, final)
330 }
331
332 default:
333 panic("unreachable")
334 }
335
336
337
338 if !final && isUntyped(typ) {
339 old.typ = under(typ).(*Basic)
340 check.untyped[x] = old
341 return
342 }
343
344
345
346 delete(check.untyped, x)
347
348 if old.isLhs {
349
350
351
352 if !allInteger(typ) {
353 check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
354 return
355 }
356
357
358
359 }
360 if old.val != nil {
361
362 c := operand{old.mode, x, old.typ, old.val, 0}
363 check.convertUntyped(&c, typ)
364 if c.mode == invalid {
365 return
366 }
367 }
368
369
370 check.recordTypeAndValue(x, old.mode, typ, old.val)
371 }
372
373
374 func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
375 if info, ok := check.untyped[x]; ok {
376 info.val = val
377 check.untyped[x] = info
378 }
379 }
380
381
382
383
384
385
386
387 func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
388 if x.mode == invalid || isTyped(x.typ) || !isValid(target) {
389 return x.typ, nil, 0
390 }
391
392
393 if isUntyped(target) {
394
395 if m := maxType(x.typ, target); m != nil {
396 return m, nil, 0
397 }
398 return nil, nil, InvalidUntypedConversion
399 }
400
401 switch u := under(target).(type) {
402 case *Basic:
403 if x.mode == constant_ {
404 v, code := check.representation(x, u)
405 if code != 0 {
406 return nil, nil, code
407 }
408 return target, v, code
409 }
410
411
412
413
414 switch x.typ.(*Basic).kind {
415 case UntypedBool:
416 if !isBoolean(target) {
417 return nil, nil, InvalidUntypedConversion
418 }
419 case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
420 if !isNumeric(target) {
421 return nil, nil, InvalidUntypedConversion
422 }
423 case UntypedString:
424
425
426
427 if !isString(target) {
428 return nil, nil, InvalidUntypedConversion
429 }
430 case UntypedNil:
431
432 if !hasNil(target) {
433 return nil, nil, InvalidUntypedConversion
434 }
435
436 return Typ[UntypedNil], nil, 0
437 default:
438 return nil, nil, InvalidUntypedConversion
439 }
440 case *Interface:
441 if isTypeParam(target) {
442 if !underIs(target, func(u Type) bool {
443 if u == nil {
444 return false
445 }
446 t, _, _ := check.implicitTypeAndValue(x, u)
447 return t != nil
448 }) {
449 return nil, nil, InvalidUntypedConversion
450 }
451
452 if x.isNil() {
453 return Typ[UntypedNil], nil, 0
454 }
455 break
456 }
457
458
459
460
461 if x.isNil() {
462 return Typ[UntypedNil], nil, 0
463 }
464
465 if !u.Empty() {
466 return nil, nil, InvalidUntypedConversion
467 }
468 return Default(x.typ), nil, 0
469 case *Pointer, *Signature, *Slice, *Map, *Chan:
470 if !x.isNil() {
471 return nil, nil, InvalidUntypedConversion
472 }
473
474 return Typ[UntypedNil], nil, 0
475 default:
476 return nil, nil, InvalidUntypedConversion
477 }
478 return target, nil, 0
479 }
480
481
482 func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) {
483
484 if !isValid(x.typ) || !isValid(y.typ) {
485 x.mode = invalid
486 return
487 }
488
489 if switchCase {
490 op = token.EQL
491 }
492
493 errOp := x
494 cause := ""
495
496
497
498 code := MismatchedTypes
499 ok, _ := x.assignableTo(check, y.typ, nil)
500 if !ok {
501 ok, _ = y.assignableTo(check, x.typ, nil)
502 }
503 if !ok {
504
505
506
507 errOp = y
508 cause = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
509 goto Error
510 }
511
512
513 code = UndefinedOp
514 switch op {
515 case token.EQL, token.NEQ:
516
517 switch {
518 case x.isNil() || y.isNil():
519
520 typ := x.typ
521 if x.isNil() {
522 typ = y.typ
523 }
524 if !hasNil(typ) {
525
526
527
528
529 errOp = y
530 goto Error
531 }
532
533 case !Comparable(x.typ):
534 errOp = x
535 cause = check.incomparableCause(x.typ)
536 goto Error
537
538 case !Comparable(y.typ):
539 errOp = y
540 cause = check.incomparableCause(y.typ)
541 goto Error
542 }
543
544 case token.LSS, token.LEQ, token.GTR, token.GEQ:
545
546 switch {
547 case !allOrdered(x.typ):
548 errOp = x
549 goto Error
550 case !allOrdered(y.typ):
551 errOp = y
552 goto Error
553 }
554
555 default:
556 panic("unreachable")
557 }
558
559
560 if x.mode == constant_ && y.mode == constant_ {
561 x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
562
563
564 } else {
565 x.mode = value
566
567
568
569
570 check.updateExprType(x.expr, Default(x.typ), true)
571 check.updateExprType(y.expr, Default(y.typ), true)
572 }
573
574
575
576 x.typ = Typ[UntypedBool]
577 return
578
579 Error:
580
581 if cause == "" {
582 if isTypeParam(x.typ) || isTypeParam(y.typ) {
583
584 if !isTypeParam(x.typ) {
585 errOp = y
586 }
587 cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ, op)
588 } else {
589
590 what := compositeKind(errOp.typ)
591 if what == "" {
592 what = check.sprintf("%s", errOp.typ)
593 }
594 cause = check.sprintf("operator %s not defined on %s", op, what)
595 }
596 }
597 if switchCase {
598 check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause)
599 } else {
600 check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
601 }
602 x.mode = invalid
603 }
604
605
606
607 func (check *Checker) incomparableCause(typ Type) string {
608 switch under(typ).(type) {
609 case *Slice, *Signature, *Map:
610 return compositeKind(typ) + " can only be compared to nil"
611 }
612
613 return comparableType(typ, true, nil).format(check)
614 }
615
616
617 func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
618
619
620 var xval constant.Value
621 if x.mode == constant_ {
622 xval = constant.ToInt(x.val)
623 }
624
625 if allInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
626
627
628 } else {
629
630 check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
631 x.mode = invalid
632 return
633 }
634
635
636
637
638
639
640 var yval constant.Value
641 if y.mode == constant_ {
642
643 yval = constant.ToInt(y.val)
644 if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
645 check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
646 x.mode = invalid
647 return
648 }
649
650 if isUntyped(y.typ) {
651
652
653 check.representable(y, Typ[Uint])
654 if y.mode == invalid {
655 x.mode = invalid
656 return
657 }
658 }
659 } else {
660
661 switch {
662 case allInteger(y.typ):
663 if !allUnsigned(y.typ) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
664 x.mode = invalid
665 return
666 }
667 case isUntyped(y.typ):
668
669
670 check.convertUntyped(y, Typ[Uint])
671 if y.mode == invalid {
672 x.mode = invalid
673 return
674 }
675 default:
676 check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
677 x.mode = invalid
678 return
679 }
680 }
681
682 if x.mode == constant_ {
683 if y.mode == constant_ {
684
685 if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
686 x.val = constant.MakeUnknown()
687
688 if !isInteger(x.typ) {
689 x.typ = Typ[UntypedInt]
690 }
691 return
692 }
693
694 const shiftBound = 1023 - 1 + 52
695 s, ok := constant.Uint64Val(yval)
696 if !ok || s > shiftBound {
697 check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
698 x.mode = invalid
699 return
700 }
701
702
703
704
705 if !isInteger(x.typ) {
706 x.typ = Typ[UntypedInt]
707 }
708
709 x.val = constant.Shift(xval, op, uint(s))
710 x.expr = e
711 check.overflow(x, opPos(x.expr))
712 return
713 }
714
715
716 if isUntyped(x.typ) {
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736 if info, found := check.untyped[x.expr]; found {
737 info.isLhs = true
738 check.untyped[x.expr] = info
739 }
740
741 x.mode = value
742 return
743 }
744 }
745
746
747 if !allInteger(x.typ) {
748 check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
749 x.mode = invalid
750 return
751 }
752
753 x.mode = value
754 }
755
756 var binaryOpPredicates opPredicates
757
758 func init() {
759
760 binaryOpPredicates = opPredicates{
761 token.ADD: allNumericOrString,
762 token.SUB: allNumeric,
763 token.MUL: allNumeric,
764 token.QUO: allNumeric,
765 token.REM: allInteger,
766
767 token.AND: allInteger,
768 token.OR: allInteger,
769 token.XOR: allInteger,
770 token.AND_NOT: allInteger,
771
772 token.LAND: allBoolean,
773 token.LOR: allBoolean,
774 }
775 }
776
777
778
779 func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) {
780 var y operand
781
782 check.expr(nil, x, lhs)
783 check.expr(nil, &y, rhs)
784
785 if x.mode == invalid {
786 return
787 }
788 if y.mode == invalid {
789 x.mode = invalid
790 x.expr = y.expr
791 return
792 }
793
794 if isShift(op) {
795 check.shift(x, &y, e, op)
796 return
797 }
798
799 check.matchTypes(x, &y)
800 if x.mode == invalid {
801 return
802 }
803
804 if isComparison(op) {
805 check.comparison(x, &y, op, false)
806 return
807 }
808
809 if !Identical(x.typ, y.typ) {
810
811
812 if isValid(x.typ) && isValid(y.typ) {
813 var posn positioner = x
814 if e != nil {
815 posn = e
816 }
817 if e != nil {
818 check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
819 } else {
820 check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
821 }
822 }
823 x.mode = invalid
824 return
825 }
826
827 if !check.op(binaryOpPredicates, x, op) {
828 x.mode = invalid
829 return
830 }
831
832 if op == token.QUO || op == token.REM {
833
834 if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
835 check.error(&y, DivByZero, invalidOp+"division by zero")
836 x.mode = invalid
837 return
838 }
839
840
841 if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) {
842 re, im := constant.Real(y.val), constant.Imag(y.val)
843 re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
844 if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
845 check.error(&y, DivByZero, invalidOp+"division by zero")
846 x.mode = invalid
847 return
848 }
849 }
850 }
851
852 if x.mode == constant_ && y.mode == constant_ {
853
854 if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
855 x.val = constant.MakeUnknown()
856
857 return
858 }
859
860 if op == token.QUO && isInteger(x.typ) {
861 op = token.QUO_ASSIGN
862 }
863 x.val = constant.BinaryOp(x.val, op, y.val)
864 x.expr = e
865 check.overflow(x, opPos)
866 return
867 }
868
869 x.mode = value
870
871 }
872
873
874
875 func (check *Checker) matchTypes(x, y *operand) {
876
877
878
879
880
881
882
883
884
885 mayConvert := func(x, y *operand) bool {
886
887 if isTyped(x.typ) && isTyped(y.typ) {
888 return false
889 }
890
891
892
893
894 if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
895 return true
896 }
897
898 if allBoolean(x.typ) != allBoolean(y.typ) {
899 return false
900 }
901
902 if allString(x.typ) != allString(y.typ) {
903 return false
904 }
905
906 if x.isNil() {
907 return hasNil(y.typ)
908 }
909 if y.isNil() {
910 return hasNil(x.typ)
911 }
912
913
914 if isPointer(x.typ) || isPointer(y.typ) {
915 return false
916 }
917 return true
918 }
919
920 if mayConvert(x, y) {
921 check.convertUntyped(x, y.typ)
922 if x.mode == invalid {
923 return
924 }
925 check.convertUntyped(y, x.typ)
926 if y.mode == invalid {
927 x.mode = invalid
928 return
929 }
930 }
931 }
932
933
934
935 type exprKind int
936
937 const (
938 conversion exprKind = iota
939 expression
940 statement
941 )
942
943
944
945 type target struct {
946 sig *Signature
947 desc string
948 }
949
950
951
952 func newTarget(typ Type, desc string) *target {
953 if typ != nil {
954 if sig, _ := under(typ).(*Signature); sig != nil {
955 return &target{sig, desc}
956 }
957 }
958 return nil
959 }
960
961
962
963
964
965
966
967
968 func (check *Checker) rawExpr(T *target, x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind {
969 if check.conf._Trace {
970 check.trace(e.Pos(), "-- expr %s", e)
971 check.indent++
972 defer func() {
973 check.indent--
974 check.trace(e.Pos(), "=> %s", x)
975 }()
976 }
977
978 kind := check.exprInternal(T, x, e, hint)
979
980 if !allowGeneric {
981 check.nonGeneric(T, x)
982 }
983
984 check.record(x)
985
986 return kind
987 }
988
989
990
991
992 func (check *Checker) nonGeneric(T *target, x *operand) {
993 if x.mode == invalid || x.mode == novalue {
994 return
995 }
996 var what string
997 switch t := x.typ.(type) {
998 case *Alias, *Named:
999 if isGeneric(t) {
1000 what = "type"
1001 }
1002 case *Signature:
1003 if t.tparams != nil {
1004 if enableReverseTypeInference && T != nil {
1005 check.funcInst(T, x.Pos(), x, nil, true)
1006 return
1007 }
1008 what = "function"
1009 }
1010 }
1011 if what != "" {
1012 check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
1013 x.mode = invalid
1014 x.typ = Typ[Invalid]
1015 }
1016 }
1017
1018
1019
1020
1021 func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type) exprKind {
1022
1023
1024 x.mode = invalid
1025 x.typ = Typ[Invalid]
1026
1027 switch e := e.(type) {
1028 case *ast.BadExpr:
1029 goto Error
1030
1031 case *ast.Ident:
1032 check.ident(x, e, nil, false)
1033
1034 case *ast.Ellipsis:
1035
1036 check.error(e, InvalidSyntaxTree, "invalid use of ...")
1037 goto Error
1038
1039 case *ast.BasicLit:
1040 check.basicLit(x, e)
1041 if x.mode == invalid {
1042 goto Error
1043 }
1044
1045 case *ast.FuncLit:
1046 check.funcLit(x, e)
1047 if x.mode == invalid {
1048 goto Error
1049 }
1050
1051 case *ast.CompositeLit:
1052 check.compositeLit(x, e, hint)
1053 if x.mode == invalid {
1054 goto Error
1055 }
1056
1057 case *ast.ParenExpr:
1058
1059 kind := check.rawExpr(nil, x, e.X, nil, false)
1060 x.expr = e
1061 return kind
1062
1063 case *ast.SelectorExpr:
1064 check.selector(x, e, nil, false)
1065
1066 case *ast.IndexExpr, *ast.IndexListExpr:
1067 ix := unpackIndexedExpr(e)
1068 if check.indexExpr(x, ix) {
1069 if !enableReverseTypeInference {
1070 T = nil
1071 }
1072 check.funcInst(T, e.Pos(), x, ix, true)
1073 }
1074 if x.mode == invalid {
1075 goto Error
1076 }
1077
1078 case *ast.SliceExpr:
1079 check.sliceExpr(x, e)
1080 if x.mode == invalid {
1081 goto Error
1082 }
1083
1084 case *ast.TypeAssertExpr:
1085 check.expr(nil, x, e.X)
1086 if x.mode == invalid {
1087 goto Error
1088 }
1089
1090 if e.Type == nil {
1091
1092
1093 check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
1094 goto Error
1095 }
1096 if isTypeParam(x.typ) {
1097 check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
1098 goto Error
1099 }
1100 if _, ok := under(x.typ).(*Interface); !ok {
1101 check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
1102 goto Error
1103 }
1104 T := check.varType(e.Type)
1105 if !isValid(T) {
1106 goto Error
1107 }
1108 check.typeAssertion(e, x, T, false)
1109 x.mode = commaok
1110 x.typ = T
1111
1112 case *ast.CallExpr:
1113 return check.callExpr(x, e)
1114
1115 case *ast.StarExpr:
1116 check.exprOrType(x, e.X, false)
1117 switch x.mode {
1118 case invalid:
1119 goto Error
1120 case typexpr:
1121 check.validVarType(e.X, x.typ)
1122 x.typ = &Pointer{base: x.typ}
1123 default:
1124 var base Type
1125 if !underIs(x.typ, func(u Type) bool {
1126 p, _ := u.(*Pointer)
1127 if p == nil {
1128 check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
1129 return false
1130 }
1131 if base != nil && !Identical(p.base, base) {
1132 check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
1133 return false
1134 }
1135 base = p.base
1136 return true
1137 }) {
1138 goto Error
1139 }
1140 x.mode = variable
1141 x.typ = base
1142 }
1143
1144 case *ast.UnaryExpr:
1145 check.unary(x, e)
1146 if x.mode == invalid {
1147 goto Error
1148 }
1149 if e.Op == token.ARROW {
1150 x.expr = e
1151 return statement
1152 }
1153
1154 case *ast.BinaryExpr:
1155 check.binary(x, e, e.X, e.Y, e.Op, e.OpPos)
1156 if x.mode == invalid {
1157 goto Error
1158 }
1159
1160 case *ast.KeyValueExpr:
1161
1162 check.error(e, InvalidSyntaxTree, "no key:value expected")
1163 goto Error
1164
1165 case *ast.ArrayType, *ast.StructType, *ast.FuncType,
1166 *ast.InterfaceType, *ast.MapType, *ast.ChanType:
1167 x.mode = typexpr
1168 x.typ = check.typ(e)
1169
1170
1171
1172
1173
1174
1175 default:
1176 panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
1177 }
1178
1179
1180 x.expr = e
1181 return expression
1182
1183 Error:
1184 x.mode = invalid
1185 x.expr = e
1186 return statement
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197 func keyVal(x constant.Value) interface{} {
1198 switch x.Kind() {
1199 case constant.Complex:
1200 f := constant.ToFloat(x)
1201 if f.Kind() != constant.Float {
1202 r, _ := constant.Float64Val(constant.Real(x))
1203 i, _ := constant.Float64Val(constant.Imag(x))
1204 return complex(r, i)
1205 }
1206 x = f
1207 fallthrough
1208 case constant.Float:
1209 i := constant.ToInt(x)
1210 if i.Kind() != constant.Int {
1211 v, _ := constant.Float64Val(x)
1212 return v
1213 }
1214 x = i
1215 fallthrough
1216 case constant.Int:
1217 if v, ok := constant.Int64Val(x); ok {
1218 return v
1219 }
1220 if v, ok := constant.Uint64Val(x); ok {
1221 return v
1222 }
1223 case constant.String:
1224 return constant.StringVal(x)
1225 case constant.Bool:
1226 return constant.BoolVal(x)
1227 }
1228 return x
1229 }
1230
1231
1232 func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch bool) {
1233 var cause string
1234 if check.assertableTo(x.typ, T, &cause) {
1235 return
1236 }
1237
1238 if typeSwitch {
1239 check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
1240 return
1241 }
1242
1243 check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
1244 }
1245
1246
1247
1248
1249
1250
1251 func (check *Checker) expr(T *target, x *operand, e ast.Expr) {
1252 check.rawExpr(T, x, e, nil, false)
1253 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1254 check.singleValue(x)
1255 }
1256
1257
1258 func (check *Checker) genericExpr(x *operand, e ast.Expr) {
1259 check.rawExpr(nil, x, e, nil, true)
1260 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1261 check.singleValue(x)
1262 }
1263
1264
1265
1266
1267
1268
1269 func (check *Checker) multiExpr(e ast.Expr, allowCommaOk bool) (list []*operand, commaOk bool) {
1270 var x operand
1271 check.rawExpr(nil, &x, e, nil, false)
1272 check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
1273
1274 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
1275
1276 list = make([]*operand, t.Len())
1277 for i, v := range t.vars {
1278 list[i] = &operand{mode: value, expr: e, typ: v.typ}
1279 }
1280 return
1281 }
1282
1283
1284 list = []*operand{&x}
1285 if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
1286 x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
1287 if x.mode == commaerr {
1288 x2.typ = universeError
1289 }
1290 list = append(list, x2)
1291 commaOk = true
1292 }
1293
1294 return
1295 }
1296
1297
1298
1299
1300 func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
1301 assert(hint != nil)
1302 check.rawExpr(nil, x, e, hint, false)
1303 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1304 check.singleValue(x)
1305 }
1306
1307
1308
1309
1310
1311 func (check *Checker) exprOrType(x *operand, e ast.Expr, allowGeneric bool) {
1312 check.rawExpr(nil, x, e, nil, allowGeneric)
1313 check.exclude(x, 1<<novalue)
1314 check.singleValue(x)
1315 }
1316
1317
1318
1319 func (check *Checker) exclude(x *operand, modeset uint) {
1320 if modeset&(1<<x.mode) != 0 {
1321 var msg string
1322 var code Code
1323 switch x.mode {
1324 case novalue:
1325 if modeset&(1<<typexpr) != 0 {
1326 msg = "%s used as value"
1327 } else {
1328 msg = "%s used as value or type"
1329 }
1330 code = TooManyValues
1331 case builtin:
1332 msg = "%s must be called"
1333 code = UncalledBuiltin
1334 case typexpr:
1335 msg = "%s is not an expression"
1336 code = NotAnExpr
1337 default:
1338 panic("unreachable")
1339 }
1340 check.errorf(x, code, msg, x)
1341 x.mode = invalid
1342 }
1343 }
1344
1345
1346 func (check *Checker) singleValue(x *operand) {
1347 if x.mode == value {
1348
1349 if t, ok := x.typ.(*Tuple); ok {
1350 assert(t.Len() != 1)
1351 check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
1352 x.mode = invalid
1353 }
1354 }
1355 }
1356
View as plain text