Skip to content

Commit cf5ab74

Browse files
authored
Merge pull request #82744 from xedin/rdar-154808850-6.2
[6.2][Concurrency] SE-0461: Extend `nonisolated(nonsending)` inference to …
2 parents ca00dc4 + d1a1b2f commit cf5ab74

File tree

4 files changed

+130
-28
lines changed

4 files changed

+130
-28
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4280,8 +4280,15 @@ NeverNullType TypeResolver::resolveASTFunctionType(
42804280
if (!repr->isInvalid())
42814281
isolation = FunctionTypeIsolation::forNonIsolated();
42824282
} else if (!getWithoutClaiming<CallerIsolatedTypeRepr>(attrs)) {
4283-
if (ctx.LangOpts.getFeatureState(Feature::NonisolatedNonsendingByDefault)
4284-
.isEnabledForMigration()) {
4283+
// Infer async function type as `nonisolated(nonsending)` if there is
4284+
// no `@concurrent` or `nonisolated(nonsending)` attribute and isolation
4285+
// is nonisolated.
4286+
if (ctx.LangOpts.hasFeature(Feature::NonisolatedNonsendingByDefault) &&
4287+
repr->isAsync() && isolation.isNonIsolated()) {
4288+
isolation = FunctionTypeIsolation::forNonIsolatedCaller();
4289+
} else if (ctx.LangOpts
4290+
.getFeatureState(Feature::NonisolatedNonsendingByDefault)
4291+
.isEnabledForMigration()) {
42854292
// Diagnose only in the interface stage, which is run once.
42864293
if (inStage(TypeResolutionStage::Interface)) {
42874294
warnAboutNewNonisolatedAsyncExecutionBehavior(ctx, repr, isolation);

test/Concurrency/attr_execution/attr_execution.swift

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,69 @@ func concurrentTest() async {}
1414
// CHECK: sil hidden [ossa] @$s14attr_execution10callerTestyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
1515
nonisolated(nonsending)
1616
func callerTest() async {}
17+
18+
struct Test {
19+
// CHECK-LABEL: // closure #1 in variable initialization expression of Test.x
20+
// CHECK: // Isolation: caller_isolation_inheriting
21+
// CHECK: sil private [ossa] @$s14attr_execution4TestV1xyyYaYCcvpfiyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
22+
var x: () async -> Void = {}
23+
24+
// CHECK-LABEL: // Test.test()
25+
// CHECK: // Isolation: caller_isolation_inheriting
26+
// CHECK: sil hidden [ossa] @$s14attr_execution4TestV4testyyYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed Test) -> ()
27+
// CHECK: bb0([[ISOLATION:%.*]] : @guaranteed $Optional<any Actor>, [[SELF:%.*]] : @guaranteed $Test)
28+
// CHECK: [[X_REF:%.*]] = struct_extract %1, #Test.x
29+
// CHECK: [[X_REF_COPY:%.]] = copy_value [[X_REF]]
30+
// CHECK: [[BORROWED_X:%.*]] = begin_borrow [[X_REF_COPY]]
31+
// CHECK: apply [[BORROWED_X]]([[ISOLATION]]) : $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
32+
// CHECK: } // end sil function '$s14attr_execution4TestV4testyyYaF'
33+
func test() async {
34+
await x()
35+
}
36+
37+
// CHECK-LABEL: // Test.testParam(fn:)
38+
// CHECK: // Isolation: caller_isolation_inheriting
39+
// CHECK: sil hidden [ossa] @$s14attr_execution4TestV9testParam2fnyyyYaYCcSg_tYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed Optional<@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()>, @guaranteed Test) -> ()
40+
// CHECK: bb0([[ISOLATION:%.*]] : @guaranteed $Optional<any Actor>, [[OPT_FN:%.*]] : @guaranteed $Optional<@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()>, [[SELF:%.*]] : @guaranteed $Test)
41+
// CHECK: bb1([[FN:%.*]] : @owned $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ())
42+
// CHECK: [[BORROWED_FN:%.*]] = begin_borrow [[FN]]
43+
// CHECK: apply [[BORROWED_FN]]([[ISOLATION]]) : $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
44+
// CHECK: } // end sil function '$s14attr_execution4TestV9testParam2fnyyyYaYCcSg_tYaF'
45+
func testParam(fn: (() async -> Void)?) async {
46+
await fn?()
47+
}
48+
}
49+
50+
// CHECK-LABEL: // testLocal()
51+
// CHECK: // Isolation: caller_isolation_inheriting
52+
// CHECK: sil hidden [ossa] @$s14attr_execution9testLocalyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
53+
// CHECK: bb0([[ISOLATION:%.*]] : @guaranteed $Optional<any Actor>)
54+
// CHECK: bb1([[FN:%.*]] : @owned $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ())
55+
// CHECK: [[BORROWED_FN:%.*]] = begin_borrow [[FN]]
56+
// CHECK: apply [[BORROWED_FN]]([[ISOLATION]]) : $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
57+
// CHECK: } // end sil function '$s14attr_execution9testLocalyyYaF'
58+
func testLocal() async {
59+
let fn: (() async -> Void)? = nil
60+
await fn?()
61+
}
62+
63+
// CHECK-LABEL: // takesClosure(fn:)
64+
// CHECK: // Isolation: unspecified
65+
// CHECK: sil hidden [ossa] @$s14attr_execution12takesClosure2fnyyyYaYCXE_tF : $@convention(thin) (@guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
66+
func takesClosure(fn: () async -> Void) {
67+
}
68+
69+
// CHECK-LABEL: sil hidden [ossa] @$s14attr_execution11testClosureyyF : $@convention(thin) () -> ()
70+
// CHECK: [[CLOSURE:%.*]] = function_ref @$s14attr_execution11testClosureyyFyyYaYCXEfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
71+
// CHECK: [[THUNKED_CLOSURE:%.*]] = thin_to_thick_function %0 to $@noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
72+
// CHECK: [[TAKES_CLOSURE:%.*]] = function_ref @$s14attr_execution12takesClosure2fnyyyYaYCXE_tF : $@convention(thin) (@guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
73+
// CHECK: apply [[TAKES_CLOSURE]]([[THUNKED_CLOSURE]])
74+
// CHECK: } // end sil function '$s14attr_execution11testClosureyyF'
75+
76+
// CHECK-LABEL: // closure #1 in testClosure()
77+
// CHECK: // Isolation: caller_isolation_inheriting
78+
// CHECK: sil private [ossa] @$s14attr_execution11testClosureyyFyyYaYCXEfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
79+
func testClosure() {
80+
takesClosure {
81+
}
82+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-upcoming-feature NonisolatedNonsendingByDefault %s
2+
3+
// REQUIRES: swift_feature_NonisolatedNonsendingByDefault
4+
5+
func testCasts() {
6+
let defaultedType = (() async -> ()).self
7+
_ = defaultedType as (@concurrent () async -> ()).Type
8+
// expected-error@-1 {{cannot convert value of type '(nonisolated(nonsending) () async -> ()).Type' to type '(() async -> ()).Type' in coercion}}
9+
_ = defaultedType as (nonisolated(nonsending) () async -> ()).Type // Ok
10+
}

0 commit comments

Comments
 (0)