...

Source file src/go/types/call.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 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