...

Source file src/go/types/stmt.go

Documentation: go/types

		 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  	"go/ast"
		11  	"go/constant"
		12  	"go/token"
		13  	"sort"
		14  )
		15  
		16  func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt, iota constant.Value) {
		17  	if check.conf.IgnoreFuncBodies {
		18  		panic("internal error: function body not ignored")
		19  	}
		20  
		21  	if trace {
		22  		check.trace(body.Pos(), "--- %s: %s", name, sig)
		23  		defer func() {
		24  			check.trace(body.End(), "--- <end>")
		25  		}()
		26  	}
		27  
		28  	// set function scope extent
		29  	sig.scope.pos = body.Pos()
		30  	sig.scope.end = body.End()
		31  
		32  	// save/restore current context and setup function context
		33  	// (and use 0 indentation at function start)
		34  	defer func(ctxt context, indent int) {
		35  		check.context = ctxt
		36  		check.indent = indent
		37  	}(check.context, check.indent)
		38  	check.context = context{
		39  		decl:	decl,
		40  		scope: sig.scope,
		41  		iota:	iota,
		42  		sig:	 sig,
		43  	}
		44  	check.indent = 0
		45  
		46  	check.stmtList(0, body.List)
		47  
		48  	if check.hasLabel {
		49  		check.labels(body)
		50  	}
		51  
		52  	if sig.results.Len() > 0 && !check.isTerminating(body, "") {
		53  		check.error(atPos(body.Rbrace), _MissingReturn, "missing return")
		54  	}
		55  
		56  	// TODO(gri) Should we make it an error to declare generic functions
		57  	//					 where the type parameters are not used?
		58  	// 12/19/2018: Probably not - it can make sense to have an API with
		59  	//					 all functions uniformly sharing the same type parameters.
		60  
		61  	// spec: "Implementation restriction: A compiler may make it illegal to
		62  	// declare a variable inside a function body if the variable is never used."
		63  	check.usage(sig.scope)
		64  }
		65  
		66  func (check *Checker) usage(scope *Scope) {
		67  	var unused []*Var
		68  	for _, elem := range scope.elems {
		69  		if v, _ := elem.(*Var); v != nil && !v.used {
		70  			unused = append(unused, v)
		71  		}
		72  	}
		73  	sort.Slice(unused, func(i, j int) bool {
		74  		return unused[i].pos < unused[j].pos
		75  	})
		76  	for _, v := range unused {
		77  		check.softErrorf(v, _UnusedVar, "%s declared but not used", v.name)
		78  	}
		79  
		80  	for _, scope := range scope.children {
		81  		// Don't go inside function literal scopes a second time;
		82  		// they are handled explicitly by funcBody.
		83  		if !scope.isFunc {
		84  			check.usage(scope)
		85  		}
		86  	}
		87  }
		88  
		89  // stmtContext is a bitset describing which
		90  // control-flow statements are permissible,
		91  // and provides additional context information
		92  // for better error messages.
		93  type stmtContext uint
		94  
		95  const (
		96  	// permissible control-flow statements
		97  	breakOk stmtContext = 1 << iota
		98  	continueOk
		99  	fallthroughOk
	 100  
	 101  	// additional context information
	 102  	finalSwitchCase
	 103  )
	 104  
	 105  func (check *Checker) simpleStmt(s ast.Stmt) {
	 106  	if s != nil {
	 107  		check.stmt(0, s)
	 108  	}
	 109  }
	 110  
	 111  func trimTrailingEmptyStmts(list []ast.Stmt) []ast.Stmt {
	 112  	for i := len(list); i > 0; i-- {
	 113  		if _, ok := list[i-1].(*ast.EmptyStmt); !ok {
	 114  			return list[:i]
	 115  		}
	 116  	}
	 117  	return nil
	 118  }
	 119  
	 120  func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) {
	 121  	ok := ctxt&fallthroughOk != 0
	 122  	inner := ctxt &^ fallthroughOk
	 123  	list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis
	 124  	for i, s := range list {
	 125  		inner := inner
	 126  		if ok && i+1 == len(list) {
	 127  			inner |= fallthroughOk
	 128  		}
	 129  		check.stmt(inner, s)
	 130  	}
	 131  }
	 132  
	 133  func (check *Checker) multipleDefaults(list []ast.Stmt) {
	 134  	var first ast.Stmt
	 135  	for _, s := range list {
	 136  		var d ast.Stmt
	 137  		switch c := s.(type) {
	 138  		case *ast.CaseClause:
	 139  			if len(c.List) == 0 {
	 140  				d = s
	 141  			}
	 142  		case *ast.CommClause:
	 143  			if c.Comm == nil {
	 144  				d = s
	 145  			}
	 146  		default:
	 147  			check.invalidAST(s, "case/communication clause expected")
	 148  		}
	 149  		if d != nil {
	 150  			if first != nil {
	 151  				check.errorf(d, _DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos()))
	 152  			} else {
	 153  				first = d
	 154  			}
	 155  		}
	 156  	}
	 157  }
	 158  
	 159  func (check *Checker) openScope(node ast.Node, comment string) {
	 160  	scope := NewScope(check.scope, node.Pos(), node.End(), comment)
	 161  	check.recordScope(node, scope)
	 162  	check.scope = scope
	 163  }
	 164  
	 165  func (check *Checker) closeScope() {
	 166  	check.scope = check.scope.Parent()
	 167  }
	 168  
	 169  func assignOp(op token.Token) token.Token {
	 170  	// token_test.go verifies the token ordering this function relies on
	 171  	if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN {
	 172  		return op + (token.ADD - token.ADD_ASSIGN)
	 173  	}
	 174  	return token.ILLEGAL
	 175  }
	 176  
	 177  func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
	 178  	var x operand
	 179  	var msg string
	 180  	var code errorCode
	 181  	switch check.rawExpr(&x, call, nil) {
	 182  	case conversion:
	 183  		msg = "requires function call, not conversion"
	 184  		code = _InvalidDefer
	 185  		if keyword == "go" {
	 186  			code = _InvalidGo
	 187  		}
	 188  	case expression:
	 189  		msg = "discards result of"
	 190  		code = _UnusedResults
	 191  	case statement:
	 192  		return
	 193  	default:
	 194  		unreachable()
	 195  	}
	 196  	check.errorf(&x, code, "%s %s %s", keyword, msg, &x)
	 197  }
	 198  
	 199  // goVal returns the Go value for val, or nil.
	 200  func goVal(val constant.Value) interface{} {
	 201  	// val should exist, but be conservative and check
	 202  	if val == nil {
	 203  		return nil
	 204  	}
	 205  	// Match implementation restriction of other compilers.
	 206  	// gc only checks duplicates for integer, floating-point
	 207  	// and string values, so only create Go values for these
	 208  	// types.
	 209  	switch val.Kind() {
	 210  	case constant.Int:
	 211  		if x, ok := constant.Int64Val(val); ok {
	 212  			return x
	 213  		}
	 214  		if x, ok := constant.Uint64Val(val); ok {
	 215  			return x
	 216  		}
	 217  	case constant.Float:
	 218  		if x, ok := constant.Float64Val(val); ok {
	 219  			return x
	 220  		}
	 221  	case constant.String:
	 222  		return constant.StringVal(val)
	 223  	}
	 224  	return nil
	 225  }
	 226  
	 227  // A valueMap maps a case value (of a basic Go type) to a list of positions
	 228  // where the same case value appeared, together with the corresponding case
	 229  // types.
	 230  // Since two case values may have the same "underlying" value but different
	 231  // types we need to also check the value's types (e.g., byte(1) vs myByte(1))
	 232  // when the switch expression is of interface type.
	 233  type (
	 234  	valueMap	map[interface{}][]valueType // underlying Go value -> valueType
	 235  	valueType struct {
	 236  		pos token.Pos
	 237  		typ Type
	 238  	}
	 239  )
	 240  
	 241  func (check *Checker) caseValues(x *operand, values []ast.Expr, seen valueMap) {
	 242  L:
	 243  	for _, e := range values {
	 244  		var v operand
	 245  		check.expr(&v, e)
	 246  		if x.mode == invalid || v.mode == invalid {
	 247  			continue L
	 248  		}
	 249  		check.convertUntyped(&v, x.typ)
	 250  		if v.mode == invalid {
	 251  			continue L
	 252  		}
	 253  		// Order matters: By comparing v against x, error positions are at the case values.
	 254  		res := v // keep original v unchanged
	 255  		check.comparison(&res, x, token.EQL)
	 256  		if res.mode == invalid {
	 257  			continue L
	 258  		}
	 259  		if v.mode != constant_ {
	 260  			continue L // we're done
	 261  		}
	 262  		// look for duplicate values
	 263  		if val := goVal(v.val); val != nil {
	 264  			// look for duplicate types for a given value
	 265  			// (quadratic algorithm, but these lists tend to be very short)
	 266  			for _, vt := range seen[val] {
	 267  				if check.identical(v.typ, vt.typ) {
	 268  					check.errorf(&v, _DuplicateCase, "duplicate case %s in expression switch", &v)
	 269  					check.error(atPos(vt.pos), _DuplicateCase, "\tprevious case") // secondary error, \t indented
	 270  					continue L
	 271  				}
	 272  			}
	 273  			seen[val] = append(seen[val], valueType{v.Pos(), v.typ})
	 274  		}
	 275  	}
	 276  }
	 277  
	 278  func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]ast.Expr) (T Type) {
	 279  L:
	 280  	for _, e := range types {
	 281  		T = check.typeOrNil(e)
	 282  		if T == Typ[Invalid] {
	 283  			continue L
	 284  		}
	 285  		if T != nil {
	 286  			check.ordinaryType(e, T)
	 287  		}
	 288  		// look for duplicate types
	 289  		// (quadratic algorithm, but type switches tend to be reasonably small)
	 290  		for t, other := range seen {
	 291  			if T == nil && t == nil || T != nil && t != nil && check.identical(T, t) {
	 292  				// talk about "case" rather than "type" because of nil case
	 293  				Ts := "nil"
	 294  				if T != nil {
	 295  					Ts = T.String()
	 296  				}
	 297  				check.errorf(e, _DuplicateCase, "duplicate case %s in type switch", Ts)
	 298  				check.error(other, _DuplicateCase, "\tprevious case") // secondary error, \t indented
	 299  				continue L
	 300  			}
	 301  		}
	 302  		seen[T] = e
	 303  		if T != nil {
	 304  			check.typeAssertion(e, x, xtyp, T)
	 305  		}
	 306  	}
	 307  	return
	 308  }
	 309  
	 310  // stmt typechecks statement s.
	 311  func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
	 312  	// statements must end with the same top scope as they started with
	 313  	if debug {
	 314  		defer func(scope *Scope) {
	 315  			// don't check if code is panicking
	 316  			if p := recover(); p != nil {
	 317  				panic(p)
	 318  			}
	 319  			assert(scope == check.scope)
	 320  		}(check.scope)
	 321  	}
	 322  
	 323  	// process collected function literals before scope changes
	 324  	defer check.processDelayed(len(check.delayed))
	 325  
	 326  	inner := ctxt &^ (fallthroughOk | finalSwitchCase)
	 327  	switch s := s.(type) {
	 328  	case *ast.BadStmt, *ast.EmptyStmt:
	 329  		// ignore
	 330  
	 331  	case *ast.DeclStmt:
	 332  		check.declStmt(s.Decl)
	 333  
	 334  	case *ast.LabeledStmt:
	 335  		check.hasLabel = true
	 336  		check.stmt(ctxt, s.Stmt)
	 337  
	 338  	case *ast.ExprStmt:
	 339  		// spec: "With the exception of specific built-in functions,
	 340  		// function and method calls and receive operations can appear
	 341  		// in statement context. Such statements may be parenthesized."
	 342  		var x operand
	 343  		kind := check.rawExpr(&x, s.X, nil)
	 344  		var msg string
	 345  		var code errorCode
	 346  		switch x.mode {
	 347  		default:
	 348  			if kind == statement {
	 349  				return
	 350  			}
	 351  			msg = "is not used"
	 352  			code = _UnusedExpr
	 353  		case builtin:
	 354  			msg = "must be called"
	 355  			code = _UncalledBuiltin
	 356  		case typexpr:
	 357  			msg = "is not an expression"
	 358  			code = _NotAnExpr
	 359  		}
	 360  		check.errorf(&x, code, "%s %s", &x, msg)
	 361  
	 362  	case *ast.SendStmt:
	 363  		var ch, x operand
	 364  		check.expr(&ch, s.Chan)
	 365  		check.expr(&x, s.Value)
	 366  		if ch.mode == invalid || x.mode == invalid {
	 367  			return
	 368  		}
	 369  
	 370  		tch := asChan(ch.typ)
	 371  		if tch == nil {
	 372  			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to non-chan type %s", ch.typ)
	 373  			return
	 374  		}
	 375  
	 376  		if tch.dir == RecvOnly {
	 377  			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to receive-only type %s", tch)
	 378  			return
	 379  		}
	 380  
	 381  		check.assignment(&x, tch.elem, "send")
	 382  
	 383  	case *ast.IncDecStmt:
	 384  		var op token.Token
	 385  		switch s.Tok {
	 386  		case token.INC:
	 387  			op = token.ADD
	 388  		case token.DEC:
	 389  			op = token.SUB
	 390  		default:
	 391  			check.invalidAST(inNode(s, s.TokPos), "unknown inc/dec operation %s", s.Tok)
	 392  			return
	 393  		}
	 394  
	 395  		var x operand
	 396  		check.expr(&x, s.X)
	 397  		if x.mode == invalid {
	 398  			return
	 399  		}
	 400  		if !isNumeric(x.typ) {
	 401  			check.invalidOp(s.X, _NonNumericIncDec, "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ)
	 402  			return
	 403  		}
	 404  
	 405  		Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
	 406  		check.binary(&x, nil, s.X, Y, op, s.TokPos)
	 407  		if x.mode == invalid {
	 408  			return
	 409  		}
	 410  		check.assignVar(s.X, &x)
	 411  
	 412  	case *ast.AssignStmt:
	 413  		switch s.Tok {
	 414  		case token.ASSIGN, token.DEFINE:
	 415  			if len(s.Lhs) == 0 {
	 416  				check.invalidAST(s, "missing lhs in assignment")
	 417  				return
	 418  			}
	 419  			if s.Tok == token.DEFINE {
	 420  				check.shortVarDecl(inNode(s, s.TokPos), s.Lhs, s.Rhs)
	 421  			} else {
	 422  				// regular assignment
	 423  				check.assignVars(s.Lhs, s.Rhs)
	 424  			}
	 425  
	 426  		default:
	 427  			// assignment operations
	 428  			if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
	 429  				check.errorf(inNode(s, s.TokPos), _MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok)
	 430  				return
	 431  			}
	 432  			op := assignOp(s.Tok)
	 433  			if op == token.ILLEGAL {
	 434  				check.invalidAST(atPos(s.TokPos), "unknown assignment operation %s", s.Tok)
	 435  				return
	 436  			}
	 437  			var x operand
	 438  			check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op, s.TokPos)
	 439  			if x.mode == invalid {
	 440  				return
	 441  			}
	 442  			check.assignVar(s.Lhs[0], &x)
	 443  		}
	 444  
	 445  	case *ast.GoStmt:
	 446  		check.suspendedCall("go", s.Call)
	 447  
	 448  	case *ast.DeferStmt:
	 449  		check.suspendedCall("defer", s.Call)
	 450  
	 451  	case *ast.ReturnStmt:
	 452  		res := check.sig.results
	 453  		if res.Len() > 0 {
	 454  			// function returns results
	 455  			// (if one, say the first, result parameter is named, all of them are named)
	 456  			if len(s.Results) == 0 && res.vars[0].name != "" {
	 457  				// spec: "Implementation restriction: A compiler may disallow an empty expression
	 458  				// list in a "return" statement if a different entity (constant, type, or variable)
	 459  				// with the same name as a result parameter is in scope at the place of the return."
	 460  				for _, obj := range res.vars {
	 461  					if alt := check.lookup(obj.name); alt != nil && alt != obj {
	 462  						check.errorf(s, _OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
	 463  						check.errorf(alt, _OutOfScopeResult, "\tinner declaration of %s", obj)
	 464  						// ok to continue
	 465  					}
	 466  				}
	 467  			} else {
	 468  				// return has results or result parameters are unnamed
	 469  				check.initVars(res.vars, s.Results, s.Return)
	 470  			}
	 471  		} else if len(s.Results) > 0 {
	 472  			check.error(s.Results[0], _WrongResultCount, "no result values expected")
	 473  			check.use(s.Results...)
	 474  		}
	 475  
	 476  	case *ast.BranchStmt:
	 477  		if s.Label != nil {
	 478  			check.hasLabel = true
	 479  			return // checked in 2nd pass (check.labels)
	 480  		}
	 481  		switch s.Tok {
	 482  		case token.BREAK:
	 483  			if ctxt&breakOk == 0 {
	 484  				check.error(s, _MisplacedBreak, "break not in for, switch, or select statement")
	 485  			}
	 486  		case token.CONTINUE:
	 487  			if ctxt&continueOk == 0 {
	 488  				check.error(s, _MisplacedContinue, "continue not in for statement")
	 489  			}
	 490  		case token.FALLTHROUGH:
	 491  			if ctxt&fallthroughOk == 0 {
	 492  				msg := "fallthrough statement out of place"
	 493  				code := _MisplacedFallthrough
	 494  				if ctxt&finalSwitchCase != 0 {
	 495  					msg = "cannot fallthrough final case in switch"
	 496  				}
	 497  				check.error(s, code, msg)
	 498  			}
	 499  		default:
	 500  			check.invalidAST(s, "branch statement: %s", s.Tok)
	 501  		}
	 502  
	 503  	case *ast.BlockStmt:
	 504  		check.openScope(s, "block")
	 505  		defer check.closeScope()
	 506  
	 507  		check.stmtList(inner, s.List)
	 508  
	 509  	case *ast.IfStmt:
	 510  		check.openScope(s, "if")
	 511  		defer check.closeScope()
	 512  
	 513  		check.simpleStmt(s.Init)
	 514  		var x operand
	 515  		check.expr(&x, s.Cond)
	 516  		if x.mode != invalid && !isBoolean(x.typ) {
	 517  			check.error(s.Cond, _InvalidCond, "non-boolean condition in if statement")
	 518  		}
	 519  		check.stmt(inner, s.Body)
	 520  		// The parser produces a correct AST but if it was modified
	 521  		// elsewhere the else branch may be invalid. Check again.
	 522  		switch s.Else.(type) {
	 523  		case nil, *ast.BadStmt:
	 524  			// valid or error already reported
	 525  		case *ast.IfStmt, *ast.BlockStmt:
	 526  			check.stmt(inner, s.Else)
	 527  		default:
	 528  			check.invalidAST(s.Else, "invalid else branch in if statement")
	 529  		}
	 530  
	 531  	case *ast.SwitchStmt:
	 532  		inner |= breakOk
	 533  		check.openScope(s, "switch")
	 534  		defer check.closeScope()
	 535  
	 536  		check.simpleStmt(s.Init)
	 537  		var x operand
	 538  		if s.Tag != nil {
	 539  			check.expr(&x, s.Tag)
	 540  			// By checking assignment of x to an invisible temporary
	 541  			// (as a compiler would), we get all the relevant checks.
	 542  			check.assignment(&x, nil, "switch expression")
	 543  			if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
	 544  				check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
	 545  				x.mode = invalid
	 546  			}
	 547  		} else {
	 548  			// spec: "A missing switch expression is
	 549  			// equivalent to the boolean value true."
	 550  			x.mode = constant_
	 551  			x.typ = Typ[Bool]
	 552  			x.val = constant.MakeBool(true)
	 553  			x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
	 554  		}
	 555  
	 556  		check.multipleDefaults(s.Body.List)
	 557  
	 558  		seen := make(valueMap) // map of seen case values to positions and types
	 559  		for i, c := range s.Body.List {
	 560  			clause, _ := c.(*ast.CaseClause)
	 561  			if clause == nil {
	 562  				check.invalidAST(c, "incorrect expression switch case")
	 563  				continue
	 564  			}
	 565  			check.caseValues(&x, clause.List, seen)
	 566  			check.openScope(clause, "case")
	 567  			inner := inner
	 568  			if i+1 < len(s.Body.List) {
	 569  				inner |= fallthroughOk
	 570  			} else {
	 571  				inner |= finalSwitchCase
	 572  			}
	 573  			check.stmtList(inner, clause.Body)
	 574  			check.closeScope()
	 575  		}
	 576  
	 577  	case *ast.TypeSwitchStmt:
	 578  		inner |= breakOk
	 579  		check.openScope(s, "type switch")
	 580  		defer check.closeScope()
	 581  
	 582  		check.simpleStmt(s.Init)
	 583  
	 584  		// A type switch guard must be of the form:
	 585  		//
	 586  		//		 TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
	 587  		//
	 588  		// The parser is checking syntactic correctness;
	 589  		// remaining syntactic errors are considered AST errors here.
	 590  		// TODO(gri) better factoring of error handling (invalid ASTs)
	 591  		//
	 592  		var lhs *ast.Ident // lhs identifier or nil
	 593  		var rhs ast.Expr
	 594  		switch guard := s.Assign.(type) {
	 595  		case *ast.ExprStmt:
	 596  			rhs = guard.X
	 597  		case *ast.AssignStmt:
	 598  			if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
	 599  				check.invalidAST(s, "incorrect form of type switch guard")
	 600  				return
	 601  			}
	 602  
	 603  			lhs, _ = guard.Lhs[0].(*ast.Ident)
	 604  			if lhs == nil {
	 605  				check.invalidAST(s, "incorrect form of type switch guard")
	 606  				return
	 607  			}
	 608  
	 609  			if lhs.Name == "_" {
	 610  				// _ := x.(type) is an invalid short variable declaration
	 611  				check.softErrorf(lhs, _NoNewVar, "no new variable on left side of :=")
	 612  				lhs = nil // avoid declared but not used error below
	 613  			} else {
	 614  				check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
	 615  			}
	 616  
	 617  			rhs = guard.Rhs[0]
	 618  
	 619  		default:
	 620  			check.invalidAST(s, "incorrect form of type switch guard")
	 621  			return
	 622  		}
	 623  
	 624  		// rhs must be of the form: expr.(type) and expr must be an ordinary interface
	 625  		expr, _ := rhs.(*ast.TypeAssertExpr)
	 626  		if expr == nil || expr.Type != nil {
	 627  			check.invalidAST(s, "incorrect form of type switch guard")
	 628  			return
	 629  		}
	 630  		var x operand
	 631  		check.expr(&x, expr.X)
	 632  		if x.mode == invalid {
	 633  			return
	 634  		}
	 635  		xtyp, _ := under(x.typ).(*Interface)
	 636  		if xtyp == nil {
	 637  			check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x)
	 638  			return
	 639  		}
	 640  		check.ordinaryType(&x, xtyp)
	 641  
	 642  		check.multipleDefaults(s.Body.List)
	 643  
	 644  		var lhsVars []*Var							// list of implicitly declared lhs variables
	 645  		seen := make(map[Type]ast.Expr) // map of seen types to positions
	 646  		for _, s := range s.Body.List {
	 647  			clause, _ := s.(*ast.CaseClause)
	 648  			if clause == nil {
	 649  				check.invalidAST(s, "incorrect type switch case")
	 650  				continue
	 651  			}
	 652  			// Check each type in this type switch case.
	 653  			T := check.caseTypes(&x, xtyp, clause.List, seen)
	 654  			check.openScope(clause, "case")
	 655  			// If lhs exists, declare a corresponding variable in the case-local scope.
	 656  			if lhs != nil {
	 657  				// spec: "The TypeSwitchGuard may include a short variable declaration.
	 658  				// When that form is used, the variable is declared at the beginning of
	 659  				// the implicit block in each clause. In clauses with a case listing
	 660  				// exactly one type, the variable has that type; otherwise, the variable
	 661  				// has the type of the expression in the TypeSwitchGuard."
	 662  				if len(clause.List) != 1 || T == nil {
	 663  					T = x.typ
	 664  				}
	 665  				obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
	 666  				scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0)
	 667  				if n := len(clause.List); n > 0 {
	 668  					scopePos = clause.List[n-1].End()
	 669  				}
	 670  				check.declare(check.scope, nil, obj, scopePos)
	 671  				check.recordImplicit(clause, obj)
	 672  				// For the "declared but not used" error, all lhs variables act as
	 673  				// one; i.e., if any one of them is 'used', all of them are 'used'.
	 674  				// Collect them for later analysis.
	 675  				lhsVars = append(lhsVars, obj)
	 676  			}
	 677  			check.stmtList(inner, clause.Body)
	 678  			check.closeScope()
	 679  		}
	 680  
	 681  		// If lhs exists, we must have at least one lhs variable that was used.
	 682  		if lhs != nil {
	 683  			var used bool
	 684  			for _, v := range lhsVars {
	 685  				if v.used {
	 686  					used = true
	 687  				}
	 688  				v.used = true // avoid usage error when checking entire function
	 689  			}
	 690  			if !used {
	 691  				check.softErrorf(lhs, _UnusedVar, "%s declared but not used", lhs.Name)
	 692  			}
	 693  		}
	 694  
	 695  	case *ast.SelectStmt:
	 696  		inner |= breakOk
	 697  
	 698  		check.multipleDefaults(s.Body.List)
	 699  
	 700  		for _, s := range s.Body.List {
	 701  			clause, _ := s.(*ast.CommClause)
	 702  			if clause == nil {
	 703  				continue // error reported before
	 704  			}
	 705  
	 706  			// clause.Comm must be a SendStmt, RecvStmt, or default case
	 707  			valid := false
	 708  			var rhs ast.Expr // rhs of RecvStmt, or nil
	 709  			switch s := clause.Comm.(type) {
	 710  			case nil, *ast.SendStmt:
	 711  				valid = true
	 712  			case *ast.AssignStmt:
	 713  				if len(s.Rhs) == 1 {
	 714  					rhs = s.Rhs[0]
	 715  				}
	 716  			case *ast.ExprStmt:
	 717  				rhs = s.X
	 718  			}
	 719  
	 720  			// if present, rhs must be a receive operation
	 721  			if rhs != nil {
	 722  				if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
	 723  					valid = true
	 724  				}
	 725  			}
	 726  
	 727  			if !valid {
	 728  				check.error(clause.Comm, _InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
	 729  				continue
	 730  			}
	 731  
	 732  			check.openScope(s, "case")
	 733  			if clause.Comm != nil {
	 734  				check.stmt(inner, clause.Comm)
	 735  			}
	 736  			check.stmtList(inner, clause.Body)
	 737  			check.closeScope()
	 738  		}
	 739  
	 740  	case *ast.ForStmt:
	 741  		inner |= breakOk | continueOk
	 742  		check.openScope(s, "for")
	 743  		defer check.closeScope()
	 744  
	 745  		check.simpleStmt(s.Init)
	 746  		if s.Cond != nil {
	 747  			var x operand
	 748  			check.expr(&x, s.Cond)
	 749  			if x.mode != invalid && !isBoolean(x.typ) {
	 750  				check.error(s.Cond, _InvalidCond, "non-boolean condition in for statement")
	 751  			}
	 752  		}
	 753  		check.simpleStmt(s.Post)
	 754  		// spec: "The init statement may be a short variable
	 755  		// declaration, but the post statement must not."
	 756  		if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
	 757  			check.softErrorf(s, _InvalidPostDecl, "cannot declare in post statement")
	 758  			// Don't call useLHS here because we want to use the lhs in
	 759  			// this erroneous statement so that we don't get errors about
	 760  			// these lhs variables being declared but not used.
	 761  			check.use(s.Lhs...) // avoid follow-up errors
	 762  		}
	 763  		check.stmt(inner, s.Body)
	 764  
	 765  	case *ast.RangeStmt:
	 766  		inner |= breakOk | continueOk
	 767  		check.openScope(s, "for")
	 768  		defer check.closeScope()
	 769  
	 770  		// check expression to iterate over
	 771  		var x operand
	 772  		check.expr(&x, s.X)
	 773  
	 774  		// determine key/value types
	 775  		var key, val Type
	 776  		if x.mode != invalid {
	 777  			typ := optype(x.typ)
	 778  			if _, ok := typ.(*Chan); ok && s.Value != nil {
	 779  				// TODO(gri) this also needs to happen for channels in generic variables
	 780  				check.softErrorf(atPos(s.Value.Pos()), _InvalidIterVar, "range over %s permits only one iteration variable", &x)
	 781  				// ok to continue
	 782  			}
	 783  			var msg string
	 784  			key, val, msg = rangeKeyVal(typ, isVarName(s.Key), isVarName(s.Value))
	 785  			if key == nil || msg != "" {
	 786  				if msg != "" {
	 787  					// TODO(rFindley) should this be parenthesized, to be consistent with other qualifiers?
	 788  					msg = ": " + msg
	 789  				}
	 790  				check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s%s", &x, msg)
	 791  				// ok to continue
	 792  			}
	 793  		}
	 794  
	 795  		// check assignment to/declaration of iteration variables
	 796  		// (irregular assignment, cannot easily map to existing assignment checks)
	 797  
	 798  		// lhs expressions and initialization value (rhs) types
	 799  		lhs := [2]ast.Expr{s.Key, s.Value}
	 800  		rhs := [2]Type{key, val} // key, val may be nil
	 801  
	 802  		if s.Tok == token.DEFINE {
	 803  			// short variable declaration; variable scope starts after the range clause
	 804  			// (the for loop opens a new scope, so variables on the lhs never redeclare
	 805  			// previously declared variables)
	 806  			var vars []*Var
	 807  			for i, lhs := range lhs {
	 808  				if lhs == nil {
	 809  					continue
	 810  				}
	 811  
	 812  				// determine lhs variable
	 813  				var obj *Var
	 814  				if ident, _ := lhs.(*ast.Ident); ident != nil {
	 815  					// declare new variable
	 816  					name := ident.Name
	 817  					obj = NewVar(ident.Pos(), check.pkg, name, nil)
	 818  					check.recordDef(ident, obj)
	 819  					// _ variables don't count as new variables
	 820  					if name != "_" {
	 821  						vars = append(vars, obj)
	 822  					}
	 823  				} else {
	 824  					check.invalidAST(lhs, "cannot declare %s", lhs)
	 825  					obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
	 826  				}
	 827  
	 828  				// initialize lhs variable
	 829  				if typ := rhs[i]; typ != nil {
	 830  					x.mode = value
	 831  					x.expr = lhs // we don't have a better rhs expression to use here
	 832  					x.typ = typ
	 833  					check.initVar(obj, &x, "range clause")
	 834  				} else {
	 835  					obj.typ = Typ[Invalid]
	 836  					obj.used = true // don't complain about unused variable
	 837  				}
	 838  			}
	 839  
	 840  			// declare variables
	 841  			if len(vars) > 0 {
	 842  				scopePos := s.X.End()
	 843  				for _, obj := range vars {
	 844  					// spec: "The scope of a constant or variable identifier declared inside
	 845  					// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
	 846  					// for short variable declarations) and ends at the end of the innermost
	 847  					// containing block."
	 848  					check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
	 849  				}
	 850  			} else {
	 851  				check.error(inNode(s, s.TokPos), _NoNewVar, "no new variables on left side of :=")
	 852  			}
	 853  		} else {
	 854  			// ordinary assignment
	 855  			for i, lhs := range lhs {
	 856  				if lhs == nil {
	 857  					continue
	 858  				}
	 859  				if typ := rhs[i]; typ != nil {
	 860  					x.mode = value
	 861  					x.expr = lhs // we don't have a better rhs expression to use here
	 862  					x.typ = typ
	 863  					check.assignVar(lhs, &x)
	 864  				}
	 865  			}
	 866  		}
	 867  
	 868  		check.stmt(inner, s.Body)
	 869  
	 870  	default:
	 871  		check.invalidAST(s, "invalid statement")
	 872  	}
	 873  }
	 874  
	 875  // isVarName reports whether x is a non-nil, non-blank (_) expression.
	 876  func isVarName(x ast.Expr) bool {
	 877  	if x == nil {
	 878  		return false
	 879  	}
	 880  	ident, _ := unparen(x).(*ast.Ident)
	 881  	return ident == nil || ident.Name != "_"
	 882  }
	 883  
	 884  // rangeKeyVal returns the key and value type produced by a range clause
	 885  // over an expression of type typ, and possibly an error message. If the
	 886  // range clause is not permitted the returned key is nil or msg is not
	 887  // empty (in that case we still may have a non-nil key type which can be
	 888  // used to reduce the chance for follow-on errors).
	 889  // The wantKey, wantVal, and hasVal flags indicate which of the iteration
	 890  // variables are used or present; this matters if we range over a generic
	 891  // type where not all keys or values are of the same type.
	 892  func rangeKeyVal(typ Type, wantKey, wantVal bool) (Type, Type, string) {
	 893  	switch typ := typ.(type) {
	 894  	case *Basic:
	 895  		if isString(typ) {
	 896  			return Typ[Int], universeRune, "" // use 'rune' name
	 897  		}
	 898  	case *Array:
	 899  		return Typ[Int], typ.elem, ""
	 900  	case *Slice:
	 901  		return Typ[Int], typ.elem, ""
	 902  	case *Pointer:
	 903  		if typ := asArray(typ.base); typ != nil {
	 904  			return Typ[Int], typ.elem, ""
	 905  		}
	 906  	case *Map:
	 907  		return typ.key, typ.elem, ""
	 908  	case *Chan:
	 909  		var msg string
	 910  		if typ.dir == SendOnly {
	 911  			msg = "send-only channel"
	 912  		}
	 913  		return typ.elem, Typ[Invalid], msg
	 914  	case *_Sum:
	 915  		first := true
	 916  		var key, val Type
	 917  		var msg string
	 918  		typ.is(func(t Type) bool {
	 919  			k, v, m := rangeKeyVal(under(t), wantKey, wantVal)
	 920  			if k == nil || m != "" {
	 921  				key, val, msg = k, v, m
	 922  				return false
	 923  			}
	 924  			if first {
	 925  				key, val, msg = k, v, m
	 926  				first = false
	 927  				return true
	 928  			}
	 929  			if wantKey && !Identical(key, k) {
	 930  				key, val, msg = nil, nil, "all possible values must have the same key type"
	 931  				return false
	 932  			}
	 933  			if wantVal && !Identical(val, v) {
	 934  				key, val, msg = nil, nil, "all possible values must have the same element type"
	 935  				return false
	 936  			}
	 937  			return true
	 938  		})
	 939  		return key, val, msg
	 940  	}
	 941  	return nil, nil, ""
	 942  }
	 943  

View as plain text