swiftlang / swift

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

[SR-9774] Forbid the syntax "dynamic static func" #52200

Open swift-ci opened 5 years ago

swift-ci commented 5 years ago
Previous ID SR-9774
Radar None
Original Reporter bang.nguyen (JIRA User)
Type Improvement
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Improvement | |Assignee | None | |Priority | Medium | md5: 836b0a2566d616fb175a8f25b7a2e488

Issue Description:

In both Xcode 9.4 (Swift 4.1.2) and Xcode 10 (Swift 4.2), we can declare a function like this:

@objc dynamic static func test() {

}

Xcode 10, this function will be dynamic dispatch. But in Xcode 9, it's static dispatch. It's confusing. In fact, the syntax "dynamic static", "dynamic private static",... should be forbidden, because a function can't be "dynamic" and "static" at the same time.

Eg: this swizzling code works on Xcode 10 (Swift 4.2) but doesn't work on Xcode 9 (Swift 4.1):

class TestSwizzle {

static func swizzle() {

    let sel1 = \#selector(TestSwizzle.doSomething)

    let sel2 = \#selector(TestSwizzle.swizzled_doSomething)

    let cls: AnyClass = TestSwizzle.self

    guard let m1 = class_getClassMethod(cls, sel1),

        let m2 = class_getClassMethod(cls, sel2) else

{ return assertionFailure() }

    method_exchangeImplementations(m1, m2)

}

@objc dynamic static func doSomething()

{ print("orignal") }

@objc dynamic static func swizzled_doSomething()

{ print("swizzled one") swizzled_doSomething() }

}

belkadan commented 5 years ago

static means class + final in a class context, so it's not entirely unreasonable: "subclasses can't override this, but the implementation for all instances might get changed out at run time". I agree that it looks silly, though, since the two words are normally opposites. Any ideas for how to improve the situation?

belkadan commented 5 years ago

cc @slavapestov

swift-ci commented 5 years ago

Comment by Bang Nguyen (JIRA)

@belkadan but in Xcode 9.4 (Swift 4.1), Swizzling a `dynamic static function` doesn't work (I put an example in the Description). Swizzling successfully, but when we call this function, it doesn't go through Objective C runtime.