Skip to content

Commit 6a063a2

Browse files
committed
clarify assertion comment: some actor members can be @objc.
An actor can have @objc members, but not if those members are "actor-isolated", i.e., not accessible from outside the actor according to the fundamental design of actors. For example, a sync function is considered actor-isolated since it needs special protection, so it cannot be @objc. But, we now have special capabilities to treat sync actor functions as implicitly async at use-sites outside of the actor. Does this mean that we can now allow sync actor functions to be @objc? No. Because the implicitly-async functionality does not extend to the world of ObjC: it simply would not be feasible to implement it there. Thus, I've added some extra regression-test coverage to handle these cases, and clarified the assertion here to not confuse others.
1 parent b03d921 commit 6a063a2

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,7 @@ RValue RValueEmitter::visitMemberRefExpr(MemberRefExpr *e,
21982198

21992199
RValue RValueEmitter::visitDynamicMemberRefExpr(DynamicMemberRefExpr *E,
22002200
SGFContext C) {
2201-
assert(!E->isImplicitlyAsync() && "actors do not have @objc members");
2201+
assert(!E->isImplicitlyAsync() && "an actor-isolated @objc member?");
22022202
return SGF.emitDynamicMemberRefExpr(E, C);
22032203
}
22042204

@@ -2220,7 +2220,7 @@ RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
22202220

22212221
RValue RValueEmitter::visitDynamicSubscriptExpr(
22222222
DynamicSubscriptExpr *E, SGFContext C) {
2223-
assert(!E->isImplicitlyAsync() && "actors do not have @objc members");
2223+
assert(!E->isImplicitlyAsync() && "an actor-isolated @objc member?");
22242224
return SGF.emitDynamicSubscriptExpr(E, C);
22252225
}
22262226

test/Concurrency/actor_isolation_objc.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,31 @@ actor A {
1616
func keypaths() {
1717
_ = #keyPath(A.x) // expected-error{{argument of '#keyPath' refers to non-'@objc' property 'x'}}
1818
_ = #keyPath(A.y) // expected-error{{argument of '#keyPath' refers to non-'@objc' property 'y'}}
19+
_ = #keyPath(A.computed) // expected-error{{argument of '#keyPath' refers to non-'@objc' property 'computed'}}
1920
_ = #keyPath(A.z)
2021
}
2122

2223
var x: Int = 0 // expected-note{{add '@objc' to expose this property to Objective-C}}
24+
2325
@objc var y: Int = 0 // expected-note{{add '@objc' to expose this property to Objective-C}}
2426
// expected-error@-1{{actor-isolated property 'y' cannot be @objc}}
27+
2528
@objc @actorIndependent(unsafe) var z: Int = 0
2629

30+
// expected-note@+1 {{add '@objc' to expose this property to Objective-C}}
31+
@objc var computed : Int { // expected-error{{actor-isolated property 'computed' cannot be @objc}}
32+
get { 120 }
33+
}
34+
2735
func f() { } // expected-note{{add '@objc' to expose this instance method to Objective-C}}
2836
func g() { } // expected-note{{add '@objc' to expose this instance method to Objective-C}}
2937
@objc func h() async { }
38+
39+
@objc @asyncHandler func i() {}
40+
}
41+
42+
func outside(a : A) async {
43+
await a.i() // expected-warning {{no 'async' operations occur within 'await' expression}}
3044
}
3145

3246

0 commit comments

Comments
 (0)