Skip to content

Commit b88e678

Browse files
committed
[SE-0306] Disable actor inheritance.
Actor inheritance was removed in the second revision of SE-0306. Remove the ability to inherit actors. Note that this doesn't fully eliminate all vestigates of inheritance from actors. There are simplifications that need to be performed still, e.g., there's no need to distinguish designated/convenience/required initializers. That will follow.
1 parent 7cc19b5 commit b88e678

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)