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 if allNumeric(x.typ) != allNumeric(y.typ) {
892 return false
893 }
894
895
896
897
898 if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
899 return true
900 }
901
902 if allBoolean(x.typ) != allBoolean(y.typ) {
903 return false
904 }
905
906 if allString(x.typ) != allString(y.typ) {
907 return false
908 }
909
910 if x.isNil() {
911 return hasNil(y.typ)
912 }
913 if y.isNil() {
914 return hasNil(x.typ)
915 }
916
917
918 if isPointer(x.typ) || isPointer(y.typ) {
919 return false
920 }
921 return true
922 }
923
924 if mayConvert(x, y) {
925 check.convertUntyped(x, y.typ)
926 if x.mode == invalid {
927 return
928 }
929 check.convertUntyped(y, x.typ)
930 if y.mode == invalid {
931 x.mode = invalid
932 return
933 }
934 }
935 }
936
937
938
939 type exprKind int
940
941 const (
942 conversion exprKind = iota
943 expression
944 statement
945 )
946
947
948
949 type target struct {
950 sig *Signature
951 desc string
952 }
953
954
955
956 func newTarget(typ Type, desc string) *target {
957 if typ != nil {
958 if sig, _ := under(typ).(*Signature); sig != nil {
959 return &target{sig, desc}
960 }
961 }
962 return nil
963 }
964
965
966
967
968
969
970
971
972 func (check *Checker) rawExpr(T *target, x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind {
973 if check.conf._Trace {
974 check.trace(e.Pos(), "-- expr %s", e)
975 check.indent++
976 defer func() {
977 check.indent--
978 check.trace(e.Pos(), "=> %s", x)
979 }()
980 }
981
982 kind := check.exprInternal(T, x, e, hint)
983
984 if !allowGeneric {
985 check.nonGeneric(T, x)
986 }
987
988 check.record(x)
989
990 return kind
991 }
992
993
994
995
996 func (check *Checker) nonGeneric(T *target, x *operand) {
997 if x.mode == invalid || x.mode == novalue {
998 return
999 }
1000 var what string
1001 switch t := x.typ.(type) {
1002 case *Alias, *Named:
1003 if isGeneric(t) {
1004 what = "type"
1005 }
1006 case *Signature:
1007 if t.tparams != nil {
1008 if enableReverseTypeInference && T != nil {
1009 check.funcInst(T, x.Pos(), x, nil, true)
1010 return
1011 }
1012 what = "function"
1013 }
1014 }
1015 if what != "" {
1016 check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
1017 x.mode = invalid
1018 x.typ = Typ[Invalid]
1019 }
1020 }
1021
1022
1023
1024
1025 func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type) exprKind {
1026
1027
1028 x.mode = invalid
1029 x.typ = Typ[Invalid]
1030
1031 switch e := e.(type) {
1032 case *ast.BadExpr:
1033 goto Error
1034
1035 case *ast.Ident:
1036 check.ident(x, e, nil, false)
1037
1038 case *ast.Ellipsis:
1039
1040 check.error(e, InvalidSyntaxTree, "invalid use of ...")
1041 goto Error
1042
1043 case *ast.BasicLit:
1044 check.basicLit(x, e)
1045 if x.mode == invalid {
1046 goto Error
1047 }
1048
1049 case *ast.FuncLit:
1050 check.funcLit(x, e)
1051 if x.mode == invalid {
1052 goto Error
1053 }
1054
1055 case *ast.CompositeLit:
1056 check.compositeLit(x, e, hint)
1057 if x.mode == invalid {
1058 goto Error
1059 }
1060
1061 case *ast.ParenExpr:
1062
1063 kind := check.rawExpr(nil, x, e.X, nil, false)
1064 x.expr = e
1065 return kind
1066
1067 case *ast.SelectorExpr:
1068 check.selector(x, e, nil, false)
1069
1070 case *ast.IndexExpr, *ast.IndexListExpr:
1071 ix := unpackIndexedExpr(e)
1072 if check.indexExpr(x, ix) {
1073 if !enableReverseTypeInference {
1074 T = nil
1075 }
1076 check.funcInst(T, e.Pos(), x, ix, true)
1077 }
1078 if x.mode == invalid {
1079 goto Error
1080 }
1081
1082 case *ast.SliceExpr:
1083 check.sliceExpr(x, e)
1084 if x.mode == invalid {
1085 goto Error
1086 }
1087
1088 case *ast.TypeAssertExpr:
1089 check.expr(nil, x, e.X)
1090 if x.mode == invalid {
1091 goto Error
1092 }
1093
1094 if e.Type == nil {
1095
1096
1097 check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
1098 goto Error
1099 }
1100 if isTypeParam(x.typ) {
1101 check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
1102 goto Error
1103 }
1104 if _, ok := under(x.typ).(*Interface); !ok {
1105 check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
1106 goto Error
1107 }
1108 T := check.varType(e.Type)
1109 if !isValid(T) {
1110 goto Error
1111 }
1112 check.typeAssertion(e, x, T, false)
1113 x.mode = commaok
1114 x.typ = T
1115
1116 case *ast.CallExpr:
1117 return check.callExpr(x, e)
1118
1119 case *ast.StarExpr:
1120 check.exprOrType(x, e.X, false)
1121 switch x.mode {
1122 case invalid:
1123 goto Error
1124 case typexpr:
1125 check.validVarType(e.X, x.typ)
1126 x.typ = &Pointer{base: x.typ}
1127 default:
1128 var base Type
1129 if !underIs(x.typ, func(u Type) bool {
1130 p, _ := u.(*Pointer)
1131 if p == nil {
1132 check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
1133 return false
1134 }
1135 if base != nil && !Identical(p.base, base) {
1136 check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
1137 return false
1138 }
1139 base = p.base
1140 return true
1141 }) {
1142 goto Error
1143 }
1144 x.mode = variable
1145 x.typ = base
1146 }
1147
1148 case *ast.UnaryExpr:
1149 check.unary(x, e)
1150 if x.mode == invalid {
1151 goto Error
1152 }
1153 if e.Op == token.ARROW {
1154 x.expr = e
1155 return statement
1156 }
1157
1158 case *ast.BinaryExpr:
1159 check.binary(x, e, e.X, e.Y, e.Op, e.OpPos)
1160 if x.mode == invalid {
1161 goto Error
1162 }
1163
1164 case *ast.KeyValueExpr:
1165
1166 check.error(e, InvalidSyntaxTree, "no key:value expected")
1167 goto Error
1168
1169 case *ast.ArrayType, *ast.StructType, *ast.FuncType,
1170 *ast.InterfaceType, *ast.MapType, *ast.ChanType:
1171 x.mode = typexpr
1172 x.typ = check.typ(e)
1173
1174
1175
1176
1177
1178
1179 default:
1180 panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
1181 }
1182
1183
1184 x.expr = e
1185 return expression
1186
1187 Error:
1188 x.mode = invalid
1189 x.expr = e
1190 return statement
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 func keyVal(x constant.Value) interface{} {
1202 switch x.Kind() {
1203 case constant.Complex:
1204 f := constant.ToFloat(x)
1205 if f.Kind() != constant.Float {
1206 r, _ := constant.Float64Val(constant.Real(x))
1207 i, _ := constant.Float64Val(constant.Imag(x))
1208 return complex(r, i)
1209 }
1210 x = f
1211 fallthrough
1212 case constant.Float:
1213 i := constant.ToInt(x)
1214 if i.Kind() != constant.Int {
1215 v, _ := constant.Float64Val(x)
1216 return v
1217 }
1218 x = i
1219 fallthrough
1220 case constant.Int:
1221 if v, ok := constant.Int64Val(x); ok {
1222 return v
1223 }
1224 if v, ok := constant.Uint64Val(x); ok {
1225 return v
1226 }
1227 case constant.String:
1228 return constant.StringVal(x)
1229 case constant.Bool:
1230 return constant.BoolVal(x)
1231 }
1232 return x
1233 }
1234
1235
1236 func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch bool) {
1237 var cause string
1238 if check.assertableTo(x.typ, T, &cause) {
1239 return
1240 }
1241
1242 if typeSwitch {
1243 check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
1244 return
1245 }
1246
1247 check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
1248 }
1249
1250
1251
1252
1253
1254
1255 func (check *Checker) expr(T *target, x *operand, e ast.Expr) {
1256 check.rawExpr(T, x, e, nil, false)
1257 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1258 check.singleValue(x)
1259 }
1260
1261
1262 func (check *Checker) genericExpr(x *operand, e ast.Expr) {
1263 check.rawExpr(nil, x, e, nil, true)
1264 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1265 check.singleValue(x)
1266 }
1267
1268
1269
1270
1271
1272
1273 func (check *Checker) multiExpr(e ast.Expr, allowCommaOk bool) (list []*operand, commaOk bool) {
1274 var x operand
1275 check.rawExpr(nil, &x, e, nil, false)
1276 check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
1277
1278 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
1279
1280 list = make([]*operand, t.Len())
1281 for i, v := range t.vars {
1282 list[i] = &operand{mode: value, expr: e, typ: v.typ}
1283 }
1284 return
1285 }
1286
1287
1288 list = []*operand{&x}
1289 if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
1290 x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
1291 if x.mode == commaerr {
1292 x2.typ = universeError
1293 }
1294 list = append(list, x2)
1295 commaOk = true
1296 }
1297
1298 return
1299 }
1300
1301
1302
1303
1304 func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
1305 assert(hint != nil)
1306 check.rawExpr(nil, x, e, hint, false)
1307 check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
1308 check.singleValue(x)
1309 }
1310
1311
1312
1313
1314
1315 func (check *Checker) exprOrType(x *operand, e ast.Expr, allowGeneric bool) {
1316 check.rawExpr(nil, x, e, nil, allowGeneric)
1317 check.exclude(x, 1<<novalue)
1318 check.singleValue(x)
1319 }
1320
1321
1322
1323 func (check *Checker) exclude(x *operand, modeset uint) {
1324 if modeset&(1<<x.mode) != 0 {
1325 var msg string
1326 var code Code
1327 switch x.mode {
1328 case novalue:
1329 if modeset&(1<<typexpr) != 0 {
1330 msg = "%s used as value"
1331 } else {
1332 msg = "%s used as value or type"
1333 }
1334 code = TooManyValues
1335 case builtin:
1336 msg = "%s must be called"
1337 code = UncalledBuiltin
1338 case typexpr:
1339 msg = "%s is not an expression"
1340 code = NotAnExpr
1341 default:
1342 panic("unreachable")
1343 }
1344 check.errorf(x, code, msg, x)
1345 x.mode = invalid
1346 }
1347 }
1348
1349
1350 func (check *Checker) singleValue(x *operand) {
1351 if x.mode == value {
1352
1353 if t, ok := x.typ.(*Tuple); ok {
1354 assert(t.Len() != 1)
1355 check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
1356 x.mode = invalid
1357 }
1358 }
1359 }
1360
View as plain text