github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/types/stmt.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements typechecking of statements. 6 7 package types 8 9 import ( 10 "fmt" 11 "go/ast" 12 "go/exact" 13 "go/token" 14 ) 15 16 func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) { 17 if trace { 18 if name == "" { 19 name = "<function literal>" 20 } 21 fmt.Printf("--- %s: %s {\n", name, sig) 22 defer fmt.Println("--- <end>") 23 } 24 25 // save/restore current context and setup function context 26 // (and use 0 indentation at function start) 27 defer func(ctxt context, indent int) { 28 check.context = ctxt 29 check.indent = indent 30 }(check.context, check.indent) 31 check.context = context{ 32 decl: decl, 33 scope: sig.scope, 34 sig: sig, 35 } 36 check.indent = 0 37 38 check.stmtList(0, body.List) 39 40 if check.hasLabel { 41 check.labels(body) 42 } 43 44 if sig.results.Len() > 0 && !check.isTerminating(body, "") { 45 check.error(body.Rbrace, "missing return") 46 } 47 48 // spec: "Implementation restriction: A compiler may make it illegal to 49 // declare a variable inside a function body if the variable is never used." 50 // (One could check each scope after use, but that distributes this check 51 // over several places because CloseScope is not always called explicitly.) 52 check.usage(sig.scope) 53 } 54 55 func (check *Checker) usage(scope *Scope) { 56 for _, obj := range scope.elems { 57 if v, _ := obj.(*Var); v != nil && !v.used { 58 check.softErrorf(v.pos, "%s declared but not used", v.name) 59 } 60 } 61 for _, scope := range scope.children { 62 check.usage(scope) 63 } 64 } 65 66 // stmtContext is a bitset describing which 67 // control-flow statements are permissible. 68 type stmtContext uint 69 70 const ( 71 breakOk stmtContext = 1 << iota 72 continueOk 73 fallthroughOk 74 ) 75 76 func (check *Checker) simpleStmt(s ast.Stmt) { 77 if s != nil { 78 check.stmt(0, s) 79 } 80 } 81 82 func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) { 83 ok := ctxt&fallthroughOk != 0 84 inner := ctxt &^ fallthroughOk 85 for i, s := range list { 86 inner := inner 87 if ok && i+1 == len(list) { 88 inner |= fallthroughOk 89 } 90 check.stmt(inner, s) 91 } 92 } 93 94 func (check *Checker) multipleDefaults(list []ast.Stmt) { 95 var first ast.Stmt 96 for _, s := range list { 97 var d ast.Stmt 98 switch c := s.(type) { 99 case *ast.CaseClause: 100 if len(c.List) == 0 { 101 d = s 102 } 103 case *ast.CommClause: 104 if c.Comm == nil { 105 d = s 106 } 107 default: 108 check.invalidAST(s.Pos(), "case/communication clause expected") 109 } 110 if d != nil { 111 if first != nil { 112 check.errorf(d.Pos(), "multiple defaults (first at %s)", first.Pos()) 113 } else { 114 first = d 115 } 116 } 117 } 118 } 119 120 func (check *Checker) openScope(s ast.Stmt, comment string) { 121 scope := NewScope(check.scope, comment) 122 check.recordScope(s, scope) 123 check.scope = scope 124 } 125 126 func (check *Checker) closeScope() { 127 check.scope = check.scope.Parent() 128 } 129 130 func assignOp(op token.Token) token.Token { 131 // token_test.go verifies the token ordering this function relies on 132 if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN { 133 return op + (token.ADD - token.ADD_ASSIGN) 134 } 135 return token.ILLEGAL 136 } 137 138 func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) { 139 var x operand 140 var msg string 141 switch check.rawExpr(&x, call, nil) { 142 case conversion: 143 msg = "requires function call, not conversion" 144 case expression: 145 msg = "discards result of" 146 case statement: 147 return 148 default: 149 unreachable() 150 } 151 check.errorf(x.pos(), "%s %s %s", keyword, msg, &x) 152 } 153 154 func (check *Checker) caseValues(x operand /* copy argument (not *operand!) */, values []ast.Expr) { 155 // No duplicate checking for now. See issue 4524. 156 for _, e := range values { 157 var y operand 158 check.expr(&y, e) 159 if y.mode == invalid { 160 return 161 } 162 // TODO(gri) The convertUntyped call pair below appears in other places. Factor! 163 // Order matters: By comparing y against x, error positions are at the case values. 164 check.convertUntyped(&y, x.typ) 165 if y.mode == invalid { 166 return 167 } 168 check.convertUntyped(&x, y.typ) 169 if x.mode == invalid { 170 return 171 } 172 check.comparison(&y, &x, token.EQL) 173 } 174 } 175 176 func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) { 177 L: 178 for _, e := range types { 179 T = check.typOrNil(e) 180 if T == Typ[Invalid] { 181 continue 182 } 183 // complain about duplicate types 184 // TODO(gri) use a type hash to avoid quadratic algorithm 185 for t, pos := range seen { 186 if T == nil && t == nil || T != nil && t != nil && Identical(T, t) { 187 // talk about "case" rather than "type" because of nil case 188 check.error(e.Pos(), "duplicate case in type switch") 189 check.errorf(pos, "\tprevious case %s", T) // secondary error, \t indented 190 continue L 191 } 192 } 193 seen[T] = e.Pos() 194 if T != nil { 195 check.typeAssertion(e.Pos(), x, xtyp, T) 196 } 197 } 198 return 199 } 200 201 // stmt typechecks statement s. 202 func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { 203 // statements cannot use iota in general 204 // (constant declarations set it explicitly) 205 assert(check.iota == nil) 206 207 // statements must end with the same top scope as they started with 208 if debug { 209 defer func(scope *Scope) { 210 // don't check if code is panicking 211 if p := recover(); p != nil { 212 panic(p) 213 } 214 assert(scope == check.scope) 215 }(check.scope) 216 } 217 218 inner := ctxt &^ fallthroughOk 219 switch s := s.(type) { 220 case *ast.BadStmt, *ast.EmptyStmt: 221 // ignore 222 223 case *ast.DeclStmt: 224 check.declStmt(s.Decl) 225 226 case *ast.LabeledStmt: 227 check.hasLabel = true 228 check.stmt(ctxt, s.Stmt) 229 230 case *ast.ExprStmt: 231 // spec: "With the exception of specific built-in functions, 232 // function and method calls and receive operations can appear 233 // in statement context. Such statements may be parenthesized." 234 var x operand 235 kind := check.rawExpr(&x, s.X, nil) 236 var msg string 237 switch x.mode { 238 default: 239 if kind == statement { 240 return 241 } 242 msg = "is not used" 243 case builtin: 244 msg = "must be called" 245 case typexpr: 246 msg = "is not an expression" 247 } 248 check.errorf(x.pos(), "%s %s", &x, msg) 249 250 case *ast.SendStmt: 251 var ch, x operand 252 check.expr(&ch, s.Chan) 253 check.expr(&x, s.Value) 254 if ch.mode == invalid || x.mode == invalid { 255 return 256 } 257 if tch, ok := ch.typ.Underlying().(*Chan); !ok || tch.dir == RecvOnly || !check.assignment(&x, tch.elem) { 258 if x.mode != invalid { 259 check.invalidOp(ch.pos(), "cannot send %s to channel %s", &x, &ch) 260 } 261 } 262 263 case *ast.IncDecStmt: 264 var op token.Token 265 switch s.Tok { 266 case token.INC: 267 op = token.ADD 268 case token.DEC: 269 op = token.SUB 270 default: 271 check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok) 272 return 273 } 274 var x operand 275 Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position 276 check.binary(&x, s.X, Y, op) 277 if x.mode == invalid { 278 return 279 } 280 check.assignVar(s.X, &x) 281 282 case *ast.AssignStmt: 283 switch s.Tok { 284 case token.ASSIGN, token.DEFINE: 285 if len(s.Lhs) == 0 { 286 check.invalidAST(s.Pos(), "missing lhs in assignment") 287 return 288 } 289 if s.Tok == token.DEFINE { 290 check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs) 291 } else { 292 // regular assignment 293 check.assignVars(s.Lhs, s.Rhs) 294 } 295 296 default: 297 // assignment operations 298 if len(s.Lhs) != 1 || len(s.Rhs) != 1 { 299 check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok) 300 return 301 } 302 op := assignOp(s.Tok) 303 if op == token.ILLEGAL { 304 check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok) 305 return 306 } 307 var x operand 308 check.binary(&x, s.Lhs[0], s.Rhs[0], op) 309 if x.mode == invalid { 310 return 311 } 312 check.assignVar(s.Lhs[0], &x) 313 } 314 315 case *ast.GoStmt: 316 check.suspendedCall("go", s.Call) 317 318 case *ast.DeferStmt: 319 check.suspendedCall("defer", s.Call) 320 321 case *ast.ReturnStmt: 322 res := check.sig.results 323 if res.Len() > 0 { 324 // function returns results 325 // (if one, say the first, result parameter is named, all of them are named) 326 if len(s.Results) == 0 && res.vars[0].name != "" { 327 // spec: "Implementation restriction: A compiler may disallow an empty expression 328 // list in a "return" statement if a different entity (constant, type, or variable) 329 // with the same name as a result parameter is in scope at the place of the return." 330 for _, obj := range res.vars { 331 if _, alt := check.scope.LookupParent(obj.name); alt != nil && alt != obj { 332 check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name) 333 check.errorf(alt.Pos(), "\tinner declaration of %s", obj) 334 // ok to continue 335 } 336 } 337 } else { 338 // return has results or result parameters are unnamed 339 check.initVars(res.vars, s.Results, s.Return) 340 } 341 } else if len(s.Results) > 0 { 342 check.error(s.Results[0].Pos(), "no result values expected") 343 check.use(s.Results...) 344 } 345 346 case *ast.BranchStmt: 347 if s.Label != nil { 348 check.hasLabel = true 349 return // checked in 2nd pass (check.labels) 350 } 351 switch s.Tok { 352 case token.BREAK: 353 if ctxt&breakOk == 0 { 354 check.error(s.Pos(), "break not in for, switch, or select statement") 355 } 356 case token.CONTINUE: 357 if ctxt&continueOk == 0 { 358 check.error(s.Pos(), "continue not in for statement") 359 } 360 case token.FALLTHROUGH: 361 if ctxt&fallthroughOk == 0 { 362 check.error(s.Pos(), "fallthrough statement out of place") 363 } 364 default: 365 check.invalidAST(s.Pos(), "branch statement: %s", s.Tok) 366 } 367 368 case *ast.BlockStmt: 369 check.openScope(s, "block") 370 defer check.closeScope() 371 372 check.stmtList(inner, s.List) 373 374 case *ast.IfStmt: 375 check.openScope(s, "if") 376 defer check.closeScope() 377 378 check.simpleStmt(s.Init) 379 var x operand 380 check.expr(&x, s.Cond) 381 if x.mode != invalid && !isBoolean(x.typ) { 382 check.error(s.Cond.Pos(), "non-boolean condition in if statement") 383 } 384 check.stmt(inner, s.Body) 385 if s.Else != nil { 386 check.stmt(inner, s.Else) 387 } 388 389 case *ast.SwitchStmt: 390 inner |= breakOk 391 check.openScope(s, "switch") 392 defer check.closeScope() 393 394 check.simpleStmt(s.Init) 395 var x operand 396 if s.Tag != nil { 397 check.expr(&x, s.Tag) 398 } else { 399 // spec: "A missing switch expression is 400 // equivalent to the boolean value true." 401 x.mode = constant 402 x.typ = Typ[Bool] 403 x.val = exact.MakeBool(true) 404 x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"} 405 } 406 407 check.multipleDefaults(s.Body.List) 408 409 for i, c := range s.Body.List { 410 clause, _ := c.(*ast.CaseClause) 411 if clause == nil { 412 check.invalidAST(c.Pos(), "incorrect expression switch case") 413 continue 414 } 415 if x.mode != invalid { 416 check.caseValues(x, clause.List) 417 } 418 check.openScope(clause, "case") 419 inner := inner 420 if i+1 < len(s.Body.List) { 421 inner |= fallthroughOk 422 } 423 check.stmtList(inner, clause.Body) 424 check.closeScope() 425 } 426 427 case *ast.TypeSwitchStmt: 428 inner |= breakOk 429 check.openScope(s, "type switch") 430 defer check.closeScope() 431 432 check.simpleStmt(s.Init) 433 434 // A type switch guard must be of the form: 435 // 436 // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" . 437 // 438 // The parser is checking syntactic correctness; 439 // remaining syntactic errors are considered AST errors here. 440 // TODO(gri) better factoring of error handling (invalid ASTs) 441 // 442 var lhs *ast.Ident // lhs identifier or nil 443 var rhs ast.Expr 444 switch guard := s.Assign.(type) { 445 case *ast.ExprStmt: 446 rhs = guard.X 447 case *ast.AssignStmt: 448 if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 { 449 check.invalidAST(s.Pos(), "incorrect form of type switch guard") 450 return 451 } 452 453 lhs, _ = guard.Lhs[0].(*ast.Ident) 454 if lhs == nil { 455 check.invalidAST(s.Pos(), "incorrect form of type switch guard") 456 return 457 } 458 459 if lhs.Name == "_" { 460 // _ := x.(type) is an invalid short variable declaration 461 check.softErrorf(lhs.Pos(), "no new variable on left side of :=") 462 lhs = nil // avoid declared but not used error below 463 } else { 464 check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause 465 } 466 467 rhs = guard.Rhs[0] 468 469 default: 470 check.invalidAST(s.Pos(), "incorrect form of type switch guard") 471 return 472 } 473 474 // rhs must be of the form: expr.(type) and expr must be an interface 475 expr, _ := rhs.(*ast.TypeAssertExpr) 476 if expr == nil || expr.Type != nil { 477 check.invalidAST(s.Pos(), "incorrect form of type switch guard") 478 return 479 } 480 var x operand 481 check.expr(&x, expr.X) 482 if x.mode == invalid { 483 return 484 } 485 xtyp, _ := x.typ.Underlying().(*Interface) 486 if xtyp == nil { 487 check.errorf(x.pos(), "%s is not an interface", &x) 488 return 489 } 490 491 check.multipleDefaults(s.Body.List) 492 493 var lhsVars []*Var // list of implicitly declared lhs variables 494 seen := make(map[Type]token.Pos) // map of seen types to positions 495 for _, s := range s.Body.List { 496 clause, _ := s.(*ast.CaseClause) 497 if clause == nil { 498 check.invalidAST(s.Pos(), "incorrect type switch case") 499 continue 500 } 501 // Check each type in this type switch case. 502 T := check.caseTypes(&x, xtyp, clause.List, seen) 503 check.openScope(clause, "case") 504 // If lhs exists, declare a corresponding variable in the case-local scope. 505 if lhs != nil { 506 // spec: "The TypeSwitchGuard may include a short variable declaration. 507 // When that form is used, the variable is declared at the beginning of 508 // the implicit block in each clause. In clauses with a case listing 509 // exactly one type, the variable has that type; otherwise, the variable 510 // has the type of the expression in the TypeSwitchGuard." 511 if len(clause.List) != 1 || T == nil { 512 T = x.typ 513 } 514 obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T) 515 check.declare(check.scope, nil, obj) 516 check.recordImplicit(clause, obj) 517 // For the "declared but not used" error, all lhs variables act as 518 // one; i.e., if any one of them is 'used', all of them are 'used'. 519 // Collect them for later analysis. 520 lhsVars = append(lhsVars, obj) 521 } 522 check.stmtList(inner, clause.Body) 523 check.closeScope() 524 } 525 526 // If lhs exists, we must have at least one lhs variable that was used. 527 if lhs != nil { 528 var used bool 529 for _, v := range lhsVars { 530 if v.used { 531 used = true 532 } 533 v.used = true // avoid usage error when checking entire function 534 } 535 if !used { 536 check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name) 537 } 538 } 539 540 case *ast.SelectStmt: 541 inner |= breakOk 542 543 check.multipleDefaults(s.Body.List) 544 545 for _, s := range s.Body.List { 546 clause, _ := s.(*ast.CommClause) 547 if clause == nil { 548 continue // error reported before 549 } 550 551 // clause.Comm must be a SendStmt, RecvStmt, or default case 552 valid := false 553 var rhs ast.Expr // rhs of RecvStmt, or nil 554 switch s := clause.Comm.(type) { 555 case nil, *ast.SendStmt: 556 valid = true 557 case *ast.AssignStmt: 558 if len(s.Rhs) == 1 { 559 rhs = s.Rhs[0] 560 } 561 case *ast.ExprStmt: 562 rhs = s.X 563 } 564 565 // if present, rhs must be a receive operation 566 if rhs != nil { 567 if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW { 568 valid = true 569 } 570 } 571 572 if !valid { 573 check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)") 574 continue 575 } 576 577 check.openScope(s, "case") 578 if clause.Comm != nil { 579 check.stmt(inner, clause.Comm) 580 } 581 check.stmtList(inner, clause.Body) 582 check.closeScope() 583 } 584 585 case *ast.ForStmt: 586 inner |= breakOk | continueOk 587 check.openScope(s, "for") 588 defer check.closeScope() 589 590 check.simpleStmt(s.Init) 591 if s.Cond != nil { 592 var x operand 593 check.expr(&x, s.Cond) 594 if x.mode != invalid && !isBoolean(x.typ) { 595 check.error(s.Cond.Pos(), "non-boolean condition in for statement") 596 } 597 } 598 check.simpleStmt(s.Post) 599 // spec: "The init statement may be a short variable 600 // declaration, but the post statement must not." 601 if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE { 602 check.softErrorf(s.Pos(), "cannot declare in post statement") 603 check.use(s.Lhs...) // avoid follow-up errors 604 } 605 check.stmt(inner, s.Body) 606 607 case *ast.RangeStmt: 608 inner |= breakOk | continueOk 609 check.openScope(s, "for") 610 defer check.closeScope() 611 612 // check expression to iterate over 613 var x operand 614 check.expr(&x, s.X) 615 616 // determine key/value types 617 var key, val Type 618 if x.mode != invalid { 619 switch typ := x.typ.Underlying().(type) { 620 case *Basic: 621 if isString(typ) { 622 key = Typ[Int] 623 val = UniverseRune // use 'rune' name 624 } 625 case *Array: 626 key = Typ[Int] 627 val = typ.elem 628 case *Slice: 629 key = Typ[Int] 630 val = typ.elem 631 case *Pointer: 632 if typ, _ := typ.base.Underlying().(*Array); typ != nil { 633 key = Typ[Int] 634 val = typ.elem 635 } 636 case *Map: 637 key = typ.key 638 val = typ.elem 639 case *Chan: 640 key = typ.elem 641 val = Typ[Invalid] 642 if typ.dir == SendOnly { 643 check.errorf(x.pos(), "cannot range over send-only channel %s", &x) 644 // ok to continue 645 } 646 if s.Value != nil { 647 check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x) 648 // ok to continue 649 } 650 } 651 } 652 653 if key == nil { 654 check.errorf(x.pos(), "cannot range over %s", &x) 655 // ok to continue 656 } 657 658 // check assignment to/declaration of iteration variables 659 // (irregular assignment, cannot easily map to existing assignment checks) 660 661 // lhs expressions and initialization value (rhs) types 662 lhs := [2]ast.Expr{s.Key, s.Value} 663 rhs := [2]Type{key, val} // key, val may be nil 664 665 if s.Tok == token.DEFINE { 666 // short variable declaration; variable scope starts after the range clause 667 // (the for loop opens a new scope, so variables on the lhs never redeclare 668 // previously declared variables) 669 var vars []*Var 670 for i, lhs := range lhs { 671 if lhs == nil { 672 continue 673 } 674 675 // determine lhs variable 676 var obj *Var 677 if ident, _ := lhs.(*ast.Ident); ident != nil { 678 // declare new variable 679 name := ident.Name 680 obj = NewVar(ident.Pos(), check.pkg, name, nil) 681 check.recordDef(ident, obj) 682 // _ variables don't count as new variables 683 if name != "_" { 684 vars = append(vars, obj) 685 } 686 } else { 687 check.errorf(lhs.Pos(), "cannot declare %s", lhs) 688 obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable 689 } 690 691 // initialize lhs variable 692 if typ := rhs[i]; typ != nil { 693 x.mode = value 694 x.expr = lhs // we don't have a better rhs expression to use here 695 x.typ = typ 696 check.initVar(obj, &x, false) 697 } else { 698 obj.typ = Typ[Invalid] 699 obj.used = true // don't complain about unused variable 700 } 701 } 702 703 // declare variables 704 if len(vars) > 0 { 705 for _, obj := range vars { 706 check.declare(check.scope, nil /* recordDef already called */, obj) 707 } 708 } else { 709 check.error(s.TokPos, "no new variables on left side of :=") 710 } 711 } else { 712 // ordinary assignment 713 for i, lhs := range lhs { 714 if lhs == nil { 715 continue 716 } 717 if typ := rhs[i]; typ != nil { 718 x.mode = value 719 x.expr = lhs // we don't have a better rhs expression to use here 720 x.typ = typ 721 check.assignVar(lhs, &x) 722 } 723 } 724 } 725 726 check.stmt(inner, s.Body) 727 728 default: 729 check.error(s.Pos(), "invalid statement") 730 } 731 }