Skip to content

Commit d76e743

Browse files
Merge pull request #59526 from AnthonyLatsis/closure_result_mismatch_diagQoI
Sema, DiagQoI: Fix and tailor diagnosis of explicit closure result type conflicts
2 parents 8702707 + a07f2b4 commit d76e743

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

23372337
Diag<Type, Type> diagnostic;
2338-
switch (path.back().getKind()) {
2338+
2339+
const auto lastPathEltKind = path.back().getKind();
2340+
switch (lastPathEltKind) {
23392341
case ConstraintLocator::ClosureBody:
23402342
case ConstraintLocator::ClosureResult: {
23412343
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
23422344
if (closure->hasExplicitResultType() &&
23432345
closure->getExplicitResultTypeRepr()) {
23442346
auto resultRepr = closure->getExplicitResultTypeRepr();
2345-
emitDiagnosticAt(resultRepr->getStartLoc(),
2346-
diag::incorrect_explicit_closure_result, fromType,
2347-
toType)
2348-
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2347+
2348+
if (lastPathEltKind == ConstraintLocator::ClosureBody) {
2349+
// The conflict is between the return type and the declared result type.
2350+
emitDiagnosticAt(resultRepr->getStartLoc(),
2351+
diag::incorrect_explicit_closure_result_vs_return_type,
2352+
toType, fromType)
2353+
.fixItReplace(resultRepr->getSourceRange(), fromType.getString());
2354+
} else {
2355+
// The conflict is between the declared result type and the
2356+
// contextual type.
2357+
emitDiagnosticAt(
2358+
resultRepr->getStartLoc(),
2359+
diag::incorrect_explicit_closure_result_vs_contextual_type,
2360+
fromType, toType)
2361+
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2362+
}
2363+
23492364
return true;
23502365
}
23512366

test/Constraints/closures.swift

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

10031003
// 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)