Skip to content

go-critic/ruleguard: unreachable #3136

Closed
@pierrre

Description

@pierrre

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

When I run golangci-lint on a package that contains generic code, the go-critic/ruleguard linter panics with the message "unreachable".

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version 1.49.0 built from cc2d97f3 on 2022-08-24T10:24:37Z

Configuration file

$ cat .golangci.yml
run:
  timeout: "10m"
output:
  uniq-by-line: false
  sort-results: true
linters:
  disable-all: true
  enable:
    - "asciicheck"
    - "bidichk"
    - "bodyclose"
    - "containedctx"
    - "contextcheck"
    # - "cyclop" # Redundant with gocyclo.
    # - "deadcode" # Replaced by unused.
    # - "decorder" # Maybe overkill.
    - "depguard"
    - "dogsled"
    - "dupl"
    - "durationcheck"
    - "errcheck"
    - "errchkjson"
    - "errname"
    - "errorlint"
    - "execinquery"
    - "exhaustive"
    # - "exhaustivestruct " # Replaced by exhaustruct.
    # - "exhaustruct" # Too many false positive, and not always relevant.
    - "exportloopref"
    - "forbidigo"
    - "forcetypeassert"
    # - "funlen" # It causes issues in table driven tests, and cyclomatic complexity is more relevant.
    # - "gci" # Redundant with goimports and grouper.
    # - "gochecknoglobals" # It's OK.
    # - "gochecknoinits" # It's OK.
    # - "gocognit" # Redundant with gocyclo.
    # - "goconst" # Too many false positive.
    - "gocritic"
    - "gocyclo"
    - "godot"
    # - "godox" # Should not be reported as error.
    # - "goerr113" # Not useful.
    - "gofmt"
    - "gofumpt"
    # - "goheader" # Not useful.
    - "goimports"
    # - "golint" # Replaced by revive.
    # - "gomnd" # Too many false positive.
    # - "gomoddirectives" # Not useful.
    # - "gomodguard" # Redundant with depguard.
    - "goprintffuncname"
    - "gosec"
    - "gosimple"
    - "govet"
    - "grouper"
    # - "ifshort" # Deprecated.
    - "importas"
    - "ineffassign"
    - "interfacebloat"
    # - "interfacer" # Archived.
    # - "ireturn" # Too many false positive.
    # - "lll" # We don't use punch cards anymore.
    # - "logrlint" # Not used.
    # - "maintidx" # Redundant with gocyclo.
    - "makezero"
    # - "maligned" # Replaced by govet 'fieldalignment'.
    - "misspell"
    - "nakedret"
    - "nestif"
    - "nilerr"
    - "nilnil"
    # - "nlreturn" # Is that a good practice ?
    - "noctx"
    - "nolintlint"
    # - "nonamedreturns" # Named returns are OK.
    # - "nosnakecase" # Deprecated.
    - "nosprintfhostport"
    # - "paralleltest" # Not useful.
    - "prealloc"
    - "predeclared"
    # - "promlinter" # Not useful.
    - "reassign"
    - "revive"
    - "rowserrcheck"
    # - "scopelint" # Replaced by exportloopref.
    - "sqlclosecheck"
    - "staticcheck"
    #- "structcheck" # Replaced by unused.
    - "stylecheck"
    #- "tagliatelle" # Not useful.
    - "tenv"
    # - "testpackage" # Not useful.
    - "thelper"
    # - "tparallel" # Not useful.
    - "typecheck"
    - "unconvert"
    - "unparam"
    - "unused"
    - "usestdlibvars"
    # - "varcheck" # Replaced by unused.
    # - "varnamelen" # Maybe overkill.
    - "wastedassign"
    # - "whitespace" # Not useful.
    - "wrapcheck"
    # - "wsl" # Not useful.
