Skip to content

Commit 02821fd

Browse files
authored
Merge pull request #37053 from DougGregor/disable-actor-inheritance
2 parents c9b880d + b88e678 commit 02821fd

14 files changed

+22
-203
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4351,8 +4351,8 @@ NOTE(objc_ambiguous_async_convention_candidate,none,
43514351
ERROR(async_objc_dynamic_self,none,
43524352
"asynchronous method returning 'Self' cannot be '@objc'", ())
43534353

4354-
ERROR(actor_with_nonactor_superclass,none,
4355-
"actor cannot inherit from non-actor class %0", (DeclName))
4354+
ERROR(actor_inheritance,none,
4355+
"actor types do not support inheritance", ())
43564356

43574357
ERROR(actor_isolated_non_self_reference,none,
43584358
"actor-isolated %0 %1 can only be %select{referenced|mutated|used 'inout'}3 "

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -270,32 +270,8 @@ bool IsActorRequest::evaluate(
270270
if (!classDecl)
271271
return false;
272272

273-
bool isExplicitActor = classDecl->isExplicitActor() ||
274-
classDecl->getAttrs().getAttribute<ActorAttr>();
275-
276-
// If there is a superclass, we can infer actor-ness from it.
277-
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
278-
// The superclass is an actor, so we are, too.
279-
if (superclassDecl->isActor())
280-
return true;
281-
282-
// The superclass is 'NSObject', which is known to have no state and no
283-
// superclass.
284-
if (superclassDecl->isNSObject() && isExplicitActor)
285-
return true;
286-
287-
// This class cannot be an actor; complain if the 'actor' modifier was
288-
// provided.
289-
if (isExplicitActor) {
290-
classDecl->diagnose(diag::actor_with_nonactor_superclass,
291-
superclassDecl->getName())
292-
.highlight(classDecl->getStartLoc());
293-
}
294-
295-
return false;
296-
}
297-
298-
return isExplicitActor;
273+
return classDecl->isExplicitActor() ||
274+
classDecl->getAttrs().getAttribute<ActorAttr>();
299275
}
300276

301277
bool IsDefaultActorRequest::evaluate(
@@ -305,21 +281,6 @@ bool IsDefaultActorRequest::evaluate(
305281
if (!classDecl->isActor())
306282
return false;
307283

308-
// If there is a superclass, and it's an actor, we defer
309-
// the decision to it.
310-
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
311-
// If the superclass is an actor, we inherit its default-actor-ness.
312-
if (superclassDecl->isActor())
313-
return superclassDecl->isDefaultActor();
314-
315-
// If the superclass is not an actor, it can only be
316-
// a default actor if it's NSObject. (For now, other classes simply
317-
// can't be actors at all.) We don't need to diagnose this; we
318-
// should've done that already in isActor().
319-
if (!superclassDecl->isNSObject())
320-
return false;
321-
}
322-
323284
// If the class is resilient from the perspective of the module
324285
// module, it's not a default actor.
325286
if (classDecl->isForeign() || classDecl->isResilient(M, expansion))

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,6 +2314,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23142314
// Check for circular inheritance.
23152315
(void)CD->getSuperclassDecl();
23162316

2317+
if (auto superclass = CD->getSuperclassDecl()) {
2318+
// Actors cannot have superclasses, nor can they be superclasses.
2319+
if (CD->isActor() && !superclass->isNSObject())
2320+
CD->diagnose(diag::actor_inheritance);
2321+
else if (superclass->isActor())
2322+
CD->diagnose(diag::actor_inheritance);
2323+
}
2324+
23172325
// Force lowering of stored properties.
23182326
(void) CD->getStoredProperties();
23192327

test/Concurrency/actor_isolation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class Point {
4848
}
4949

5050
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
51-
actor MyActor: MySuperActor {
51+
actor MyActor: MySuperActor { // expected-error{{actor types do not support inheritance}}
5252
nonisolated let immutable: Int = 17
5353
// expected-note@+2 2{{property declared here}}
5454
// expected-note@+1 6{{mutation of this property is only permitted within the actor}}

test/Concurrency/async_initializer.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ actor A {
9191
}
9292
}
9393

94-
// NOTE: actor inheritance is probably being removed soon, so just remove this def of B
95-
actor B: A {
94+
actor B: A { // expected-error{{actor types do not support inheritance}}
9695
init(x : String) async {} // expected-error {{missing call to superclass's initializer; 'super.init' is 'async' and requires an explicit call}}
9796
}
9897

test/Concurrency/global_actor_inference.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ actor GenericSuper<T> {
173173
@GenericGlobalActor<T> func method5() { }
174174
}
175175

176-
actor GenericSub<T> : GenericSuper<[T]> {
176+
actor GenericSub<T> : GenericSuper<[T]> { // expected-error{{actor types do not support inheritance}}
177177
override func method() { } // expected-note {{calls to instance method 'method()' from outside of its actor context are implicitly asynchronous}}
178178

179179
@GenericGlobalActor<T> override func method2() { } // expected-error{{global actor 'GenericGlobalActor<T>'-isolated instance method 'method2()' has different actor isolation from global actor 'GenericGlobalActor<[T]>'-isolated overridden declaration}}

test/IRGen/actor_class_forbid_objc_assoc_objects.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ final actor Actor {
1515
actor Actor2 {
1616
}
1717

18-
// CHECK: @_METACLASS_DATA__TtC37actor_class_forbid_objc_assoc_objects6Actor3 = internal constant { {{.*}} } { i32 [[METAFLAGS]],
19-
// CHECK: @_DATA__TtC37actor_class_forbid_objc_assoc_objects6Actor3 = internal constant { {{.*}} } { i32 [[OBJECTFLAGS]],
20-
class Actor3 : Actor2 {}
21-
2218
actor GenericActor<T> {
2319
var state: T
2420
init(state: T) { self.state = state }

test/IRGen/async/Inputs/resilient_actor.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ open actor ResilientBaseActor {
22
public init() {}
33
}
44

5-
@_fixed_layout
6-
open actor FixedSubclassOfResilientBaseActor : ResilientBaseActor {
7-
public override init() {}
8-
}
9-
105
@_fixed_layout
116
open actor FixedBaseActor {
127
public init() {}

test/IRGen/async/default_actor.swift

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,10 @@
88
// 0x81010050: the same, but using a singleton metadata initialization
99
// CHECK-SAME: i32 {{-2130706352|-2130640816}},
1010

11-
// CHECK: @"$s13default_actor1BCMn" = hidden constant
12-
// 0x62010050: 0x02000000 IndirectTypeDescriptor + 0x01000000 IsDefaultActor
13-
// CHECK-SAME: i32 1644232784,
14-
15-
// CHECK: @"$s13default_actor1CCMn" = hidden constant
16-
// 0x62010050: 0x02000000 IndirectTypeDescriptor + 0x01000000 IsDefaultActor
17-
// CHECK-SAME: i32 1644232784,
18-
19-
// CHECK: @"$s13default_actor1DCMn" = hidden constant
20-
// 0x63010050: 0x02000000 IndirectTypeDescriptor + 0x01000000 IsDefaultActor
21-
// CHECK-SAME: i32 1661010000,
22-
2311
import resilient_actor
2412

2513
// CHECK-LABEL: define hidden swiftcc void @"$s13default_actor1ACfD"(%T13default_actor1AC* swiftself %0)
2614
// CHECK-NOT: ret void
2715
// CHECK: call swiftcc void @swift_defaultActor_deallocate(
2816
// CHECK: ret void
2917
actor A {}
30-
31-
// CHECK-LABEL: define hidden swiftcc void @"$s13default_actor1BCfD"(%T13default_actor1BC* swiftself %0)
32-
// CHECK-NOT: ret void
33-
// CHECK: call swiftcc void @swift_defaultActor_deallocateResilient(
34-
// CHECK: ret void
35-
actor B : ResilientBaseActor {}
36-
37-
// CHECK-LABEL: define hidden swiftcc void @"$s13default_actor1CCfD"(%T13default_actor1CC* swiftself %0)
38-
// CHECK-NOT: ret void
39-
// CHECK: call swiftcc void @swift_defaultActor_deallocateResilient(
40-
// CHECK: ret void
41-
actor C : FixedSubclassOfResilientBaseActor {}
42-
43-
// CHECK-LABEL: define hidden swiftcc void @"$s13default_actor1DCfD"(%T13default_actor1DC* swiftself %0)
44-
// CHECK-NOT: ret void
45-
// CHECK: call swiftcc void @swift_defaultActor_deallocate(
46-
// CHECK: ret void
47-
actor D : FixedBaseActor {}

test/Interpreter/actor_class_forbid_objc_assoc_objects.swift

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -44,48 +44,6 @@ if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
4444
}
4545
}
4646

47-
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
48-
class Actor3 : Actor2 {}
49-
50-
if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
51-
Tests.test("non-final subclass crash when set assoc object")
52-
.crashOutputMatches("objc_setAssociatedObject called on instance")
53-
.code {
54-
expectCrashLater()
55-
let x = Actor3()
56-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
57-
}
58-
}
59-
60-
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
61-
final class Actor3Final : Actor2 {}
62-
63-
if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
64-
Tests.test("final subclass crash when set assoc object")
65-
.crashOutputMatches("objc_setAssociatedObject called on instance")
66-
.code {
67-
expectCrashLater()
68-
let x = Actor3Final()
69-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
70-
}
71-
}
72-
73-
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
74-
class Actor4<T> : Actor2 {
75-
var state: T
76-
init(state: T) { self.state = state }
77-
}
78-
79-
if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
80-
Tests.test("generic subclass crash when set assoc object")
81-
.crashOutputMatches("objc_setAssociatedObject called on instance")
82-
.code {
83-
expectCrashLater()
84-
let x = Actor4(state: 5)
85-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
86-
}
87-
}
88-
8947
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
9048
actor Actor5<T> {
9149
var state: T
@@ -110,50 +68,6 @@ if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
11068
}
11169
}
11270

113-
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
114-
class Actor6<T> : Actor5<T> {
115-
override init(state: T) { super.init(state: state) }
116-
}
117-
118-
if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
119-
Tests.test("sub-generic class base generic class crash when set assoc object")
120-
.crashOutputMatches("objc_setAssociatedObject called on instance")
121-
.code {
122-
expectCrashLater()
123-
let x = Actor6(state: 5)
124-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
125-
}
126-
}
127-
128-
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
129-
final class Actor6Final<T> : Actor5<T> {
130-
override init(state: T) { super.init(state: state) }
131-
}
132-
133-
if #available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *) {
134-
Tests.test("final sub-generic class base generic class crash when set assoc object")
135-
.crashOutputMatches("objc_setAssociatedObject called on instance")
136-
.code {
137-
expectCrashLater()
138-
let x = Actor6Final(state: 5)
139-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
140-
}
141-
142-
Tests.test("final sub-generic class base generic class crash when set assoc object2")
143-
.code {
144-
let x = Actor6Final(state: 5)
145-
print(type(of: x))
146-
}
147-
148-
Tests.test("final sub-generic class metatype, base generic class crash when set assoc object")
149-
.crashOutputMatches("objc_setAssociatedObject called on instance")
150-
.code {
151-
expectCrashLater()
152-
let x = Actor6Final<Int>.self
153-
objc_setAssociatedObject(x, "myKey", "myValue", .OBJC_ASSOCIATION_RETAIN)
154-
}
155-
}
156-
15771
@available(macOS 10.4.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)
15872
actor ActorNSObjectSubKlass : NSObject {}
15973

test/Interpreter/actor_subclass_metatypes.swift

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,3 @@ Tests.test("base generic class")
2626
let x = Actor5(state: 5)
2727
print(type(of: x))
2828
}
29-
30-
class Actor6<T> : Actor5<T> {
31-
override init(state: T) { super.init(state: state) }
32-
}
33-
34-
Tests.test("non-final sub-generic class parent generic class crash")
35-
.code {
36-
let x = Actor6(state: 5)
37-
print(type(of: x))
38-
}
39-
40-
final class Actor6Final<T> : Actor5<T> {
41-
override init(state: T) { super.init(state: state) }
42-
}
43-
44-
Tests.test("final sub-generic class parent generic class crash")
45-
.code {
46-
let x = Actor6Final(state: 5)
47-
print(type(of: x))
48-
}

