Skip to content

Commit 63e538e

Browse files
Import dealloc method as deinit
1 parent 856a509 commit 63e538e

File tree

11 files changed

+377
-26
lines changed

11 files changed

+377
-26
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,8 @@ struct PrintOptions {
703703
result.SkipPrivateStdlibDecls = true;
704704
result.SkipUnderscoredStdlibProtocols = true;
705705
result.SkipUnsafeCXXMethods = true;
706-
result.SkipDeinit = true;
706+
result.SkipDeinit = false; // Deinit may have isolation attributes, which
707+
// are part of the interface
707708
result.EmptyLineBetweenDecls = true;
708709
result.CascadeDocComment = true;
709710
result.ShouldQualifyNestedDeclarations =

lib/ClangImporter/ImportDecl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5304,6 +5304,22 @@ namespace {
53045304
result->setHasMissingVTableEntries(false);
53055305
result->setMemberLoader(&Impl, 0);
53065306

5307+
// GetDestructorRequest does not trigger lazy member loading
5308+
// And typechecking may ask for destructor before member loading is
5309+
// triggered. Create deinit explicitly
5310+
auto deallocII = &clangCtx.Idents.get("dealloc");
5311+
auto deallocSelector = clangCtx.Selectors.getNullarySelector(deallocII);
5312+
auto deallocName = clang::DeclarationName(deallocSelector);
5313+
for (auto nd : decl->lookup(deallocName)) {
5314+
if (auto deallocDecl = dyn_cast<clang::ObjCMethodDecl>(nd)) {
5315+
if (deallocDecl->isInstanceMethod()) {
5316+
auto loc = Impl.importSourceLoc(deallocDecl->getLocation());
5317+
auto dtor = Impl.createDeclWithClangNode<DestructorDecl>(
5318+
deallocDecl, access, loc, result);
5319+
result->addMember(dtor);
5320+
}
5321+
}
5322+
}
53075323
return result;
53085324
}
53095325

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5082,24 +5082,28 @@ ActorIsolation ActorIsolationRequest::evaluate(
50825082
}
50835083
};
50845084

5085+
auto isolationFromAttr = getIsolationFromAttributes(value);
5086+
50855087
// No need to isolate implicit deinit, unless there is already an isolated one
50865088
// in the superclass
5087-
if (value->isImplicit() && isa<DestructorDecl>(value)) {
5088-
ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit();
5089-
ActorIsolation isolation = ActorIsolation::forUnspecified();
5090-
if (overriddenValue) {
5091-
isolation = getOverriddenIsolationFor(value);
5092-
}
5089+
if (isa<DestructorDecl>(value)) {
5090+
if (value->isImplicit() && !isolationFromAttr) {
5091+
ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit();
5092+
ActorIsolation isolation = ActorIsolation::forUnspecified();
5093+
if (overriddenValue) {
5094+
isolation = getOverriddenIsolationFor(value);
5095+
}
50935096

5094-
if (hasIsolatedSelf && isolation.isUnspecified()) {
5095-
// Don't use 'unspecified' for actors, use 'nonisolated' instead
5096-
// To force generation of the 'nonisolated' attribute in SIL and
5097-
// .swiftmodule
5098-
isolation = ActorIsolation::forNonisolated(false);
5099-
}
5097+
if (hasIsolatedSelf && isolation.isUnspecified()) {
5098+
// Don't use 'unspecified' for actors, use 'nonisolated' instead
5099+
// To force generation of the 'nonisolated' attribute in SIL and
5100+
// .swiftmodule
5101+
isolation = ActorIsolation::forNonisolated(false);
5102+
}
51005103

5101-
addAttributesForActorIsolation(isolation);
5102-
return isolation;
5104+
addAttributesForActorIsolation(isolation);
5105+
return isolation;
5106+
}
51035107
}
51045108

51055109
// If this declaration has actor-isolated "self", it's isolated to that
@@ -5113,7 +5117,9 @@ ActorIsolation ActorIsolationRequest::evaluate(
51135117
if (isa<DestructorDecl>(value) && actor->getName().is("MainActor") &&
51145118
actor->getDeclContext()->isModuleScopeContext() &&
51155119
actor->getDeclContext()->getParentModule()->getABIName().is("Swift")) {
5116-
return ActorIsolation::forUnspecified();
5120+
auto isolation = ActorIsolation::forNonisolated(false);
5121+
addAttributesForActorIsolation(isolation);
5122+
return isolation;
51175123
}
51185124
return ActorIsolation::forActorInstanceSelf(value);
51195125
}
@@ -5192,7 +5198,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
51925198
return isolation;
51935199
};
51945200

