dominikh / go-tools

Staticcheck - The advanced Go linter
https://staticcheck.dev
MIT License
6.21k stars 377 forks source link

Detect never-nil interface returns #1615

Open FiloSottile opened 2 weeks ago

FiloSottile commented 2 weeks ago

The following program prints false because the foo() return value is always a non-nil interface wrapping a nil bar() return value.

package main

import "errors"

func main() {
    x, _ := foo()
    println(x == nil)
}

func foo() (interface{}, error) {
    return bar()
}

func bar() (*struct{}, error) {
    return nil, errors.New("error")
}

Today I was about to ship something similar to an exposed standard library interface when a test stopped me.

Not sure it can be done with few enough false positives, but I would have loved for staticcheck to point out that foo() always returns non-nil, which given the error return is almost certainly not intended.

dominikh commented 2 weeks ago

ISTM that we already catch this?

bar.go:7:10: this comparison is never true (SA4023)
    bar.go:6:2: the lhs of the comparison is the 1st return value of this function call
    bar.go:10:6: command-line-arguments.foo never returns a nil interface value