@@ -36,7 +36,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
3636 precondition ( type. isNominal, " non-copyable non-nominal types not supported, yet " )
3737
3838 let result : Bool
39- if type. nominal. hasValueDeinit && !destroy. hasDropDeinit {
39+ if type. nominal. hasValueDeinit && !destroy. shouldDropDeinit {
4040 guard let deinitFunc = context. lookupDeinit ( ofNominal: type. nominal) else {
4141 return false
4242 }
@@ -58,6 +58,7 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
5858
5959// Used to dispatch devirtualization tasks to `destroy_value` and `destroy_addr`.
6060private protocol DevirtualizableDestroy : UnaryInstruction {
61+ var shouldDropDeinit : Bool { get }
6162 func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext )
6263 func devirtualizeStructFields( _ context: some MutatingContext ) -> Bool
6364 func devirtualizeEnumPayload( enumCase: EnumCase , in block: BasicBlock , _ context: some MutatingContext ) -> Bool
@@ -67,8 +68,6 @@ private protocol DevirtualizableDestroy : UnaryInstruction {
6768private extension DevirtualizableDestroy {
6869 var type : Type { operand. value. type }
6970
70- var hasDropDeinit : Bool { operand. value. lookThoughOwnershipInstructions is DropDeinitInst }
71-
7271 func devirtualizeEnumPayloads( _ context: some MutatingContext ) -> Bool {
7372 guard let cases = type. getEnumCases ( in: parentFunction) else {
7473 return false
@@ -99,6 +98,8 @@ private extension DevirtualizableDestroy {
9998}
10099
101100extension DestroyValueInst : DevirtualizableDestroy {
101+ fileprivate var shouldDropDeinit : Bool { operand. value. lookThoughOwnershipInstructions is DropDeinitInst }
102+
102103 fileprivate func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext ) {
103104 let builder = Builder ( before: self , context)
104105 let subs = context. getContextSubstitutionMap ( for: type)
@@ -162,6 +163,11 @@ extension DestroyValueInst : DevirtualizableDestroy {
162163}
163164
164165extension 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+
165171 fileprivate func createDeinitCall( to deinitializer: Function , _ context: some MutatingContext ) {
166172 let builder = Builder ( before: self , context)
167173 let subs = context. getContextSubstitutionMap ( for: destroyedAddress. type)
0 commit comments