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