x/tools/cmd/deadcode: Deadcode not reported with different argument order in workspace #73652
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
ToolProposal
Issues describing a requested change to a Go tool or command-line program.
Tools
This label describes issues relating to any tools in the x/tools repository.
Milestone
Go version
go version go1.24.2 linux/amd64
Output of
go env
in your module/workspace:What did you do?
Argument order can hide some dead code
Real Life example
At
$work
we use a private monorepo with several services, along with library packages that are shared across services.Each service may contain several other packages that are not shared with other services.
In addition we has a "tools" module that doesn't import much from the library.
Each service is a module, tools is a module, and the library is a module.
The root of the repo is a workspace.
Linter
We have an internal linter that runs
deadcode
and allows us to ignore certain dead functions (etc) based on//nolint:deadcode
comments.So we expect some deadcode to be reported as dead, and then our linter can ignore it.
The linter also reports when code with a
//nolint:deadcode
comment was not reported as dead (that way we can remove the comment).This works pretty well, but isn't actually relevant to the issue.
Problem
It was discovered that running
deadcode
across all the modules sometimes produces a much smaller report than other times.This appears to happen only in specific circumstances, but it is reliable to reproduce.
Additionally, we were able to reproduce it with some package names, but not others.
In one specific case, adding
tools/a/a.go
with a singlepackage a
line (no added dead code), causesdeadcode
to fail to report dead code (from another module).But moving that same file to
tools/x/x.go
does not trigger the bug.While debugging, we discovered that the order of package arguments to
deadcode
reliably causes it to fail.The difference is remarkable too: Depending on the order of the arguments,
deadcode
will report either one or several thousand lines.Minimal Reproduction
Setup
$ tree . ├── go.work ├── lib │ ├── a │ │ └── a.go │ └── go.mod └── svc ├── go.mod └── s └── main.go
This is an example workspace with a service and library module, which each contain a single package.
The only
main()
is insvc/s/main.go
and it does not importlib/a
.Therefore
lib/a.A()
is unused and dead.But this is only found based on the order of the arguments to
deadcode
:What did you see happen?
Based on argument order, in a workspace,
deadcode
may fail to report dead codeWhat did you expect to see?
Reporting of dead code is consistent even with different argument orders
The text was updated successfully, but these errors were encountered: