1 // Copyright 2013 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.
5 // This file implements initialization and assignment checks.
14 // assignment reports whether x can be assigned to a variable of type T,
15 // if necessary by attempting to convert untyped values to the appropriate
16 // type. context describes the context in which the assignment takes place.
17 // Use T == nil to indicate assignment to an untyped blank identifier.
18 // x.mode is set to invalid if the assignment failed.
19 func (check *Checker) assignment(x *operand, T Type, context string) {
24 return // error reported before
25 case constant_, variable, mapindex, value, commaok, commaerr:
28 // we may get here because of other problems (issue #39634, crash 12)
29 check.errorf(x, 0, "cannot assign %s to %s in %s", x, T, context)
35 // spec: "If an untyped constant is assigned to a variable of interface
36 // type or the blank identifier, the constant is first converted to type
37 // bool, rune, int, float64, complex128 or string respectively, depending
38 // on whether the value is a boolean, rune, integer, floating-point,
39 // complex, or string constant."
40 if T == nil || IsInterface(T) {
41 if T == nil && x.typ == Typ[UntypedNil] {
42 check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
46 target = Default(x.typ)
48 newType, val, code := check.implicitTypeAndValue(x, target)
50 msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
54 case _NumericOverflow:
57 code = _IncompatibleAssign
59 check.error(x, code, msg)
65 check.updateExprVal(x.expr, val)
69 check.updateExprType(x.expr, newType, false)
73 // A generic (non-instantiated) function value cannot be assigned to a variable.
74 if sig := asSignature(x.typ); sig != nil && len(sig.tparams) > 0 {
75 check.errorf(x, _Todo, "cannot use generic function %s without instantiation in %s", x, context)
78 // spec: "If a left-hand side is the blank identifier, any typed or
79 // non-constant value except for the predeclared identifier nil may
80 // be assigned to it."
86 if ok, code := x.assignableTo(check, T, &reason); !ok {
88 check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
90 check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
96 func (check *Checker) initConst(lhs *Const, x *operand) {
97 if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
99 lhs.typ = Typ[Invalid]
104 // rhs must be a constant
105 if x.mode != constant_ {
106 check.errorf(x, _InvalidConstInit, "%s is not constant", x)
108 lhs.typ = Typ[Invalid]
112 assert(isConstType(x.typ))
114 // If the lhs doesn't have a type yet, use the type of x.
119 check.assignment(x, lhs.typ, "constant declaration")
120 if x.mode == invalid {
127 func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
128 if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
130 lhs.typ = Typ[Invalid]
135 // If the lhs doesn't have a type yet, use the type of x.
139 // convert untyped types to default types
140 if typ == Typ[UntypedNil] {
141 check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
142 lhs.typ = Typ[Invalid]
150 check.assignment(x, lhs.typ, context)
151 if x.mode == invalid {
158 func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
159 if x.mode == invalid || x.typ == Typ[Invalid] {
164 // Determine if the lhs is a (possibly parenthesized) identifier.
165 ident, _ := unparen(lhs).(*ast.Ident)
167 // Don't evaluate lhs if it is the blank identifier.
168 if ident != nil && ident.Name == "_" {
169 check.recordDef(ident, nil)
170 check.assignment(x, nil, "assignment to _ identifier")
171 if x.mode == invalid {
177 // If the lhs is an identifier denoting a variable v, this assignment
178 // is not a 'use' of v. Remember current value of v.used and restore
179 // after evaluating the lhs via check.expr.
183 if obj := check.lookup(ident.Name); obj != nil {
184 // It's ok to mark non-local variables, but ignore variables
185 // from other packages to avoid potential race conditions with
186 // dot-imported variables.
187 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
197 v.used = v_used // restore v.used
200 if z.mode == invalid || z.typ == Typ[Invalid] {
204 // spec: "Each left-hand side operand must be addressable, a map index
205 // expression, or the blank identifier. Operands may be parenthesized."
209 case variable, mapindex:
212 if sel, ok := z.expr.(*ast.SelectorExpr); ok {
214 check.expr(&op, sel.X)
215 if op.mode == mapindex {
216 check.errorf(&z, _UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr))
220 check.errorf(&z, _UnassignableOperand, "cannot assign to %s", &z)
224 check.assignment(x, z.typ, "assignment")
225 if x.mode == invalid {
232 // If returnPos is valid, initVars is called to type-check the assignment of
233 // return expressions, and returnPos is the position of the return statement.
234 func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnPos token.Pos) {
235 rhs, commaOk := check.exprList(origRHS, len(lhs) == 2 && !returnPos.IsValid())
237 if len(lhs) != len(rhs) {
239 for _, obj := range lhs {
241 obj.typ = Typ[Invalid]
244 // don't report an error if we already reported one
245 for _, x := range rhs {
246 if x.mode == invalid {
250 if returnPos.IsValid() {
251 check.errorf(atPos(returnPos), _WrongResultCount, "wrong number of return values (want %d, got %d)", len(lhs), len(rhs))
254 check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
258 context := "assignment"
259 if returnPos.IsValid() {
260 context = "return statement"
266 a[i] = check.initVar(lhs[i], rhs[i], context)
268 check.recordCommaOkTypes(origRHS[0], a)
272 for i, lhs := range lhs {
273 check.initVar(lhs, rhs[i], context)
277 func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
278 rhs, commaOk := check.exprList(origRHS, len(lhs) == 2)
280 if len(lhs) != len(rhs) {
282 // don't report an error if we already reported one
283 for _, x := range rhs {
284 if x.mode == invalid {
288 check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
295 a[i] = check.assignVar(lhs[i], rhs[i])
297 check.recordCommaOkTypes(origRHS[0], a)
301 for i, lhs := range lhs {
302 check.assignVar(lhs, rhs[i])
306 func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) {
307 top := len(check.delayed)
310 // collect lhs variables
312 var lhsVars = make([]*Var, len(lhs))
313 for i, lhs := range lhs {
315 if ident, _ := lhs.(*ast.Ident); ident != nil {
316 // Use the correct obj if the ident is redeclared. The
317 // variable's scope starts after the declaration; so we
318 // must use Scope.Lookup here and call Scope.Insert
319 // (via check.declare) later.
321 if alt := scope.Lookup(name); alt != nil {
322 // redeclared object must be a variable
323 if alt, _ := alt.(*Var); alt != nil {
326 check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
328 check.recordUse(ident, alt)
330 // declare new variable, possibly a blank (_) variable
331 obj = NewVar(ident.Pos(), check.pkg, name, nil)
333 newVars = append(newVars, obj)
335 check.recordDef(ident, obj)
339 check.invalidAST(lhs, "cannot declare %s", lhs)
342 obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
347 check.initVars(lhsVars, rhs, token.NoPos)
349 // process function literals in rhs expressions before scope changes
350 check.processDelayed(top)
352 // declare new variables
353 if len(newVars) > 0 {
354 // spec: "The scope of a constant or variable identifier declared inside
355 // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
356 // for short variable declarations) and ends at the end of the innermost
357 // containing block."
358 scopePos := rhs[len(rhs)-1].End()
359 for _, obj := range newVars {
360 check.declare(scope, nil, obj, scopePos) // recordObject already called
363 check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=")