$ staticcheck -debug.version
staticcheck (devel, v0.0.0-20191028234905-f51cd49dbadb)
Compiled with Go version: devel +a2b1dc863f Wed Nov 6 17:03:51 2019 +0000
Main module:
honnef.co/go/[email protected] (sum: h1:zwVuj3NBk70CHiI+u8OAjE2u05Xq1M/8845ac9+uwMY=)
Dependencies:
github.com/BurntSushi/[email protected] (sum: h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=)
golang.org/x/[email protected] (sum: h1:RzzIfXstYPS78k0QViPGpDcTlV+QuYrbxVmsxDHdxTs=)
$ go version
go version devel +a2b1dc863f Wed Nov 6 17:03:51 2019 +0000 darwin/amd64
$ envdir envs/localdev/ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/kevin/Library/Caches/go-build"
GOENV="/Users/kevin/Library/Application Support/go/env"
GOEXE=""
GOFLAGS="-mod=vendor -race"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY="github.com/meterup"
GONOSUMDB="github.com/meterup/somepackages"
GOOS="darwin"
GOPATH="/Users/kevin"
GOPRIVATE="github.com/meterup"
GOPROXY="direct"
GOROOT="/Users/kevin/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/Users/kevin/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/kevin/src/github.com/meterup/provision/go.mod"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/s1/909yt58s4wj8h_7v7frr8rkm0000gn/T/go-build146612164=/tmp/go-build -gno-record-gcc-switches -fno-common"
I have a package that only contains these files:
// +build cmds
// Per https://github.com/golang/go/issues/25922 we need to do this so that
// go.mod can be fooled into downloading and keeping commands in the vendor
// folder.
package provision
import (
_ "honnef.co/go/tools/cmd/staticcheck"
)
And this file:
package provision
import (
"testing"
)
func TestRegression(t *testing.T) {
t.Fail()
}
The _first_ time I recompile Go, install staticcheck, and install x/tools, staticcheck ./... passes.
The _second_ time I run staticcheck ./... it fails.
0s kevin at hyena in ~/src/github.com/meterup/provision
卤 (master*) $ make lint
envdir envs/localdev go install ./vendor/honnef.co/go/tools/cmd/staticcheck
envdir envs/localdev /Users/kevin/bin/staticcheck ./...
39s kevin at hyena in ~/src/github.com/meterup/provision
卤 (master*) $ make lint
envdir envs/localdev /Users/kevin/bin/staticcheck ./...
-: could not load export data: no export data for "github.com/meterup/provision/src" (compile)
make: *** [Makefile:94: lint] Error 1
Frustratingly, I've been trying to reproduce the exact conditions where I can get it to _pass_, and it's difficult. It's some combination of:
Ah, got it. I can reproduce by adding e.g. var a = 4 to a random file in Staticcheck, say, ir/ssa.go, then recompiling with go install -v -race ./... and then rerunning make lint (the -race seems to be the key). After recompile it passes the first time and fails the subsequent times.
To reproduce again, change the integer, reinstall, rerun make lint, etc.
If I add src/dummy.go with these contents:
package provision
The linter also succeeds - no errors.
Please let me know if I need to report this upstream, I'm not sure where exactly the issue lies.
Here's the contents of pkg.Package right before lint/runner.go returns an error
pkg: &packages.Package{
ID: "github.com/meterup/provision/src",
Name: "provision",
PkgPath: "github.com/meterup/provision/src",
Errors: nil,
GoFiles: nil,
CompiledGoFiles: nil,
OtherFiles: nil,
ExportFile: "",
Imports: {
},
Types: (*types.Package)(nil),
Fset: &token.FileSet{
mutex: sync.RWMutex{},
base: 131075,
files: {
&token.File{
set: &token.FileSet{(CYCLIC REFERENCE)},
name: "$GOROOT/src/internal/nettrace/nettrace.go",
base: 1,
size: 65536,
mutex: sync.Mutex{},
lines: {0},
infos: nil,
},
&token.File{
set: &token.FileSet{(CYCLIC REFERENCE)},
name: "$GOROOT/src/unicode/utf8/utf8.go",
base: 65538,
size: 65536,
mutex: sync.Mutex{},
lines: {0},
infos: nil,
},
},
last: &token.File{
set: &token.FileSet{(CYCLIC REFERENCE)},
name: "$GOROOT/src/unicode/utf8/utf8.go",
base: 65538,
size: 65536,
mutex: sync.Mutex{},
lines: {0},
infos: nil,
},
},
IllTyped: true,
Syntax: nil,
TypesInfo: (*types.Info)(nil),
TypesSizes: &types.StdSizes{WordSize:8, MaxAlign:8},
}
I can reproduce the problem locally. I'll let you know once I know more.
What triggers the problem is the fact that your Go package doesn't have any files that aren't *_test.go files or that aren't excluded by build tags. In other words, go build doesn't work in the package. This causes go/packages to behave unexpectedly. We're still discussing whether this is something that should be changed in go/packages or if staticcheck will have to work around it.
In either case, using the dummy file sounds like a decent enough workaround right now; I'm planning on having the bug fixed one way or another next week.
Ok is there an x/tools or golang/go issue I can also follow?
Ok is there an x/tools or golang/go issue I can also follow?
There is not. In the meantime, I'll work around the issue in staticcheck.
Most helpful comment
I can reproduce the problem locally. I'll let you know once I know more.