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
Due to some changes in how the AST is constructed by CSApply to handle
global actors from @preconcurrency declarations, the AST for a force-call to
an optional ObjC method that is part of a global-actor qualified protocol, such as:
```
import Foundation
@mainactor@objc protocol P {
@objc optional func generateMaybe() async
}
extension P {
func test() async -> Void {
await self.generateMaybe!()
}
}
```
now contains a function conversion in between the forced-value operation and the dynamic-ref:
```
(force_value_expr type='@mainactor () async -> ()'
(optional_evaluation_expr implicit type='(@mainactor () async -> ())?'
(inject_into_optional implicit type='(@mainactor () async -> ())?'
(function_conversion_expr implicit type='@mainactor () async -> ()' <<<<< new!
(bind_optional_expr implicit type='() async -> ()'
(dynamic_member_ref_expr type='(() async -> ())?' ... )))))
```
For compatibility with how ObjC does message sends to these optional methods, in Swift there
is a difference between how something like `a.method!()` and the following are compiled:
```
let meth = a.method!
meth()
```
The former will directly call the optional method and let the "unknown selector" error be emitted
if it's not implemented. But the latter will query the dynamic method and inject that result into an
`Optional<...>` to then be forced, yielding a "force-unwrap nil" error. It's a subtle difference but
those two scenarios lead to different code paths in SILGen.
Now, this patch fixes the issue by enhancing the recognition of these direct call scenarios so that it
can look past these function conversions. Because that recognition already tries to ignore implicit
conversions, this is not something new. The problem was that we weren't considering implicit conversions
between the optional-evaluation and bind-optional expressions.
This patch is intentionally precise about what kind of function conversions can be skipped, because I
do not know if all of them are OK to blindly skip or not. We might need to expand that in the future.
Resolves rdar://97646309
0 commit comments