1
2
3
4
5 package typecheck
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/types"
11 "cmd/internal/src"
12 )
13
14 func RangeExprType(t *types.Type) *types.Type {
15 if t.IsPtr() && t.Elem().IsArray() {
16 return t.Elem()
17 }
18 return t
19 }
20
21 func typecheckrangeExpr(n *ir.RangeStmt) {
22 n.X = Expr(n.X)
23 if n.X.Type() == nil {
24 return
25 }
26
27 t := RangeExprType(n.X.Type())
28
29 if n.Key != nil && !ir.DeclaredBy(n.Key, n) {
30 n.Key = AssignExpr(n.Key)
31 }
32 if n.Value != nil && !ir.DeclaredBy(n.Value, n) {
33 n.Value = AssignExpr(n.Value)
34 }
35
36 var tk, tv *types.Type
37 toomany := false
38 switch t.Kind() {
39 default:
40 base.ErrorfAt(n.Pos(), "cannot range over %L", n.X)
41 return
42
43 case types.TARRAY, types.TSLICE:
44 tk = types.Types[types.TINT]
45 tv = t.Elem()
46
47 case types.TMAP:
48 tk = t.Key()
49 tv = t.Elem()
50
51 case types.TCHAN:
52 if !t.ChanDir().CanRecv() {
53 base.ErrorfAt(n.Pos(), "invalid operation: range %v (receive from send-only type %v)", n.X, n.X.Type())
54 return
55 }
56
57 tk = t.Elem()
58 tv = nil
59 if n.Value != nil {
60 toomany = true
61 }
62
63 case types.TSTRING:
64 tk = types.Types[types.TINT]
65 tv = types.RuneType
66 }
67
68 if toomany {
69 base.ErrorfAt(n.Pos(), "too many variables in range")
70 }
71
72 do := func(nn ir.Node, t *types.Type) {
73 if nn != nil {
74 if ir.DeclaredBy(nn, n) {
75 nn.SetType(t)
76 } else if nn.Type() != nil {
77 if op, why := Assignop(t, nn.Type()); op == ir.OXXX {
78 base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t, nn, why)
79 }
80 }
81 checkassign(n, nn)
82 }
83 }
84 do(n.Key, tk)
85 do(n.Value, tv)
86 }
87
88
89
90
91 func tcAssign(n *ir.AssignStmt) {
92 if base.EnableTrace && base.Flag.LowerT {
93 defer tracePrint("tcAssign", n)(nil)
94 }
95
96 if n.Y == nil {
97 n.X = AssignExpr(n.X)
98 return
99 }
100
101 lhs, rhs := []ir.Node{n.X}, []ir.Node{n.Y}
102 assign(n, lhs, rhs)
103 n.X, n.Y = lhs[0], rhs[0]
104
105
106 if !ir.IsBlank(n.X) {
107 types.CheckSize(n.X.Type())
108 }
109 }
110
111 func tcAssignList(n *ir.AssignListStmt) {
112 if base.EnableTrace && base.Flag.LowerT {
113 defer tracePrint("tcAssignList", n)(nil)
114 }
115
116 assign(n, n.Lhs, n.Rhs)
117 }
118
119 func assign(stmt ir.Node, lhs, rhs []ir.Node) {
120
121
122
123
124
125
126
127
128 checkLHS := func(i int, typ *types.Type) {
129 lhs[i] = Resolve(lhs[i])
130 if base.Flag.G != 0 || base.Debug.Unified != 0 {
131
132 if n := lhs[i]; typ != nil && ir.DeclaredBy(n, stmt) && n.Type() == nil {
133 base.Assertf(typ.Kind() == types.TNIL, "unexpected untyped nil")
134 n.SetType(defaultType(typ))
135 }
136 } else {
137
138 if n := lhs[i]; typ != nil && ir.DeclaredBy(n, stmt) && n.Name().Ntype == nil {
139 if typ.Kind() != types.TNIL {
140 n.SetType(defaultType(typ))
141 } else {
142 base.Errorf("use of untyped nil")
143 }
144 }
145 }
146
147 if lhs[i].Typecheck() == 0 {
148 lhs[i] = AssignExpr(lhs[i])
149 }
150 checkassign(stmt, lhs[i])
151 }
152
153 assignType := func(i int, typ *types.Type) {
154 checkLHS(i, typ)
155 if typ != nil {
156 checkassignto(typ, lhs[i])
157 }
158 }
159
160 cr := len(rhs)
161 if len(rhs) == 1 {
162 rhs[0] = typecheck(rhs[0], ctxExpr|ctxMultiOK)
163 if rtyp := rhs[0].Type(); rtyp != nil && rtyp.IsFuncArgStruct() {
164 cr = rtyp.NumFields()
165 }
166 } else {
167 Exprs(rhs)
168 }
169
170
171 assignOK:
172 for len(lhs) == 2 && cr == 1 {
173 stmt := stmt.(*ir.AssignListStmt)
174 r := rhs[0]
175
176 switch r.Op() {
177 case ir.OINDEXMAP:
178 stmt.SetOp(ir.OAS2MAPR)
179 case ir.ORECV:
180 stmt.SetOp(ir.OAS2RECV)
181 case ir.ODOTTYPE:
182 r := r.(*ir.TypeAssertExpr)
183 stmt.SetOp(ir.OAS2DOTTYPE)
184 r.SetOp(ir.ODOTTYPE2)
185 case ir.ODYNAMICDOTTYPE:
186 r := r.(*ir.DynamicTypeAssertExpr)
187 stmt.SetOp(ir.OAS2DOTTYPE)
188 r.SetOp(ir.ODYNAMICDOTTYPE2)
189 default:
190 break assignOK
191 }
192
193 assignType(0, r.Type())
194 assignType(1, types.UntypedBool)
195 return
196 }
197
198 if len(lhs) != cr {
199 if r, ok := rhs[0].(*ir.CallExpr); ok && len(rhs) == 1 {
200 if r.Type() != nil {
201 base.ErrorfAt(stmt.Pos(), "assignment mismatch: %d variable%s but %v returns %d value%s", len(lhs), plural(len(lhs)), r.X, cr, plural(cr))
202 }
203 } else {
204 base.ErrorfAt(stmt.Pos(), "assignment mismatch: %d variable%s but %v value%s", len(lhs), plural(len(lhs)), len(rhs), plural(len(rhs)))
205 }
206
207 for i := range lhs {
208 checkLHS(i, nil)
209 }
210 return
211 }
212
213
214 if cr > len(rhs) {
215 stmt := stmt.(*ir.AssignListStmt)
216 stmt.SetOp(ir.OAS2FUNC)
217 r := rhs[0].(*ir.CallExpr)
218 rtyp := r.Type()
219
220 mismatched := false
221 failed := false
222 for i := range lhs {
223 result := rtyp.Field(i).Type
224 assignType(i, result)
225
226 if lhs[i].Type() == nil || result == nil {
227 failed = true
228 } else if lhs[i] != ir.BlankNode && !types.Identical(lhs[i].Type(), result) {
229 mismatched = true
230 }
231 }
232 if mismatched && !failed {
233 RewriteMultiValueCall(stmt, r)
234 }
235 return
236 }
237
238 for i, r := range rhs {
239 checkLHS(i, r.Type())
240 if lhs[i].Type() != nil {
241 rhs[i] = AssignConv(r, lhs[i].Type(), "assignment")
242 }
243 }
244 }
245
246 func plural(n int) string {
247 if n == 1 {
248 return ""
249 }
250 return "s"
251 }
252
253
254 func tcCheckNil(n *ir.UnaryExpr) ir.Node {
255 n.X = Expr(n.X)
256 if !n.X.Type().IsPtrShaped() {
257 base.FatalfAt(n.Pos(), "%L is not pointer shaped", n.X)
258 }
259 return n
260 }
261
262
263 func tcFor(n *ir.ForStmt) ir.Node {
264 Stmts(n.Init())
265 n.Cond = Expr(n.Cond)
266 n.Cond = DefaultLit(n.Cond, nil)
267 if n.Cond != nil {
268 t := n.Cond.Type()
269 if t != nil && !t.IsBoolean() {
270 base.Errorf("non-bool %L used as for condition", n.Cond)
271 }
272 }
273 n.Post = Stmt(n.Post)
274 if n.Op() == ir.OFORUNTIL {
275 Stmts(n.Late)
276 }
277 Stmts(n.Body)
278 return n
279 }
280
281 func tcGoDefer(n *ir.GoDeferStmt) {
282 what := "defer"
283 if n.Op() == ir.OGO {
284 what = "go"
285 }
286
287 switch n.Call.Op() {
288
289 case ir.OCALLINTER,
290 ir.OCALLMETH,
291 ir.OCALLFUNC,
292 ir.OCLOSE,
293 ir.OCOPY,
294 ir.ODELETE,
295 ir.OPANIC,
296 ir.OPRINT,
297 ir.OPRINTN,
298 ir.ORECOVER:
299 return
300
301 case ir.OAPPEND,
302 ir.OCAP,
303 ir.OCOMPLEX,
304 ir.OIMAG,
305 ir.OLEN,
306 ir.OMAKE,
307 ir.OMAKESLICE,
308 ir.OMAKECHAN,
309 ir.OMAKEMAP,
310 ir.ONEW,
311 ir.OREAL,
312 ir.OLITERAL:
313 if orig := ir.Orig(n.Call); orig.Op() == ir.OCONV {
314 break
315 }
316 base.ErrorfAt(n.Pos(), "%s discards result of %v", what, n.Call)
317 return
318 }
319
320
321
322 if n.Call.Type() == nil || n.Call.Type().Broke() {
323 return
324 }
325
326 if !n.Diag() {
327
328
329 n.SetDiag(true)
330 base.ErrorfAt(n.Pos(), "%s requires function call, not conversion", what)
331 }
332 }
333
334
335 func tcIf(n *ir.IfStmt) ir.Node {
336 Stmts(n.Init())
337 n.Cond = Expr(n.Cond)
338 n.Cond = DefaultLit(n.Cond, nil)
339 if n.Cond != nil {
340 t := n.Cond.Type()
341 if t != nil && !t.IsBoolean() {
342 base.Errorf("non-bool %L used as if condition", n.Cond)
343 }
344 }
345 Stmts(n.Body)
346 Stmts(n.Else)
347 return n
348 }
349
350
351 func tcRange(n *ir.RangeStmt) {
352
353
354
355
356
357
358
359
360
361 typecheckrangeExpr(n)
362
363
364 n.SetTypecheck(1)
365 if n.Key != nil && n.Key.Typecheck() == 0 {
366 n.Key = AssignExpr(n.Key)
367 }
368 if n.Value != nil && n.Value.Typecheck() == 0 {
369 n.Value = AssignExpr(n.Value)
370 }
371
372 Stmts(n.Body)
373 }
374
375
376 func tcReturn(n *ir.ReturnStmt) ir.Node {
377 typecheckargs(n)
378 if ir.CurFunc == nil {
379 base.Errorf("return outside function")
380 n.SetType(nil)
381 return n
382 }
383
384 if ir.HasNamedResults(ir.CurFunc) && len(n.Results) == 0 {
385 return n
386 }
387 typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, func() string { return "return argument" })
388 return n
389 }
390
391
392 func tcSelect(sel *ir.SelectStmt) {
393 var def *ir.CommClause
394 lno := ir.SetPos(sel)
395 Stmts(sel.Init())
396 for _, ncase := range sel.Cases {
397 if ncase.Comm == nil {
398
399 if def != nil {
400 base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def))
401 } else {
402 def = ncase
403 }
404 } else {
405 n := Stmt(ncase.Comm)
406 ncase.Comm = n
407 oselrecv2 := func(dst, recv ir.Node, def bool) {
408 selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
409 selrecv.Def = def
410 selrecv.SetTypecheck(1)
411 selrecv.SetInit(n.Init())
412 ncase.Comm = selrecv
413 }
414 switch n.Op() {
415 default:
416 pos := n.Pos()
417 if n.Op() == ir.ONAME {
418
419
420
421
422 pos = ncase.Pos()
423 }
424 base.ErrorfAt(pos, "select case must be receive, send or assign recv")
425
426 case ir.OAS:
427
428
429
430 n := n.(*ir.AssignStmt)
431 if r := n.Y; r.Op() == ir.OCONVNOP || r.Op() == ir.OCONVIFACE {
432 r := r.(*ir.ConvExpr)
433 if r.Implicit() {
434 n.Y = r.X
435 }
436 }
437 if n.Y.Op() != ir.ORECV {
438 base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
439 break
440 }
441 oselrecv2(n.X, n.Y, n.Def)
442
443 case ir.OAS2RECV:
444 n := n.(*ir.AssignListStmt)
445 if n.Rhs[0].Op() != ir.ORECV {
446 base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
447 break
448 }
449 n.SetOp(ir.OSELRECV2)
450
451 case ir.ORECV:
452
453 n := n.(*ir.UnaryExpr)
454 oselrecv2(ir.BlankNode, n, false)
455
456 case ir.OSEND:
457 break
458 }
459 }
460
461 Stmts(ncase.Body)
462 }
463
464 base.Pos = lno
465 }
466
467
468 func tcSend(n *ir.SendStmt) ir.Node {
469 n.Chan = Expr(n.Chan)
470 n.Value = Expr(n.Value)
471 n.Chan = DefaultLit(n.Chan, nil)
472 t := n.Chan.Type()
473 if t == nil {
474 return n
475 }
476 if !t.IsChan() {
477 base.Errorf("invalid operation: %v (send to non-chan type %v)", n, t)
478 return n
479 }
480
481 if !t.ChanDir().CanSend() {
482 base.Errorf("invalid operation: %v (send to receive-only type %v)", n, t)
483 return n
484 }
485
486 n.Value = AssignConv(n.Value, t.Elem(), "send")
487 if n.Value.Type() == nil {
488 return n
489 }
490 return n
491 }
492
493
494 func tcSwitch(n *ir.SwitchStmt) {
495 Stmts(n.Init())
496 if n.Tag != nil && n.Tag.Op() == ir.OTYPESW {
497 tcSwitchType(n)
498 } else {
499 tcSwitchExpr(n)
500 }
501 }
502
503 func tcSwitchExpr(n *ir.SwitchStmt) {
504 t := types.Types[types.TBOOL]
505 if n.Tag != nil {
506 n.Tag = Expr(n.Tag)
507 n.Tag = DefaultLit(n.Tag, nil)
508 t = n.Tag.Type()
509 }
510
511 var nilonly string
512 if t != nil {
513 switch {
514 case t.IsMap():
515 nilonly = "map"
516 case t.Kind() == types.TFUNC:
517 nilonly = "func"
518 case t.IsSlice():
519 nilonly = "slice"
520
521 case !types.IsComparable(t):
522 if t.IsStruct() {
523 base.ErrorfAt(n.Pos(), "cannot switch on %L (struct containing %v cannot be compared)", n.Tag, types.IncomparableField(t).Type)
524 } else {
525 base.ErrorfAt(n.Pos(), "cannot switch on %L", n.Tag)
526 }
527 t = nil
528 }
529 }
530
531 var defCase ir.Node
532 var cs constSet
533 for _, ncase := range n.Cases {
534 ls := ncase.List
535 if len(ls) == 0 {
536 if defCase != nil {
537 base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase))
538 } else {
539 defCase = ncase
540 }
541 }
542
543 for i := range ls {
544 ir.SetPos(ncase)
545 ls[i] = Expr(ls[i])
546 ls[i] = DefaultLit(ls[i], t)
547 n1 := ls[i]
548 if t == nil || n1.Type() == nil {
549 continue
550 }
551
552 if nilonly != "" && !ir.IsNil(n1) {
553 base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Tag)
554 } else if t.IsInterface() && !n1.Type().IsInterface() && !types.IsComparable(n1.Type()) {
555 base.ErrorfAt(ncase.Pos(), "invalid case %L in switch (incomparable type)", n1)
556 } else {
557 op1, _ := Assignop(n1.Type(), t)
558 op2, _ := Assignop(t, n1.Type())
559 if op1 == ir.OXXX && op2 == ir.OXXX {
560 if n.Tag != nil {
561 base.ErrorfAt(ncase.Pos(), "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Tag, n1.Type(), t)
562 } else {
563 base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type())
564 }
565 }
566 }
567
568
569
570
571
572
573
574 if !n1.Type().IsBoolean() {
575 cs.add(ncase.Pos(), n1, "case", "switch")
576 }
577 }
578
579 Stmts(ncase.Body)
580 }
581 }
582
583 func tcSwitchType(n *ir.SwitchStmt) {
584 guard := n.Tag.(*ir.TypeSwitchGuard)
585 guard.X = Expr(guard.X)
586 t := guard.X.Type()
587 if t != nil && !t.IsInterface() {
588 base.ErrorfAt(n.Pos(), "cannot type switch on non-interface value %L", guard.X)
589 t = nil
590 }
591
592
593
594
595 if v := guard.Tag; v != nil && !ir.IsBlank(v) && len(n.Cases) == 0 {
596 base.ErrorfAt(v.Pos(), "%v declared but not used", v.Sym())
597 }
598
599 var defCase, nilCase ir.Node
600 var ts typeSet
601 for _, ncase := range n.Cases {
602 ls := ncase.List
603 if len(ls) == 0 {
604 if defCase != nil {
605 base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase))
606 } else {
607 defCase = ncase
608 }
609 }
610
611 for i := range ls {
612 ls[i] = typecheck(ls[i], ctxExpr|ctxType)
613 n1 := ls[i]
614 if t == nil || n1.Type() == nil {
615 continue
616 }
617
618 var missing, have *types.Field
619 var ptr int
620 if ir.IsNil(n1) {
621 if nilCase != nil {
622 base.ErrorfAt(ncase.Pos(), "multiple nil cases in type switch (first at %v)", ir.Line(nilCase))
623 } else {
624 nilCase = ncase
625 }
626 continue
627 }
628 if n1.Op() != ir.OTYPE {
629 base.ErrorfAt(ncase.Pos(), "%L is not a type", n1)
630 continue
631 }
632 if !n1.Type().IsInterface() && !implements(n1.Type(), t, &missing, &have, &ptr) && !missing.Broke() {
633 if have != nil && !have.Broke() {
634 base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
635 " (wrong type for %v method)\n\thave %v%S\n\twant %v%S", guard.X, n1.Type(), missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
636 } else if ptr != 0 {
637 base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
638 " (%v method has pointer receiver)", guard.X, n1.Type(), missing.Sym)
639 } else {
640 base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
641 " (missing %v method)", guard.X, n1.Type(), missing.Sym)
642 }
643 continue
644 }
645
646 ts.add(ncase.Pos(), n1.Type())
647 }
648
649 if ncase.Var != nil {
650
651 vt := t
652 if len(ls) == 1 {
653 if ls[0].Op() == ir.OTYPE {
654 vt = ls[0].Type()
655 } else if !ir.IsNil(ls[0]) {
656
657
658 vt = nil
659 }
660 }
661
662 nvar := ncase.Var
663 nvar.SetType(vt)
664 if vt != nil {
665 nvar = AssignExpr(nvar).(*ir.Name)
666 } else {
667
668 nvar.SetTypecheck(1)
669 nvar.SetWalkdef(1)
670 }
671 ncase.Var = nvar
672 }
673
674 Stmts(ncase.Body)
675 }
676 }
677
678 type typeSet struct {
679 m map[string]src.XPos
680 }
681
682 func (s *typeSet) add(pos src.XPos, typ *types.Type) {
683 if s.m == nil {
684 s.m = make(map[string]src.XPos)
685 }
686
687 ls := typ.LinkString()
688 if prev, ok := s.m[ls]; ok {
689 base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev))
690 return
691 }
692 s.m[ls] = pos
693 }
694
View as plain text