@@ -475,31 +475,38 @@ ConstraintSystem::getCalleeLocator(ConstraintLocator *locator,
475
475
if (isa<SubscriptExpr>(anchor))
476
476
return getConstraintLocator (anchor, ConstraintLocator::SubscriptMember);
477
477
478
+ auto getSpecialFnCalleeLoc = [&](Type fnTy) -> ConstraintLocator * {
479
+ // FIXME: We should probably assert that we don't get a type variable
480
+ // here to make sure we only retrieve callee locators for resolved calls,
481
+ // ensuring that callee locators don't change after binding a type.
482
+ // Unfortunately CSDiag currently calls into getCalleeLocator, so all bets
483
+ // are off. Once we remove that legacy diagnostic logic, we should be able
484
+ // to assert here.
485
+ fnTy = getFixedTypeRecursive (fnTy, /* wantRValue*/ true );
486
+
487
+ // For an apply of a metatype, we have a short-form constructor. Unlike
488
+ // other locators to callees, these are anchored on the apply expression
489
+ // rather than the function expr.
490
+ if (fnTy->is <AnyMetatypeType>()) {
491
+ return getConstraintLocator (anchor,
492
+ {LocatorPathElt::ApplyFunction (),
493
+ LocatorPathElt::ConstructorMember ()});
494
+ }
495
+
496
+ // Handle an apply of a nominal type which supports callAsFunction.
497
+ if (fnTy->isCallableNominalType (DC))
498
+ return getConstraintLocator (anchor, ConstraintLocator::ApplyFunction);
499
+
500
+ return nullptr ;
501
+ };
502
+
478
503
if (lookThroughApply) {
479
504
if (auto *applyExpr = dyn_cast<ApplyExpr>(anchor)) {
480
505
auto *fnExpr = applyExpr->getFn ();
481
506
482
- // FIXME: We should probably assert that we don't get a type variable
483
- // here to make sure we only retrieve callee locators for resolved calls,
484
- // ensuring that callee locators don't change after binding a type.
485
- // Unfortunately CSDiag currently calls into getCalleeLocator, so all bets
486
- // are off. Once we remove that legacy diagnostic logic, we should be able
487
- // to assert here.
488
- auto fnTy = getFixedTypeRecursive (getType (fnExpr), /* wantRValue*/ true );
489
-
490
- // For an apply of a metatype, we have a short-form constructor. Unlike
491
- // other locators to callees, these are anchored on the apply expression
492
- // rather than the function expr.
493
- if (fnTy->is <AnyMetatypeType>()) {
494
- auto *fnLocator =
495
- getConstraintLocator (applyExpr, ConstraintLocator::ApplyFunction);
496
- return getConstraintLocator (fnLocator,
497
- ConstraintLocator::ConstructorMember);
498
- }
499
-
500
- // Handle an apply of a nominal type which supports callAsFunction.
501
- if (fnTy->isCallableNominalType (DC))
502
- return getConstraintLocator (anchor, ConstraintLocator::ApplyFunction);
507
+ // Handle special cases for applies of non-function types.
508
+ if (auto *loc = getSpecialFnCalleeLoc (getType (fnExpr)))
509
+ return loc;
503
510
504
511
// Otherwise fall through and look for locators anchored on the function
505
512
// expr. For CallExprs, this can look through things like parens and
@@ -519,8 +526,23 @@ ConstraintSystem::getCalleeLocator(ConstraintLocator *locator,
519
526
: ConstraintLocator::Member);
520
527
}
521
528
522
- if (isa<UnresolvedMemberExpr>(anchor))
523
- return getConstraintLocator (anchor, ConstraintLocator::UnresolvedMember);
529
+ if (auto *UME = dyn_cast<UnresolvedMemberExpr>(anchor)) {
530
+ auto *calleeLoc =
531
+ getConstraintLocator (UME, ConstraintLocator::UnresolvedMember);
532
+
533
+ // Handle special cases for applies of non-function types.
534
+ // FIXME: Consider re-designing the AST such that an unresolved member expr
535
+ // with arguments uses a CallExpr, which would make this logic unnecessary
536
+ // and clean up a bunch of other special cases. Doing so may require a bit
537
+ // of hacking in CSGen though.
538
+ if (UME->hasArguments ()) {
539
+ if (auto overload = findSelectedOverloadFor (calleeLoc)) {
540
+ if (auto *loc = getSpecialFnCalleeLoc (overload->boundType ))
541
+ return loc;
542
+ }
543
+ }
544
+ return calleeLoc;
545
+ }
524
546
525
547
if (isa<MemberRefExpr>(anchor))
526
548
return getConstraintLocator (anchor, ConstraintLocator::Member);
@@ -3356,11 +3378,17 @@ ConstraintSystem::getArgumentInfoLocator(ConstraintLocator *locator) {
3356
3378
if (!anchor)
3357
3379
return nullptr ;
3358
3380
3381
+ // Applies and unresolved member exprs can have callee locators that are
3382
+ // dependent on the type of their function, which may not have been resolved
3383
+ // yet. Therefore we need to handle them specially.
3359
3384
if (auto *apply = dyn_cast<ApplyExpr>(anchor)) {
3360
3385
auto *fnExpr = getArgumentLabelTargetExpr (apply->getFn ());
3361
3386
return getConstraintLocator (fnExpr);
3362
3387
}
3363
3388
3389
+ if (auto *UME = dyn_cast<UnresolvedMemberExpr>(anchor))
3390
+ return getConstraintLocator (UME);
3391
+
3364
3392
return getCalleeLocator (locator);
3365
3393
}
3366
3394
0 commit comments