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-2198] @discardableResult not inherited on override #44805

Open
swift-ci opened this issue Jul 28, 2016 · 4 comments
Open

[SR-2198] @discardableResult not inherited on override #44805

swift-ci opened this issue Jul 28, 2016 · 4 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-2198
Radar None
Original Reporter Kyro (JIRA User)
Type Bug
Environment

Swift 3, Xcode8b3

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

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.

@belkadan
Copy link
Contributor

Should @discardableResult be inherited? There's no way to undo it in an override, then.

@swift-ci
Copy link
Collaborator Author

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.

@swift-ci
Copy link
Collaborator Author

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

@belkadan
Copy link
Contributor

Being part of a method declaration doesn't automatically mean it's part of a method signature. For example, throws is part of a method's declaration and even its type, but you can't have two methods that differ only in whether or not they throw.

@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
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