Intended behavior with @discardableResult?


(Christian Schnorr) #1

In the following snippet, I expect to be able to discard the return value after invoking bar, but the compiler even allows me to discard a reference to the function, which makes no sense to me.

@discardableResult func baz() -> Int {
    return 0
}

class Foo {
    @discardableResult func bar() -> Int {
        return 0
    }

    func test() {
        self.bar()
        self.bar // I'd expect an error here

        baz()
        baz // I do get an error here as expected
    }
}

This is also inconsistent with non-method functions: for the free function baz, the compiler generates an error:

Expression resolves to an unused function


(Erik Little) #2

I don't think this is intended, probably a bug.


(Jordan Rose) #3

Yes, please do file this at https://bugs.swift.org!


(Suyash Srijan) #4

I am able to reproduce this without the @discardableResult attribute as well (Swift 4.2/Xcode 10.1 playgrounds)


(Christian Schnorr) #5

I am able to reproduce this without the @discardableResult attribute as well (Swift 4.2/Xcode 10.1 playgrounds)

That's because in a playground nothing is ever really discarded but always printed to the sidebar.


(Suyash Srijan) #6

Ah ok. Seems like the DeclRefExpr we want (i.e. bar) is being wrapped in a DotSyntaxCallExpr node (makes sense as we're doing self.foo), hence why the error is missing. Here's a PR: https://github.com/apple/swift/pull/22518


(Christian Schnorr) #7

Thanks for the quick fix. The error is not being emitted if I leave out the self. too though. Does your PR address this as well?

I would test it myself, but I never built the Swift compiler locally — I might look into that tomorrow.


(Suyash Srijan) #8

Yes it does. In the other case, it gets wrapped in an implicit DotSyntaxCallExpr.