Skip to content

Commit 91e97a0

Browse files
committed
[Diagnostics] Diagnose ambiguity resulting from subscript operator fix as a missing member
Since the rule is to prioritize names over types, let's diagnose ambiguous solutions containing subscript operator fix as missing member and list possible candidates to use.
1 parent 06a7ad6 commit 91e97a0

File tree

4 files changed

+15
-13
lines changed

4 files changed

+15
-13
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ ERROR(ambiguous_reference_to_decl,none,
6464
ERROR(ambiguous_subscript,none,
6565
"ambiguous subscript with base type %0 and index type %1",
6666
(Type, Type))
67-
NOTE(ambiguous_subscript_candidate_requires_operator,none,
68-
"candidate requires use of the subscript operator", ())
69-
7067
ERROR(could_not_find_value_subscript,none,
7168
"value of type %0 has no subscripts",
7269
(Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,8 +1327,7 @@ bool SubscriptMisuseFailure::diagnoseAsError() {
13271327

13281328
bool SubscriptMisuseFailure::diagnoseAsNote() {
13291329
if (auto overload = getOverloadChoiceIfAvailable(getLocator())) {
1330-
emitDiagnostic(overload->choice.getDecl(),
1331-
diag::ambiguous_subscript_candidate_requires_operator);
1330+
emitDiagnostic(overload->choice.getDecl(), diag::found_candidate);
13321331
return true;
13331332
}
13341333
return false;

lib/Sema/ConstraintSystem.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,8 +2205,16 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
22052205
{
22062206
DiagnosticTransaction transaction(TC.Diags);
22072207

2208-
TC.diagnose(commonAnchor->getLoc(), diag::ambiguous_reference_to_decl,
2209-
decl->getDescriptiveKind(), decl->getFullName());
2208+
const auto *fix = viableSolutions.front().second;
2209+
if (fix->getKind() == FixKind::UseSubscriptOperator) {
2210+
auto *UDE = cast<UnresolvedDotExpr>(commonAnchor);
2211+
TC.diagnose(commonAnchor->getLoc(),
2212+
diag::could_not_find_subscript_member_did_you_mean,
2213+
getType(UDE->getBase()));
2214+
} else {
2215+
TC.diagnose(commonAnchor->getLoc(), diag::ambiguous_reference_to_decl,
2216+
decl->getDescriptiveKind(), decl->getFullName());
2217+
}
22102218

22112219
for (const auto &viable : viableSolutions) {
22122220
// Create scope so each applied solution is rolled back.

test/decl/subscript/subscripting.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,9 @@ func testGenSubscriptFixit(_ s0: GenSubscriptFixitTest) {
266266

267267
struct SubscriptTest1 {
268268
subscript(keyword:String) -> Bool { return true }
269-
// expected-note@-1 2 {{found this candidate}}
270-
// expected-note@-2 2 {{candidate requires use of the subscript operator}}
269+
// expected-note@-1 4 {{found this candidate}}
271270
subscript(keyword:String) -> String? {return nil }
272-
// expected-note@-1 2 {{found this candidate}}
273-
// expected-note@-2 2 {{candidate requires use of the subscript operator}}
271+
// expected-note@-1 4 {{found this candidate}}
274272

275273
subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}}
276274
subscript(arg: Protocol) -> Bool { return true } // expected-note 2 {{declared here}}
@@ -303,9 +301,9 @@ func testSubscript1(_ s1 : SubscriptTest1) {
303301
// expected-error@-1 {{cannot invoke 'subscript' with an argument list of type '(SuperClass)'}}
304302
// expected-note@-2 {{overloads for 'subscript' exist with these partially matching parameter lists: (Protocol), (String), (SubClass)}}
305303
_ = s1.subscript("hello")
306-
// expected-error@-1 {{ambiguous reference to subscript 'subscript(_:)'}}
304+
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
307305
_ = s1.subscript("hello"
308-
// expected-error@-1 {{ambiguous reference to subscript 'subscript(_:)'}}
306+
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
309307
// expected-note@-2 {{to match this opening '('}}
310308

311309
let _ = s1["hello"]

0 commit comments

Comments
 (0)