github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/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 "fmt" 11 "go/ast" 12 "go/internal/typeparams" 13 "go/token" 14 . "internal/types/errors" 15 "strings" 16 "unicode" 17 ) 18 19 // funcInst type-checks a function instantiation. 20 // The incoming x must be a generic function. 21 // If ix != nil, it provides some or all of the type arguments (ix.Indices). 22 // If target type tsig != nil, the signature may be used to infer missing type 23 // arguments of x, if any. At least one of tsig or inst must be provided. 24 // 25 // There are two modes of operation: 26 // 27 // 1. If infer == true, funcInst infers missing type arguments as needed and 28 // instantiates the function x. The returned results are nil. 29 // 30 // 2. If infer == false and inst provides all type arguments, funcInst 31 // instantiates the function x. The returned results are nil. 32 // If inst doesn't provide enough type arguments, funcInst returns the 33 // available arguments and the corresponding expression list; x remains 34 // unchanged. 35 // 36 // If an error (other than a version error) occurs in any case, it is reported 37 // and x.mode is set to invalid. 38 func (check *Checker) funcInst(tsig *Signature, pos token.Pos, x *operand, ix *typeparams.IndexExpr, infer bool) ([]Type, []ast.Expr) { 39 assert(tsig != nil || ix != nil) 40 41 var instErrPos positioner 42 if ix != nil { 43 instErrPos = inNode(ix.Orig, ix.Lbrack) 44 } else { 45 instErrPos = atPos(pos) 46 } 47 versionErr := !check.verifyVersionf(check.pkg, instErrPos, go1_18, "function instantiation") 48 49 // targs and xlist are the type arguments and corresponding type expressions, or nil. 50 var targs []Type 51 var xlist []ast.Expr 52 if ix != nil { 53 xlist = ix.Indices 54 targs = check.typeList(xlist) 55 if targs == nil { 56 x.mode = invalid 57 x.expr = ix 58 return nil, nil 59 } 60 assert(len(targs) == len(xlist)) 61 } 62 63 // Check the number of type arguments (got) vs number of type parameters (want). 64 // Note that x is a function value, not a type expression, so we don't need to 65 // call under below. 66 sig := x.typ.(*Signature) 67 got, want := len(targs), sig.TypeParams().Len() 68 if got > want { 69 // Providing too many type arguments is always an error. 70 check.errorf(ix.Indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want) 71 x.mode = invalid 72 x.expr = ix.Orig 73 return nil, nil 74 } 75 76 if got < want { 77 if !infer { 78 return targs, xlist 79 } 80 81 // If the uninstantiated or partially instantiated function x is used in an 82 // assignment (tsig != nil), use the respective function parameter and result 83 // types to infer additional type arguments. 84 var args []*operand 85 var params []*Var 86 if tsig != nil && sig.tparams != nil && tsig.params.Len() == sig.params.Len() && tsig.results.Len() == sig.results.Len() { 87 // x is a generic function and the signature arity matches the target function. 88 // To infer x's missing type arguments, treat the function assignment as a call 89 // of a synthetic function f where f's parameters are the parameters and results 90 // of x and where the arguments to the call of f are values of the parameter and 91 // result types of x. 92 if !versionErr && !check.allowVersion(check.pkg, instErrPos, go1_21) { 93 if ix != nil { 94 check.versionErrorf(instErrPos, go1_21, "partially instantiated function in assignment") 95 } else { 96 check.versionErrorf(instErrPos, go1_21, "implicitly instantiated function in assignment") 97 } 98 } 99 n := tsig.params.Len() 100 m := tsig.results.Len() 101 args = make([]*operand, n+m) 102 params = make([]*Var, n+m) 103 for i := 0; i < n; i++ { 104 lvar := tsig.params.At(i) 105 lname := ast.NewIdent(paramName(lvar.name, i, "parameter")) 106 lname.NamePos = x.Pos() // correct position 107 args[i] = &operand{mode: value, expr: lname, typ: lvar.typ} 108 params[i] = sig.params.At(i) 109 } 110 for i := 0; i < m; i++ { 111 lvar := tsig.results.At(i) 112 lname := ast.NewIdent(paramName(lvar.name, i, "result parameter")) 113 lname.NamePos = x.Pos() // correct position 114 args[n+i] = &operand{mode: value, expr: lname, typ: lvar.typ} 115 params[n+i] = sig.results.At(i) 116 } 117 } 118 119 // Rename type parameters to avoid problems with recursive instantiations. 120 // Note that NewTuple(params...) below is (*Tuple)(nil) if len(params) == 0, as desired. 121 tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...)) 122 123 targs = check.infer(atPos(pos), tparams, targs, params2.(*Tuple), args) 124 if targs == nil { 125 // error was already reported 126 x.mode = invalid 127 x.expr = ix // TODO(gri) is this correct? 128 return nil, nil 129 } 130 got = len(targs) 131 } 132 assert(got == want) 133 134 // instantiate function signature 135 expr := x.expr // if we don't have an index expression, keep the existing expression of x 136 if ix != nil { 137 expr = ix.Orig 138 } 139 sig = check.instantiateSignature(x.Pos(), expr, sig, targs, xlist) 140 141 x.typ = sig 142 x.mode = value 143 x.expr = expr 144 return nil, nil 145 } 146 147 func paramName(name string, i int, kind string) string { 148 if name != "" { 149 return name 150 } 151 return nth(i+1) + " " + kind 152 } 153 154 func nth(n int) string { 155 switch n { 156 case 1: 157 return "1st" 158 case 2: 159 return "2nd" 160 case 3: 161 return "3rd" 162 } 163 return fmt.Sprintf("%dth", n) 164 } 165 166 func (check *Checker) instantiateSignature(pos token.Pos, expr ast.Expr, typ *Signature, targs []Type, xlist []ast.Expr) (res *Signature) { 167 assert(check != nil) 168 assert(len(targs) == typ.TypeParams().Len()) 169 170 if check.conf._Trace { 171 check.trace(pos, "-- instantiating signature %s with %s", typ, targs) 172 check.indent++ 173 defer func() { 174 check.indent-- 175 check.trace(pos, "=> %s (under = %s)", res, res.Underlying()) 176 }() 177 } 178 179 inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature) 180 assert(inst.TypeParams().Len() == 0) // signature is not generic anymore 181 check.recordInstance(expr, targs, inst) 182 assert(len(xlist) <= len(targs)) 183 184 // verify instantiation lazily (was go.dev/issue/50450) 185 check.later(func() { 186 tparams := typ.TypeParams().list() 187 if i, err := check.verify(pos, tparams, targs, check.context()); err != nil { 188 // best position for error reporting 189 pos := pos 190 if i < len(xlist) { 191 pos = xlist[i].Pos() 192 } 193 check.softErrorf(atPos(pos), InvalidTypeArg, "%s", err) 194 } else { 195 check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist) 196 } 197 }).describef(atPos(pos), "verify instantiation") 198 199 return inst 200 } 201 202 func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind { 203 ix := typeparams.UnpackIndexExpr(call.Fun) 204 if ix != nil { 205 if check.indexExpr(x, ix) { 206 // Delay function instantiation to argument checking, 207 // where we combine type and value arguments for type 208 // inference. 209 assert(x.mode == value) 210 } else { 211 ix = nil 212 } 213 x.expr = call.Fun 214 check.record(x) 215 } else { 216 check.exprOrType(x, call.Fun, true) 217 } 218 // x.typ may be generic 219 220 switch x.mode { 221 case invalid: 222 check.use(call.Args...) 223 x.expr = call 224 return statement 225 226 case typexpr: 227 // conversion 228 check.nonGeneric(nil, x) 229 if x.mode == invalid { 230 return conversion 231 } 232 T := x.typ 233 x.mode = invalid 234 switch n := len(call.Args); n { 235 case 0: 236 check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T) 237 case 1: 238 check.expr(nil, x, call.Args[0]) 239 if x.mode != invalid { 240 if call.Ellipsis.IsValid() { 241 check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T) 242 break 243 } 244 if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) { 245 if !t.IsMethodSet() { 246 check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T) 247 break 248 } 249 } 250 check.conversion(x, T) 251 } 252 default: 253 check.use(call.Args...) 254 check.errorf(call.Args[n-1], WrongArgCount, "too many arguments in conversion to %s", T) 255 } 256 x.expr = call 257 return conversion 258 259 case builtin: 260 // no need to check for non-genericity here 261 id := x.id 262 if !check.builtin(x, call, id) { 263 x.mode = invalid 264 } 265 x.expr = call 266 // a non-constant result implies a function call 267 if x.mode != invalid && x.mode != constant_ { 268 check.hasCallOrRecv = true 269 } 270 return predeclaredFuncs[id].kind 271 } 272 273 // ordinary function/method call 274 // signature may be generic 275 cgocall := x.mode == cgofunc 276 277 // a type parameter may be "called" if all types have the same signature 278 sig, _ := coreType(x.typ).(*Signature) 279 if sig == nil { 280 check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x) 281 x.mode = invalid 282 x.expr = call 283 return statement 284 } 285 286 // Capture wasGeneric before sig is potentially instantiated below. 287 wasGeneric := sig.TypeParams().Len() > 0 288 289 // evaluate type arguments, if any 290 var xlist []ast.Expr 291 var targs []Type 292 if ix != nil { 293 xlist = ix.Indices 294 targs = check.typeList(xlist) 295 if targs == nil { 296 check.use(call.Args...) 297 x.mode = invalid 298 x.expr = call 299 return statement 300 } 301 assert(len(targs) == len(xlist)) 302 303 // check number of type arguments (got) vs number of type parameters (want) 304 got, want := len(targs), sig.TypeParams().Len() 305 if got > want { 306 check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want) 307 check.use(call.Args...) 308 x.mode = invalid 309 x.expr = call 310 return statement 311 } 312 313 // If sig is generic and all type arguments are provided, preempt function 314 // argument type inference by explicitly instantiating the signature. This 315 // ensures that we record accurate type information for sig, even if there 316 // is an error checking its arguments (for example, if an incorrect number 317 // of arguments is supplied). 318 if got == want && want > 0 { 319 check.verifyVersionf(check.pkg, atPos(ix.Lbrack), go1_18, "function instantiation") 320 sig = check.instantiateSignature(ix.Pos(), ix.Orig, sig, targs, xlist) 321 // targs have been consumed; proceed with checking arguments of the 322 // non-generic signature. 323 targs = nil 324 xlist = nil 325 } 326 } 327 328 // evaluate arguments 329 args, atargs, atxlist := check.genericExprList(call.Args) 330 sig = check.arguments(call, sig, targs, xlist, args, atargs, atxlist) 331 332 if wasGeneric && sig.TypeParams().Len() == 0 { 333 // Update the recorded type of call.Fun to its instantiated type. 334 check.recordTypeAndValue(call.Fun, value, sig, nil) 335 } 336 337 // determine result 338 switch sig.results.Len() { 339 case 0: 340 x.mode = novalue 341 case 1: 342 if cgocall { 343 x.mode = commaerr 344 } else { 345 x.mode = value 346 } 347 x.typ = sig.results.vars[0].typ // unpack tuple 348 default: 349 x.mode = value 350 x.typ = sig.results 351 } 352 x.expr = call 353 check.hasCallOrRecv = true 354 355 // if type inference failed, a parameterized result must be invalidated 356 // (operands cannot have a parameterized type) 357 if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) { 358 x.mode = invalid 359 } 360 361 return statement 362 } 363 364 // exprList evaluates a list of expressions and returns the corresponding operands. 365 // A single-element expression list may evaluate to multiple operands. 366 func (check *Checker) exprList(elist []ast.Expr) (xlist []*operand) { 367 if n := len(elist); n == 1 { 368 xlist, _ = check.multiExpr(elist[0], false) 369 } else if n > 1 { 370 // multiple (possibly invalid) values 371 xlist = make([]*operand, n) 372 for i, e := range elist { 373 var x operand 374 check.expr(nil, &x, e) 375 xlist[i] = &x 376 } 377 } 378 return 379 } 380 381 // genericExprList is like exprList but result operands may be uninstantiated or partially 382 // instantiated generic functions. 383 // For each non-generic or uninstantiated generic operand, the corresponding targsList and 384 // xlistList elements do not exist (targsList and xlistList are nil) or the elements are nil. 385 // For each partially instantiated generic function operand, the corresponding targsList and 386 // xlistList elements are the operand's partial type arguments and type expression lists. 387 func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, targsList [][]Type, xlistList [][]ast.Expr) { 388 if debug { 389 defer func() { 390 // targsList and xlistList must have matching lengths 391 assert(len(targsList) == len(xlistList)) 392 // type arguments must only exist for partially instantiated functions 393 for i, x := range resList { 394 if i < len(targsList) { 395 if n := len(targsList[i]); n > 0 { 396 // x must be a partially instantiated function 397 assert(n < x.typ.(*Signature).TypeParams().Len()) 398 } 399 } 400 } 401 }() 402 } 403 404 if n := len(elist); n == 1 { 405 // single value (possibly a partially instantiated function), or a multi-valued expression 406 e := elist[0] 407 var x operand 408 if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) { 409 // x is a generic function. 410 targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, false) 411 if targs != nil { 412 // x was not instantiated: collect the (partial) type arguments. 413 targsList = [][]Type{targs} 414 xlistList = [][]ast.Expr{xlist} 415 // Update x.expr so that we can record the partially instantiated function. 416 x.expr = ix.Orig 417 } else { 418 // x was instantiated: we must record it here because we didn't 419 // use the usual expression evaluators. 420 check.record(&x) 421 } 422 resList = []*operand{&x} 423 } else { 424 // x is not a function instantiation (it may still be a generic function). 425 check.rawExpr(nil, &x, e, nil, true) 426 check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr) 427 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid { 428 // x is a function call returning multiple values; it cannot be generic. 429 resList = make([]*operand, t.Len()) 430 for i, v := range t.vars { 431 resList[i] = &operand{mode: value, expr: e, typ: v.typ} 432 } 433 } else { 434 // x is exactly one value (possibly invalid or uninstantiated generic function). 435 resList = []*operand{&x} 436 } 437 } 438 } else if n > 1 { 439 // multiple values 440 resList = make([]*operand, n) 441 targsList = make([][]Type, n) 442 xlistList = make([][]ast.Expr, n) 443 for i, e := range elist { 444 var x operand 445 if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) { 446 // x is a generic function. 447 targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, false) 448 if targs != nil { 449 // x was not instantiated: collect the (partial) type arguments. 450 targsList[i] = targs 451 xlistList[i] = xlist 452 // Update x.expr so that we can record the partially instantiated function. 453 x.expr = ix.Orig 454 } else { 455 // x was instantiated: we must record it here because we didn't 456 // use the usual expression evaluators. 457 check.record(&x) 458 } 459 } else { 460 // x is exactly one value (possibly invalid or uninstantiated generic function). 461 check.genericExpr(&x, e) 462 } 463 resList[i] = &x 464 } 465 } 466 467 return 468 } 469 470 // arguments type-checks arguments passed to a function call with the given signature. 471 // The function and its arguments may be generic, and possibly partially instantiated. 472 // targs and xlist are the function's type arguments (and corresponding expressions). 473 // args are the function arguments. If an argument args[i] is a partially instantiated 474 // generic function, atargs[i] and atxlist[i] are the corresponding type arguments 475 // (and corresponding expressions). 476 // If the callee is variadic, arguments adjusts its signature to match the provided 477 // arguments. The type parameters and arguments of the callee and all its arguments 478 // are used together to infer any missing type arguments, and the callee and argument 479 // functions are instantiated as necessary. 480 // The result signature is the (possibly adjusted and instantiated) function signature. 481 // If an error occurred, the result signature is the incoming sig. 482 func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, xlist []ast.Expr, args []*operand, atargs [][]Type, atxlist [][]ast.Expr) (rsig *Signature) { 483 rsig = sig 484 485 // Function call argument/parameter count requirements 486 // 487 // | standard call | dotdotdot call | 488 // --------------+------------------+----------------+ 489 // standard func | nargs == npars | invalid | 490 // --------------+------------------+----------------+ 491 // variadic func | nargs >= npars-1 | nargs == npars | 492 // --------------+------------------+----------------+ 493 494 nargs := len(args) 495 npars := sig.params.Len() 496 ddd := call.Ellipsis.IsValid() 497 498 // set up parameters 499 sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!) 500 adjusted := false // indicates if sigParams is different from sig.params 501 if sig.variadic { 502 if ddd { 503 // variadic_func(a, b, c...) 504 if len(call.Args) == 1 && nargs > 1 { 505 // f()... is not permitted if f() is multi-valued 506 check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0]) 507 return 508 } 509 } else { 510 // variadic_func(a, b, c) 511 if nargs >= npars-1 { 512 // Create custom parameters for arguments: keep 513 // the first npars-1 parameters and add one for 514 // each argument mapping to the ... parameter. 515 vars := make([]*Var, npars-1) // npars > 0 for variadic functions 516 copy(vars, sig.params.vars) 517 last := sig.params.vars[npars-1] 518 typ := last.typ.(*Slice).elem 519 for len(vars) < nargs { 520 vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ)) 521 } 522 sigParams = NewTuple(vars...) // possibly nil! 523 adjusted = true 524 npars = nargs 525 } else { 526 // nargs < npars-1 527 npars-- // for correct error message below 528 } 529 } 530 } else { 531 if ddd { 532 // standard_func(a, b, c...) 533 check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun) 534 return 535 } 536 // standard_func(a, b, c) 537 } 538 539 // check argument count 540 if nargs != npars { 541 var at positioner = call 542 qualifier := "not enough" 543 if nargs > npars { 544 at = args[npars].expr // report at first extra argument 545 qualifier = "too many" 546 } else { 547 at = atPos(call.Rparen) // report at closing ) 548 } 549 // take care of empty parameter lists represented by nil tuples 550 var params []*Var 551 if sig.params != nil { 552 params = sig.params.vars 553 } 554 err := newErrorf(at, WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun) 555 err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false)) 556 err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic)) 557 check.report(err) 558 return 559 } 560 561 // collect type parameters of callee and generic function arguments 562 var tparams []*TypeParam 563 564 // collect type parameters of callee 565 n := sig.TypeParams().Len() 566 if n > 0 { 567 if !check.allowVersion(check.pkg, call, go1_18) { 568 switch call.Fun.(type) { 569 case *ast.IndexExpr, *ast.IndexListExpr: 570 ix := typeparams.UnpackIndexExpr(call.Fun) 571 check.versionErrorf(inNode(call.Fun, ix.Lbrack), go1_18, "function instantiation") 572 default: 573 check.versionErrorf(inNode(call, call.Lparen), go1_18, "implicit function instantiation") 574 } 575 } 576 // rename type parameters to avoid problems with recursive calls 577 var tmp Type 578 tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams) 579 sigParams = tmp.(*Tuple) 580 // make sure targs and tparams have the same length 581 for len(targs) < len(tparams) { 582 targs = append(targs, nil) 583 } 584 } 585 assert(len(tparams) == len(targs)) 586 587 // collect type parameters from generic function arguments 588 var genericArgs []int // indices of generic function arguments 589 if enableReverseTypeInference { 590 for i, arg := range args { 591 // generic arguments cannot have a defined (*Named) type - no need for underlying type below 592 if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 { 593 // Rename type parameters for cases like f(g, g); this gives each 594 // generic function argument a unique type identity (go.dev/issues/59956). 595 // TODO(gri) Consider only doing this if a function argument appears 596 // multiple times, which is rare (possible optimization). 597 atparams, tmp := check.renameTParams(call.Pos(), asig.TypeParams().list(), asig) 598 asig = tmp.(*Signature) 599 asig.tparams = &TypeParamList{atparams} // renameTParams doesn't touch associated type parameters 600 arg.typ = asig // new type identity for the function argument 601 tparams = append(tparams, atparams...) 602 // add partial list of type arguments, if any 603 if i < len(atargs) { 604 targs = append(targs, atargs[i]...) 605 } 606 // make sure targs and tparams have the same length 607 for len(targs) < len(tparams) { 608 targs = append(targs, nil) 609 } 610 genericArgs = append(genericArgs, i) 611 } 612 } 613 } 614 assert(len(tparams) == len(targs)) 615 616 // at the moment we only support implicit instantiations of argument functions 617 _ = len(genericArgs) > 0 && check.verifyVersionf(check.pkg, args[genericArgs[0]], go1_21, "implicitly instantiated function as argument") 618 619 // tparams holds the type parameters of the callee and generic function arguments, if any: 620 // the first n type parameters belong to the callee, followed by mi type parameters for each 621 // of the generic function arguments, where mi = args[i].typ.(*Signature).TypeParams().Len(). 622 623 // infer missing type arguments of callee and function arguments 624 if len(tparams) > 0 { 625 targs = check.infer(call, tparams, targs, sigParams, args) 626 if targs == nil { 627 // TODO(gri) If infer inferred the first targs[:n], consider instantiating 628 // the call signature for better error messages/gopls behavior. 629 // Perhaps instantiate as much as we can, also for arguments. 630 // This will require changes to how infer returns its results. 631 return // error already reported 632 } 633 634 // compute result signature: instantiate if needed 635 rsig = sig 636 if n > 0 { 637 rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist) 638 } 639 640 // Optimization: Only if the callee's parameter list was adjusted do we need to 641 // compute it from the adjusted list; otherwise we can simply use the result 642 // signature's parameter list. We only need the n type parameters and arguments 643 // of the callee. 644 if n > 0 && adjusted { 645 sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple) 646 } else { 647 sigParams = rsig.params 648 } 649 650 // compute argument signatures: instantiate if needed 651 j := n 652 for _, i := range genericArgs { 653 arg := args[i] 654 asig := arg.typ.(*Signature) 655 k := j + asig.TypeParams().Len() 656 // targs[j:k] are the inferred type arguments for asig 657 arg.typ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil) // TODO(gri) provide xlist if possible (partial instantiations) 658 check.record(arg) // record here because we didn't use the usual expr evaluators 659 j = k 660 } 661 } 662 663 // check arguments 664 if len(args) > 0 { 665 context := check.sprintf("argument to %s", call.Fun) 666 for i, a := range args { 667 check.assignment(a, sigParams.vars[i].typ, context) 668 } 669 } 670 671 return 672 } 673 674 var cgoPrefixes = [...]string{ 675 "_Ciconst_", 676 "_Cfconst_", 677 "_Csconst_", 678 "_Ctype_", 679 "_Cvar_", // actually a pointer to the var 680 "_Cfpvar_fp_", 681 "_Cfunc_", 682 "_Cmacro_", // function to evaluate the expanded expression 683 } 684 685 func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) { 686 // these must be declared before the "goto Error" statements 687 var ( 688 obj Object 689 index []int 690 indirect bool 691 ) 692 693 sel := e.Sel.Name 694 // If the identifier refers to a package, handle everything here 695 // so we don't need a "package" mode for operands: package names 696 // can only appear in qualified identifiers which are mapped to 697 // selector expressions. 698 if ident, ok := e.X.(*ast.Ident); ok { 699 obj := check.lookup(ident.Name) 700 if pname, _ := obj.(*PkgName); pname != nil { 701 assert(pname.pkg == check.pkg) 702 check.recordUse(ident, pname) 703 pname.used = true 704 pkg := pname.imported 705 706 var exp Object 707 funcMode := value 708 if pkg.cgo { 709 // cgo special cases C.malloc: it's 710 // rewritten to _CMalloc and does not 711 // support two-result calls. 712 if sel == "malloc" { 713 sel = "_CMalloc" 714 } else { 715 funcMode = cgofunc 716 } 717 for _, prefix := range cgoPrefixes { 718 // cgo objects are part of the current package (in file 719 // _cgo_gotypes.go). Use regular lookup. 720 _, exp = check.scope.LookupParent(prefix+sel, check.pos) 721 if exp != nil { 722 break 723 } 724 } 725 if exp == nil { 726 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) // cast to ast.Expr to silence vet 727 goto Error 728 } 729 check.objDecl(exp, nil) 730 } else { 731 exp = pkg.scope.Lookup(sel) 732 if exp == nil { 733 if !pkg.fake { 734 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) 735 } 736 goto Error 737 } 738 if !exp.Exported() { 739 check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name) 740 // ok to continue 741 } 742 } 743 check.recordUse(e.Sel, exp) 744 745 // Simplified version of the code for *ast.Idents: 746 // - imported objects are always fully initialized 747 switch exp := exp.(type) { 748 case *Const: 749 assert(exp.Val() != nil) 750 x.mode = constant_ 751 x.typ = exp.typ 752 x.val = exp.val 753 case *TypeName: 754 x.mode = typexpr 755 x.typ = exp.typ 756 case *Var: 757 x.mode = variable 758 x.typ = exp.typ 759 if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") { 760 x.typ = x.typ.(*Pointer).base 761 } 762 case *Func: 763 x.mode = funcMode 764 x.typ = exp.typ 765 if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") { 766 x.mode = value 767 x.typ = x.typ.(*Signature).results.vars[0].typ 768 } 769 case *Builtin: 770 x.mode = builtin 771 x.typ = exp.typ 772 x.id = exp.id 773 default: 774 check.dump("%v: unexpected object %v", e.Sel.Pos(), exp) 775 unreachable() 776 } 777 x.expr = e 778 return 779 } 780 } 781 782 check.exprOrType(x, e.X, false) 783 switch x.mode { 784 case typexpr: 785 // don't crash for "type T T.x" (was go.dev/issue/51509) 786 if def != nil && x.typ == def { 787 check.cycleError([]Object{def.obj}) 788 goto Error 789 } 790 case builtin: 791 // types2 uses the position of '.' for the error 792 check.errorf(e.Sel, UncalledBuiltin, "cannot select on %s", x) 793 goto Error 794 case invalid: 795 goto Error 796 } 797 798 // Avoid crashing when checking an invalid selector in a method declaration 799 // (i.e., where def is not set): 800 // 801 // type S[T any] struct{} 802 // type V = S[any] 803 // func (fs *S[T]) M(x V.M) {} 804 // 805 // All codepaths below return a non-type expression. If we get here while 806 // expecting a type expression, it is an error. 807 // 808 // See go.dev/issue/57522 for more details. 809 // 810 // TODO(rfindley): We should do better by refusing to check selectors in all cases where 811 // x.typ is incomplete. 812 if wantType { 813 check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e)) 814 goto Error 815 } 816 817 obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel) 818 if obj == nil { 819 // Don't report another error if the underlying type was invalid (go.dev/issue/49541). 820 if under(x.typ) == Typ[Invalid] { 821 goto Error 822 } 823 824 if index != nil { 825 // TODO(gri) should provide actual type where the conflict happens 826 check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel) 827 goto Error 828 } 829 830 if indirect { 831 if x.mode == typexpr { 832 check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel) 833 } else { 834 check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ) 835 } 836 goto Error 837 } 838 839 var why string 840 if isInterfacePtr(x.typ) { 841 why = check.interfacePtrError(x.typ) 842 } else { 843 why = check.sprintf("type %s has no field or method %s", x.typ, sel) 844 // Check if capitalization of sel matters and provide better error message in that case. 845 // TODO(gri) This code only looks at the first character but LookupFieldOrMethod should 846 // have an (internal) mechanism for case-insensitive lookup that we should use 847 // instead (see types2). 848 if len(sel) > 0 { 849 var changeCase string 850 if r := rune(sel[0]); unicode.IsUpper(r) { 851 changeCase = string(unicode.ToLower(r)) + sel[1:] 852 } else { 853 changeCase = string(unicode.ToUpper(r)) + sel[1:] 854 } 855 if obj, _, _ = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil { 856 why += ", but does have " + changeCase 857 } 858 } 859 } 860 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why) 861 goto Error 862 } 863 864 // methods may not have a fully set up signature yet 865 if m, _ := obj.(*Func); m != nil { 866 check.objDecl(m, nil) 867 } 868 869 if x.mode == typexpr { 870 // method expression 871 m, _ := obj.(*Func) 872 if m == nil { 873 // TODO(gri) should check if capitalization of sel matters and provide better error message in that case 874 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel) 875 goto Error 876 } 877 878 check.recordSelection(e, MethodExpr, x.typ, m, index, indirect) 879 880 sig := m.typ.(*Signature) 881 if sig.recv == nil { 882 check.error(e, InvalidDeclCycle, "illegal cycle in method declaration") 883 goto Error 884 } 885 886 // the receiver type becomes the type of the first function 887 // argument of the method expression's function type 888 var params []*Var 889 if sig.params != nil { 890 params = sig.params.vars 891 } 892 // Be consistent about named/unnamed parameters. This is not needed 893 // for type-checking, but the newly constructed signature may appear 894 // in an error message and then have mixed named/unnamed parameters. 895 // (An alternative would be to not print parameter names in errors, 896 // but it's useful to see them; this is cheap and method expressions 897 // are rare.) 898 name := "" 899 if len(params) > 0 && params[0].name != "" { 900 // name needed 901 name = sig.recv.name 902 if name == "" { 903 name = "_" 904 } 905 } 906 params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...) 907 x.mode = value 908 x.typ = &Signature{ 909 tparams: sig.tparams, 910 params: NewTuple(params...), 911 results: sig.results, 912 variadic: sig.variadic, 913 } 914 915 check.addDeclDep(m) 916 917 } else { 918 // regular selector 919 switch obj := obj.(type) { 920 case *Var: 921 check.recordSelection(e, FieldVal, x.typ, obj, index, indirect) 922 if x.mode == variable || indirect { 923 x.mode = variable 924 } else { 925 x.mode = value 926 } 927 x.typ = obj.typ 928 929 case *Func: 930 // TODO(gri) If we needed to take into account the receiver's 931 // addressability, should we report the type &(x.typ) instead? 932 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect) 933 934 // TODO(gri) The verification pass below is disabled for now because 935 // method sets don't match method lookup in some cases. 936 // For instance, if we made a copy above when creating a 937 // custom method for a parameterized received type, the 938 // method set method doesn't match (no copy there). There 939 /// may be other situations. 940 disabled := true 941 if !disabled && debug { 942 // Verify that LookupFieldOrMethod and MethodSet.Lookup agree. 943 // TODO(gri) This only works because we call LookupFieldOrMethod 944 // _before_ calling NewMethodSet: LookupFieldOrMethod completes 945 // any incomplete interfaces so they are available to NewMethodSet 946 // (which assumes that interfaces have been completed already). 947 typ := x.typ 948 if x.mode == variable { 949 // If typ is not an (unnamed) pointer or an interface, 950 // use *typ instead, because the method set of *typ 951 // includes the methods of typ. 952 // Variables are addressable, so we can always take their 953 // address. 954 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) { 955 typ = &Pointer{base: typ} 956 } 957 } 958 // If we created a synthetic pointer type above, we will throw 959 // away the method set computed here after use. 960 // TODO(gri) Method set computation should probably always compute 961 // both, the value and the pointer receiver method set and represent 962 // them in a single structure. 963 // TODO(gri) Consider also using a method set cache for the lifetime 964 // of checker once we rely on MethodSet lookup instead of individual 965 // lookup. 966 mset := NewMethodSet(typ) 967 if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj { 968 check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m) 969 check.dump("%s\n", mset) 970 // Caution: MethodSets are supposed to be used externally 971 // only (after all interface types were completed). It's 972 // now possible that we get here incorrectly. Not urgent 973 // to fix since we only run this code in debug mode. 974 // TODO(gri) fix this eventually. 975 panic("method sets and lookup don't agree") 976 } 977 } 978 979 x.mode = value 980 981 // remove receiver 982 sig := *obj.typ.(*Signature) 983 sig.recv = nil 984 x.typ = &sig 985 986 check.addDeclDep(obj) 987 988 default: 989 unreachable() 990 } 991 } 992 993 // everything went well 994 x.expr = e 995 return 996 997 Error: 998 x.mode = invalid 999 x.expr = e 1000 } 1001 1002 // use type-checks each argument. 1003 // Useful to make sure expressions are evaluated 1004 // (and variables are "used") in the presence of 1005 // other errors. Arguments may be nil. 1006 // Reports if all arguments evaluated without error. 1007 func (check *Checker) use(args ...ast.Expr) bool { return check.useN(args, false) } 1008 1009 // useLHS is like use, but doesn't "use" top-level identifiers. 1010 // It should be called instead of use if the arguments are 1011 // expressions on the lhs of an assignment. 1012 func (check *Checker) useLHS(args ...ast.Expr) bool { return check.useN(args, true) } 1013 1014 func (check *Checker) useN(args []ast.Expr, lhs bool) bool { 1015 ok := true 1016 for _, e := range args { 1017 if !check.use1(e, lhs) { 1018 ok = false 1019 } 1020 } 1021 return ok 1022 } 1023 1024 func (check *Checker) use1(e ast.Expr, lhs bool) bool { 1025 var x operand 1026 x.mode = value // anything but invalid 1027 switch n := unparen(e).(type) { 1028 case nil: 1029 // nothing to do 1030 case *ast.Ident: 1031 // don't report an error evaluating blank 1032 if n.Name == "_" { 1033 break 1034 } 1035 // If the lhs is an identifier denoting a variable v, this assignment 1036 // is not a 'use' of v. Remember current value of v.used and restore 1037 // after evaluating the lhs via check.rawExpr. 1038 var v *Var 1039 var v_used bool 1040 if lhs { 1041 if _, obj := check.scope.LookupParent(n.Name, nopos); obj != nil { 1042 // It's ok to mark non-local variables, but ignore variables 1043 // from other packages to avoid potential race conditions with 1044 // dot-imported variables. 1045 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg { 1046 v = w 1047 v_used = v.used 1048 } 1049 } 1050 } 1051 check.exprOrType(&x, n, true) 1052 if v != nil { 1053 v.used = v_used // restore v.used 1054 } 1055 default: 1056 check.rawExpr(nil, &x, e, nil, true) 1057 } 1058 return x.mode != invalid 1059 }