Skip to content

Commit 14e5ba6

Browse files
authored
Merge pull request #83545 from tshortli/isolated-deinit-inlining-availability
Sema: Fix isolated deinit availability checking
2 parents 035ede3 + a0cfe64 commit 14e5ba6

File tree

3 files changed

+186
-56
lines changed

3 files changed

+186
-56
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,31 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
114114
return true;
115115
}
116116

117-
void diagnoseIsolatedDeinitInValueTypes(DeclAttribute *attr) {
117+
void checkIsolatedDeinitAttr(DeclAttribute *attr) {
118118
auto &C = D->getASTContext();
119119

120-
if (isa<DestructorDecl>(D)) {
121-
if (auto nominal = dyn_cast<NominalTypeDecl>(D->getDeclContext())) {
122-
if (!isa<ClassDecl>(nominal)) {
123-
// only classes and actors can have isolated deinit.
124-
diagnoseAndRemoveAttr(attr, diag::isolated_deinit_on_value_type);
125-
return;
126-
}
120+
auto destructor = dyn_cast<DestructorDecl>(D);
121+
if (!destructor)
122+
return;
127123

128-
if (!getActorIsolation(nominal).isMainActor()) {
129-
TypeChecker::checkAvailability(
130-
attr->getRange(), C.getIsolatedDeinitAvailability(),
131-
D->getDeclContext(),
132-
[&](AvailabilityDomain domain, AvailabilityRange range) {
133-
return diagnoseAndRemoveAttr(
134-
attr, diag::isolated_deinit_unavailable, domain, range);
135-
});
136-
}
137-
}
124+
auto nominal = dyn_cast<NominalTypeDecl>(D->getDeclContext());
125+
if (!nominal)
126+
return;
127+
128+
if (!isa<ClassDecl>(nominal)) {
129+
// only classes and actors can have isolated deinit.
130+
diagnoseAndRemoveAttr(attr, diag::isolated_deinit_on_value_type);
131+
return;
132+
}
133+
134+
if (!getActorIsolation(nominal).isMainActor() && destructor->hasBody()) {
135+
TypeChecker::checkAvailability(
136+
destructor->getBodySourceRange(), C.getIsolatedDeinitAvailability(),
137+
D->getDeclContext(),
138+
[&](AvailabilityDomain domain, AvailabilityRange range) {
139+
return diagnoseAndRemoveAttr(
140+
attr, diag::isolated_deinit_unavailable, domain, range);
141+
});
138142
}
139143
}
140144

@@ -4736,7 +4740,7 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
47364740
// If the nominal type is a global actor, let the global actor attribute
47374741
// retrieval request perform checking for us.
47384742
if (nominal->isGlobalActor()) {
4739-
diagnoseIsolatedDeinitInValueTypes(attr);
4743+
checkIsolatedDeinitAttr(attr);
47404744
if (auto g = D->getGlobalActorAttr()) {
47414745
checkGlobalActorAttr(D, *g);
47424746
}
@@ -7891,7 +7895,7 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
78917895
}
78927896

78937897
void AttributeChecker::visitIsolatedAttr(IsolatedAttr *attr) {
7894-
diagnoseIsolatedDeinitInValueTypes(attr);
7898+
checkIsolatedDeinitAttr(attr);
78957899
}
78967900

78977901
void AttributeChecker::visitGlobalActorAttr(GlobalActorAttr *attr) {
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 %s -strict-concurrency=complete -target %target-swift-5.1-abi-triple -verify-additional-prefix deployment- -verify-additional-prefix inlining-
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 %s -strict-concurrency=complete -target %target-swift-6.1-abi-triple
3+
// RUN: %target-typecheck-verify-swift -swift-version 5 %s -strict-concurrency=complete -target %target-swift-6.1-abi-triple -target-min-inlining-version min -verify-additional-prefix inlining-
4+
5+
// REQUIRES: concurrency
6+
// REQUIRES: OS=macosx
7+
8+
@MainActor class C {
9+
var x: Int = 0
10+
11+
nonisolated deinit {
12+
print(x)
13+
}
14+
}
15+
16+
@MainActor public class C1 {
17+
var x: Int = 0
18+
19+
nonisolated deinit {
20+
print(x)
21+
}
22+
}
23+
24+
@MainActor class C2 {
25+
var x: Int = 0
26+
27+
isolated deinit { // okay, this back-deploys
28+
print(x)
29+
}
30+
}
31+
32+
@MainActor public class C3 {
33+
var x: Int = 0
34+
35+
isolated deinit { // okay, this back-deploys
36+
print(x)
37+
}
38+
}
39+
40+
41+
@available(SwiftStdlib 5.1, *)
42+
@globalActor
43+
public actor SomeGlobalActor {
44+
public static let shared = SomeGlobalActor()
45+
}
46+
47+
// expected-deployment-note@+1{{add '@available' attribute to enclosing class}}
48+
@SomeGlobalActor class C4 {
49+
var x: Int = 0
50+
51+
isolated deinit { // expected-deployment-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
52+
print(x)
53+
}
54+
}
55+
56+
@available(SwiftStdlib 6.1, *)
57+
@SomeGlobalActor class C5 {
58+
var x: Int = 0
59+
60+
isolated deinit {
61+
print(x)
62+
}
63+
}
64+
65+
@available(SwiftStdlib 5.1, *)
66+
@SomeGlobalActor public class C6 {
67+
var x: Int = 0
68+
69+
isolated deinit { // expected-deployment-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
70+
print(x)
71+
}
72+
}
73+
74+
@available(SwiftStdlib 6.1, *)
75+
@SomeGlobalActor public class C7 {
76+
var x: Int = 0
77+
78+
isolated deinit {
79+
print(x)
80+
}
81+
}
82+
83+
@available(SwiftStdlib 5.1, *)
84+
@_fixed_layout @SomeGlobalActor public class C8 {
85+
@usableFromInline var x: Int = 0
86+
87+
@inlinable isolated deinit { // expected-inlining-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
88+
print(x)
89+
}
90+
}
91+
92+
@available(SwiftStdlib 6.1, *)
93+
@_fixed_layout @SomeGlobalActor public class C9 {
94+
@usableFromInline var x: Int = 0
95+
96+
@inlinable isolated deinit {
97+
print(x)
98+
}
99+
}
100+
101+
// expected-deployment-note@+1{{add '@available' attribute to enclosing actor}}
102+
actor A {
103+
var x: Int = 0
104+
105+
isolated deinit { // expected-deployment-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
106+
print(x)
107+
}
108+
}
109+
110+
@available(SwiftStdlib 5.1, *)
111+
public actor A1 {
112+
var x: Int = 0
113+
114+
isolated deinit { // expected-deployment-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
115+
print(x)
116+
}
117+
}
118+
119+
@available(SwiftStdlib 5.1, *)
120+
public actor A2 {
121+
@usableFromInline var x: Int = 0
122+
123+
@inlinable isolated deinit { // expected-inlining-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
124+
print(x)
125+
}
126+
}
127+
128+
@available(SwiftStdlib 6.1, *)
129+
public actor A3 {
130+
@usableFromInline var x: Int = 0
131+
132+
@inlinable isolated deinit {
133+
print(x)
134+
}
135+
}
136+
137+
@available(SwiftStdlib 6.1, *)
138+
actor A4 {
139+
var x: Int = 0
140+
141+
isolated deinit {
142+
print(x)
143+
}
144+
}
145+
146+
@available(SwiftStdlib 6.1, *)
147+
public actor A5 {
148+
var x: Int = 0
149+
150+
isolated deinit {
151+
print(x)
152+
}
153+
}
154+
155+
@available(SwiftStdlib 6.1, *)
156+
public actor A6 {
157+
@usableFromInline var x: Int = 0
158+
159+
@inlinable isolated deinit {
160+
print(x)
161+
}
162+
}

test/Concurrency/nonisolated_deinit.swift

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)