Skip to content

Commit ce33100

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.
1 parent 40c9674 commit ce33100

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
@@ -2666,7 +2666,8 @@ namespace {
26662666

26672667
/// Some function conversions synthesized by the constraint solver may not
26682668
/// be correct AND the solver doesn't know, so we must emit a diagnostic.
2669-
void checkFunctionConversion(Expr *funcConv, Type fromType, Type toType) {
2669+
void checkFunctionConversion(ImplicitConversionExpr *funcConv,
2670+
Type fromType, Type toType) {
26702671
auto diagnoseNonSendableParametersAndResult =
26712672
[&](FunctionType *fnType,
26722673
std::optional<unsigned> warnUntilSwiftMode = std::nullopt) {
@@ -2771,6 +2772,18 @@ namespace {
27712772
if (!fromFnType->isAsync())
27722773
break;
27732774

2775+
// Applying `nonisolated(nonsending)` to an interface type
2776+
// of a declaration.
2777+
if (auto *declRef =
2778+
dyn_cast<DeclRefExpr>(funcConv->getSubExpr())) {
2779+
auto *decl = declRef->getDecl();
2780+
if (auto *nonisolatedAttr =
2781+
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2782+
if (nonisolatedAttr->isNonSending())
2783+
return;
2784+
}
2785+
}
2786+
27742787
// @concurrent -> nonisolated(nonsending)
27752788
// crosses an isolation boundary.
27762789
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)