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

View as plain text