swiftlang / swift

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

[SR-1016] #selector broken for no-argument initializers and functions #43628

Open swift-ci opened 8 years ago

swift-ci commented 8 years ago
Previous ID SR-1016
Radar rdar://problem/25315833
Original Reporter marc (JIRA User)
Type Bug
Environment Xcode 7.3 / Swift 2.2
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 3 | |Component/s | Compiler | |Labels | Bug | |Assignee | @DougGregor | |Priority | Medium | md5: 5b9028031618d217e4b82fcbe4d30fd1

is duplicated by:

Issue Description:

#selector(init()) does not work:

import UIKit
#selector(UIViewController.init())

// error: argument of '#selector' does not refer to an initializer or method

And using #selector(init) as a workaround does not work if there is more than one initializer:

import UIKit
#selector(UIViewController.init)

// error: ambiguous use of 'init(nibName:bundle:)'
// note: found this candidate
//    public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
// note: found this candidate
//    public init?(coder aDecoder: NSCoder)
// note: found this candidate
//    public convenience init()

The bug affects regular non-argument functions as well.

belkadan commented 8 years ago

You can work around this by using #selector(UIViewController.init as () -> UIViewController).

belkadan commented 8 years ago

cc @DougGregor

swift-ci commented 7 years ago

Comment by Marc Knaup (JIRA)

Still not working in swift-DEVELOPMENT-SNAPSHOT-2017-09-26-a-osx but by now with a different error message:

import UIKit
#selector(UIViewController.init())

// error: argument of '#selector' does not refer to an '@objc' method, property, or initializer

Since init() is inherited from NSObject it should be a valid @objc initializer.

DougGregor commented 7 years ago

Given that this would be a change in the language semantics, it should go through swift-evolution.

swift-ci commented 7 years ago

Comment by Marc Knaup (JIRA)

What would be a change in semantics here?

#selector(NSObject.init()) and #selector(NSObject()) also don't work with the same error, but NSObject's init() is an ObjC initializer, isn't it?

DougGregor commented 7 years ago

Well, it's making some ill-formed code well-formed, and means that the expression

UIViewController.init()

has a different meaning within #selector than it does outside of #selector.

swift-ci commented 7 years ago

Comment by Marc Knaup (JIRA)

I understand. But why is that a problem?

#selector(UIViewController.init()) and alike isn't valid code at the moment anyway and results in a compile error which is not helpful.

The way I understand #selector is that it gives me a Selector to whatever method/initializer/property I put in there. Why should that no-arg example above be treated differently than #selector(UIViewController.init(_:))? Also Swift and Xcode both refer to it as init() for example in #function and in auto-completion. Why would a user expect .init() to be executed but not {{.init(: )}}_?

This is inconsistent and confusing.

To sum it up - the actual issue is still the same:
It's not possible to refer to a zero-argument initializers / methods if there is another initializer / method with the same name. Unless you add a cast to fix the ambiguity.