5195-
auto isolationFromAttr = getIsolationFromAttributes(value);
51965201
if (isolationFromAttr && isolationFromAttr->preconcurrency() &&
51975202
!value->getAttrs().hasAttribute<PreconcurrencyAttr>()) {
51985203
auto preconcurrency =
@@ -5216,6 +5221,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
52165221
return *mainIsolation;
52175222
}
52185223
}
5224+
52195225
// If this declaration has one of the actor isolation attributes, report
52205226
// that.
52215227
if (isolationFromAttr) {

test/Concurrency/deinit_isolation.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
// Fixtures
88

99
@globalActor final actor FirstActor {
10-
static let shared: FirstActor = FirstActor()
10+
static let shared = FirstActor()
1111
}
1212

1313
@globalActor final actor SecondActor {
14-
static let shared: SecondActor = SecondActor()
14+
static let shared = SecondActor()
1515
}
1616

17+
@globalActor private final actor PrivateActor {
18+
static let shared = PrivateActor()
19+
}
1720

1821
@FirstActor
1922
func isolatedFunc() {} // expected-note 11{{calls to global function 'isolatedFunc()' from outside of its actor context are implicitly asynchronous}}
@@ -432,3 +435,10 @@ class DifferentIsolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor {
432435
}
433436
}
434437

438+
#if !SILGEN
439+
public class PublicIsolatedOnPrivateActor {
440+
// TODO: Both should be producing an error
441+
@PrivateActor public func ababahalamaha() {}
442+
@PrivateActor deinit {}
443+
}
444+
#endif
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
framework module Alpha [system] {
2+
header "Alpha-Swift.h"
3+
requires objc
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import ObjectiveC
2+
3+
@objc open class RoundtripNonisolated: NSObject {}
4+
5+
@objc open class RoundtripIsolated: NSObject {
6+
@MainActor deinit {}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
framework module Beta {
2+
umbrella header "Beta.h"
3+
4+
export *
5+
module * { export * }
6+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@import Foundation;
2+
@import Alpha;
3+
4+
#define MAIN_ACTOR __attribute__((swift_attr("@MainActor")))
5+
6+
@interface BaseNonisolated : NSObject
7+
@end
8+
@interface DerivedNonisolated : BaseNonisolated
9+
@end
10+
11+
MAIN_ACTOR
12+
@interface BaseIsolatedClass : NSObject
13+
@end
14+
@interface DerivedIsolatedClass : BaseIsolatedClass
15+
@end
16+
17+
@interface BaseIsolatedDealloc : NSObject
18+
- (void)dealloc MAIN_ACTOR;
19+
@end
20+
@interface DerivedIsolatedDealloc : BaseIsolatedDealloc
21+
@end
22+
23+
@protocol DeallocP
24+
- (void)dealloc MAIN_ACTOR;
25+
@end
26+
27+
@interface DeallocIsolatedFromProtocol : NSObject <DeallocP>
28+
@end
29+
30+
@interface DeallocIsolatedFromCategory : NSObject
31+
@end
32+
33+
@interface DeallocIsolatedFromCategory (Extra)
34+
- (void)dealloc MAIN_ACTOR;
35+
@end
36+
37+
@interface DeallocIsolatedFromExtension : NSObject
38+
@end
39+
40+
@interface DeallocIsolatedFromExtension ()
41+
- (void)dealloc MAIN_ACTOR;
42+
@end

0 commit comments

Comments
 (0)