linters-settings:
  depguard:
    list-type: blacklist
    include-go-root: true
    packages-with-error-message:
      - reflect: "shouldn't be used by most application"
      - unsafe: "it's not safe"
  gocritic:
    enabled-tags:
      - experimental
      - diagnostic
      - opinionated
      - performance
      - style
  gocyclo:
    min-complexity: 10
  gofumpt:
    extra-rules: true
  gosimple:
    checks: [ "all" ]
  govet:
    enable-all: true
    disable:
      - fieldalignment # Too many false positive.
  grouper:
    import-require-single-import: true
    import-require-grouping: true
  nolintlint:
    allow-unused: false
    allow-no-explanation:
      - errcheck
      - misspell
    require-explanation: true
    require-specific: true
  staticcheck:
    checks: [ "all" ]
  stylecheck:
    checks: [ "all" ]
issues:
  exclude-use-default: false
  max-issues-per-linter: 0
  max-same-issues: 0

Go environment

$ go version && go env
go version go1.19 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/pierre/.cache/go-build"
GOENV="/home/pierre/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/pierre/go/pkg/mod"
GONOPROXY="*.infra.online.net"
GONOSUMDB="*.infra.online.net"
GOOS="linux"
GOPATH="/home/pierre/go"
GOPRIVATE="*.infra.online.net"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/pierre/.gimme/versions/go1.19.src"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/pierre/.gimme/versions/go1.19.src/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/pierre/Git/pierrre/di/go.mod"
GOWORK=""
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 -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3097190385=/tmp/go-build -gno-record-gcc-switches"

Verbose output of running

$ golangci-lint cache clean
$ golangci-lint run -vdi git:(feature/golangci-lint-gocritic) make golangci-lint-cache-clean golangci-lint
/home/pierre/go/pkg/golangci-lint/v1.49.0/golangci-lint cache clean
/home/pierre/go/pkg/golangci-lint/v1.49.0/golangci-lint -v run --fix
INFO [config_reader] Config search paths: [./ /home/pierre/Git/pierrre/di /home/pierre/Git/pierrre /home/pierre/Git /home/pierre /home /] 
INFO [config_reader] Used config file .golangci.yml 
INFO [lintersdb] Active 58 linters: [asciicheck bidichk bodyclose containedctx contextcheck depguard dogsled dupl durationcheck errcheck errchkjson errname errorlint execinquery exhaustive exportloopref forbidigo forcetypeassert gocritic gocyclo godot gofmt gofumpt goimports goprintffuncname gosec gosimple govet grouper importas ineffassign interfacebloat makezero misspell nakedret nestif nilerr nilnil noctx nolintlint nosprintfhostport prealloc predeclared reassign revive rowserrcheck sqlclosecheck staticcheck stylecheck tenv thelper typecheck unconvert unparam unused usestdlibvars wastedassign wrapcheck] 
INFO [loader] Go packages loading at mode 575 (compiled_files|deps|exports_file|files|imports|name|types_sizes) took 80.514453ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 537.36µs 
INFO [linters context] importas settings found, but no aliases listed. List aliases under alias: key. 
INFO [linters context/goanalysis] analyzers took 3.133131114s with top 10 stages: buildir: 1.439911158s, buildssa: 924.231733ms, exhaustive: 188.786073ms, inspect: 78.516637ms, ctrlflow: 72.606301ms, findcall: 64.835389ms, printf: 57.115256ms, fact_deprecated: 48.373611ms, SA5012: 44.859397ms, nilness: 32.395418ms 
ERRO [runner] Panic: gocritic: package "di" (isInitialPkg: true, needAnalyzeSource: true): unreachable: goroutine 1585 [running]:
runtime/debug.Stack()
        runtime/debug/stack.go:24 +0x65
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func1()
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:101 +0x155
panic({0xf149a0, 0x12f3500})
        runtime/panic.go:884 +0x212
github.com/quasilyte/go-ruleguard/internal/xtypes.typeIdentical({0x12fb460?, 0xc0075b7950?}, {0x12fb2d0?, 0xc0001b8540?}, 0x0)
        github.com/quasilyte/go-ruleguard@v0.3.17/internal/xtypes/xtypes.go:218 +0x687
