@@ -36,7 +36,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
36
36
precondition ( type. isNominal, " non-copyable non-nominal types not supported, yet " )
37
37
38
38
let result : Bool
39
- if type. nominal. hasValueDeinit && !destroy. hasDropDeinit {
39
+ if type. nominal. hasValueDeinit && !destroy. shouldDropDeinit {
40
40
guard let deinitFunc = context. lookupDeinit ( ofNominal: type. nominal) else {
41
41
return false
42
42
}
@@ -58,6 +58,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
58
58
59
59
// Used to dispatch devirtualization tasks to `destroy_value` and `destroy_addr`.
60
60
private protocol DevirtualizableDestroy : UnaryInstruction {
61
+ var shouldDropDeinit : Bool { get }
61
62
func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext )
62
63
func devirtualizeStructFields( _ context: some MutatingContext ) -> Bool
63
64
func devirtualizeEnumPayload( enumCase: EnumCase , in block: BasicBlock , _ context: some MutatingContext ) -> Bool
@@ -67,8 +68,6 @@ private protocol DevirtualizableDestroy : UnaryInstruction {
67
68
private extension DevirtualizableDestroy {
68
69
var type : Type { operand. value. type }
69
70
70
- var hasDropDeinit : Bool { operand. value. lookThoughOwnershipInstructions is DropDeinitInst }
71
-
72
71
func devirtualizeEnumPayloads( _ context: some MutatingContext ) -> Bool {
73
72
guard let cases = type. getEnumCases ( in: parentFunction) else {
74
73
return false
@@ -99,6 +98,8 @@ private extension DevirtualizableDestroy {
99
98
}
100
99
101
100
extension DestroyValueInst : DevirtualizableDestroy {
101
+ fileprivate var shouldDropDeinit : Bool { operand. value. lookThoughOwnershipInstructions is DropDeinitInst }
102
+
102
103
fileprivate func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext ) {
103
104
let builder = Builder ( before: self , context)
104
105
let subs = context. getContextSubstitutionMap ( for: type)
@@ -162,6 +163,11 @@ extension DestroyValueInst : DevirtualizableDestroy {
162
163
}
163
164
164
165
extension DestroyAddrInst : DevirtualizableDestroy {
166
+ fileprivate var shouldDropDeinit : Bool {
167
+ // The deinit is always called by a destroy_addr. There must not be a `drop_deinit` as operand.
168
+ false
169
+ }
170
+
165
171
fileprivate func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext ) {
166
172
let builder = Builder ( before: self , context)
167
173
let subs = context. getContextSubstitutionMap ( for: destroyedAddress. type)
0 commit comments