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-13788] Collision between property name and optional objc protocol method call when calling super implementation. #56185

Open
swift-ci opened this issue Oct 29, 2020 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-13788
Radar rdar://problem/70846907
Original Reporter and (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: 86e9235375d9f28057fb808cb05f2265

Issue Description:

Consider the following code:

extension UINavigationController: UINavigationBarDelegate {}
class CustomNavigationController: UINavigationController {
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        return super.navigationBar?(navigationBar, shouldPop: item) ?? true
    }
}

Swift compiler error:

Cannot call value of non-function type 'UINavigationBar'

There seem to be no way to distinguish between the call to one of the methods in `

UINavigationBarDelegate` and `navigationBar` prop.

@typesanitizer
Copy link

Ah, this is a tricky one. When you see a complicated name collision like this, to help the type-checker (as a workaround):

  1. First narrow down the type as much as you can, to reduce the scopes that will be looked up, excluding things that you don't want.

  2. Pick the right protocol method.

extension UINavigationController: UINavigationBarDelegate {}
class CustomNavigationController: UINavigationController {
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        return (self as UINavigationBarDelegate).navigationBar?(navigationBar, shouldPop: item) ?? true
    }
} 

@typesanitizer
Copy link

@swift-ci create

@swift-ci
Copy link
Collaborator Author

Comment by Andrej Mihajlov (JIRA)

theindigamer (JIRA User) what you suggest creates an infinite loop. I need to call `super` & not `self`.

@typesanitizer
Copy link

Oh sorry, made a mistake there. For some reason, using as on super is not permitted, so you can use one level of indirection:

extension UINavigationController: UINavigationBarDelegate {}
extension UINavigationController {
    func customNavigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        return (self as UINavigationBarDelegate).navigationBar?(navigationBar, shouldPop: item) ?? true
    }
}
class CustomNavigationController: UINavigationController {
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        return customNavigationBar(navigationBar, shouldPop: item)
    }
} 

It's not ideal, but it does solve the immediate problem (unless I made an error again).

@swift-ci
Copy link
Collaborator Author

swift-ci commented Nov 3, 2020

Comment by Andrej Mihajlov (JIRA)

theindigamer (JIRA User) unfortunately that doesn't work either. `self` within category points to `CustomNavigationController`, so it creates an infinite recursion once again. The only solution that worked so far was to use method swizzling.

@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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants