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-2633] Overload resolution between methods and properties is broken in some cases #45238

Closed
swift-ci opened this issue Sep 14, 2016 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-2633
Radar rdar://problem/28967770
Original Reporter snej (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Xcode 8, macOS 10.12

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug
Assignee snej (JIRA)
Priority Medium

md5: 1dafeda3b6dbaefd94365ed469dc1120

Issue Description:

If a property and a method with the same name exist, then (at least in one circumstance) the compiler interprets a reference to the property as a reference to the method, or rather as a pointer to the method. I can reproduce this in a playground in Xcode 8 like this:

{{
protocol QueryRow {
var key: Any { get }
func key(at index: UInt) -> Any?
}
var row: QueryRow
row.key as? String
}}

This obviously produces an error that 'row' hasn't been initialized yet. But there's also a warning: "cast from '(UInt) -> Any?' to unrelated type 'String' always fails". This implies that the compiler treated `.key` as a reference to the method, not the property. I have not been able to figure out a syntax to use to work around this and get a reference to the property.

This is causing trouble in the real world, because this situation manifests in the (bridged) API of our Objective-C framework Couchbase Lite, when used from Swift 3 (but not earlier). We have a class CBLQueryRow that includes the following:

{{
@Property (readonly) id key;

  • (nullable id) keyAtIndex: (NSUInteger)index;
    }}
    In Swift 3 this becomes
    {{
    open var key: Any { get }
    open func key(at index: UInt) -> Any?
    }}
    which triggers this problem. Here's an actual warning message from the Swift 3 compiler in Xcode 8.0:

{{
TaskListsViewController.swift:95:40: warning: cast from '(UInt) -> Any?' to unrelated type 'String' always fails
cell.textLabel?.text = row.key as? String
~~~~~~~ ^ ~~~~~~
}}
That’s a warning not an error, but obviously at runtime the `as?` would always fail and result in nil.

This is rather bad for us, since the `key` property is a crucial part of our API, while the `key()` method that ends up hiding it it is obscure and little-used.

@swift-ci
Copy link
Collaborator Author

Comment by Jens Alfke (JIRA)

FYI, the initial discussion of this is in a thread on swift-users titled "Method of same name is shadowing a property in Swift 3", starting on 9/13/16 (today).

@rudkx
Copy link
Member

rudkx commented Oct 26, 2016

This is not actually shadowing. What's happening here is that both the property and method are considered by the type checker and it considers the method to be the better choice based on it's current scoring model.

That seems pretty broken considering that the conditional cast from Any to String is a far more reasonable choice than a conditional cast from a function type to a String.

@rudkx
Copy link
Member

rudkx commented Dec 21, 2016

Fixed on master: 170dc8a

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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
Projects
None yet
Development

No branches or pull requests

2 participants