golangci / golangci-lint

Fast linters runner for Go
https://golangci-lint.run
GNU General Public License v3.0
15.82k stars 1.39k forks source link

`gochecksumtype`: works only inside one package #4158

Open maratori opened 1 year ago

maratori commented 1 year ago

Welcome

Description of the problem

gochecksumtype doesn't report missing cases if the sum type is declared in one package and the type switch is in a different package (see https://github.com/golangci/golangci-lint/pull/3671#discussion_r1370424897).

Version of golangci-lint

```console $ golangci-lint --version golangci-lint has version v1.55.0 built with go1.21.3 from de1c3919 on 2023-10-20T11:56:32Z ```

Configuration

```console # paste configuration file or CLI flags here ```

Go environment

```console $ go version && go env go version go1.21.3 linux/amd64 GO111MODULE='' GOARCH='amd64' GOBIN='' GOCACHE='/root/.cache/go-build' GOENV='/root/.config/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='amd64' GOHOSTOS='linux' GOINSECURE='' GOMODCACHE='/go/pkg/mod' GONOPROXY='' GONOSUMDB='' GOOS='linux' GOPATH='/go' GOPRIVATE='' GOPROXY='https://proxy.golang.org,direct' GOROOT='/usr/local/go' GOSUMDB='sum.golang.org' GOTMPDIR='' GOTOOLCHAIN='local' GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64' GOVCS='' GOVERSION='go1.21.3' GCCGO='gccgo' GOAMD64='v1' AR='ar' CC='gcc' CXX='g++' CGO_ENABLED='1' GOMOD='/app/go.mod' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2772357518=/tmp/go-build -gno-record-gcc-switches' ```

Verbose output of running

```console $ golangci-lint cache clean $ golangci-lint run -v # paste output here ```

A minimal reproducible example or link to a public repository

`/decl/decl.go` ```go package decl //sumtype:decl type MySumType interface { sealed() } type VariantA struct{} func (*VariantA) sealed() {} type VariantB struct{} func (*VariantB) sealed() {} ``` `/usage/usage.go` ```go package usage import "decl" func DoSomething(x decl.MySumType) { switch x.(type) { // <-- here is expected a report about missing VariantB case *decl.VariantA: } } ```

Validation

ldez commented 1 year ago

Hello,

there is something missing in your report: Does the standalone linter has the same behavior?

After it's not unexpected based on how golangci-lint analyzes things.

maratori commented 1 year ago

Does the standalone linter has the same behavior?

No, the standalone linter works well if you pass all packages to it (go-check-sumtype ./...).

navijation commented 10 months ago

Analysis drivers like golangci-lint may leverage the analysis framework's fact interface to avoid rerunning analysis on packages that are not either directly or indirectly modified since the last run. What this means is that an analyzer should:

  1. not strongly (caching might be fine for some drivers) rely on any kind of statefulness across packages, except for state exported using the facts API
  2. store all information that is required across packages and not available natively from Go's type system as facts

It looks like go-check-sumtype does not leverage facts at all. So it seems incompatible golangci-lint's caching mechanism unless rewritten appropriately such as in exhaustive.