Skip to content

Commit 154cde1

Browse files
Merge pull request #59596 from AnthonyLatsis/5.7-closure_result_mismatch_diagQoI
🍒 [5.7] Sema, DiagQoI: Fix and tailor diagnosis of explicit closure result type conflicts
2 parents fc85f1b + b5a64d6 commit 154cde1

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
@@ -2323,17 +2323,32 @@ bool ContextualFailure::diagnoseAsError() {
23232323
auto toType = getToType();
23242324

23252325
Diag<Type, Type> diagnostic;
2326-
switch (path.back().getKind()) {
2326+
2327+
const auto lastPathEltKind = path.back().getKind();
2328+
switch (lastPathEltKind) {
23272329
case ConstraintLocator::ClosureBody:
23282330
case ConstraintLocator::ClosureResult: {
23292331
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
23302332
if (closure->hasExplicitResultType() &&
23312333
closure->getExplicitResultTypeRepr()) {
23322334
auto resultRepr = closure->getExplicitResultTypeRepr();
2333-
emitDiagnosticAt(resultRepr->getStartLoc(),
2334-
diag::incorrect_explicit_closure_result, fromType,
2335-
toType)
2336-
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2335+
2336+
if (lastPathEltKind == ConstraintLocator::ClosureBody) {
2337+
// The conflict is between the return type and the declared result type.
2338+
emitDiagnosticAt(resultRepr->getStartLoc(),
2339+
diag::incorrect_explicit_closure_result_vs_return_type,
2340+
toType, fromType)
2341+
.fixItReplace(resultRepr->getSourceRange(), fromType.getString());
2342+
} else {
2343+
// The conflict is between the declared result type and the
2344+
// contextual type.
2345+
emitDiagnosticAt(
2346+
resultRepr->getStartLoc(),
2347+
diag::incorrect_explicit_closure_result_vs_contextual_type,
2348+
fromType, toType)
2349+
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2350+
}
2351+
23372352
return true;
23382353
}
23392354

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)