swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.61k stars 10.37k forks source link

[SR-12733] The swizzled in method of a final class resolves static references to its type incorrectly since Xcode 11.4 #55178

Open abdulowork opened 4 years ago

abdulowork commented 4 years ago
Previous ID SR-12733
Radar rdar://problem/62895101
Original Reporter @biboran
Type Bug
Environment **Reproducable in Playground, with any platform selected**
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 5343d71f949baac6d34987d9b6effea5

Issue Description:

Since Xcode 11.4 static references to the type within a swizzled in method of a final class will resolve to the class whose method is being replaced. The issue can be reproduced in a Playground with the following code:

import Foundation

class A: NSObject {
    @objc dynamic func foo() {
    }
}

final class B: NSObject {
    @objc func swizzled_foo() {
        print("Swizzled foo in \(B.self)")
    }
}

method_exchangeImplementations(
    class_getInstanceMethod(A.self, #selector(A.foo))!,
    class_getInstanceMethod(B.self, #selector(B.swizzled_foo))!
)

A().foo()

In Xcode 11.3 the output is the expected:

Swizzled foo in B

but since Xcode 11.4 the output is:

Swizzled foo in A

Removing the final modifier from the B declaration resolves the issue.

beccadax commented 4 years ago

@swift-ci create