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-11904] EXC_BAD_ACCESS when calling overridden generic function as parent's one. #54321

Closed
swift-ci opened this issue Dec 5, 2019 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 5, 2019

Previous ID SR-11904
Radar None
Original Reporter 0xceed (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

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

md5: 67f6f4a9ed6e5e0ae6829b50f9348dc6

duplicates:

  • SR-4206 Override checking does not properly enforce requirements

Issue Description:

1) Create generic class function which is constrained to some type T.

2) Override this function within child class and add additional constraints to the T type.

3) Make a call to that overridden function using parent class. This will cause EXC_BAD_ACCESS on that line even in case you passed values which are constrained according to the overridden function declaration. See playground attached.

P.S. Real-world case includes same issue when calling super.function within overridden one. See another playground attached.

@theblixguy
Copy link
Collaborator

The override is invalid - an overridden method is not allowed to have generic requirements that are not imposed by the base method. Previously, we used to crash however this is now resolved in Swift 5.2. Your example diagnoses as expected and does not crash anymore:

error: overridden declaration is here
    class func work<Input>(input: Input) {
               ^
error: overridden method 'work' has generic signature <Input where Input : TitleProvider> which is incompatible with base method's generic signature <Input>; expected generic signature to be <Input>

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 6, 2019

Comment by Alexander Orlov (JIRA)

First, yes, not compiling that code would be way better than crashing in runtime. But I used more specific constraints than base method's. Moreover, if you remove `doWork()` method from the code and will use `work` directly — it will work even now, as expected and with expected result.

Maybe you could consider to allow us to use more specific constrains in overridden methods, because we have that ability with generic classes already 🙂. Thus, now I will need to create separate generic class which actually allows me to do what I wanted and works perfectly.

P.S. Sorry for duplicating, hadn't found any others by the moment I created my own.

@theblixguy
Copy link
Collaborator

The problem is that you're violating Liskov:

protocol Proto {
  var value: Int { get }
}

class Base {
  func foo<T>(arg: T) {}
}


class Derived: Base {
  override func foo<T: Proto>(arg: T) {
    print(arg.value)
  }
}

class Test {}

let base: Base = Derived()
base.foo(arg: Test()) // Uh oh

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 6, 2019

Comment by Alexander Orlov (JIRA)

I understand that. I am worrying about generic class inheritance and their constraints. I mean, what I should expect about them in future versions?

@beccadax
Copy link
Contributor

beccadax commented Dec 6, 2019

@swift-ci create

@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.
Projects
None yet
Development

No branches or pull requests

3 participants