Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-7301] Bad fixit suggested for protocol extension implementation for inherited objc protocol #49849

Open
swift-ci opened this issue Mar 28, 2018 · 11 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself good first issue Good for newcomers

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-7301
Radar None
Original Reporter kdawgwilk (JIRA User)
Type Bug

Attachment: Download

Environment

Xcode 9.2

Swift 4

macOS 10.13.3

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, StarterBug
Assignee None
Priority Medium

md5: f483fe309b1876278257725a1dc2b1b5

relates to:

  • SR-3349 @objc methods cannot be contained in protocol extensions

Issue Description:

I have the following code that has a compiler error

@objc protocol IntroAnimationController: UIViewControllerAnimatedTransitioning {
    func frame(for view: UIView, fromView: UIView) -> CGRect
    func animations(fromView: UIView, toView: UIView) -> () -> Void
}

extension IntroAnimationController {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.20
    }
}

The error says:

![](Screen Shot 2018-03-28 at 3.47.33 PM.png)

and includes a fixit that that turns my code into this:

extension IntroAnimationController {
    @objc(transitionDuration:) func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.20
    }
}

And then gives me these two wonderful new errors:

![](Screen Shot 2018-03-28 at 3.46.32 PM.png)

None of the fixits are helpful and the error message does not give me any clue why I can't do this

@swift-ci
Copy link
Collaborator Author

Comment by Kaden Wilkinson (JIRA)

Also get the same fixits using Xcode 9.3 beta 4

@belkadan
Copy link
Contributor

Yep, this just isn't possible, and we shouldn't offer the fix-it. (It's not possible because Objective-C doesn't have a way to add a method to every adopter of a protocol.)

@swift-ci
Copy link
Collaborator Author

Comment by Tapan Thaker (JIRA)

Taking this up

@swift-ci
Copy link
Collaborator Author

Comment by Tapan Thaker (JIRA)

The above code compiles fine on `Apple Swift version 4.1` from Xcode 9.3. Not sure what changed the behaviour.

@belkadan
Copy link
Contributor

I think Swift 4.1 just ignored the extension method, rather than complaining that it was a near-match. The intended change here is that the note and fix-it are not offered if the method is defined on a protocol extension.

@swift-ci
Copy link
Collaborator Author

Comment by Tapan Thaker (JIRA)

The compilation also fails on Swift 4.1 as soon as we make a ViewController conform to a protocol.
Like the code below:

class CustomViewController: UIViewController, IntroAnimationController {
func frame(for view: UIView, fromView: UIView) -> CGRect { return CGRect(x: 0, y: 0, width: 0, height: 0) }

func animations(fromView: UIView, toView: UIView) -> () -> Void {
let x : () -> Void = {
}
return x
}

public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {}
}

I think all we need to do is delete the following:
https://github.com/apple/swift/blob/master/lib/AST/ASTContext.cpp#L2297-L2328
Also, couldn't find any tests for this.

@belkadan
Copy link
Contributor

In that case the fix-it is correct, no?

@swift-ci
Copy link
Collaborator Author

Comment by Tapan Thaker (JIRA)

No, the fix-it doesn't seem to be correct. Once you apply the fix-it, you get into the same problem of 2 new errors
I think the problem is just that @objc protocol can never have extensions. So if we emit a diagnostic for that it would make more sense.

A simpler code snippet for reproducing the issue:

import Foundation

@objc protocol Print {
    func log(message string: NSString)
}

extension Print {
    func log(message string: NSString) {
        print(string)
    }
}

class CustomClass: NSObject, Print { }

@belkadan
Copy link
Contributor

It's totally fine for an @objc protocol to have extensions; what's not valid is to use those extensions to satisfy the requirements. You get the same bad fix-it if the requirement is declared in one protocol but the default implementation comes from another.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 1, 2018

Comment by Suyash Shekhar (JIRA)

tt (JIRA User) Are you still working on this? If not I would like to give it a shot 🙂

@belkadan
Copy link
Contributor

Resetting assignee for all Starter Bugs not modified since 2018.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants