Source file src/go/types/assignments.go

     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.
     4  
     5  // This file implements initialization and assignment checks.
     6  
     7  package types
     8  
     9  import (
    10  	"fmt"
    11  	"go/ast"
    12  	"strings"
    13  )
    14  
    15  // assignment reports whether x can be assigned to a variable of type T,
    16  // if necessary by attempting to convert untyped values to the appropriate
    17  // type. context describes the context in which the assignment takes place.
    18  // Use T == nil to indicate assignment to an untyped blank identifier.
    19  // x.mode is set to invalid if the assignment failed.
    20  func (check *Checker) assignment(x *operand, T Type, context string) {
    21  	check.singleValue(x)
    22  
    23  	switch x.mode {
    24  	case invalid:
    25  		return // error reported before
    26  	case constant_, variable, mapindex, value, commaok, commaerr:
    27  		// ok
    28  	default:
    29  		// we may get here because of other problems (issue #39634, crash 12)
    30  		check.errorf(x, 0, "cannot assign %s to %s in %s", x, T, context)
    31  		return
    32  	}
    33  
    34  	if isUntyped(x.typ) {
    35  		target := T
    36  		// spec: "If an untyped constant is assigned to a variable of interface
    37  		// type or the blank identifier, the constant is first converted to type
    38  		// bool, rune, int, float64, complex128 or string respectively, depending
    39  		// on whether the value is a boolean, rune, integer, floating-point,
    40  		// complex, or string constant."
    41  		if T == nil || IsInterface(T) && !isTypeParam(T) {
    42  			if T == nil && x.typ == Typ[UntypedNil] {
    43  				check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
    44  				x.mode = invalid
    45  				return
    46  			}
    47  			target = Default(x.typ)
    48  		}
    49  		newType, val, code := check.implicitTypeAndValue(x, target)
    50  		if code != 0 {
    51  			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
    52  			switch code {
    53  			case _TruncatedFloat:
    54  				msg += " (truncated)"
    55  			case _NumericOverflow:
    56  				msg += " (overflows)"
    57  			default:
    58  				code = _IncompatibleAssign
    59  			}
    60  			check.error(x, code, msg)
    61  			x.mode = invalid
    62  			return
    63  		}
    64  		if val != nil {
    65  			x.val = val
    66  			check.updateExprVal(x.expr, val)
    67  		}
    68  		if newType != x.typ {
    69  			x.typ = newType
    70  			check.updateExprType(x.expr, newType, false)
    71  		}
    72  	}
    73  
    74  	// A generic (non-instantiated) function value cannot be assigned to a variable.
    75  	if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
    76  		check.errorf(x, _WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
    77  	}
    78  
    79  	// spec: "If a left-hand side is the blank identifier, any typed or
    80  	// non-constant value except for the predeclared identifier nil may
    81  	// be assigned to it."
    82  	if T == nil {
    83  		return
    84  	}
    85  
    86  	reason := ""
    87  	if ok, code := x.assignableTo(check, T, &reason); !ok {
    88  		if compilerErrorMessages {
    89  			if reason != "" {
    90  				check.errorf(x, code, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
    91  			} else {
    92  				check.errorf(x, code, "cannot use %s as type %s in %s", x, T, context)
    93  			}
    94  		} else {
    95  			if reason != "" {
    96  				check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
    97  			} else {
    98  				check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
    99  			}
   100  		}
   101  		x.mode = invalid
   102  	}
   103  }
   104  
   105  func (check *Checker) initConst(lhs *Const, x *operand) {
   106  	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
   107  		if lhs.typ == nil {
   108  			lhs.typ = Typ[Invalid]
   109  		}
   110  		return
   111  	}
   112  
   113  	// rhs must be a constant
   114  	if x.mode != constant_ {
   115  		check.errorf(x, _InvalidConstInit, "%s is not constant", x)
   116  		if lhs.typ == nil {
   117  			lhs.typ = Typ[Invalid]
   118  		}
   119  		return
   120  	}
   121  	assert(isConstType(x.typ))
   122  
   123  	// If the lhs doesn't have a type yet, use the type of x.
   124  	if lhs.typ == nil {
   125  		lhs.typ = x.typ
   126  	}
   127  
   128  	check.assignment(x, lhs.typ, "constant declaration")
   129  	if x.mode == invalid {
   130  		return
   131  	}
   132  
   133  	lhs.val = x.val
   134  }
   135  
   136  func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
   137  	if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
   138  		if lhs.typ == nil {
   139  			lhs.typ = Typ[Invalid]
   140  		}
   141  		return nil
   142  	}
   143  
   144  	// If the lhs doesn't have a type yet, use the type of x.
   145  	if lhs.typ == nil {
   146  		typ := x.typ
   147  		if isUntyped(typ) {
   148  			// convert untyped types to default types
   149  			if typ == Typ[UntypedNil] {
   150  				check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
   151  				lhs.typ = Typ[Invalid]
   152  				return nil
   153  			}
   154  			typ = Default(typ)
   155  		}
   156  		lhs.typ = typ
   157  	}
   158  
   159  	check.assignment(x, lhs.typ, context)
   160  	if x.mode == invalid {
   161  		return nil
   162  	}
   163  
   164  	return x.typ
   165  }
   166  
   167  func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
   168  	if x.mode == invalid || x.typ == Typ[Invalid] {
   169  		check.useLHS(lhs)
   170  		return nil
   171  	}
   172  
   173  	// Determine if the lhs is a (possibly parenthesized) identifier.
   174  	ident, _ := unparen(lhs).(*ast.Ident)
   175  
   176  	// Don't evaluate lhs if it is the blank identifier.
   177  	if ident != nil && ident.Name == "_" {
   178  		check.recordDef(ident, nil)
   179  		check.assignment(x, nil, "assignment to _ identifier")
   180  		if x.mode == invalid {
   181  			return nil
   182  		}
   183  		return x.typ
   184  	}
   185  
   186  	// If the lhs is an identifier denoting a variable v, this assignment
   187  	// is not a 'use' of v. Remember current value of v.used and restore
   188  	// after evaluating the lhs via check.expr.
   189  	var v *Var
   190  	var v_used bool
   191  	if ident != nil {
   192  		if obj := check.lookup(ident.Name); obj != nil {
   193  			// It's ok to mark non-local variables, but ignore variables
   194  			// from other packages to avoid potential race conditions with
   195  			// dot-imported variables.
   196  			if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
   197  				v = w
   198  				v_used = v.used
   199  			}
   200  		}
   201  	}
   202  
   203  	var z operand
   204  	check.expr(&z, lhs)
   205  	if v != nil {
   206  		v.used = v_used // restore v.used
   207  	}
   208  
   209  	if z.mode == invalid || z.typ == Typ[Invalid] {
   210  		return nil
   211  	}
   212  
   213  	// spec: "Each left-hand side operand must be addressable, a map index
   214  	// expression, or the blank identifier. Operands may be parenthesized."
   215  	switch z.mode {
   216  	case invalid:
   217  		return nil
   218  	case variable, mapindex:
   219  		// ok
   220  	default:
   221  		if sel, ok := z.expr.(*ast.SelectorExpr); ok {
   222  			var op operand
   223  			check.expr(&op, sel.X)
   224  			if op.mode == mapindex {
   225  				check.errorf(&z, _UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr))
   226  				return nil
   227  			}
   228  		}
   229  		check.errorf(&z, _UnassignableOperand, "cannot assign to %s", &z)
   230  		return nil
   231  	}
   232  
   233  	check.assignment(x, z.typ, "assignment")
   234  	if x.mode == invalid {
   235  		return nil
   236  	}
   237  
   238  	return x.typ
   239  }
   240  
   241  // operandTypes returns the list of types for the given operands.
   242  func operandTypes(list []*operand) (res []Type) {
   243  	for _, x := range list {
   244  		res = append(res, x.typ)
   245  	}
   246  	return res
   247  }
   248  
   249  // varTypes returns the list of types for the given variables.
   250  func varTypes(list []*Var) (res []Type) {
   251  	for _, x := range list {
   252  		res = append(res, x.typ)
   253  	}
   254  	return res
   255  }
   256  
   257  // typesSummary returns a string of the form "(t1, t2, ...)" where the
   258  // ti's are user-friendly string representations for the given types.
   259  // If variadic is set and the last type is a slice, its string is of
   260  // the form "...E" where E is the slice's element type.
   261  func (check *Checker) typesSummary(list []Type, variadic bool) string {
   262  	var res []string
   263  	for i, t := range list {
   264  		var s string
   265  		switch {
   266  		case t == nil:
   267  			fallthrough // should not happen but be cautious
   268  		case t == Typ[Invalid]:
   269  			s = "<T>"
   270  		case isUntyped(t):
   271  			if isNumeric(t) {
   272  				// Do not imply a specific type requirement:
   273  				// "have number, want float64" is better than
   274  				// "have untyped int, want float64" or
   275  				// "have int, want float64".
   276  				s = "number"
   277  			} else {
   278  				// If we don't have a number, omit the "untyped" qualifier
   279  				// for compactness.
   280  				s = strings.Replace(t.(*Basic).name, "untyped ", "", -1)
   281  			}
   282  		case variadic && i == len(list)-1:
   283  			s = check.sprintf("...%s", t.(*Slice).elem)
   284  		}
   285  		if s == "" {
   286  			s = check.sprintf("%s", t)
   287  		}
   288  		res = append(res, s)
   289  	}
   290  	return "(" + strings.Join(res, ", ") + ")"
   291  }
   292  
   293  func measure(x int, unit string) string {
   294  	if x != 1 {
   295  		unit += "s"
   296  	}
   297  	return fmt.Sprintf("%d %s", x, unit)
   298  }
   299  
   300  func (check *Checker) assignError(rhs []ast.Expr, nvars, nvals int) {
   301  	vars := measure(nvars, "variable")
   302  	vals := measure(nvals, "value")
   303  	rhs0 := rhs[0]
   304  
   305  	if len(rhs) == 1 {
   306  		if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
   307  			check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
   308  			return
   309  		}
   310  	}
   311  	check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
   312  }
   313  
   314  // If returnStmt != nil, initVars is called to type-check the assignment
   315  // of return expressions, and returnStmt is the return statement.
   316  func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnStmt ast.Stmt) {
   317  	rhs, commaOk := check.exprList(origRHS, len(lhs) == 2 && returnStmt == nil)
   318  
   319  	if len(lhs) != len(rhs) {
   320  		// invalidate lhs
   321  		for _, obj := range lhs {
   322  			obj.used = true // avoid declared but not used errors
   323  			if obj.typ == nil {
   324  				obj.typ = Typ[Invalid]
   325  			}
   326  		}
   327  		// don't report an error if we already reported one
   328  		for _, x := range rhs {
   329  			if x.mode == invalid {
   330  				return
   331  			}
   332  		}
   333  		if returnStmt != nil {
   334  			var at positioner = returnStmt
   335  			qualifier := "not enough"
   336  			if len(rhs) > len(lhs) {
   337  				at = rhs[len(lhs)].expr // report at first extra value
   338  				qualifier = "too many"
   339  			} else if len(rhs) > 0 {
   340  				at = rhs[len(rhs)-1].expr // report at last value
   341  			}
   342  			check.errorf(at, _WrongResultCount, "%s return values\n\thave %s\n\twant %s",
   343  				qualifier,
   344  				check.typesSummary(operandTypes(rhs), false),
   345  				check.typesSummary(varTypes(lhs), false),
   346  			)
   347  			return
   348  		}
   349  		if compilerErrorMessages {
   350  			check.assignError(origRHS, len(lhs), len(rhs))
   351  		} else {
   352  			check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
   353  		}
   354  		return
   355  	}
   356  
   357  	context := "assignment"
   358  	if returnStmt != nil {
   359  		context = "return statement"
   360  	}
   361  
   362  	if commaOk {
   363  		var a [2]Type
   364  		for i := range a {
   365  			a[i] = check.initVar(lhs[i], rhs[i], context)
   366  		}
   367  		check.recordCommaOkTypes(origRHS[0], a)
   368  		return
   369  	}
   370  
   371  	for i, lhs := range lhs {
   372  		check.initVar(lhs, rhs[i], context)
   373  	}
   374  }
   375  
   376  func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
   377  	rhs, commaOk := check.exprList(origRHS, len(lhs) == 2)
   378  
   379  	if len(lhs) != len(rhs) {
   380  		check.useLHS(lhs...)
   381  		// don't report an error if we already reported one
   382  		for _, x := range rhs {
   383  			if x.mode == invalid {
   384  				return
   385  			}
   386  		}
   387  		if compilerErrorMessages {
   388  			check.assignError(origRHS, len(lhs), len(rhs))
   389  		} else {
   390  			check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
   391  		}
   392  		return
   393  	}
   394  
   395  	if commaOk {
   396  		var a [2]Type
   397  		for i := range a {
   398  			a[i] = check.assignVar(lhs[i], rhs[i])
   399  		}
   400  		check.recordCommaOkTypes(origRHS[0], a)
   401  		return
   402  	}
   403  
   404  	for i, lhs := range lhs {
   405  		check.assignVar(lhs, rhs[i])
   406  	}
   407  }
   408  
   409  func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) {
   410  	top := len(check.delayed)
   411  	scope := check.scope
   412  
   413  	// collect lhs variables
   414  	seen := make(map[string]bool, len(lhs))
   415  	lhsVars := make([]*Var, len(lhs))
   416  	newVars := make([]*Var, 0, len(lhs))
   417  	hasErr := false
   418  	for i, lhs := range lhs {
   419  		ident, _ := lhs.(*ast.Ident)
   420  		if ident == nil {
   421  			check.useLHS(lhs)
   422  			// TODO(rFindley) this is redundant with a parser error. Consider omitting?
   423  			check.errorf(lhs, _BadDecl, "non-name %s on left side of :=", lhs)
   424  			hasErr = true
   425  			continue
   426  		}
   427  
   428  		name := ident.Name
   429  		if name != "_" {
   430  			if seen[name] {
   431  				check.errorf(lhs, _RepeatedDecl, "%s repeated on left side of :=", lhs)
   432  				hasErr = true
   433  				continue
   434  			}
   435  			seen[name] = true
   436  		}
   437  
   438  		// Use the correct obj if the ident is redeclared. The
   439  		// variable's scope starts after the declaration; so we
   440  		// must use Scope.Lookup here and call Scope.Insert
   441  		// (via check.declare) later.
   442  		if alt := scope.Lookup(name); alt != nil {
   443  			check.recordUse(ident, alt)
   444  			// redeclared object must be a variable
   445  			if obj, _ := alt.(*Var); obj != nil {
   446  				lhsVars[i] = obj
   447  			} else {
   448  				check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
   449  				hasErr = true
   450  			}
   451  			continue
   452  		}
   453  
   454  		// declare new variable
   455  		obj := NewVar(ident.Pos(), check.pkg, name, nil)
   456  		lhsVars[i] = obj
   457  		if name != "_" {
   458  			newVars = append(newVars, obj)
   459  		}
   460  		check.recordDef(ident, obj)
   461  	}
   462  
   463  	// create dummy variables where the lhs is invalid
   464  	for i, obj := range lhsVars {
   465  		if obj == nil {
   466  			lhsVars[i] = NewVar(lhs[i].Pos(), check.pkg, "_", nil)
   467  		}
   468  	}
   469  
   470  	check.initVars(lhsVars, rhs, nil)
   471  
   472  	// process function literals in rhs expressions before scope changes
   473  	check.processDelayed(top)
   474  
   475  	if len(newVars) == 0 && !hasErr {
   476  		check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=")
   477  		return
   478  	}
   479  
   480  	// declare new variables
   481  	// spec: "The scope of a constant or variable identifier declared inside
   482  	// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
   483  	// for short variable declarations) and ends at the end of the innermost
   484  	// containing block."
   485  	scopePos := rhs[len(rhs)-1].End()
   486  	for _, obj := range newVars {
   487  		check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
   488  	}
   489  }
   490  

View as plain text