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