Skip to content

Commit ef570d1

Browse files
authored
Merge pull request #41226 from xedin/rdar-88256059
[CSDiagnostics] Diagnose ambiguous empty closures
2 parents 67628b7 + 94188b8 commit ef570d1

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ ERROR(cannot_infer_closure_parameter_type,none,
274274
(StringRef))
275275
ERROR(cannot_infer_closure_type,none,
276276
"unable to infer closure type in the current context", ())
277+
ERROR(cannot_infer_empty_closure_result_type,none,
278+
"cannot infer return type of empty closure", ())
277279
ERROR(cannot_infer_closure_result_type,none,
278280
"cannot infer return type for closure with multiple statements; "
279281
"add explicit type to disambiguate", ())

include/swift/Sema/CSFix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,10 @@ class SpecifyClosureReturnType final : public ConstraintFix {
23352335

23362336
bool diagnose(const Solution &solution, bool asNote = false) const override;
23372337

2338+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
2339+
return diagnose(*commonFixes.front().first);
2340+
}
2341+
23382342
static SpecifyClosureReturnType *create(ConstraintSystem &cs,
23392343
ConstraintLocator *locator);
23402344

lib/Sema/CSDiagnostics.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7054,6 +7054,20 @@ bool UnableToInferClosureParameterType::diagnoseAsError() {
70547054
bool UnableToInferClosureReturnType::diagnoseAsError() {
70557055
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
70567056

7057+
auto *body = closure->getBody();
7058+
// For empty closures, let's produce a tailored message and suggest
7059+
// adding an expression to the body.
7060+
if (body->empty()) {
7061+
auto diagnostic =
7062+
emitDiagnostic(diag::cannot_infer_empty_closure_result_type);
7063+
7064+
diagnostic.fixItInsertAfter(closure->getInLoc().isValid()
7065+
? closure->getInLoc()
7066+
: body->getLBraceLoc(),
7067+
"<#result#>");
7068+
return true;
7069+
}
7070+
70577071
auto diagnostic = emitDiagnostic(diag::cannot_infer_closure_result_type);
70587072

70597073
// If there is a location for an 'in' token, then the argument list was
@@ -7068,7 +7082,7 @@ bool UnableToInferClosureReturnType::diagnoseAsError() {
70687082
//
70697083
// As such, we insert " () -> ReturnType in " right after the '{' that
70707084
// starts the closure body.
7071-
diagnostic.fixItInsertAfter(closure->getBody()->getLBraceLoc(),
7085+
diagnostic.fixItInsertAfter(body->getLBraceLoc(),
70727086
diag::insert_closure_return_type_placeholder,
70737087
/*argListSpecified=*/true);
70747088
}

0 commit comments

Comments
 (0)