Skip to content

Commit b5a64d6

Browse files
committed
Sema, DiagQoI: Fix and tailor diagnosis of explicit closure result type conflicts
1 parent 33818ff commit b5a64d6

File tree

5 files changed

+29
-8
lines changed

5 files changed

+29
-8
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,12 @@ FIXIT(insert_closure_return_type_placeholder,
288288
NOTE(use_of_anon_closure_param,none,
289289
"anonymous closure parameter %0 is used here", (Identifier))
290290

291-
ERROR(incorrect_explicit_closure_result,none,
291+
ERROR(incorrect_explicit_closure_result_vs_contextual_type,none,
292292
"declared closure result %0 is incompatible with contextual type %1",
293293
(Type, Type))
294+
ERROR(incorrect_explicit_closure_result_vs_return_type,none,
295+
"declared closure result %0 is incompatible with return type %1",
296+
(Type, Type))
294297

295298
ERROR(unsupported_closure_attr,none,
296299
"%select{attribute |}0 '%1' is not supported on a closure",

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ SIMPLE_LOCATOR_PATH_ELT(AutoclosureResult)
5454
/// The result of a closure.
5555
SIMPLE_LOCATOR_PATH_ELT(ClosureResult)
5656

57+
/// FIXME: Misleading name: this locator is used only for single-expression
58+
/// closure returns.
59+
///
5760
/// The type of a closure body.
5861
CUSTOM_LOCATOR_PATH_ELT(ClosureBody)
5962

lib/Sema/CSDiagnostics.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,17 +2318,32 @@ bool ContextualFailure::diagnoseAsError() {
23182318
auto toType = getToType();
23192319

23202320
Diag<Type, Type> diagnostic;
2321-
switch (path.back().getKind()) {
2321+
2322+
const auto lastPathEltKind = path.back().getKind();
2323+
switch (lastPathEltKind) {
23222324
case ConstraintLocator::ClosureBody:
23232325
case ConstraintLocator::ClosureResult: {
23242326
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
23252327
if (closure->hasExplicitResultType() &&
23262328
closure->getExplicitResultTypeRepr()) {
23272329
auto resultRepr = closure->getExplicitResultTypeRepr();
2328-
emitDiagnosticAt(resultRepr->getStartLoc(),
2329-
diag::incorrect_explicit_closure_result, fromType,
2330-
toType)
2331-
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2330+
2331+
if (lastPathEltKind == ConstraintLocator::ClosureBody) {
2332+
// The conflict is between the return type and the declared result type.
2333+
emitDiagnosticAt(resultRepr->getStartLoc(),
2334+
diag::incorrect_explicit_closure_result_vs_return_type,
2335+
toType, fromType)
2336+
.fixItReplace(resultRepr->getSourceRange(), fromType.getString());
2337+
} else {
2338+
// The conflict is between the declared result type and the
2339+
// contextual type.
2340+
emitDiagnosticAt(
2341+
resultRepr->getStartLoc(),
2342+
diag::incorrect_explicit_closure_result_vs_contextual_type,
2343+
fromType, toType)
2344+
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2345+
}
2346+
23322347
return true;
23332348
}
23342349

test/Constraints/closures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ func rdar52204414() {
996996
let _: () -> Void = { return 42 }
997997
// expected-error@-1 {{cannot convert value of type 'Int' to closure result type 'Void'}}
998998
let _ = { () -> Void in return 42 }
999-
// expected-error@-1 {{declared closure result 'Int' is incompatible with contextual type 'Void'}}
999+
// expected-error@-1 {{declared closure result 'Void' is incompatible with return type 'Int'}} {{19-23=Int}}
10001000
}
10011001

10021002
// SR-12291 - trailing closure is used as an argument to the last (positionally) parameter.

test/Sema/substring_to_string_conversion_swift4.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ do {
4545

4646
// CTP_ClosureResult
4747
do {
48-
[ss].map { (x: Substring) -> String in x } // expected-error {{declared closure result 'Substring' is incompatible with contextual type 'String'}}
48+
[ss].map { (x: Substring) -> String in x } // expected-error {{declared closure result 'String' is incompatible with return type 'Substring'}} {{32-38=Substring}}
4949
}
5050

5151
// CTP_ArrayElement

0 commit comments

Comments
 (0)