Skip to content

Commit 03e5c9f

Browse files
committed
[CS] A couple of minor improvements to operator diagnostics
- Simplify the fix locator when looking for a fix already present in a pattern match, this avoids us emitting both a diagnostic for the argument conversion, and for a conformance failure. - Include tuples in the diagnostic logic where we emit a generic "operator cannot be applied" diagnostic, as a conformance diagnostic is unlikely to be helpful in that case.
1 parent 2f64b7f commit 03e5c9f

File tree

4 files changed

+13
-13
lines changed

4 files changed

+13
-13
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,10 @@ bool MissingConformanceFailure::diagnoseAsError() {
562562
llvm::SmallPtrSet<Expr *, 4> anchors;
563563
for (const auto *fix : getSolution().Fixes) {
564564
if (auto anchor = fix->getAnchor()) {
565-
if (anchor.is<Expr *>())
565+
auto path = fix->getLocator()->getPath();
566+
SourceRange range;
567+
simplifyLocator(anchor, path, range);
568+
if (anchor && anchor.is<Expr *>())
566569
anchors.insert(getAsExpr(anchor));
567570
}
568571
}
@@ -703,10 +706,15 @@ bool MissingConformanceFailure::diagnoseAsAmbiguousOperatorRef() {
703706
if (!ODRE)
704707
return false;
705708

709+
auto isStandardType = [](Type ty) {
710+
return ty->isStdlibType() || ty->is<TupleType>();
711+
};
712+
706713
auto name = ODRE->getDecls().front()->getBaseName();
707-
if (!(name.isOperator() && getLHS()->isStdlibType() && getRHS()->isStdlibType()))
714+
if (!(name.isOperator() && isStandardType(getLHS()) &&
715+
isStandardType(getRHS()))) {
708716
return false;
709-
717+
}
710718
// If this is an operator reference and both types are from stdlib,
711719
// let's produce a generic diagnostic about invocation and a note
712720
// about missing conformance just in case.

test/Misc/misc_diagnostics.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,6 @@ func test17875634() {
144144
func test20770032() {
145145
if case let 1...10 = (1, 1) { // expected-warning{{'let' pattern has no effect; sub-pattern didn't bind any variables}} {{11-15=}}
146146
// expected-error@-1 {{expression pattern of type 'ClosedRange<Int>' cannot match values of type '(Int, Int)'}}
147-
// expected-error@-2 {{type '(Int, Int)' cannot conform to 'Equatable'}}
148-
// expected-note@-3 {{only concrete types such as structs, enums and classes can conform to protocols}}
149-
// expected-note@-4 {{required by operator function '~=' where 'T' = '(Int, Int)'}}
150147
}
151148
}
152149

test/Parse/confusables.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@ if (true ꝸꝸꝸ false) {} // expected-note {{identifier 'ꝸꝸꝸ' contains
1818

1919
// expected-error @+3 {{invalid character in source file}}
2020
// expected-error @+2 {{expected ',' separator}}
21-
// expected-error @+1 {{type '(Int, Int)' cannot conform to 'BinaryInteger'}}
21+
// expected-error @+1 {{binary operator '==' cannot be applied to operands of type '(Int, Int)' and 'Int'}}
2222
if (55) == 0 {} // expected-note {{unicode character '‒' (Figure Dash) looks similar to '-' (Hyphen Minus); did you mean to use '-' (Hyphen Minus)?}} {{7-10=-}}
23-
// expected-note @-1 {{operator function '=='}}
24-
// expected-note @-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
25-
26-
// FIXME(rdar://61028087): The above note should read "required by referencing operator function '==' on 'BinaryInteger' where 'Self' = '(Int, Int)'".
2723

2824
// GREEK QUESTION MARK (which looks like a semicolon)
2925
print("A"); print("B")

test/StringProcessing/Parse/forward-slash-regex.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ default:
263263

264264
do {} catch /x/ {}
265265
// expected-error@-1 {{expression pattern of type 'Regex<Substring>' cannot match values of type 'any Error'}}
266-
// expected-error@-2 {{binary operator '~=' cannot be applied to two 'any Error' operands}}
267-
// expected-warning@-3 {{'catch' block is unreachable because no errors are thrown in 'do' block}}
266+
// expected-warning@-2 {{'catch' block is unreachable because no errors are thrown in 'do' block}}
268267

269268
switch /x/ {
270269
default:

0 commit comments

Comments
 (0)