Skip to content

Commit a886c5f

Browse files
committed
[Concurrency] Prevent extraneous sendability checking when applying nonisolated(nonsending)
`nonisolated(nonsending)` is not presented in interface types which means that references to declarations that have this attribute require a function conversion to apply it. Function conversion checking should detect that and avoid sendability checking for situations like that but there is really no conversion there. (cherry picked from commit ce33100)
1 parent 1880935 commit a886c5f

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,8 @@ namespace {
26832683

26842684
/// Some function conversions synthesized by the constraint solver may not
26852685
/// be correct AND the solver doesn't know, so we must emit a diagnostic.
2686-
void checkFunctionConversion(Expr *funcConv, Type fromType, Type toType) {
2686+
void checkFunctionConversion(ImplicitConversionExpr *funcConv,
2687+
Type fromType, Type toType) {
26872688
auto diagnoseNonSendableParametersAndResult =
26882689
[&](FunctionType *fnType,
26892690
std::optional<unsigned> warnUntilSwiftMode = std::nullopt) {
@@ -2788,6 +2789,18 @@ namespace {
27882789
if (!fromFnType->isAsync())
27892790
break;
27902791

2792+
// Applying `nonisolated(nonsending)` to an interface type
2793+
// of a declaration.
2794+
if (auto *declRef =
2795+
dyn_cast<DeclRefExpr>(funcConv->getSubExpr())) {
2796+
auto *decl = declRef->getDecl();
2797+
if (auto *nonisolatedAttr =
2798+
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2799+
if (nonisolatedAttr->isNonSending())
2800+
return;
2801+
}
2802+
}
2803+
27912804
// @concurrent -> nonisolated(nonsending)
27922805
// crosses an isolation boundary.
27932806
LLVM_FALLTHROUGH;

test/Concurrency/attr_execution/conversions_silgen.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,17 @@ func testSendableClosureNonisolatedNonSendingInference() {
629629
nonisolated(nonsending) @escaping (String) async throws -> String
630630
) async throws -> Void = { _ in }
631631
}
632+
633+
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF : $@convention(thin) () -> ()
634+
// CHECK: [[TEST_REF:%.*]] = function_ref @$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF0D0L_7closureyS2SYaKYCc_tYaYbKF : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String) -> (@owned String, @error any Error)) -> @error any Error
635+
// CHECK: // end sil function '$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF'
636+
func testSendableToSendableConversionWithNonisilatedNonsending() {
637+
@Sendable nonisolated(nonsending) func test(
638+
closure: nonisolated(nonsending) @escaping (String) async throws -> String
639+
) async throws {
640+
}
641+
642+
let _: nonisolated(nonsending) @Sendable (
643+
nonisolated(nonsending) @escaping (String) async throws -> String
644+
) async throws -> Void = test
645+
}

0 commit comments

Comments
 (0)