test/ModuleInterface/actor_isolation.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,3 @@ public class C2 { }
3838

3939
// CHECK: @{{(Test.)?}}SomeGlobalActor public class C2
4040
public class C3: C2 { }
41-
42-
// CHECK: public actor SomeSubActor
43-
// CHECK-NEXT: @actorIndependent public func maine()
44-
public actor SomeSubActor: SomeActor {
45-
override public func maine() { }
46-
}

test/decl/class/actor/basic.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44

55
actor MyActor { }
66

7-
class MyActorSubclass1: MyActor { }
7+
class MyActorSubclass1: MyActor { } // expected-error{{actor types do not support inheritance}}
8+
// expected-error@-1{{non-final class 'MyActorSubclass1' cannot conform to `Sendable`; use `UnsafeSendable`}}
89

9-
actor MyActorSubclass2: MyActor { }
10+
actor MyActorSubclass2: MyActor { } // expected-error{{actor types do not support inheritance}}
1011

1112
// expected-warning@+1{{'actor class' has been renamed to 'actor'}}{{7-13=}}
1213
actor class MyActorClass { }
1314

1415
class NonActor { }
1516

16-
actor NonActorSubclass : NonActor { } // expected-error{{actor cannot inherit from non-actor class 'NonActor'}}
17+
actor NonActorSubclass : NonActor { } // expected-error{{actor types do not support inheritance}}
1718

1819
// expected-warning@+1{{'actor class' has been renamed to 'actor'}}{{14-20=}}
1920
public actor class BobHope {}

test/decl/protocol/special/Actor.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ actor A3<T>: Actor {
1919
}
2020

2121
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
22-
actor A4: A1 {
22+
actor A4: A1 { // expected-error{{actor types do not support inheritance}}
2323
}
2424

2525
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
26-
actor A5: A2 {
26+
actor A5: A2 { // expected-error{{actor types do not support inheritance}}
2727
}
2828

2929
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
3030
actor A6: A1, Actor { // expected-error{{redundant conformance of 'A6' to protocol 'Actor'}}
3131
// expected-note@-1{{'A6' inherits conformance to protocol 'Actor' from superclass here}}
32+
// expected-error@-2{{actor types do not support inheritance}}
3233
}
3334

3435
// Explicitly satisfying the requirement.

0 commit comments

Comments
 (0)