Is golangci-lint Generics Readiness?
Tags: go, generics
Published: 2021-12-23 15:18:16

---
title: Is golangci-lint Generics Readiness?
published: true
description: 
tags: Go, generics
//cover_image: https://direct_url_to_image.jpg
---

This post is Day 24 of [Go Advent Calendar 2021](https://qiita.com/advent-calendar/2021/go)(jp). :christmas_tree::santa:

---

[golangci-lint](https://golangci-lint.run/) is easy to use a very large of linters with a configuration file. On the other hand, it depends on a lot of linters, which makes it difficult to incorporate the latest implementations of them. Also, many of them have not been updated for some time. In such a situation, Go could introduce Generics at any moment. So I checked whether the linters support Generics or not, and summarized the results in the following list. In order to check if each linter supports or is going to support Generics, I search the issues and pull requests from the last 6 months using the keywords "generics", "type" and "1.18".

---

|Name|Status|Remark|
|:-|:-|:-|
|[deadcode](https://github.com/remyoudompheng/go-misc/tree/master/deadcode)|:white_large_square:|no update for 5 years|
|[errcheck](https://github.com/kisielk/errcheck)|:white_large_square:|-|
|[gosimple](https://github.com/dominikh/go-tools/tree/master/simple)|:white_large_square:|-|
|[govet](https://pkg.go.dev/cmd/vet)|:white_check_mark:|https://tip.golang.org/doc/go1.18#vet|
|[ineffassign](https://github.com/gordonklaus/ineffassign)|:white_large_square:|-|
|[staticcheck](https://staticcheck.io/)|:white_large_square:|[issue](https://github.com/dominikh/go-tools/issues/1146) exists but not yet supported|
|[structcheck](https://github.com/opennota/check)|:white_large_square:|no update for 3 years（Reference to the package changed from GitHub to GitLab.）|
|[typecheck](https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/typecheck.go)|:white_large_square:|-|
|[unused](https://github.com/dominikh/go-tools/tree/master/unused)|:white_large_square:|-|
|[varcheck](https://github.com/opennota/check)|:white_large_square:|same as structcheck|
|[asciicheck](https://github.com/tdakkota/asciicheck)|:white_large_square:|-|
|[bidichk](https://github.com/breml/bidichk)|:white_large_square:|-|
|[bodyclose](https://github.com/timakin/bodyclose)|:white_large_square:|-|
|[contextcheck](https://github.com/sylvia7788/contextcheck)|:white_large_square:|-|
|[cyclop](https://github.com/bkielbasa/cyclop)|:white_large_square:|-|
|[depguard](https://github.com/OpenPeeDeeP/depguard)|:white_large_square:|-|
|[dogsled](https://github.com/alexkohler/dogsled)|:white_large_square:|-|
|[dupl](https://github.com/mibk/dupl)|:white_large_square:|-|
|[durationcheck](https://github.com/charithe/durationcheck)|:white_large_square:|-|
|[errchkjson](https://github.com/breml/errchkjson)|:white_large_square:|-|
|[errname](https://github.com/Antonboom/errname)|:white_large_square:|-|
|[errorlint](https://github.com/polyfloyd/go-errorlint)|:white_large_square:|-|
|[exhaustive](https://github.com/nishanths/exhaustive)|:white_large_square:|There is no indication of how it will be implemented, but there is [an issue](https://github.com/nishanths/exhaustive/issues/31) that talks about the need to update it.|
|[exhaustivestruct](https://github.com/mbilski/exhaustivestruct)|:white_large_square:|-|
|[exportloopref](https://github.com/kyoh86/exportloopref)|:white_large_square:|-|
|[forbidigo](https://github.com/ashanbrown/forbidigo)|:white_large_square:|-|
|[forcetypeassert](https://github.com/gostaticanalysis/forcetypeassert)|:white_large_square:|-|
|[funlen](https://github.com/ultraware/funlen)|:white_large_square:|no update for a year|
|[gci](https://github.com/daixiang0/gci)|:white_large_square:|-|
|[gochecknoglobals](https://github.com/leighmcculloch/gochecknoglobals)|:white_large_square:|-|
|[gochecknoinits](https://github.com/leighmcculloch/gochecknoinits)|:white_large_square:|-|
|[gocognit](https://github.com/uudashr/gocognit)|:white_large_square:|-|
|[goconst](https://github.com/jgautheron/goconst)|:white_large_square:|-|
|[gocritic](https://github.com/go-critic/go-critic)|:white_large_square:|Previously fixed error is [recurring](https://github.com/golangci/golangci-lint/issues/2414).|
|[gocyclo](https://github.com/fzipp/gocyclo)|:white_large_square:|-|
|[godot](https://github.com/tetafro/godot)|:white_large_square:|-|
|[godox](https://github.com/matoous/godox)|:white_large_square:|issue tab is hidden|
|[goerr113](https://github.com/Djarvur/go-err113)|:white_large_square:|-|
|[gofmt](https://pkg.go.dev/cmd/gofmt)|:white_check_mark:|Referencing standard packages via [golangci/gofmt](https://github.com/golangci/gofmt/tree/master/gofmt), so some may not be supported.|
|[gofumpt](https://github.com/mvdan/gofumpt)|:white_check_mark:|https://github.com/mvdan/gofumpt/releases/tag/v0.2.0|
|[goheader](https://github.com/denis-tingaikin/go-header)|:white_large_square:|-|
|[goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)|:white_check_mark:|same as gofmt|
|[golint](https://github.com/golang/lint)|:white_large_square:|deprecated and archived|
|[gomnd](https://github.com/tommy-muehle/go-mnd)|:white_large_square:|-|
|[gomoddirectives](https://github.com/ldez/gomoddirectives)|:white_large_square:|-|
|[gomodguard](https://github.com/ryancurrah/gomodguard)|:white_large_square:|-|
|[goprintffuncname](https://github.com/jirfag/go-printf-func-name)|:white_large_square:|no update for 2 years|
|[gosec](https://github.com/securego/gosec)|:white_large_square:|-|
|[ifshort](https://github.com/esimonov/ifshort)|:white_large_square:|-|
|[importas](https://github.com/julz/importas)|:white_large_square:|-|
|[interfacer](https://github.com/mvdan/interfacer)|:white_large_square:|deprecated and archived|
|[ireturn](https://github.com/butuzov/ireturn)|:white_large_square:|-|
|[lll](https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/lll.go)|:white_large_square:|-|
|[makezero](https://github.com/ashanbrown/makezero)|:white_large_square:|-|
|[maligned](https://github.com/mdempsky/maligned)|:white_large_square:|deprecated and archived|
|[misspell](https://github.com/client9/misspell)|:white_large_square:|no update for 4 years|
|[nakedret](https://github.com/alexkohler/nakedret)|:white_large_square:|-|
|[nestif](https://github.com/nakabonne/nestif)|:white_large_square:|-|
|[nilerr](https://github.com/gostaticanalysis/nilerr)|:white_large_square:|no update for a year|
|[nilnil](https://github.com/Antonboom/nilnil)|:white_large_square:|-|
|[nlreturn](https://github.com/ssgreg/nlreturn)|:white_large_square:|-|
|[noctx](https://github.com/sonatard/noctx)|:white_large_square:|-|
|[nolintlint](https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint/README.md)|:white_large_square:|-|
|[paralleltest](https://github.com/kunwardeep/paralleltest)|:white_large_square:|-|
|[prealloc](https://github.com/alexkohler/prealloc)|:white_large_square:|-|
|[predeclared](https://github.com/nishanths/predeclared)|:white_large_square:|-|
|[promlinter](https://github.com/yeya24/promlinter)|:white_large_square:|-|
|[revive](https://github.com/mgechev/revive)|:white_large_square:|-|
|[rowserrcheck](https://github.com/jingyugao/rowserrcheck)|:white_large_square:|-|
|[scopelint](https://github.com/kyoh86/scopelint)|:white_large_square:|deprecated and archived|
|[sqlclosecheck](https://github.com/ryanrolds/sqlclosecheck)|:white_large_square:|-|
|[stylecheck](https://github.com/dominikh/go-tools/tree/master/stylecheck)|:white_large_square:|-|
|[tagliatelle](https://github.com/ldez/tagliatelle)|:white_large_square:|-|
|[tenv](https://github.com/sivchari/tenv)|:white_large_square:|-|
|[testpackage](https://github.com/maratori/testpackage)|:white_large_square:|-|
|[thelper](https://github.com/kulti/thelper)|:white_large_square:|-|
|[tparallel](https://github.com/moricho/tparallel)|:white_large_square:|-|
|[unconvert](https://github.com/mdempsky/unconvert)|:white_large_square:|no update for 2 years|
|[unparam](https://github.com/mvdan/unparam)|:white_large_square:|There is [an issue](https://github.com/mvdan/unparam/issues/60) that states that `x/tools/go/ssa` supports Generics and then supports it.|
|[varnamelen](https://github.com/blizzy78/varnamelen)|:white_large_square:|-|
|[wastedassign](https://github.com/sanposhiho/wastedassign)|:white_large_square:|https://github.com/sanposhiho/wastedassign/issues/41|
|[whitespace](https://github.com/ultraware/whitespace)|:white_large_square:|-|
|[wrapcheck](https://github.com/tomarrell/wrapcheck)|:white_check_mark:|https://github.com/tomarrell/wrapcheck/commit/213318509af6a003be2be752da826d269149ba4d|
|[wsl](https://github.com/bombsimon/wsl)|:white_large_square:|-|

---

Currently, most of the linters do not yet support Generics, and few of them have taken any action to support it. Even if the various linters support Generics, the latest golangci-lint will probably support it in due course. The reason for the lack of support may be that the official `x/tools`, including go/ssa, do not yet support Generics[^1]. Therefore, for production services that use golangci-lint regularly, it is better to experiment with Generics in the development environment only, and wait for a while before using it in the production environment. Conversely, it might be a chance to contribute them;)

[^1]: https://github.com/golang/go/issues/48525

There may be linters that do not fail with or without Generics. Also, some of them may actually support Generics due to my lack of confirmation, and some of them may support Generics after this post was published because I couldn't keep up with the latest information. In that case, please let me know in the comments.