Skip to content

Commit dba850f

Browse files
committed
[CSDiagnostics] Use getAnchormostCalleeLocator
Have FailureDiagnostic::getChoiceFor take a ConstraintLocator argument which is passed through to getAnchormostCalleeLocator, and rename to getAnchormostChoiceFor to make the semantics clear. In addition, add a convenience getAnchormostChoice member for the common case of getting the choice for the anchor of the failure's locator. This change means we can now resolve callees for failures associated with key path subscript components. Resolves SR-11435.
1 parent 67ee821 commit dba850f

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,14 @@ Expr *FailureDiagnostic::getBaseExprFor(Expr *anchor) const {
121121
return nullptr;
122122
}
123123

124-
Optional<SelectedOverload> FailureDiagnostic::getChoiceFor(Expr *expr) const {
124+
Optional<SelectedOverload> FailureDiagnostic::getAnchormostChoice() const {
125+
return getAnchormostChoiceFor(getLocator());
126+
}
127+
128+
Optional<SelectedOverload>
129+
FailureDiagnostic::getAnchormostChoiceFor(ConstraintLocator *locator) const {
125130
auto &cs = getConstraintSystem();
126-
auto *loc = cs.getConstraintLocator(expr);
127-
return getOverloadChoiceIfAvailable(cs.getAnchormostCalleeLocator(loc));
131+
return getOverloadChoiceIfAvailable(cs.getAnchormostCalleeLocator(locator));
128132
}
129133

130134
Type FailureDiagnostic::resolveInterfaceType(Type type,
@@ -159,7 +163,8 @@ Type FailureDiagnostic::resolveInterfaceType(Type type,
159163
}
160164

161165
/// Given an apply expr, returns true if it is expected to have a direct callee
162-
/// overload, resolvable using `getChoiceFor`. Otherwise, returns false.
166+
/// overload, resolvable using `getAnchormostChoiceFor`. Otherwise, returns
167+
/// false.
163168
static bool shouldHaveDirectCalleeOverload(const CallExpr *callExpr) {
164169
auto *fnExpr = callExpr->getDirectCallee();
165170

@@ -221,7 +226,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
221226

222227
ValueDecl *callee = nullptr;
223228
Type rawFnType;
224-
if (auto overload = getChoiceFor(anchor)) {
229+
if (auto overload = getAnchormostChoiceFor(argLocator)) {
225230
// If we have resolved an overload for the callee, then use that to get the
226231
// function type and callee.
227232
callee = overload->choice.getDeclOrNull();
@@ -375,7 +380,7 @@ ValueDecl *RequirementFailure::getDeclRef() const {
375380
if (isFromContextualType())
376381
return getAffectedDeclFromType(cs.getContextualType());
377382

378-
if (auto overload = getChoiceFor(getRawAnchor())) {
383+
if (auto overload = getAnchormostChoice()) {
379384
// If there is a declaration associated with this
380385
// failure e.g. an overload choice of the call
381386
// expression, let's see whether failure is
@@ -747,7 +752,7 @@ bool LabelingFailure::diagnoseAsNote() {
747752
return "(" + str + ")";
748753
};
749754

750-
auto selectedOverload = getChoiceFor(anchor);
755+
auto selectedOverload = getAnchormostChoice();
751756
if (!selectedOverload)
752757
return false;
753758

@@ -3121,8 +3126,8 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
31213126
return true;
31223127
};
31233128

3124-
auto selection = getChoiceFor(ctorRef->getBase());
3125-
if (selection) {
3129+
auto *baseLoc = cs.getConstraintLocator(ctorRef->getBase());
3130+
if (auto selection = getAnchormostChoiceFor(baseLoc)) {
31263131
OverloadChoice choice = selection->choice;
31273132
if (choice.isDecl() && isMutable(choice.getDecl()) &&
31283133
!isCallArgument(initCall) &&
@@ -4282,15 +4287,13 @@ bool MutatingMemberRefOnImmutableBase::diagnoseAsError() {
42824287
}
42834288

42844289
bool InvalidTupleSplatWithSingleParameterFailure::diagnoseAsError() {
4285-
auto *anchor = getRawAnchor();
4286-
4287-
auto selectedOverload = getChoiceFor(anchor);
4290+
auto selectedOverload = getAnchormostChoice();
42884291
if (!selectedOverload || !selectedOverload->choice.isDecl())
42894292
return false;
42904293

42914294
auto *choice = selectedOverload->choice.getDecl();
42924295

4293-
auto *argExpr = getArgumentExprFor(anchor);
4296+
auto *argExpr = getArgumentExprFor(getRawAnchor());
42944297
if (!argExpr)
42954298
return false;
42964299

lib/Sema/CSDiagnostics.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,13 @@ class FailureDiagnostic {
176176
/// reference or subscript, nullptr otherwise.
177177
Expr *getArgumentExprFor(Expr *anchor) const;
178178

179-
Optional<SelectedOverload> getChoiceFor(Expr *) const;
179+
/// \returns The overload choice made by the constraint system for the callee
180+
/// of this failure's raw anchor, or \c None if no such choice can be found.
181+
Optional<SelectedOverload> getAnchormostChoice() const;
182+
183+
/// \returns The overload choice made by the constraint system for the callee
184+
/// of a given locator's anchor, or \c None if no such choice can be found.
185+
Optional<SelectedOverload> getAnchormostChoiceFor(ConstraintLocator *) const;
180186

181187
/// For a given locator describing a function argument conversion, or a
182188
/// constraint within an argument conversion, returns information about the

test/Constraints/generics.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,16 @@ func test_correct_identification_of_requirement_source() {
819819
_ = X(A(), 17)
820820
// expected-error@-1 {{initializer 'init(_:_:)' requires that 'Int' conform to 'P'}}
821821
}
822+
823+
struct SR11435<T> {
824+
subscript<U : P & Hashable>(x x: U) -> U { x } // expected-note {{where 'U' = 'Int'}}
825+
}
826+
827+
extension SR11435 where T : P { // expected-note {{where 'T' = 'Int'}}
828+
var foo: Int { 0 }
829+
}
830+
831+
func test_identification_of_key_path_component_callees() {
832+
_ = \SR11435<Int>.foo // expected-error {{property 'foo' requires that 'Int' conform to 'P'}}
833+
_ = \SR11435<Int>.[x: 5] // expected-error {{subscript 'subscript(x:)' requires that 'Int' conform to 'P'}}
834+
}

0 commit comments

Comments
 (0)