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