Skip to content

U1000: The "unused" linting rule has misleading behaviour when interacting with generated code #1333

@adamroyjones

Description

@adamroyjones

staticcheck has, in my judgement, some misleading behaviour when it interacts with generated code.

Under some conditions, it produces an error message that doesn't suffice to resolve the underlying problem. (This was first reported here, which led me to here.)

Reproduction

The following example was produced with staticcheck 2022.1.3 (v0.3.3).

The "details" block at the bottom of this section describes the following directory structure (which I've also attached as a tarball here):

.
├── bar.go
├── Dockerfile
├── foo.go
├── go.mod
└── rc.sh

First, recreate this directory structure and set rc.sh to be executable.

  1. If you run ./rc.sh, then staticcheck will report that the function foo is unused.

  2. If you remove the first line from bar.go (that says that the file is generated) and run ./rc.sh, then staticcheck will report that both foo and bar are unused.

  3. If you replace bar with Bar, then, irrespective of the presence of the "first line" in bar.go, no errors are reported.

In my view, the messages in 1 and 2 are misleading. In both cases, the issue is that bar isn't public (and therefore isn't used); foo is only unused as a consequence of bar not being used. This is especially a problem in 1, because there's no way to resolve the problem from the error message alone.

(Ed.: I've changed my mind about 2, so I've struck this through and rewritten it. See the comments below.)

In my view, the message in option 1 is misleading; there's no way to resolve the problem from the error message alone.

Details
// bar.go
// Code generated by hand. DO NOT EDIT.
package foo

func bar() {
	foo()
}
# Dockerfile
FROM golang:1.19-bullseye
RUN go install honnef.co/go/tools/cmd/staticcheck@latest
RUN mkdir /reprex
WORKDIR /reprex
// foo.go
package foo

func foo() {}
// go.mod
module staticcheck-reprex

go 1.19
# rc.sh
#! /usr/bin/env sh

docker build --tag staticcheck-reprex .

docker container run \
  --mount type=bind,source=$(pwd),destination=/reprex \
  -it \
  staticcheck-reprex \
  staticcheck ./...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions