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-10443] Dynamic dispatch is sometimes ignored when passing a subclass object to a function that takes a protocol argument #52843

Closed
swift-ci opened this issue Apr 10, 2019 · 1 comment
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-10443
Radar rdar://problem/49776686
Original Reporter nrith (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

Environment

Xcode 10.2 (10E125)

2016 MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)

macOS Mojave

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

md5: 25c7673210e45a80636c5e66f7f8983a

duplicates:

  • SR-103 Protocol Extension: function's implementation cannot be overridden by a subclass

Issue Description:

If a protocol has an extension with default values for the protocol's properties, and a class implements that protocol without defining those property values, and a subclass of that class does define property values, passing an instance of that subclass to a function that takes a protocol argument doesn't

Steps to Reproduce:

1. Declare a protocol with a read-only properties.

    protocol Protocol {
        var string: String { get }
    }

2. Declare a protocol extension that implements the properties by returning fixed values.

    extension Protocol {
         var string: String { return "Protocol extension's string" }
    }

3. Declare an NSObject subclass that implements the protocol, but do NOT implement the protocol's properties.

    class EmptyClass: NSObject, Protocol { }

4. Subclass the empty class from step 3, and implement the protocol's properties to return the subclass's own values.

    class SubclassOfEmptyClass: EmptyClass {
         var string: String { return "SubclassOfEmptyClass's string" }
    }

5. Pass an instance of the subclass to a function that takes a parameter of the protocol's type.

    print("SubclassOfEmptyClass")
    printProperties(SubclassOfEmptyClass())

6. Inside the function, access the subclass instance's properties. Instead of seeing the subclass's own values, the protocol extension's values are returned.

    func printProperties(_ aProtocol: Protocol) {
        print(aProtocol.string)
     }

Expected Results:

Passing an instance to the function should print the SubclassOfEmptyClass's string property ("SubclassOfEmptyClass's string").

Actual Results:

It prints the protocol extension's string property ("Protocol extension's string"). This happens even if the original protocol is declared as a class-only protocol (i.e. protocol Protocol: class).

The obvious workaround is to implement the properties in the EmptyClass, which will force the SubclassOfEmptyClass's properties to specify that they override the superclass's values, but that requires any class that implements the protocol to lose access to the protocol extension's default values.

@belkadan
Copy link
Contributor

Old, old issue that's tricky to fix without breaking source compat. :-(

@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