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-3700] Compiler should issue a warning when a subclass implementation of a method with default values matches a parent implementation without them #46285

Open
swift-ci opened this issue Jan 23, 2017 · 0 comments
Labels
compiler The Swift compiler in itself improvement

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-3700
Radar None
Original Reporter trupwl (JIRA User)
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement
Assignee None
Priority Medium

md5: 00ffeef46d0399c8ad1cf51f6d15720e

Issue Description:

Consider the following code sample:

class Parent {
  func foo() {
      print("Parent foo() called")
  }
}

class Child: Parent {
  func foo(x: Int = 0) {
      print("Child foo() called")
  }
}

let c = Child()
c.foo()  // prints "Parent foo() called"

Although it's understandable why this happens, the result is unexpected and potentially confusing (not to mention a nightmare to debug when it happens in practice).

Why does it happen? Because the Child class has no direct implementation (an override) of the parameter-less method defined in the superclass so when we call c.foo() the compiler interprets this as a request to the superclass implementation.

However, it's arguable that the intuitive or expected behaviour should be that the most specialised version of the method should be invoked and the search for such method should start at the subclass. If that's the case, then the specialisation of the parameter-full method of the subclass where the argument is set to its default value should take precedence over the parameter-less superclass method, when they are syntactically identical after the specialisation (default value) is applied. In other words, the expectation is that the Child's implementation of foo should be invoked in the example above.

So, either the current behaviour is a bug or, if not, then at least it deserves a compiler warning. I'll let more knowledgeable people decide whether or not it's a bug and have, instead, created this issue as a request for improving the compiler warning capabilities.

I first raised this issue in the swift-users mailing list, and only one person of several who contributed opinions felt that this is fine as it is. Everyone else agreed that at least a compiler warning is warranted. A particularly insightful comment is [this](https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20170102/004330.html):

I think there is a clear case for a warning here, in that the introduction of a default parameter value in such cases is in effect an empty promise and just introduces unreachable code. Indeed 'unreachable code' should perhaps be the warning.

This is because as soon as there is a foo() method, whether by inheritance or a definition in the same class, it renders it impossible to invoke foo(x: ) with its default value in the normal way, or in any interesting way. In fact it makes no difference at all if the default is 0, 3, or 5, or not written in the first place. You now have to be explicit. Therefore, adding the default seems to provide no utility at all and can only lead to the confusion the OP is talking about, and bugs. Furthermore it seems like a very loud indication that the programmer expected something else to happen and it violates the 'principle of least surprise' for anyone else reading the code.

Given all that, it seems like the syntactic vinegar of having to write a pragma to get a clean compile would be appropriate. It alerts other readers of the code that 'here be dragons', and it tells the code author that they should probably achieve what they intend in another way. Most likely, by renaming foo(), or removing the useless default for foo(x: )."

@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
compiler The Swift compiler in itself improvement
Projects
None yet
Development

No branches or pull requests

1 participant