Black Lives Matter. Support the Equal Justice Initiative.

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/token"
    12  	"strings"
    13  	"unicode"
    14  )
    15  
    16  func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
    17  	check.exprOrType(x, e.Fun)
    18  
    19  	switch x.mode {
    20  	case invalid:
    21  		check.use(e.Args...)
    22  		x.mode = invalid
    23  		x.expr = e
    24  		return statement
    25  
    26  	case typexpr:
    27  		// conversion
    28  		T := x.typ
    29  		x.mode = invalid
    30  		switch n := len(e.Args); n {
    31  		case 0:
    32  			check.errorf(inNode(e, e.Rparen), _WrongArgCount, "missing argument in conversion to %s", T)
    33  		case 1:
    34  			check.expr(x, e.Args[0])
    35  			if x.mode != invalid {
    36  				if e.Ellipsis.IsValid() {
    37  					check.errorf(e.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
    38  					break
    39  				}
    40  				check.conversion(x, T)
    41  			}
    42  		default:
    43  			check.use(e.Args...)
    44  			check.errorf(e.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
    45  		}
    46  		x.expr = e
    47  		return conversion
    48  
    49  	case builtin:
    50  		id := x.id
    51  		if !check.builtin(x, e, id) {
    52  			x.mode = invalid
    53  		}
    54  		x.expr = e
    55  		// a non-constant result implies a function call
    56  		if x.mode != invalid && x.mode != constant_ {
    57  			check.hasCallOrRecv = true
    58  		}
    59  		return predeclaredFuncs[id].kind
    60  
    61  	default:
    62  		// function/method call
    63  		cgocall := x.mode == cgofunc
    64  
    65  		sig, _ := x.typ.Underlying().(*Signature)
    66  		if sig == nil {
    67  			check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
    68  			x.mode = invalid
    69  			x.expr = e
    70  			return statement
    71  		}
    72  
    73  		arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false)
    74  		if arg != nil {
    75  			check.arguments(x, e, sig, arg, n)
    76  		} else {
    77  			x.mode = invalid
    78  		}
    79  
    80  		// determine result
    81  		switch sig.results.Len() {
    82  		case 0:
    83  			x.mode = novalue
    84  		case 1:
    85  			if cgocall {
    86  				x.mode = commaerr
    87  			} else {
    88  				x.mode = value
    89  			}
    90  			x.typ = sig.results.vars[0].typ // unpack tuple
    91  		default:
    92  			x.mode = value
    93  			x.typ = sig.results
    94  		}
    95  
    96  		x.expr = e
    97  		check.hasCallOrRecv = true
    98  
    99  		return statement
   100  	}
   101  }
   102  
   103  // use type-checks each argument.
   104  // Useful to make sure expressions are evaluated
   105  // (and variables are "used") in the presence of other errors.
   106  // The arguments may be nil.
   107  func (check *Checker) use(arg ...ast.Expr) {
   108  	var x operand
   109  	for _, e := range arg {
   110  		// The nil check below is necessary since certain AST fields
   111  		// may legally be nil (e.g., the ast.SliceExpr.High field).
   112  		if e != nil {
   113  			check.rawExpr(&x, e, nil)
   114  		}
   115  	}
   116  }
   117  
   118  // useLHS is like use, but doesn't "use" top-level identifiers.
   119  // It should be called instead of use if the arguments are
   120  // expressions on the lhs of an assignment.
   121  // The arguments must not be nil.
   122  func (check *Checker) useLHS(arg ...ast.Expr) {
   123  	var x operand
   124  	for _, e := range arg {
   125  		// If the lhs is an identifier denoting a variable v, this assignment
   126  		// is not a 'use' of v. Remember current value of v.used and restore
   127  		// after evaluating the lhs via check.rawExpr.
   128  		var v *Var
   129  		var v_used bool
   130  		if ident, _ := unparen(e).(*ast.Ident); ident != nil {
   131  			// never type-check the blank name on the lhs
   132  			if ident.Name == "_" {
   133  				continue
   134  			}
   135  			if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
   136  				// It's ok to mark non-local variables, but ignore variables
   137  				// from other packages to avoid potential race conditions with
   138  				// dot-imported variables.
   139  				if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
   140  					v = w
   141  					v_used = v.used
   142  				}
   143  			}
   144  		}
   145  		check.rawExpr(&x, e, nil)
   146  		if v != nil {
   147  			v.used = v_used // restore v.used
   148  		}
   149  	}
   150  }
   151  
   152  // useGetter is like use, but takes a getter instead of a list of expressions.
   153  // It should be called instead of use if a getter is present to avoid repeated
   154  // evaluation of the first argument (since the getter was likely obtained via
   155  // unpack, which may have evaluated the first argument already).
   156  func (check *Checker) useGetter(get getter, n int) {
   157  	var x operand
   158  	for i := 0; i < n; i++ {
   159  		get(&x, i)
   160  	}
   161  }
   162  
   163  // A getter sets x as the i'th operand, where 0 <= i < n and n is the total
   164  // number of operands (context-specific, and maintained elsewhere). A getter
   165  // type-checks the i'th operand; the details of the actual check are getter-
   166  // specific.
   167  type getter func(x *operand, i int)
   168  
   169  // unpack takes a getter get and a number of operands n. If n == 1, unpack
   170  // calls the incoming getter for the first operand. If that operand is
   171  // invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
   172  // function call, or a comma-ok expression and allowCommaOk is set, the result
   173  // is a new getter and operand count providing access to the function results,
   174  // or comma-ok values, respectively. The third result value reports if it
   175  // is indeed the comma-ok case. In all other cases, the incoming getter and
   176  // operand count are returned unchanged, and the third result value is false.
   177  //
   178  // In other words, if there's exactly one operand that - after type-checking
   179  // by calling get - stands for multiple operands, the resulting getter provides
   180  // access to those operands instead.
   181  //
   182  // If the returned getter is called at most once for a given operand index i
   183  // (including i == 0), that operand is guaranteed to cause only one call of
   184  // the incoming getter with that i.
   185  //
   186  func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
   187  	if n != 1 {
   188  		// zero or multiple values
   189  		return get, n, false
   190  	}
   191  	// possibly result of an n-valued function call or comma,ok value
   192  	var x0 operand
   193  	get(&x0, 0)
   194  	if x0.mode == invalid {
   195  		return nil, 0, false
   196  	}
   197  
   198  	if t, ok := x0.typ.(*Tuple); ok {
   199  		// result of an n-valued function call
   200  		return func(x *operand, i int) {
   201  			x.mode = value
   202  			x.expr = x0.expr
   203  			x.typ = t.At(i).typ
   204  		}, t.Len(), false
   205  	}
   206  
   207  	if x0.mode == mapindex || x0.mode == commaok || x0.mode == commaerr {
   208  		// comma-ok value
   209  		if allowCommaOk {
   210  			a := [2]Type{x0.typ, Typ[UntypedBool]}
   211  			if x0.mode == commaerr {
   212  				a[1] = universeError
   213  			}
   214  			return func(x *operand, i int) {
   215  				x.mode = value
   216  				x.expr = x0.expr
   217  				x.typ = a[i]
   218  			}, 2, true
   219  		}
   220  		x0.mode = value
   221  	}
   222  
   223  	// single value
   224  	return func(x *operand, i int) {
   225  		if i != 0 {
   226  			unreachable()
   227  		}
   228  		*x = x0
   229  	}, 1, false
   230  }
   231  
   232  // arguments checks argument passing for the call with the given signature.
   233  // The arg function provides the operand for the i'th argument.
   234  func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
   235  	if call.Ellipsis.IsValid() {
   236  		// last argument is of the form x...
   237  		if !sig.variadic {
   238  			check.errorf(atPos(call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
   239  			check.useGetter(arg, n)
   240  			return
   241  		}
   242  		if len(call.Args) == 1 && n > 1 {
   243  			// f()... is not permitted if f() is multi-valued
   244  			check.errorf(atPos(call.Ellipsis), _InvalidDotDotDotOperand, "cannot use ... with %d-valued %s", n, call.Args[0])
   245  			check.useGetter(arg, n)
   246  			return
   247  		}
   248  	}
   249  
   250  	// evaluate arguments
   251  	context := check.sprintf("argument to %s", call.Fun)
   252  	for i := 0; i < n; i++ {
   253  		arg(x, i)
   254  		if x.mode != invalid {
   255  			var ellipsis token.Pos
   256  			if i == n-1 && call.Ellipsis.IsValid() {
   257  				ellipsis = call.Ellipsis
   258  			}
   259  			check.argument(sig, i, x, ellipsis, context)
   260  		}
   261  	}
   262  
   263  	// check argument count
   264  	if sig.variadic {
   265  		// a variadic function accepts an "empty"
   266  		// last argument: count one extra
   267  		n++
   268  	}
   269  	if n < sig.params.Len() {
   270  		check.errorf(inNode(call, call.Rparen), _WrongArgCount, "too few arguments in call to %s", call.Fun)
   271  		// ok to continue
   272  	}
   273  }
   274  
   275  // argument checks passing of argument x to the i'th parameter of the given signature.
   276  // If ellipsis is valid, the argument is followed by ... at that position in the call.
   277  func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos, context string) {
   278  	check.singleValue(x)
   279  	if x.mode == invalid {
   280  		return
   281  	}
   282  
   283  	n := sig.params.Len()
   284  
   285  	// determine parameter type
   286  	var typ Type
   287  	switch {
   288  	case i < n:
   289  		typ = sig.params.vars[i].typ
   290  	case sig.variadic:
   291  		typ = sig.params.vars[n-1].typ
   292  		if debug {
   293  			if _, ok := typ.(*Slice); !ok {
   294  				check.dump("%v: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
   295  			}
   296  		}
   297  	default:
   298  		check.errorf(x, _WrongArgCount, "too many arguments")
   299  		return
   300  	}
   301  
   302  	if ellipsis.IsValid() {
   303  		if i != n-1 {
   304  			check.errorf(atPos(ellipsis), _MisplacedDotDotDot, "can only use ... with matching parameter")
   305  			return
   306  		}
   307  		// argument is of the form x... and x is single-valued
   308  		if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] { // see issue #18268
   309  			check.errorf(x, _InvalidDotDotDotOperand, "cannot use %s as parameter of type %s", x, typ)
   310  			return
   311  		}
   312  	} else if sig.variadic && i >= n-1 {
   313  		// use the variadic parameter slice's element type
   314  		typ = typ.(*Slice).elem
   315  	}
   316  
   317  	check.assignment(x, typ, context)
   318  }
   319  
   320  var cgoPrefixes = [...]string{
   321  	"_Ciconst_",
   322  	"_Cfconst_",
   323  	"_Csconst_",
   324  	"_Ctype_",
   325  	"_Cvar_", // actually a pointer to the var
   326  	"_Cfpvar_fp_",
   327  	"_Cfunc_",
   328  	"_Cmacro_", // function to evaluate the expanded expression
   329  }
   330  
   331  func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
   332  	// these must be declared before the "goto Error" statements
   333  	var (
   334  		obj      Object
   335  		index    []int
   336  		indirect bool
   337  	)
   338  
   339  	sel := e.Sel.Name
   340  	// If the identifier refers to a package, handle everything here
   341  	// so we don't need a "package" mode for operands: package names
   342  	// can only appear in qualified identifiers which are mapped to
   343  	// selector expressions.
   344  	if ident, ok := e.X.(*ast.Ident); ok {
   345  		obj := check.lookup(ident.Name)
   346  		if pname, _ := obj.(*PkgName); pname != nil {
   347  			assert(pname.pkg == check.pkg)
   348  			check.recordUse(ident, pname)
   349  			pname.used = true
   350  			pkg := pname.imported
   351  
   352  			var exp Object
   353  			funcMode := value
   354  			if pkg.cgo {
   355  				// cgo special cases C.malloc: it's
   356  				// rewritten to _CMalloc and does not
   357  				// support two-result calls.
   358  				if sel == "malloc" {
   359  					sel = "_CMalloc"
   360  				} else {
   361  					funcMode = cgofunc
   362  				}
   363  				for _, prefix := range cgoPrefixes {
   364  					// cgo objects are part of the current package (in file
   365  					// _cgo_gotypes.go). Use regular lookup.
   366  					_, exp = check.scope.LookupParent(prefix+sel, check.pos)
   367  					if exp != nil {
   368  						break
   369  					}
   370  				}
   371  				if exp == nil {
   372  					check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package C", sel)
   373  					goto Error
   374  				}
   375  				check.objDecl(exp, nil)
   376  			} else {
   377  				exp = pkg.scope.Lookup(sel)
   378  				if exp == nil {
   379  					if !pkg.fake {
   380  						check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package %s", sel, pkg.name)
   381  					}
   382  					goto Error
   383  				}
   384  				if !exp.Exported() {
   385  					check.errorf(e.Sel, _UnexportedName, "%s not exported by package %s", sel, pkg.name)
   386  					// ok to continue
   387  				}
   388  			}
   389  			check.recordUse(e.Sel, exp)
   390  
   391  			// Simplified version of the code for *ast.Idents:
   392  			// - imported objects are always fully initialized
   393  			switch exp := exp.(type) {
   394  			case *Const:
   395  				assert(exp.Val() != nil)
   396  				x.mode = constant_
   397  				x.typ = exp.typ
   398  				x.val = exp.val
   399  			case *TypeName:
   400  				x.mode = typexpr
   401  				x.typ = exp.typ
   402  			case *Var:
   403  				x.mode = variable
   404  				x.typ = exp.typ
   405  				if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
   406  					x.typ = x.typ.(*Pointer).base
   407  				}
   408  			case *Func:
   409  				x.mode = funcMode
   410  				x.typ = exp.typ
   411  				if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
   412  					x.mode = value
   413  					x.typ = x.typ.(*Signature).results.vars[0].typ
   414  				}
   415  			case *Builtin:
   416  				x.mode = builtin
   417  				x.typ = exp.typ
   418  				x.id = exp.id
   419  			default:
   420  				check.dump("unexpected object %v", exp)
   421  				unreachable()
   422  			}
   423  			x.expr = e
   424  			return
   425  		}
   426  	}
   427  
   428  	check.exprOrType(x, e.X)
   429  	if x.mode == invalid {
   430  		goto Error
   431  	}
   432  
   433  	obj, index, indirect = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
   434  	if obj == nil {
   435  		switch {
   436  		case index != nil:
   437  			// TODO(gri) should provide actual type where the conflict happens
   438  			check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
   439  		case indirect:
   440  			check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
   441  		default:
   442  			// Check if capitalization of sel matters and provide better error
   443  			// message in that case.
   444  			if len(sel) > 0 {
   445  				var changeCase string
   446  				if r := rune(sel[0]); unicode.IsUpper(r) {
   447  					changeCase = string(unicode.ToLower(r)) + sel[1:]
   448  				} else {
   449  					changeCase = string(unicode.ToUpper(r)) + sel[1:]
   450  				}
   451  				if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
   452  					check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase)
   453  					break
   454  				}
   455  			}
   456  			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel)
   457  		}
   458  		goto Error
   459  	}
   460  
   461  	// methods may not have a fully set up signature yet
   462  	if m, _ := obj.(*Func); m != nil {
   463  		check.objDecl(m, nil)
   464  	}
   465  
   466  	if x.mode == typexpr {
   467  		// method expression
   468  		m, _ := obj.(*Func)
   469  		if m == nil {
   470  			// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
   471  			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
   472  			goto Error
   473  		}
   474  
   475  		check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
   476  
   477  		// the receiver type becomes the type of the first function
   478  		// argument of the method expression's function type
   479  		var params []*Var
   480  		sig := m.typ.(*Signature)
   481  		if sig.params != nil {
   482  			params = sig.params.vars
   483  		}
   484  		x.mode = value
   485  		x.typ = &Signature{
   486  			params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
   487  			results:  sig.results,
   488  			variadic: sig.variadic,
   489  		}
   490  
   491  		check.addDeclDep(m)
   492  
   493  	} else {
   494  		// regular selector
   495  		switch obj := obj.(type) {
   496  		case *Var:
   497  			check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
   498  			if x.mode == variable || indirect {
   499  				x.mode = variable
   500  			} else {
   501  				x.mode = value
   502  			}
   503  			x.typ = obj.typ
   504  
   505  		case *Func:
   506  			// TODO(gri) If we needed to take into account the receiver's
   507  			// addressability, should we report the type &(x.typ) instead?
   508  			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
   509  
   510  			if debug {
   511  				// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
   512  				// TODO(gri) This only works because we call LookupFieldOrMethod
   513  				// _before_ calling NewMethodSet: LookupFieldOrMethod completes
   514  				// any incomplete interfaces so they are available to NewMethodSet
   515  				// (which assumes that interfaces have been completed already).
   516  				typ := x.typ
   517  				if x.mode == variable {
   518  					// If typ is not an (unnamed) pointer or an interface,
   519  					// use *typ instead, because the method set of *typ
   520  					// includes the methods of typ.
   521  					// Variables are addressable, so we can always take their
   522  					// address.
   523  					if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
   524  						typ = &Pointer{base: typ}
   525  					}
   526  				}
   527  				// If we created a synthetic pointer type above, we will throw
   528  				// away the method set computed here after use.
   529  				// TODO(gri) Method set computation should probably always compute
   530  				// both, the value and the pointer receiver method set and represent
   531  				// them in a single structure.
   532  				// TODO(gri) Consider also using a method set cache for the lifetime
   533  				// of checker once we rely on MethodSet lookup instead of individual
   534  				// lookup.
   535  				mset := NewMethodSet(typ)
   536  				if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
   537  					check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
   538  					check.dump("%s\n", mset)
   539  					// Caution: MethodSets are supposed to be used externally
   540  					// only (after all interface types were completed). It's
   541  					// now possible that we get here incorrectly. Not urgent
   542  					// to fix since we only run this code in debug mode.
   543  					// TODO(gri) fix this eventually.
   544  					panic("method sets and lookup don't agree")
   545  				}
   546  			}
   547  
   548  			x.mode = value
   549  
   550  			// remove receiver
   551  			sig := *obj.typ.(*Signature)
   552  			sig.recv = nil
   553  			x.typ = &sig
   554  
   555  			check.addDeclDep(obj)
   556  
   557  		default:
   558  			unreachable()
   559  		}
   560  	}
   561  
   562  	// everything went well
   563  	x.expr = e
   564  	return
   565  
   566  Error:
   567  	x.mode = invalid
   568  	x.expr = e
   569  }
   570  

View as plain text