github.com/quasilyte/go-ruleguard/internal/xtypes.Identical(...)
        github.com/quasilyte/go-ruleguard@v0.3.17/internal/xtypes/xtypes.go:57
github.com/quasilyte/go-ruleguard/ruleguard/typematch.(*Pattern).matchIdentical(0xc004072b50?, 0xc0003ad980, 0xc00676baa0, {0x12fb460?, 0xc0075b7950?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/typematch/typematch.go:439 +0xba
github.com/quasilyte/go-ruleguard/ruleguard/typematch.(*Pattern).MatchIdentical(0xc001891688, 0xc0003ad980, {0x12fb460, 0xc0075b7950})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/typematch/typematch.go:370 +0x15d
github.com/quasilyte/go-ruleguard/ruleguard.makeTypeIsFilter.func2(0xc00dcb2cb8)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/filters.go:345 +0x117
github.com/quasilyte/go-ruleguard/ruleguard.makeAndFilter.func1(0xfdaae0?)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/filters.go:46 +0x2e
github.com/quasilyte/go-ruleguard/ruleguard.(*rulesRunner).handleMatch(0xc00dcb2b40, {0xc0033db6b0, 0x2d8, 0xc001891750, {0x1150f7f, 0x34}, {0x0, 0x0}, {0x0, 0x0}, ...}, ...)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/runner.go:352 +0x130
github.com/quasilyte/go-ruleguard/ruleguard.(*rulesRunner).runRules.func1({{0x12fa740, 0xc005f6c100}, {0xc007e54300, 0x3, 0x8}})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/runner.go:252 +0xc5
github.com/quasilyte/gogrep.(*matcher).MatchNode(0xc0023b5ec0, 0xc00dcb2bb0, {0x12fa740?, 0xc005f6c100?}, 0xc004073038)
        github.com/quasilyte/gogrep@v0.0.0-20220120141003-628d8b3623b5/match.go:84 +0x4e3
github.com/quasilyte/gogrep.(*Pattern).MatchNode(...)
        github.com/quasilyte/gogrep@v0.0.0-20220120141003-628d8b3623b5/gogrep.go:90
github.com/quasilyte/go-ruleguard/ruleguard.(*rulesRunner).runRules(0xc00dcb2b40?, {0x12fa740?, 0xc005f6c100?}, 0x2?)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/runner.go:251 +0x14b
github.com/quasilyte/go-ruleguard/ruleguard.(*rulesRunner).run.func1({0x12fa740?, 0xc005f6c100?}, 0x1?)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/runner.go:166 +0x33
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walk(0xc0040734f8, {0x12fa740?, 0xc005f6c100?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:194 +0x1851
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walkStmtList(0x12fa880?, {0xc00234e100?, 0x9, 0x7f2174518740?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:37 +0x85
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walk(0xc0040734f8, {0x12fa880?, 0xc001af9710?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:218 +0x181e
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walk(0xc0040734f8, {0x12fabc8?, 0xc001af9740?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:360 +0x7d9
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walkDeclList(0xc0040734f8?, {0xc00234e000?, 0xf, 0xc004073478?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:43 +0x85
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).walk(0xc0040734f8, {0x12fab78?, 0xc0055c6800?})
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:367 +0x135e
github.com/quasilyte/go-ruleguard/ruleguard.(*astWalker).Walk(...)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ast_walker.go:20
github.com/quasilyte/go-ruleguard/ruleguard.(*rulesRunner).run(0xc00dcb2b40, 0xc0055c6800)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/runner.go:165 +0x1c9
github.com/quasilyte/go-ruleguard/ruleguard.(*engine).Run(0xeff7a0?, 0x1b50360?, 0x0?, 0x1?)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/engine.go:130 +0x45
github.com/quasilyte/go-ruleguard/ruleguard.(*Engine).Run(...)
        github.com/quasilyte/go-ruleguard@v0.3.17/ruleguard/ruleguard.go:74
github.com/go-critic/go-critic/checkers.runRuleguardEngine(0xc0029b1208, 0xc0055c6800, 0xc0029cf560, 0xc007e52230)
        github.com/go-critic/go-critic@v0.6.4/checkers/ruleguard_checker.go:301 +0xd9
github.com/go-critic/go-critic/checkers.(*embeddedRuleguardChecker).WalkFile(0xc0029cf8f0, 0xc0055c6800?)
        github.com/go-critic/go-critic@v0.6.4/checkers/embedded_rules.go:98 +0xea
github.com/go-critic/go-critic/framework/linter.(*Checker).Check(...)
        github.com/go-critic/go-critic@v0.6.4/framework/linter/linter.go:130
github.com/golangci/golangci-lint/pkg/golinters.runGocriticOnFile(0xc002450240, 0xc000d7e13c?, {0xc00543d800, 0x69, 0xf5af20?})
        github.com/golangci/golangci-lint/pkg/golinters/gocritic.go:178 +0xd1
github.com/golangci/golangci-lint/pkg/golinters.runGocriticOnPackage(0xc002450240, {0xc00543d800, 0x69, 0x80}, {0xc0070b6890, 0x2, 0xf53a80?})
        github.com/golangci/golangci-lint/pkg/golinters/gocritic.go:166 +0x1df
github.com/golangci/golangci-lint/pkg/golinters.(*goCriticWrapper).run(0xc0001dd740, 0xc0004aaea0)
        github.com/golangci/golangci-lint/pkg/golinters/gocritic.go:126 +0x217
github.com/golangci/golangci-lint/pkg/golinters.NewGoCritic.func1(0xf531e0?)
        github.com/golangci/golangci-lint/pkg/golinters/gocritic.go:49 +0x39
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyze(0xc002835bc0)
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:187 +0x9d6
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func2()
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:105 +0x1d
github.com/golangci/golangci-lint/pkg/timeutils.(*Stopwatch).TrackStage(0xc0016e4870, {0x10a7381, 0x8}, 0xc0004bff48)
        github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go:111 +0x4a
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe(0xc001602268?)
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:104 +0x85
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze.func2(0xc002835bc0)
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:80 +0xb4
created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze
        github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:75 +0x1eb 
WARN [runner] Can't run linter goanalysis_metalinter: goanalysis_metalinter: gocritic: package "di" (isInitialPkg: true, needAnalyzeSource: true): unreachable 
WARN [linters context] rowserrcheck is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649. 
WARN [linters context] sqlclosecheck is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649. 
WARN [linters context] wastedassign is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649. 
INFO [runner] processing took 30.871µs with stages: max_same_issues: 2.375µs, max_per_file_from_linter: 1.956µs, nolint: 1.886µs, skip_dirs: 1.886µs, exclude: 1.885µs, filename_unadjuster: 1.885µs, path_shortener: 1.467µs, identifier_marker: 1.467µs, skip_files: 1.467µs, autogenerated_exclude: 1.467µs, path_prefixer: 1.466µs, uniq_by_line: 1.397µs, cgo: 1.397µs, max_from_linter: 1.397µs, sort_results: 1.397µs, exclude-rules: 1.397µs, path_prettifier: 1.397µs, severity-rules: 1.396µs, diff: 978ns, source_code: 908ns 
INFO [runner] linters took 2.589647223s with stages: goanalysis_metalinter: 2.589444333s, rowserrcheck: 16.553µs, sqlclosecheck: 13.41µs, wastedassign: 12.292µs 
ERRO Running error: 1 error occurred:
        * can't run linter goanalysis_metalinter: goanalysis_metalinter: gocritic: package "di" (isInitialPkg: true, needAnalyzeSource: true): unreachable
 
INFO Memory: 28 samples, avg is 201.3MB, max is 291.3MB 
INFO Execution took 2.676218469s                  
make: *** [Makefile-common.mk:57 : golangci-lint] Erreur 3

Code example or link to a public repository

https://github.com/pierrre/di/tree/feature/golangci-lint-gocritic

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdependenciesRelates to an upstream dependency

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions