Skip to content

Commit 075e92b

Browse files
authored
Merge pull request swiftlang#26576 from LucianoPAlmeida/SR-10597-name-lookup-failure-diagnostics
SR-10597 KeyPath dynamic member lookup
2 parents a44aa52 + 1d910fb commit 075e92b

File tree

3 files changed

+83
-14
lines changed

3 files changed

+83
-14
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ ERROR(could_not_find_value_member,none,
8181
ERROR(could_not_find_value_member_corrected,none,
8282
"value of type %0 has no member %1; did you mean %2?",
8383
(Type, DeclName, DeclName))
84+
ERROR(could_not_find_value_dynamic_member_corrected,none,
85+
"value of type %0 has no dynamic member %2 using key path from root type %1; did you mean %3?",
86+
(Type, Type, DeclName, DeclName))
87+
ERROR(could_not_find_value_dynamic_member,none,
88+
"value of type %0 has no dynamic member %2 using key path from root type %1",
89+
(Type, Type, DeclName))
90+
8491
ERROR(could_not_find_type_member,none,
8592
"type %0 has no member %1", (Type, DeclName))
8693
ERROR(could_not_find_type_member_corrected,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,8 +2258,8 @@ bool MissingMemberFailure::diagnoseAsError() {
22582258
};
22592259

22602260
TypoCorrectionResults corrections(TC, getName(), nameLoc);
2261-
auto tryTypoCorrection = [&] {
2262-
TC.performTypoCorrection(getDC(), DeclRefKind::Ordinary, baseType,
2261+
auto tryTypoCorrection = [&] (Type type) {
2262+
TC.performTypoCorrection(getDC(), DeclRefKind::Ordinary, type,
22632263
defaultMemberLookupOptions, corrections);
22642264
};
22652265

@@ -2279,7 +2279,7 @@ bool MissingMemberFailure::diagnoseAsError() {
22792279
.highlight(baseExpr->getSourceRange());
22802280
} else if (auto metatypeTy = baseType->getAs<MetatypeType>()) {
22812281
auto instanceTy = metatypeTy->getInstanceType();
2282-
tryTypoCorrection();
2282+
tryTypoCorrection(baseType);
22832283

22842284
if (DeclName rightName =
22852285
findCorrectEnumCaseName(instanceTy, corrections, getName())) {
@@ -2323,18 +2323,46 @@ bool MissingMemberFailure::diagnoseAsError() {
23232323
.fixItInsertAfter(baseExpr->getEndLoc(), " as AnyObject)");
23242324
return true;
23252325
}
2326-
2327-
tryTypoCorrection();
2328-
2329-
if (auto correction = corrections.claimUniqueCorrection()) {
2330-
auto diagnostic = emitDiagnostic(
2331-
anchor->getLoc(), diag::could_not_find_value_member_corrected,
2332-
baseType, getName(), correction->CorrectedName);
2333-
diagnostic.highlight(baseExpr->getSourceRange())
2334-
.highlight(nameLoc.getSourceRange());
2335-
correction->addFixits(diagnostic);
2326+
2327+
tryTypoCorrection(baseType);
2328+
2329+
// If locator points to the member found via key path dynamic member lookup,
2330+
// we provide a custom diagnostic and emit typo corrections for the wrapper type too.
2331+
if (getLocator()->isForKeyPathDynamicMemberLookup()) {
2332+
auto baseExprType = getType(baseExpr)->getWithoutSpecifierType();
2333+
2334+
tryTypoCorrection(baseExprType);
2335+
2336+
if (auto correction = corrections.claimUniqueCorrection()) {
2337+
auto diagnostic = emitDiagnostic(
2338+
anchor->getLoc(),
2339+
diag::could_not_find_value_dynamic_member_corrected,
2340+
baseExprType, baseType, getName(),
2341+
correction->CorrectedName);
2342+
diagnostic.highlight(baseExpr->getSourceRange())
2343+
.highlight(nameLoc.getSourceRange());
2344+
correction->addFixits(diagnostic);
2345+
} else {
2346+
auto diagnostic = emitDiagnostic(
2347+
anchor->getLoc(),
2348+
diag::could_not_find_value_dynamic_member,
2349+
baseExprType, baseType, getName());
2350+
diagnostic.highlight(baseExpr->getSourceRange())
2351+
.highlight(nameLoc.getSourceRange());
2352+
}
23362353
} else {
2337-
emitBasicError(baseType);
2354+
if (auto correction = corrections.claimUniqueCorrection()) {
2355+
auto diagnostic = emitDiagnostic(
2356+
anchor->getLoc(),
2357+
diag::could_not_find_value_member_corrected,
2358+
baseType, getName(),
2359+
correction->CorrectedName);
2360+
diagnostic.highlight(baseExpr->getSourceRange())
2361+
.highlight(nameLoc.getSourceRange());
2362+
correction->addFixits(diagnostic);
2363+
} else {
2364+
emitBasicError(baseType);
2365+
}
23382366
}
23392367
}
23402368

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,37 @@ func invalid_refs_through_dynamic_lookup() {
688688
_ = lens.baz("hello") // expected-error {{dynamic key path member lookup cannot refer to static method 'baz'}}
689689
}
690690
}
691+
692+
// SR-10597
693+
694+
final class SR10597 {
695+
}
696+
697+
@dynamicMemberLookup
698+
struct SR10597_W<T> {
699+
var obj: T
700+
init(_ obj: T) { self.obj = obj }
701+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
702+
return obj[keyPath: member]
703+
}
704+
var wooo: SR10597 { SR10597() } // expected-note {{declared here}}
705+
}
706+
707+
_ = SR10597_W<SR10597>(SR10597()).wooooo // expected-error {{value of type 'SR10597_W<SR10597>' has no dynamic member 'wooooo' using key path from root type 'SR10597'; did you mean 'wooo'?}}
708+
_ = SR10597_W<SR10597>(SR10597()).bla // expected-error {{value of type 'SR10597_W<SR10597>' has no dynamic member 'bla' using key path from root type 'SR10597'}}
709+
710+
final class SR10597_1 {
711+
var woo: Int? // expected-note 2 {{'woo' declared here}}
712+
}
713+
714+
@dynamicMemberLookup
715+
struct SR10597_1_W<T> {
716+
var obj: T
717+
init(_ obj: T) { self.obj = obj }
718+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
719+
return obj[keyPath: member]
720+
}
721+
}
722+
723+
_ = SR10597_1_W<SR10597_1>(SR10597_1()).wooo // expected-error {{value of type 'SR10597_1_W<SR10597_1>' has no dynamic member 'wooo' using key path from root type 'SR10597_1'; did you mean 'woo'?}}
724+
_ = SR10597_1_W<SR10597_1>(SR10597_1()).bla // expected-error {{value of type 'SR10597_1_W<SR10597_1>' has no dynamic member 'bla' using key path from root type 'SR10597_1'}}

0 commit comments

Comments
 (0)