...

Source file src/go/types/call.go

Documentation: go/types

		 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 typechecking of call and selector expressions.
		 6  
		 7  package types
		 8  
		 9  import (
		10  	"go/ast"
		11  	"go/internal/typeparams"
		12  	"go/token"
		13  	"strings"
		14  	"unicode"
		15  )
		16  
		17  // funcInst type-checks a function instantiation inst and returns the result in x.
		18  // The operand x must be the evaluation of inst.X and its type must be a signature.
		19  func (check *Checker) funcInst(x *operand, inst *ast.IndexExpr) {
		20  	xlist := typeparams.UnpackExpr(inst.Index)
		21  	targs := check.typeList(xlist)
		22  	if targs == nil {
		23  		x.mode = invalid
		24  		x.expr = inst
		25  		return
		26  	}
		27  	assert(len(targs) == len(xlist))
		28  
		29  	// check number of type arguments (got) vs number of type parameters (want)
		30  	sig := x.typ.(*Signature)
		31  	got, want := len(targs), len(sig.tparams)
		32  	if got > want {
		33  		check.errorf(xlist[got-1], _Todo, "got %d type arguments but want %d", got, want)
		34  		x.mode = invalid
		35  		x.expr = inst
		36  		return
		37  	}
		38  
		39  	// if we don't have enough type arguments, try type inference
		40  	inferred := false
		41  
		42  	if got < want {
		43  		targs = check.infer(inst, sig.tparams, targs, nil, nil, true)
		44  		if targs == nil {
		45  			// error was already reported
		46  			x.mode = invalid
		47  			x.expr = inst
		48  			return
		49  		}
		50  		got = len(targs)
		51  		inferred = true
		52  	}
		53  	assert(got == want)
		54  
		55  	// determine argument positions (for error reporting)
		56  	// TODO(rFindley) use a positioner here? instantiate would need to be
		57  	//								updated accordingly.
		58  	poslist := make([]token.Pos, len(xlist))
		59  	for i, x := range xlist {
		60  		poslist[i] = x.Pos()
		61  	}
		62  
		63  	// instantiate function signature
		64  	res := check.instantiate(x.Pos(), sig, targs, poslist).(*Signature)
		65  	assert(res.tparams == nil) // signature is not generic anymore
		66  	if inferred {
		67  		check.recordInferred(inst, targs, res)
		68  	}
		69  	x.typ = res
		70  	x.mode = value
		71  	x.expr = inst
		72  }
		73  
		74  func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
		75  	var inst *ast.IndexExpr
		76  	if iexpr, _ := call.Fun.(*ast.IndexExpr); iexpr != nil {
		77  		if check.indexExpr(x, iexpr) {
		78  			// Delay function instantiation to argument checking,
		79  			// where we combine type and value arguments for type
		80  			// inference.
		81  			assert(x.mode == value)
		82  			inst = iexpr
		83  		}
		84  		x.expr = iexpr
		85  		check.record(x)
		86  	} else {
		87  		check.exprOrType(x, call.Fun)
		88  	}
		89  
		90  	switch x.mode {
		91  	case invalid:
		92  		check.use(call.Args...)
		93  		x.expr = call
		94  		return statement
		95  
		96  	case typexpr:
		97  		// conversion
		98  		T := x.typ
		99  		x.mode = invalid
	 100  		switch n := len(call.Args); n {
	 101  		case 0:
	 102  			check.errorf(inNode(call, call.Rparen), _WrongArgCount, "missing argument in conversion to %s", T)
	 103  		case 1:
	 104  			check.expr(x, call.Args[0])
	 105  			if x.mode != invalid {
	 106  				if call.Ellipsis.IsValid() {
	 107  					check.errorf(call.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
	 108  					break
	 109  				}
	 110  				if t := asInterface(T); t != nil {
	 111  					check.completeInterface(token.NoPos, t)
	 112  					if t._IsConstraint() {
	 113  						check.errorf(call, _Todo, "cannot use interface %s in conversion (contains type list or is comparable)", T)
	 114  						break
	 115  					}
	 116  				}
	 117  				check.conversion(x, T)
	 118  			}
	 119  		default:
	 120  			check.use(call.Args...)
	 121  			check.errorf(call.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
	 122  		}
	 123  		x.expr = call
	 124  		return conversion
	 125  
	 126  	case builtin:
	 127  		id := x.id
	 128  		if !check.builtin(x, call, id) {
	 129  			x.mode = invalid
	 130  		}
	 131  		x.expr = call
	 132  		// a non-constant result implies a function call
	 133  		if x.mode != invalid && x.mode != constant_ {
	 134  			check.hasCallOrRecv = true
	 135  		}
	 136  		return predeclaredFuncs[id].kind
	 137  	}
	 138  
	 139  	// ordinary function/method call
	 140  	cgocall := x.mode == cgofunc
	 141  
	 142  	sig := asSignature(x.typ)
	 143  	if sig == nil {
	 144  		check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
	 145  		x.mode = invalid
	 146  		x.expr = call
	 147  		return statement
	 148  	}
	 149  
	 150  	// evaluate type arguments, if any
	 151  	var targs []Type
	 152  	if inst != nil {
	 153  		xlist := typeparams.UnpackExpr(inst.Index)
	 154  		targs = check.typeList(xlist)
	 155  		if targs == nil {
	 156  			check.use(call.Args...)
	 157  			x.mode = invalid
	 158  			x.expr = call
	 159  			return statement
	 160  		}
	 161  		assert(len(targs) == len(xlist))
	 162  
	 163  		// check number of type arguments (got) vs number of type parameters (want)
	 164  		got, want := len(targs), len(sig.tparams)
	 165  		if got > want {
	 166  			check.errorf(xlist[want], _Todo, "got %d type arguments but want %d", got, want)
	 167  			check.use(call.Args...)
	 168  			x.mode = invalid
	 169  			x.expr = call
	 170  			return statement
	 171  		}
	 172  	}
	 173  
	 174  	// evaluate arguments
	 175  	args, _ := check.exprList(call.Args, false)
	 176  	sig = check.arguments(call, sig, targs, args)
	 177  
	 178  	// determine result
	 179  	switch sig.results.Len() {
	 180  	case 0:
	 181  		x.mode = novalue
	 182  	case 1:
	 183  		if cgocall {
	 184  			x.mode = commaerr
	 185  		} else {
	 186  			x.mode = value
	 187  		}
	 188  		x.typ = sig.results.vars[0].typ // unpack tuple
	 189  	default:
	 190  		x.mode = value
	 191  		x.typ = sig.results
	 192  	}
	 193  	x.expr = call
	 194  	check.hasCallOrRecv = true
	 195  
	 196  	// if type inference failed, a parametrized result must be invalidated
	 197  	// (operands cannot have a parametrized type)
	 198  	if x.mode == value && len(sig.tparams) > 0 && isParameterized(sig.tparams, x.typ) {
	 199  		x.mode = invalid
	 200  	}
	 201  
	 202  	return statement
	 203  }
	 204  
	 205  func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
	 206  	switch len(elist) {
	 207  	case 0:
	 208  		// nothing to do
	 209  
	 210  	case 1:
	 211  		// single (possibly comma-ok) value, or function returning multiple values
	 212  		e := elist[0]
	 213  		var x operand
	 214  		check.multiExpr(&x, e)
	 215  		if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
	 216  			// multiple values
	 217  			xlist = make([]*operand, t.Len())
	 218  			for i, v := range t.vars {
	 219  				xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
	 220  			}
	 221  			break
	 222  		}
	 223  
	 224  		// exactly one (possibly invalid or comma-ok) value
	 225  		xlist = []*operand{&x}
	 226  		if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
	 227  			x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
	 228  			if x.mode == commaerr {
	 229  				x2.typ = universeError
	 230  			}
	 231  			xlist = append(xlist, x2)
	 232  			commaOk = true
	 233  		}
	 234  
	 235  	default:
	 236  		// multiple (possibly invalid) values
	 237  		xlist = make([]*operand, len(elist))
	 238  		for i, e := range elist {
	 239  			var x operand
	 240  			check.expr(&x, e)
	 241  			xlist[i] = &x
	 242  		}
	 243  	}
	 244  
	 245  	return
	 246  }
	 247  
	 248  func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, args []*operand) (rsig *Signature) {
	 249  	rsig = sig
	 250  
	 251  	// TODO(gri) try to eliminate this extra verification loop
	 252  	for _, a := range args {
	 253  		switch a.mode {
	 254  		case typexpr:
	 255  			check.errorf(a, 0, "%s used as value", a)
	 256  			return
	 257  		case invalid:
	 258  			return
	 259  		}
	 260  	}
	 261  
	 262  	// Function call argument/parameter count requirements
	 263  	//
	 264  	//							 | standard call		| dotdotdot call |
	 265  	// --------------+------------------+----------------+
	 266  	// standard func | nargs == npars	 | invalid				|
	 267  	// --------------+------------------+----------------+
	 268  	// variadic func | nargs >= npars-1 | nargs == npars |
	 269  	// --------------+------------------+----------------+
	 270  
	 271  	nargs := len(args)
	 272  	npars := sig.params.Len()
	 273  	ddd := call.Ellipsis.IsValid()
	 274  
	 275  	// set up parameters
	 276  	sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
	 277  	adjusted := false			 // indicates if sigParams is different from t.params
	 278  	if sig.variadic {
	 279  		if ddd {
	 280  			// variadic_func(a, b, c...)
	 281  			if len(call.Args) == 1 && nargs > 1 {
	 282  				// f()... is not permitted if f() is multi-valued
	 283  				check.errorf(inNode(call, call.Ellipsis), _InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
	 284  				return
	 285  			}
	 286  		} else {
	 287  			// variadic_func(a, b, c)
	 288  			if nargs >= npars-1 {
	 289  				// Create custom parameters for arguments: keep
	 290  				// the first npars-1 parameters and add one for
	 291  				// each argument mapping to the ... parameter.
	 292  				vars := make([]*Var, npars-1) // npars > 0 for variadic functions
	 293  				copy(vars, sig.params.vars)
	 294  				last := sig.params.vars[npars-1]
	 295  				typ := last.typ.(*Slice).elem
	 296  				for len(vars) < nargs {
	 297  					vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
	 298  				}
	 299  				sigParams = NewTuple(vars...) // possibly nil!
	 300  				adjusted = true
	 301  				npars = nargs
	 302  			} else {
	 303  				// nargs < npars-1
	 304  				npars-- // for correct error message below
	 305  			}
	 306  		}
	 307  	} else {
	 308  		if ddd {
	 309  			// standard_func(a, b, c...)
	 310  			check.errorf(inNode(call, call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
	 311  			return
	 312  		}
	 313  		// standard_func(a, b, c)
	 314  	}
	 315  
	 316  	// check argument count
	 317  	switch {
	 318  	case nargs < npars:
	 319  		check.errorf(inNode(call, call.Rparen), _WrongArgCount, "not enough arguments in call to %s", call.Fun)
	 320  		return
	 321  	case nargs > npars:
	 322  		check.errorf(args[npars], _WrongArgCount, "too many arguments in call to %s", call.Fun) // report at first extra argument
	 323  		return
	 324  	}
	 325  
	 326  	// infer type arguments and instantiate signature if necessary
	 327  	if len(sig.tparams) > 0 {
	 328  		// TODO(gri) provide position information for targs so we can feed
	 329  		//					 it to the instantiate call for better error reporting
	 330  		targs := check.infer(call, sig.tparams, targs, sigParams, args, true)
	 331  		if targs == nil {
	 332  			return // error already reported
	 333  		}
	 334  
	 335  		// compute result signature
	 336  		rsig = check.instantiate(call.Pos(), sig, targs, nil).(*Signature)
	 337  		assert(rsig.tparams == nil) // signature is not generic anymore
	 338  		check.recordInferred(call, targs, rsig)
	 339  
	 340  		// Optimization: Only if the parameter list was adjusted do we
	 341  		// need to compute it from the adjusted list; otherwise we can
	 342  		// simply use the result signature's parameter list.
	 343  		if adjusted {
	 344  			sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.tparams, targs)).(*Tuple)
	 345  		} else {
	 346  			sigParams = rsig.params
	 347  		}
	 348  	}
	 349  
	 350  	// check arguments
	 351  	for i, a := range args {
	 352  		check.assignment(a, sigParams.vars[i].typ, check.sprintf("argument to %s", call.Fun))
	 353  	}
	 354  
	 355  	return
	 356  }
	 357  
	 358  var cgoPrefixes = [...]string{
	 359  	"_Ciconst_",
	 360  	"_Cfconst_",
	 361  	"_Csconst_",
	 362  	"_Ctype_",
	 363  	"_Cvar_", // actually a pointer to the var
	 364  	"_Cfpvar_fp_",
	 365  	"_Cfunc_",
	 366  	"_Cmacro_", // function to evaluate the expanded expression
	 367  }
	 368  
	 369  func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
	 370  	// these must be declared before the "goto Error" statements
	 371  	var (
	 372  		obj			Object
	 373  		index		[]int
	 374  		indirect bool
	 375  	)
	 376  
	 377  	sel := e.Sel.Name
	 378  	// If the identifier refers to a package, handle everything here
	 379  	// so we don't need a "package" mode for operands: package names
	 380  	// can only appear in qualified identifiers which are mapped to
	 381  	// selector expressions.
	 382  	if ident, ok := e.X.(*ast.Ident); ok {
	 383  		obj := check.lookup(ident.Name)
	 384  		if pname, _ := obj.(*PkgName); pname != nil {
	 385  			assert(pname.pkg == check.pkg)
	 386  			check.recordUse(ident, pname)
	 387  			pname.used = true
	 388  			pkg := pname.imported
	 389  
	 390  			var exp Object
	 391  			funcMode := value
	 392  			if pkg.cgo {
	 393  				// cgo special cases C.malloc: it's
	 394  				// rewritten to _CMalloc and does not
	 395  				// support two-result calls.
	 396  				if sel == "malloc" {
	 397  					sel = "_CMalloc"
	 398  				} else {
	 399  					funcMode = cgofunc
	 400  				}
	 401  				for _, prefix := range cgoPrefixes {
	 402  					// cgo objects are part of the current package (in file
	 403  					// _cgo_gotypes.go). Use regular lookup.
	 404  					_, exp = check.scope.LookupParent(prefix+sel, check.pos)
	 405  					if exp != nil {
	 406  						break
	 407  					}
	 408  				}
	 409  				if exp == nil {
	 410  					check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package C", sel)
	 411  					goto Error
	 412  				}
	 413  				check.objDecl(exp, nil)
	 414  			} else {
	 415  				exp = pkg.scope.Lookup(sel)
	 416  				if exp == nil {
	 417  					if !pkg.fake {
	 418  						check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package %s", sel, pkg.name)
	 419  					}
	 420  					goto Error
	 421  				}
	 422  				if !exp.Exported() {
	 423  					check.errorf(e.Sel, _UnexportedName, "%s not exported by package %s", sel, pkg.name)
	 424  					// ok to continue
	 425  				}
	 426  			}
	 427  			check.recordUse(e.Sel, exp)
	 428  
	 429  			// Simplified version of the code for *ast.Idents:
	 430  			// - imported objects are always fully initialized
	 431  			switch exp := exp.(type) {
	 432  			case *Const:
	 433  				assert(exp.Val() != nil)
	 434  				x.mode = constant_
	 435  				x.typ = exp.typ
	 436  				x.val = exp.val
	 437  			case *TypeName:
	 438  				x.mode = typexpr
	 439  				x.typ = exp.typ
	 440  			case *Var:
	 441  				x.mode = variable
	 442  				x.typ = exp.typ
	 443  				if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
	 444  					x.typ = x.typ.(*Pointer).base
	 445  				}
	 446  			case *Func:
	 447  				x.mode = funcMode
	 448  				x.typ = exp.typ
	 449  				if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
	 450  					x.mode = value
	 451  					x.typ = x.typ.(*Signature).results.vars[0].typ
	 452  				}
	 453  			case *Builtin:
	 454  				x.mode = builtin
	 455  				x.typ = exp.typ
	 456  				x.id = exp.id
	 457  			default:
	 458  				check.dump("%v: unexpected object %v", e.Sel.Pos(), exp)
	 459  				unreachable()
	 460  			}
	 461  			x.expr = e
	 462  			return
	 463  		}
	 464  	}
	 465  
	 466  	check.exprOrType(x, e.X)
	 467  	if x.mode == invalid {
	 468  		goto Error
	 469  	}
	 470  
	 471  	check.instantiatedOperand(x)
	 472  
	 473  	obj, index, indirect = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
	 474  	if obj == nil {
	 475  		switch {
	 476  		case index != nil:
	 477  			// TODO(gri) should provide actual type where the conflict happens
	 478  			check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
	 479  		case indirect:
	 480  			check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
	 481  		default:
	 482  			var why string
	 483  			if tpar := asTypeParam(x.typ); tpar != nil {
	 484  				// Type parameter bounds don't specify fields, so don't mention "field".
	 485  				switch obj := tpar.Bound().obj.(type) {
	 486  				case nil:
	 487  					why = check.sprintf("type bound for %s has no method %s", x.typ, sel)
	 488  				case *TypeName:
	 489  					why = check.sprintf("interface %s has no method %s", obj.name, sel)
	 490  				}
	 491  			} else {
	 492  				why = check.sprintf("type %s has no field or method %s", x.typ, sel)
	 493  			}
	 494  
	 495  			// Check if capitalization of sel matters and provide better error message in that case.
	 496  			if len(sel) > 0 {
	 497  				var changeCase string
	 498  				if r := rune(sel[0]); unicode.IsUpper(r) {
	 499  					changeCase = string(unicode.ToLower(r)) + sel[1:]
	 500  				} else {
	 501  					changeCase = string(unicode.ToUpper(r)) + sel[1:]
	 502  				}
	 503  				if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
	 504  					why += ", but does have " + changeCase
	 505  				}
	 506  			}
	 507  
	 508  			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
	 509  		}
	 510  		goto Error
	 511  	}
	 512  
	 513  	// methods may not have a fully set up signature yet
	 514  	if m, _ := obj.(*Func); m != nil {
	 515  		check.objDecl(m, nil)
	 516  		// If m has a parameterized receiver type, infer the type arguments from
	 517  		// the actual receiver provided and then substitute the type parameters in
	 518  		// the signature accordingly.
	 519  		// TODO(gri) factor this code out
	 520  		sig := m.typ.(*Signature)
	 521  		if len(sig.rparams) > 0 {
	 522  			// For inference to work, we must use the receiver type
	 523  			// matching the receiver in the actual method declaration.
	 524  			// If the method is embedded, the matching receiver is the
	 525  			// embedded struct or interface that declared the method.
	 526  			// Traverse the embedding to find that type (issue #44688).
	 527  			recv := x.typ
	 528  			for i := 0; i < len(index)-1; i++ {
	 529  				// The embedded type is either a struct or a pointer to
	 530  				// a struct except for the last one (which we don't need).
	 531  				recv = asStruct(derefStructPtr(recv)).Field(index[i]).typ
	 532  			}
	 533  
	 534  			// The method may have a pointer receiver, but the actually provided receiver
	 535  			// may be a (hopefully addressable) non-pointer value, or vice versa. Here we
	 536  			// only care about inferring receiver type parameters; to make the inference
	 537  			// work, match up pointer-ness of receiver and argument.
	 538  			if ptrRecv := isPointer(sig.recv.typ); ptrRecv != isPointer(recv) {
	 539  				if ptrRecv {
	 540  					recv = NewPointer(recv)
	 541  				} else {
	 542  					recv = recv.(*Pointer).base
	 543  				}
	 544  			}
	 545  			// Disable reporting of errors during inference below. If we're unable to infer
	 546  			// the receiver type arguments here, the receiver must be be otherwise invalid
	 547  			// and an error has been reported elsewhere.
	 548  			arg := operand{mode: variable, expr: x.expr, typ: recv}
	 549  			targs := check.infer(m, sig.rparams, nil, NewTuple(sig.recv), []*operand{&arg}, false /* no error reporting */)
	 550  			if targs == nil {
	 551  				// We may reach here if there were other errors (see issue #40056).
	 552  				goto Error
	 553  			}
	 554  			// Don't modify m. Instead - for now - make a copy of m and use that instead.
	 555  			// (If we modify m, some tests will fail; possibly because the m is in use.)
	 556  			// TODO(gri) investigate and provide a correct explanation here
	 557  			copy := *m
	 558  			copy.typ = check.subst(e.Pos(), m.typ, makeSubstMap(sig.rparams, targs))
	 559  			obj = &copy
	 560  		}
	 561  		// TODO(gri) we also need to do substitution for parameterized interface methods
	 562  		//					 (this breaks code in testdata/linalg.go2 at the moment)
	 563  		//					 12/20/2019: Is this TODO still correct?
	 564  	}
	 565  
	 566  	if x.mode == typexpr {
	 567  		// method expression
	 568  		m, _ := obj.(*Func)
	 569  		if m == nil {
	 570  			// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
	 571  			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
	 572  			goto Error
	 573  		}
	 574  
	 575  		check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
	 576  
	 577  		// the receiver type becomes the type of the first function
	 578  		// argument of the method expression's function type
	 579  		var params []*Var
	 580  		sig := m.typ.(*Signature)
	 581  		if sig.params != nil {
	 582  			params = sig.params.vars
	 583  		}
	 584  		x.mode = value
	 585  		x.typ = &Signature{
	 586  			tparams:	sig.tparams,
	 587  			params:	 NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "_", x.typ)}, params...)...),
	 588  			results:	sig.results,
	 589  			variadic: sig.variadic,
	 590  		}
	 591  
	 592  		check.addDeclDep(m)
	 593  
	 594  	} else {
	 595  		// regular selector
	 596  		switch obj := obj.(type) {
	 597  		case *Var:
	 598  			check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
	 599  			if x.mode == variable || indirect {
	 600  				x.mode = variable
	 601  			} else {
	 602  				x.mode = value
	 603  			}
	 604  			x.typ = obj.typ
	 605  
	 606  		case *Func:
	 607  			// TODO(gri) If we needed to take into account the receiver's
	 608  			// addressability, should we report the type &(x.typ) instead?
	 609  			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
	 610  
	 611  			// TODO(gri) The verification pass below is disabled for now because
	 612  			//					 method sets don't match method lookup in some cases.
	 613  			//					 For instance, if we made a copy above when creating a
	 614  			//					 custom method for a parameterized received type, the
	 615  			//					 method set method doesn't match (no copy there). There
	 616  			///					may be other situations.
	 617  			disabled := true
	 618  			if !disabled && debug {
	 619  				// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
	 620  				// TODO(gri) This only works because we call LookupFieldOrMethod
	 621  				// _before_ calling NewMethodSet: LookupFieldOrMethod completes
	 622  				// any incomplete interfaces so they are available to NewMethodSet
	 623  				// (which assumes that interfaces have been completed already).
	 624  				typ := x.typ
	 625  				if x.mode == variable {
	 626  					// If typ is not an (unnamed) pointer or an interface,
	 627  					// use *typ instead, because the method set of *typ
	 628  					// includes the methods of typ.
	 629  					// Variables are addressable, so we can always take their
	 630  					// address.
	 631  					if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
	 632  						typ = &Pointer{base: typ}
	 633  					}
	 634  				}
	 635  				// If we created a synthetic pointer type above, we will throw
	 636  				// away the method set computed here after use.
	 637  				// TODO(gri) Method set computation should probably always compute
	 638  				// both, the value and the pointer receiver method set and represent
	 639  				// them in a single structure.
	 640  				// TODO(gri) Consider also using a method set cache for the lifetime
	 641  				// of checker once we rely on MethodSet lookup instead of individual
	 642  				// lookup.
	 643  				mset := NewMethodSet(typ)
	 644  				if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
	 645  					check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
	 646  					check.dump("%s\n", mset)
	 647  					// Caution: MethodSets are supposed to be used externally
	 648  					// only (after all interface types were completed). It's
	 649  					// now possible that we get here incorrectly. Not urgent
	 650  					// to fix since we only run this code in debug mode.
	 651  					// TODO(gri) fix this eventually.
	 652  					panic("method sets and lookup don't agree")
	 653  				}
	 654  			}
	 655  
	 656  			x.mode = value
	 657  
	 658  			// remove receiver
	 659  			sig := *obj.typ.(*Signature)
	 660  			sig.recv = nil
	 661  			x.typ = &sig
	 662  
	 663  			check.addDeclDep(obj)
	 664  
	 665  		default:
	 666  			unreachable()
	 667  		}
	 668  	}
	 669  
	 670  	// everything went well
	 671  	x.expr = e
	 672  	return
	 673  
	 674  Error:
	 675  	x.mode = invalid
	 676  	x.expr = e
	 677  }
	 678  
	 679  // use type-checks each argument.
	 680  // Useful to make sure expressions are evaluated
	 681  // (and variables are "used") in the presence of other errors.
	 682  // The arguments may be nil.
	 683  func (check *Checker) use(arg ...ast.Expr) {
	 684  	var x operand
	 685  	for _, e := range arg {
	 686  		// The nil check below is necessary since certain AST fields
	 687  		// may legally be nil (e.g., the ast.SliceExpr.High field).
	 688  		if e != nil {
	 689  			check.rawExpr(&x, e, nil)
	 690  		}
	 691  	}
	 692  }
	 693  
	 694  // useLHS is like use, but doesn't "use" top-level identifiers.
	 695  // It should be called instead of use if the arguments are
	 696  // expressions on the lhs of an assignment.
	 697  // The arguments must not be nil.
	 698  func (check *Checker) useLHS(arg ...ast.Expr) {
	 699  	var x operand
	 700  	for _, e := range arg {
	 701  		// If the lhs is an identifier denoting a variable v, this assignment
	 702  		// is not a 'use' of v. Remember current value of v.used and restore
	 703  		// after evaluating the lhs via check.rawExpr.
	 704  		var v *Var
	 705  		var v_used bool
	 706  		if ident, _ := unparen(e).(*ast.Ident); ident != nil {
	 707  			// never type-check the blank name on the lhs
	 708  			if ident.Name == "_" {
	 709  				continue
	 710  			}
	 711  			if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
	 712  				// It's ok to mark non-local variables, but ignore variables
	 713  				// from other packages to avoid potential race conditions with
	 714  				// dot-imported variables.
	 715  				if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
	 716  					v = w
	 717  					v_used = v.used
	 718  				}
	 719  			}
	 720  		}
	 721  		check.rawExpr(&x, e, nil)
	 722  		if v != nil {
	 723  			v.used = v_used // restore v.used
	 724  		}
	 725  	}
	 726  }
	 727  
	 728  // instantiatedOperand reports an error of x is an uninstantiated (generic) type and sets x.typ to Typ[Invalid].
	 729  func (check *Checker) instantiatedOperand(x *operand) {
	 730  	if x.mode == typexpr && isGeneric(x.typ) {
	 731  		check.errorf(x, _Todo, "cannot use generic type %s without instantiation", x.typ)
	 732  		x.typ = Typ[Invalid]
	 733  	}
	 734  }
	 735  

View as plain text