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

staticcheck: missed deprecated references within struct initializer #607

Open
gburt opened this issue Sep 29, 2019 · 3 comments
Open

staticcheck: missed deprecated references within struct initializer #607

gburt opened this issue Sep 29, 2019 · 3 comments

Comments

@gburt
Copy link

gburt commented Sep 29, 2019

The deprecation linter has false-negatives when:

  • instantiating structs - assignment of deprecated fields is not flagged
  • all references to deprecates structs and fields when the struct is in the same pkg as the caller

$ cat example.go:

package main

import (
        "example/bar"
        "fmt"
)

// Deprecated: do not use
type pkgObj struct {
        // Deprecated: Do not use
        DepField string
}

func main() {
        // all references to deprecated things in the same pkg are FN
        obj1 := &pkgObj{ // FN because in same pkg
                DepField: "xyz", // FN because in same pkg
        }
        obj1.DepField = "xyz"                    // FN because in same pkg
        fmt.Printf("field: %v\n", obj1.DepField) // FN because in same pkg

        // struct-instantiation references to deprecated fields in other packages are FN:
        obj := &bar.Obj{ // TP
                DepField: "xyz", // FN b/c struct instantiation
        }
        obj.DepField = "xyz"                    // TP
        fmt.Printf("field: %v\n", obj.DepField) // TP
}

$ cat bar/obj.go:

package bar

// Obj is a type with a deprecated field
//
// Deprecated: do not use
type Obj struct {
        // Foo
        //
        // Deprecated: Do not use
        DepField string
}

Actual output:

$ ~/staticcheck/staticcheck .
example.go:23:10: bar.Obj is deprecated: do not use  (SA1019)
example.go:26:2: obj.DepField is deprecated: Do not use  (SA1019)
example.go:27:28: obj.DepField is deprecated: Do not use  (SA1019)

Expected output:

$ ~/staticcheck/staticcheck .
example.go:16:11: pkgObj is deprecated: do not use  (SA1019)
example.go:17:3: pkgObj.DepField is deprecated: do not use  (SA1019)
example.go:19:2: pkgObj.DepField is deprecated: do not use  (SA1019)
example.go:20:28: pkgObj.DepField is deprecated: do not use  (SA1019)
example.go:23:10: bar.Obj is deprecated: do not use  (SA1019)
example.go:24:3: obj.DepField is deprecated: Do not use  (SA1019)
example.go:26:2: obj.DepField is deprecated: Do not use  (SA1019)
example.go:27:28: obj.DepField is deprecated: Do not use  (SA1019)

Versions etc:

$ ~/staticcheck/staticcheck -version
staticcheck 2019.2.3
$ go version
go version go1.12.8 linux/amd64
$ ~/staticcheck/staticcheck -debug.version
staticcheck 2019.2.3

Compiled with Go version: go1.13
Main module:
        honnef.co/go/[email protected] (sum: h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=)
Dependencies:
        github.com/BurntSushi/[email protected] (sum: h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=)
        golang.org/x/[email protected] (sum: h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=)
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/gburt/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/gburt/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/home/gburt/tmp/go-build252976518=/tmp/go-build -gno-record-gcc-switches"

Thanks for such a great tool!

@gburt gburt added false-negative needs-triage Newly filed issue that needs triage labels Sep 29, 2019
@gburt gburt changed the title staticcheck: missed deprecated references within struct instantiation staticcheck: missed deprecated references within struct instantiation or in same pkg Sep 29, 2019
@dominikh
Copy link
Owner

instantiating structs - assignment of deprecated fields is not flagged

That seems like a false negative, I'll look into it.

all references to deprecates structs and fields when the struct is in the same pkg as the caller

This is working as intended. Deprecation is intended for exported API that should no longer be used by other packages. A package that has deprecated API can, however, still use that very API to implement the non-deprecated alternatives. Consider this example:

// Deprecated: use SafeOp instead
func UnsafeOp() T

func SafeOp() T {
  ret := UnsafeOp()
  return makeSafe(ret)
}

Furthermore, there is no notion of deprecating unexported API that would cause intra-package deprecation warnings.

@dominikh dominikh removed the needs-triage Newly filed issue that needs triage label Sep 30, 2019
@dominikh dominikh changed the title staticcheck: missed deprecated references within struct instantiation or in same pkg staticcheck: missed deprecated references within struct initializer Sep 30, 2019
@fho
Copy link

fho commented May 4, 2022

We also encountered the issue that staticcheck does not complain if a deprecated struct field is assigned when the struct is instantiated (in another package). This causes that from now and then new code is introduced that accidentally uses deprecated functionality in our codebase.

What would need to be changed to fix the issue? If it's not too complicated / a lot of effort, I could give it a try.

@joanlopez
Copy link

instantiating structs - assignment of deprecated fields is not flagged

That seems like a false negative, I'll look into it.

#1382 seems to fix it, so I think it worths a look! @dominikh
Now, for instance this acknowledged deprecation is not being detected, and the same for many other ones similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants