assignments.go raw

   1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
   2  // Source: ../../cmd/compile/internal/types2/assignments.go
   3  
   4  // Copyright 2013 The Go Authors. All rights reserved.
   5  // Use of this source code is governed by a BSD-style
   6  // license that can be found in the LICENSE file.
   7  
   8  // This file implements initialization and assignment checks.
   9  
  10  package types
  11  
  12  import (
  13  	"fmt"
  14  	"go/ast"
  15  	. "internal/types/errors"
  16  	"strings"
  17  )
  18  
  19  // assignment reports whether x can be assigned to a variable of type T,
  20  // if necessary by attempting to convert untyped values to the appropriate
  21  // type. context describes the context in which the assignment takes place.
  22  // Use T == nil to indicate assignment to an untyped blank identifier.
  23  // If the assignment check fails, x.mode is set to invalid.
  24  func (check *Checker) assignment(x *operand, T Type, context string) {
  25  	check.singleValue(x)
  26  
  27  	switch x.mode {
  28  	case invalid:
  29  		return // error reported before
  30  	case nilvalue:
  31  		assert(isTypes2)
  32  		// ok
  33  	case constant_, variable, mapindex, value, commaok, commaerr:
  34  		// ok
  35  	default:
  36  		// we may get here because of other problems (go.dev/issue/39634, crash 12)
  37  		// TODO(gri) do we need a new "generic" error code here?
  38  		check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
  39  		x.mode = invalid
  40  		return
  41  	}
  42  
  43  	if isUntyped(x.typ) {
  44  		target := T
  45  		// spec: "If an untyped constant is assigned to a variable of interface
  46  		// type or the blank identifier, the constant is first converted to type
  47  		// bool, rune, int, float64, complex128 or string respectively, depending
  48  		// on whether the value is a boolean, rune, integer, floating-point,
  49  		// complex, or string constant."
  50  		if isTypes2 {
  51  			if x.isNil() {
  52  				if T == nil {
  53  					check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
  54  					x.mode = invalid
  55  					return
  56  				}
  57  			} else if T == nil || isNonTypeParamInterface(T) {
  58  				target = Default(x.typ)
  59  			}
  60  		} else { // go/types
  61  			if T == nil || isNonTypeParamInterface(T) {
  62  				if T == nil && x.typ == Typ[UntypedNil] {
  63  					check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
  64  					x.mode = invalid
  65  					return
  66  				}
  67  				target = Default(x.typ)
  68  			}
  69  		}
  70  		newType, val, code := check.implicitTypeAndValue(x, target)
  71  		if code != 0 {
  72  			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
  73  			switch code {
  74  			case TruncatedFloat:
  75  				msg += " (truncated)"
  76  			case NumericOverflow:
  77  				msg += " (overflows)"
  78  			default:
  79  				code = IncompatibleAssign
  80  			}
  81  			check.error(x, code, msg)
  82  			x.mode = invalid
  83  			return
  84  		}
  85  		if val != nil {
  86  			x.val = val
  87  			check.updateExprVal(x.expr, val)
  88  		}
  89  		if newType != x.typ {
  90  			x.typ = newType
  91  			check.updateExprType(x.expr, newType, false)
  92  		}
  93  	}
  94  	// x.typ is typed
  95  
  96  	// A generic (non-instantiated) function value cannot be assigned to a variable.
  97  	if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
  98  		check.errorf(x, WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
  99  		x.mode = invalid
 100  		return
 101  	}
 102  
 103  	// spec: "If a left-hand side is the blank identifier, any typed or
 104  	// non-constant value except for the predeclared identifier nil may
 105  	// be assigned to it."
 106  	if T == nil {
 107  		return
 108  	}
 109  
 110  	cause := ""
 111  	if ok, code := x.assignableTo(check, T, &cause); !ok {
 112  		if cause != "" {
 113  			check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
 114  		} else {
 115  			check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
 116  		}
 117  		x.mode = invalid
 118  	}
 119  }
 120  
 121  func (check *Checker) initConst(lhs *Const, x *operand) {
 122  	if x.mode == invalid || !isValid(x.typ) || !isValid(lhs.typ) {
 123  		if lhs.typ == nil {
 124  			lhs.typ = Typ[Invalid]
 125  		}
 126  		return
 127  	}
 128  
 129  	// rhs must be a constant
 130  	if x.mode != constant_ {
 131  		check.errorf(x, InvalidConstInit, "%s is not constant", x)
 132  		if lhs.typ == nil {
 133  			lhs.typ = Typ[Invalid]
 134  		}
 135  		return
 136  	}
 137  	assert(isConstType(x.typ))
 138  
 139  	// If the lhs doesn't have a type yet, use the type of x.
 140  	if lhs.typ == nil {
 141  		lhs.typ = x.typ
 142  	}
 143  
 144  	check.assignment(x, lhs.typ, "constant declaration")
 145  	if x.mode == invalid {
 146  		return
 147  	}
 148  
 149  	lhs.val = x.val
 150  }
 151  
 152  // initVar checks the initialization lhs = x in a variable declaration.
 153  // If lhs doesn't have a type yet, it is given the type of x,
 154  // or Typ[Invalid] in case of an error.
 155  // If the initialization check fails, x.mode is set to invalid.
 156  func (check *Checker) initVar(lhs *Var, x *operand, context string) {
 157  	if x.mode == invalid || !isValid(x.typ) || !isValid(lhs.typ) {
 158  		if lhs.typ == nil {
 159  			lhs.typ = Typ[Invalid]
 160  		}
 161  		x.mode = invalid
 162  		return
 163  	}
 164  
 165  	// If lhs doesn't have a type yet, use the type of x.
 166  	if lhs.typ == nil {
 167  		typ := x.typ
 168  		if isUntyped(typ) {
 169  			// convert untyped types to default types
 170  			if typ == Typ[UntypedNil] {
 171  				check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
 172  				lhs.typ = Typ[Invalid]
 173  				x.mode = invalid
 174  				return
 175  			}
 176  			typ = Default(typ)
 177  		}
 178  		lhs.typ = typ
 179  	}
 180  
 181  	check.assignment(x, lhs.typ, context)
 182  }
 183  
 184  // lhsVar checks a lhs variable in an assignment and returns its type.
 185  // lhsVar takes care of not counting a lhs identifier as a "use" of
 186  // that identifier. The result is nil if it is the blank identifier,
 187  // and Typ[Invalid] if it is an invalid lhs expression.
 188  func (check *Checker) lhsVar(lhs ast.Expr) Type {
 189  	// Determine if the lhs is a (possibly parenthesized) identifier.
 190  	ident, _ := ast.Unparen(lhs).(*ast.Ident)
 191  
 192  	// Don't evaluate lhs if it is the blank identifier.
 193  	if ident != nil && ident.Name == "_" {
 194  		check.recordDef(ident, nil)
 195  		return nil
 196  	}
 197  
 198  	// If the lhs is an identifier denoting a variable v, this reference
 199  	// is not a 'use' of v. Remember current value of v.used and restore
 200  	// after evaluating the lhs via check.expr.
 201  	var v *Var
 202  	var v_used bool
 203  	if ident != nil {
 204  		if obj := check.lookup(ident.Name); obj != nil {
 205  			// It's ok to mark non-local variables, but ignore variables
 206  			// from other packages to avoid potential race conditions with
 207  			// dot-imported variables.
 208  			if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
 209  				v = w
 210  				v_used = check.usedVars[v]
 211  			}
 212  		}
 213  	}
 214  
 215  	var x operand
 216  	check.expr(nil, &x, lhs)
 217  
 218  	if v != nil {
 219  		check.usedVars[v] = v_used // restore v.used
 220  	}
 221  
 222  	if x.mode == invalid || !isValid(x.typ) {
 223  		return Typ[Invalid]
 224  	}
 225  
 226  	// spec: "Each left-hand side operand must be addressable, a map index
 227  	// expression, or the blank identifier. Operands may be parenthesized."
 228  	switch x.mode {
 229  	case invalid:
 230  		return Typ[Invalid]
 231  	case variable, mapindex:
 232  		// ok
 233  	default:
 234  		if sel, ok := x.expr.(*ast.SelectorExpr); ok {
 235  			var op operand
 236  			check.expr(nil, &op, sel.X)
 237  			if op.mode == mapindex {
 238  				check.errorf(&x, UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(x.expr))
 239  				return Typ[Invalid]
 240  			}
 241  		}
 242  		check.errorf(&x, UnassignableOperand, "cannot assign to %s (neither addressable nor a map index expression)", x.expr)
 243  		return Typ[Invalid]
 244  	}
 245  
 246  	return x.typ
 247  }
 248  
 249  // assignVar checks the assignment lhs = rhs (if x == nil), or lhs = x (if x != nil).
 250  // If x != nil, it must be the evaluation of rhs (and rhs will be ignored).
 251  // If the assignment check fails and x != nil, x.mode is set to invalid.
 252  func (check *Checker) assignVar(lhs, rhs ast.Expr, x *operand, context string) {
 253  	T := check.lhsVar(lhs) // nil if lhs is _
 254  	if !isValid(T) {
 255  		if x != nil {
 256  			x.mode = invalid
 257  		} else {
 258  			check.use(rhs)
 259  		}
 260  		return
 261  	}
 262  
 263  	if x == nil {
 264  		var target *target
 265  		// avoid calling ExprString if not needed
 266  		if T != nil {
 267  			if _, ok := under(T).(*Signature); ok {
 268  				target = newTarget(T, ExprString(lhs))
 269  			}
 270  		}
 271  		x = new(operand)
 272  		check.expr(target, x, rhs)
 273  	}
 274  
 275  	if T == nil && context == "assignment" {
 276  		context = "assignment to _ identifier"
 277  	}
 278  	check.assignment(x, T, context)
 279  }
 280  
 281  // operandTypes returns the list of types for the given operands.
 282  func operandTypes(list []*operand) (res []Type) {
 283  	for _, x := range list {
 284  		res = append(res, x.typ)
 285  	}
 286  	return res
 287  }
 288  
 289  // varTypes returns the list of types for the given variables.
 290  func varTypes(list []*Var) (res []Type) {
 291  	for _, x := range list {
 292  		res = append(res, x.typ)
 293  	}
 294  	return res
 295  }
 296  
 297  // typesSummary returns a string of the form "(t1, t2, ...)" where the
 298  // ti's are user-friendly string representations for the given types.
 299  // If variadic is set and the last type is a slice, its string is of
 300  // the form "...E" where E is the slice's element type.
 301  // If hasDots is set, the last argument string is of the form "T..."
 302  // where T is the last type.
 303  // Only one of variadic and hasDots may be set.
 304  func (check *Checker) typesSummary(list []Type, variadic, hasDots bool) string {
 305  	assert(!(variadic && hasDots))
 306  	var res []string
 307  	for i, t := range list {
 308  		var s string
 309  		switch {
 310  		case t == nil:
 311  			fallthrough // should not happen but be cautious
 312  		case !isValid(t):
 313  			s = "unknown type"
 314  		case isUntyped(t): // => *Basic
 315  			if isNumeric(t) {
 316  				// Do not imply a specific type requirement:
 317  				// "have number, want float64" is better than
 318  				// "have untyped int, want float64" or
 319  				// "have int, want float64".
 320  				s = "number"
 321  			} else {
 322  				// If we don't have a number, omit the "untyped" qualifier
 323  				// for compactness.
 324  				s = strings.ReplaceAll(t.(*Basic).name, "untyped ", "")
 325  			}
 326  		default:
 327  			s = check.sprintf("%s", t)
 328  		}
 329  		// handle ... parameters/arguments
 330  		if i == len(list)-1 {
 331  			switch {
 332  			case variadic:
 333  				// In correct code, the parameter type is a slice, but be careful.
 334  				if t, _ := t.(*Slice); t != nil {
 335  					s = check.sprintf("%s", t.elem)
 336  				}
 337  				s = "..." + s
 338  			case hasDots:
 339  				s += "..."
 340  			}
 341  		}
 342  		res = append(res, s)
 343  	}
 344  	return "(" + strings.Join(res, ", ") + ")"
 345  }
 346  
 347  func measure(x int, unit string) string {
 348  	if x != 1 {
 349  		unit += "s"
 350  	}
 351  	return fmt.Sprintf("%d %s", x, unit)
 352  }
 353  
 354  func (check *Checker) assignError(rhs []ast.Expr, l, r int) {
 355  	vars := measure(l, "variable")
 356  	vals := measure(r, "value")
 357  	rhs0 := rhs[0]
 358  
 359  	if len(rhs) == 1 {
 360  		if call, _ := ast.Unparen(rhs0).(*ast.CallExpr); call != nil {
 361  			check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
 362  			return
 363  		}
 364  	}
 365  	check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
 366  }
 367  
 368  func (check *Checker) returnError(at positioner, lhs []*Var, rhs []*operand) {
 369  	l, r := len(lhs), len(rhs)
 370  	qualifier := "not enough"
 371  	if r > l {
 372  		at = rhs[l] // report at first extra value
 373  		qualifier = "too many"
 374  	} else if r > 0 {
 375  		at = rhs[r-1] // report at last value
 376  	}
 377  	err := check.newError(WrongResultCount)
 378  	err.addf(at, "%s return values", qualifier)
 379  	err.addf(noposn, "have %s", check.typesSummary(operandTypes(rhs), false, false))
 380  	err.addf(noposn, "want %s", check.typesSummary(varTypes(lhs), false, false))
 381  	err.report()
 382  }
 383  
 384  // initVars type-checks assignments of initialization expressions orig_rhs
 385  // to variables lhs.
 386  // If returnStmt is non-nil, initVars type-checks the implicit assignment
 387  // of result expressions orig_rhs to function result parameters lhs.
 388  func (check *Checker) initVars(lhs []*Var, orig_rhs []ast.Expr, returnStmt ast.Stmt) {
 389  	context := "assignment"
 390  	if returnStmt != nil {
 391  		context = "return statement"
 392  	}
 393  
 394  	l, r := len(lhs), len(orig_rhs)
 395  
 396  	// If l == 1 and the rhs is a single call, for a better
 397  	// error message don't handle it as n:n mapping below.
 398  	isCall := false
 399  	if r == 1 {
 400  		_, isCall = ast.Unparen(orig_rhs[0]).(*ast.CallExpr)
 401  	}
 402  
 403  	// If we have a n:n mapping from lhs variable to rhs expression,
 404  	// each value can be assigned to its corresponding variable.
 405  	if l == r && !isCall {
 406  		var x operand
 407  		for i, lhs := range lhs {
 408  			desc := lhs.name
 409  			if returnStmt != nil && desc == "" {
 410  				desc = "result variable"
 411  			}
 412  			check.expr(newTarget(lhs.typ, desc), &x, orig_rhs[i])
 413  			check.initVar(lhs, &x, context)
 414  		}
 415  		return
 416  	}
 417  
 418  	// If we don't have an n:n mapping, the rhs must be a single expression
 419  	// resulting in 2 or more values; otherwise we have an assignment mismatch.
 420  	if r != 1 {
 421  		// Only report a mismatch error if there are no other errors on the rhs.
 422  		if check.use(orig_rhs...) {
 423  			if returnStmt != nil {
 424  				rhs := check.exprList(orig_rhs)
 425  				check.returnError(returnStmt, lhs, rhs)
 426  			} else {
 427  				check.assignError(orig_rhs, l, r)
 428  			}
 429  		}
 430  		// ensure that LHS variables have a type
 431  		for _, v := range lhs {
 432  			if v.typ == nil {
 433  				v.typ = Typ[Invalid]
 434  			}
 435  		}
 436  		return
 437  	}
 438  
 439  	rhs, commaOk := check.multiExpr(orig_rhs[0], l == 2 && returnStmt == nil)
 440  	r = len(rhs)
 441  	if l == r {
 442  		for i, lhs := range lhs {
 443  			check.initVar(lhs, rhs[i], context)
 444  		}
 445  		// Only record comma-ok expression if both initializations succeeded
 446  		// (go.dev/issue/59371).
 447  		if commaOk && rhs[0].mode != invalid && rhs[1].mode != invalid {
 448  			check.recordCommaOkTypes(orig_rhs[0], rhs)
 449  		}
 450  		return
 451  	}
 452  
 453  	// In all other cases we have an assignment mismatch.
 454  	// Only report a mismatch error if there are no other errors on the rhs.
 455  	if rhs[0].mode != invalid {
 456  		if returnStmt != nil {
 457  			check.returnError(returnStmt, lhs, rhs)
 458  		} else {
 459  			check.assignError(orig_rhs, l, r)
 460  		}
 461  	}
 462  	// ensure that LHS variables have a type
 463  	for _, v := range lhs {
 464  		if v.typ == nil {
 465  			v.typ = Typ[Invalid]
 466  		}
 467  	}
 468  	// orig_rhs[0] was already evaluated
 469  }
 470  
 471  // assignVars type-checks assignments of expressions orig_rhs to variables lhs.
 472  func (check *Checker) assignVars(lhs, orig_rhs []ast.Expr) {
 473  	l, r := len(lhs), len(orig_rhs)
 474  
 475  	// If l == 1 and the rhs is a single call, for a better
 476  	// error message don't handle it as n:n mapping below.
 477  	isCall := false
 478  	if r == 1 {
 479  		_, isCall = ast.Unparen(orig_rhs[0]).(*ast.CallExpr)
 480  	}
 481  
 482  	// If we have a n:n mapping from lhs variable to rhs expression,
 483  	// each value can be assigned to its corresponding variable.
 484  	if l == r && !isCall {
 485  		for i, lhs := range lhs {
 486  			check.assignVar(lhs, orig_rhs[i], nil, "assignment")
 487  		}
 488  		return
 489  	}
 490  
 491  	// If we don't have an n:n mapping, the rhs must be a single expression
 492  	// resulting in 2 or more values; otherwise we have an assignment mismatch.
 493  	if r != 1 {
 494  		// Only report a mismatch error if there are no other errors on the lhs or rhs.
 495  		okLHS := check.useLHS(lhs...)
 496  		okRHS := check.use(orig_rhs...)
 497  		if okLHS && okRHS {
 498  			check.assignError(orig_rhs, l, r)
 499  		}
 500  		return
 501  	}
 502  
 503  	rhs, commaOk := check.multiExpr(orig_rhs[0], l == 2)
 504  	r = len(rhs)
 505  	if l == r {
 506  		for i, lhs := range lhs {
 507  			check.assignVar(lhs, nil, rhs[i], "assignment")
 508  		}
 509  		// Only record comma-ok expression if both assignments succeeded
 510  		// (go.dev/issue/59371).
 511  		if commaOk && rhs[0].mode != invalid && rhs[1].mode != invalid {
 512  			check.recordCommaOkTypes(orig_rhs[0], rhs)
 513  		}
 514  		return
 515  	}
 516  
 517  	// In all other cases we have an assignment mismatch.
 518  	// Only report a mismatch error if there are no other errors on the rhs.
 519  	if rhs[0].mode != invalid {
 520  		check.assignError(orig_rhs, l, r)
 521  	}
 522  	check.useLHS(lhs...)
 523  	// orig_rhs[0] was already evaluated
 524  }
 525  
 526  func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) {
 527  	top := len(check.delayed)
 528  	scope := check.scope
 529  
 530  	// collect lhs variables
 531  	seen := make(map[string]bool, len(lhs))
 532  	lhsVars := make([]*Var, len(lhs))
 533  	newVars := make([]*Var, 0, len(lhs))
 534  	hasErr := false
 535  	for i, lhs := range lhs {
 536  		ident, _ := lhs.(*ast.Ident)
 537  		if ident == nil {
 538  			check.useLHS(lhs)
 539  			// TODO(gri) This is redundant with a go/parser error. Consider omitting in go/types?
 540  			check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
 541  			hasErr = true
 542  			continue
 543  		}
 544  
 545  		name := ident.Name
 546  		if name != "_" {
 547  			if seen[name] {
 548  				check.errorf(lhs, RepeatedDecl, "%s repeated on left side of :=", lhs)
 549  				hasErr = true
 550  				continue
 551  			}
 552  			seen[name] = true
 553  		}
 554  
 555  		// Use the correct obj if the ident is redeclared. The
 556  		// variable's scope starts after the declaration; so we
 557  		// must use Scope.Lookup here and call Scope.Insert
 558  		// (via check.declare) later.
 559  		if alt := scope.Lookup(name); alt != nil {
 560  			check.recordUse(ident, alt)
 561  			// redeclared object must be a variable
 562  			if obj, _ := alt.(*Var); obj != nil {
 563  				lhsVars[i] = obj
 564  			} else {
 565  				check.errorf(lhs, UnassignableOperand, "cannot assign to %s", lhs)
 566  				hasErr = true
 567  			}
 568  			continue
 569  		}
 570  
 571  		// declare new variable
 572  		obj := newVar(LocalVar, ident.Pos(), check.pkg, name, nil)
 573  		lhsVars[i] = obj
 574  		if name != "_" {
 575  			newVars = append(newVars, obj)
 576  		}
 577  		check.recordDef(ident, obj)
 578  	}
 579  
 580  	// create dummy variables where the lhs is invalid
 581  	for i, obj := range lhsVars {
 582  		if obj == nil {
 583  			lhsVars[i] = newVar(LocalVar, lhs[i].Pos(), check.pkg, "_", nil)
 584  		}
 585  	}
 586  
 587  	check.initVars(lhsVars, rhs, nil)
 588  
 589  	// process function literals in rhs expressions before scope changes
 590  	check.processDelayed(top)
 591  
 592  	if len(newVars) == 0 && !hasErr {
 593  		check.softErrorf(pos, NoNewVar, "no new variables on left side of :=")
 594  		return
 595  	}
 596  
 597  	// declare new variables
 598  	// spec: "The scope of a constant or variable identifier declared inside
 599  	// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
 600  	// for short variable declarations) and ends at the end of the innermost
 601  	// containing block."
 602  	scopePos := endPos(rhs[len(rhs)-1])
 603  	for _, obj := range newVars {
 604  		check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
 605  	}
 606  }
 607