[Diagnostics] Improve diagnostics when passing async to a sync parameter

If `async` effect has been inferred from the body of the closure,
let's find out the first occurrence of `async` node and point it out
to make it clear why closure is `async`.

Resolves: rdar://70610141
This commit is contained in:
Pavel Yaskevich
2021-05-03 10:55:49 -07:00
parent 53992d04b6
commit 886a8ab6b7
4 changed files with 34 additions and 5 deletions

View File

@@ -5884,6 +5884,28 @@ bool ThrowingFunctionConversionFailure::diagnoseAsError() {
}
bool AsyncFunctionConversionFailure::diagnoseAsError() {
auto *locator = getLocator();
if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
emitDiagnostic(diag::cannot_pass_async_func_to_sync_parameter,
getFromType());
if (auto *closure = getAsExpr<ClosureExpr>(getAnchor())) {
auto asyncLoc = closure->getAsyncLoc();
// 'async' effect is inferred from the body of the closure.
if (asyncLoc.isInvalid()) {
if (auto asyncNode = findAsyncNode(closure)) {
emitDiagnosticAt(
::getLoc(asyncNode),
diag::async_in_closure_that_does_not_support_concurrency);
}
}
}
return true;
}
emitDiagnostic(diag::async_functiontype_mismatch, getFromType(),
getToType());
return true;