Skip to content

Commit 8ed2e05

Browse files
committed
[concurrency] Eliminate a double error emission caused by erroring on an autoclosure and the callexpr it calls.
Specifically, when one is emitting a non-Sendable diagnostic for an async let, we will emit an error both for the async let and for the call expr inside the async let. This just puts in a check so that we do not emit the error for the autoclosure if we can show that the autoclosure's child subexpr would have the same type implying we would also emit the same error.
1 parent e3197e9 commit 8ed2e05

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,15 +3539,36 @@ namespace {
35393539
// Check for sendability of the result type if we do not have a
35403540
// transferring result.
35413541
if ((!ctx.LangOpts.hasFeature(Feature::TransferringArgsAndResults) ||
3542-
!fnType->hasTransferringResult()) &&
3543-
diagnoseNonSendableTypes(
3544-
fnType->getResult(), getDeclContext(),
3545-
/*inDerivedConformance*/Type(),
3546-
apply->getLoc(),
3547-
diag::non_sendable_call_result_type,
3548-
apply->isImplicitlyAsync().has_value(),
3549-
*unsatisfiedIsolation))
3550-
return true;
3542+
!fnType->hasTransferringResult())) {
3543+
// See if we are a autoclosure that has a direct callee that has the
3544+
// same non-transferred type value returned. If so, do not emit an
3545+
// error... we are going to emit an error on the call expr and do not
3546+
// want to emit the error twice.
3547+
auto willDoubleError = [&]() -> bool {
3548+
auto *autoclosure = dyn_cast<AutoClosureExpr>(apply->getFn());
3549+
if (!autoclosure)
3550+
return false;
3551+
auto *await =
3552+
dyn_cast<AwaitExpr>(autoclosure->getSingleExpressionBody());
3553+
if (!await)
3554+
return false;
3555+
auto *subCallExpr = dyn_cast<CallExpr>(await->getSubExpr());
3556+
if (!subCallExpr)
3557+
return false;
3558+
return subCallExpr->getType().getPointer() ==
3559+
fnType->getResult().getPointer();
3560+
};
3561+
3562+
if (!willDoubleError() &&
3563+
diagnoseNonSendableTypes(fnType->getResult(), getDeclContext(),
3564+
/*inDerivedConformance*/ Type(),
3565+
apply->getLoc(),
3566+
diag::non_sendable_call_result_type,
3567+
apply->isImplicitlyAsync().has_value(),
3568+
*unsatisfiedIsolation)) {
3569+
return true;
3570+
}
3571+
}
35513572

35523573
return false;
35533574
}

0 commit comments

Comments
 (0)