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