Commit d3f644a
committed
[SILGen] fix crash invoking global-actor qualified optional ObjC async method
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://976463091 parent bd999a5 commit d3f644a
1 file changed
+43
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1595 | 1595 | | |
1596 | 1596 | | |
1597 | 1597 | | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
| 1630 | + | |
1598 | 1631 | | |
1599 | 1632 | | |
1600 | 1633 | | |
| |||
1608 | 1641 | | |
1609 | 1642 | | |
1610 | 1643 | | |
1611 | | - | |
| 1644 | + | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
| 1651 | + | |
| 1652 | + | |
| 1653 | + | |
1612 | 1654 | | |
1613 | 1655 | | |
1614 | 1656 | | |
| |||
0 commit comments