You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
witnesses for an async ObjC protocol requirement cannot be sync
While a Swift protocol can have its async requirements satisfied
by a sync witness, this is not the case for ObjC protocols because
it is not just a calling convention difference.
Because every async ObjC function requirement in the protocol also
has a sibling that is sync, a sync witness might be trying
to conform to the sync version that takes a completion handler.
Without this change, we were seeing an issue where we would
consider both the async and sync versions of an ObjC requirement,
and accidentially choose the async version when the witness was
sync, and then raise an error about the typechecker's mistake.
Instead of raising an error, this change removes the ability for
the typechecker to even consider the errornous conformance.
resolves rdar://73326234
func track(event:String)async // expected-note {{protocol requires function 'track(event:)' with type '(String) async -> ()'; do you want to add a stub?}}
10
+
}
11
+
classDog:NSObject,Tracker{ // expected-error {{type 'Dog' does not conform to protocol 'Tracker'}}
12
+
func track(event:String){} // expected-note {{candidate is not 'async', but @objc protocol requirement is}}
13
+
}
14
+
15
+
// sync objc requirement, async witness
16
+
@objcprotocolRunner{
17
+
func run(event:String) // expected-note {{protocol requires function 'run(event:)' with type '(String) -> ()'; do you want to add a stub?}}
18
+
}
19
+
classAthlete:NSObject,Runner{ // expected-error {{type 'Athlete' does not conform to protocol 'Runner'}}
20
+
func run(event:String)async{} // expected-note {{candidate is 'async', but @objc protocol requirement is not}}
21
+
}
22
+
23
+
24
+
// async swift protocol, sync witness
25
+
protocolSnacker{
26
+
func snack(food:String)async
27
+
}
28
+
29
+
classFoodie:Snacker{
30
+
func snack(food:String){}
31
+
}
32
+
33
+
34
+
// sync swift protocol, async witness
35
+
protocolBacker{
36
+
func back(stonk:String) // expected-note {{protocol requires function 'back(stonk:)' with type '(String) -> ()'; do you want to add a stub?}}
37
+
}
38
+
39
+
classInvestor:Backer{ // expected-error {{type 'Investor' does not conform to protocol 'Backer'}}
40
+
func back(stonk:String)async{} // expected-note {{candidate is 'async', but protocol requirement is not}}
0 commit comments