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-2198] @discardableResult not inherited on override #44805
Comments
Should @discardableResult be inherited? There's no way to undo it in an override, then. |
Comment by Matthieu Riegler (JIRA) Since I would expect the same behavior as the super method, in the case you give, I would create a new method and not override the original one. |
Comment by Filip Zawada (JIRA) Although this rationale initially made sense to me, I don't think it's correct. In swift `methods declarations` and `@attribute` are completely different things. If @Attribute was a part of a method declaration, then indeed it should be inherited. But then following would also work: class Foo {
func bar() -> Int { print("result matters"; return 0 }
@discardableResult
func bar() -> Int { print("result is forgotten"); return 1 }
}
let x = Foo().bar() // prints: result matters
Foo().bar() // prints: result is forgotten Now, imagine following example: protocol P1 {
func then() -> Self
}
protocol P2 {
@discardableResult
func then() -> Self
}
class A1 {
@discardableResult
func then() -> A1 {
return A1()
}
}
final class C: A1, P1, P2 {
override func then() -> C {
return C()
}
}
let p1: P1 = C()
let p2: P2 = C()
let a1: A1 = C()
let c : C = C()
// actually that's how it works. How shall it works after the fix?
p1.then() // warns
p2.then() // silent
a1.then() // silent
c .then() // warns After the fix, what would be the result of that? And the real world use-case could be: class Promise<T> {
init(_ arg: T) {}
func then(closure: () -> T) -> Promise<T> {
return Promise<T>(closure())
}
func `catch`() {}
}
class UnfailablePromise<T>: Promise<T> {
@discardableResult
override func then(closure: () -> T) -> UnfailablePromise<T> {
return UnfailablePromise<T>(closure())
}
}
Promise<Int>(0).then(closure: { 5 }) // warns (the intention is to force user to use `catch`)
Promise<Int>(0).then(closure: { 5 }).catch() // potential error caught, no warning
UnfailablePromise<Int>(0).then(closure: { 5 }) // no warning, since promise can't fail |
Being part of a method declaration doesn't automatically mean it's part of a method signature. For example, |
Environment
Swift 3, Xcode8b3
Additional Detail from JIRA
md5: 2cb32a0ca57df75df0627098e812d67c
is duplicated by:
Issue Description:
It seems that the attribute @discardableResult is not inherited when overriding a method.
In my usecase, I subclassed UIView and overrode `becomeFirstResponder()`.
When calling `becomeFirstResponder()` on my subclass, the compiler returns the following warning : Result of call to 'becomeFirstResponder()' is Unused
There were no warnings when calling the super method.
PS: I asked a question about it on Stack Overflow.
The text was updated successfully, but these errors were encountered: