Skip to content

Commit 6807569

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 b5e9bbb commit 6807569

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
@@ -513,7 +513,10 @@ bool MissingConformanceFailure::diagnoseAsError() {
513513
llvm::SmallPtrSet<Expr *, 4> anchors;
514514
for (const auto *fix : getSolution().Fixes) {
515515
if (auto anchor = fix->getAnchor()) {
516-
if (anchor.is<Expr *>())
516+
auto path = fix->getLocator()->getPath();
517+
SourceRange range;
518+
simplifyLocator(anchor, path, range);
519+
if (anchor && anchor.is<Expr *>())
517520
anchors.insert(getAsExpr(anchor));
518521
}
519522
}
@@ -654,10 +657,15 @@ bool MissingConformanceFailure::diagnoseAsAmbiguousOperatorRef() {
654657
if (!ODRE)
655658
return false;
656659

660+
auto isStandardType = [](Type ty) {
661+
return ty->isStdlibType() || ty->is<TupleType>();
662+
};
663+
657664
auto name = ODRE->getDecls().front()->getBaseName();
658-
if (!(name.isOperator() && getLHS()->isStdlibType() && getRHS()->isStdlibType()))
665+
if (!(name.isOperator() && isStandardType(getLHS()) &&
666+
isStandardType(getRHS()))) {
659667
return false;
660-
668+
}
661669
// If this is an operator reference and both types are from stdlib,
662670
// let's produce a generic diagnostic about invocation and a note
663671
// 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
@@ -264,8 +264,7 @@ default:
264264

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

270269
switch /x/ {
271270
default:

0 commit comments

Comments
 (0)