Build faillint from the main module instead of go install - #7816
Merged
Conversation
`go install pkg@version` resolves the target's own go.mod, so `go install github.com/fatih/faillint@v1.15.0` builds faillint against golang.org/x/tools v0.30.0, the version faillint pins. That decoder tops out at pkgbits V2. Go 1.27 writes unified IR export data at pkgbits V4, so as soon as faillint type-checks a package whose dependencies come from export data it fails with `internal error: package "net/http" without types was imported from ...`. Go 1.24, 1.25 and 1.26 all wrote V2, which is why the stale pin cost nothing for the last three releases. faillint has had no upstream commit since March 2025, so its pin will never advance on its own and every future pkgbits increment breaks it again. Declare faillint as a tool dependency instead. Its x/tools version is then chosen by the main module's graph rather than by faillint, and the repo already requires golang.org/x/tools v0.47.0, which declares V4 and carries the corrected unified reader. Minimum viable versions/skew handling is now a property of MVS, not of a hardcoded number in a Dockerfile, so bumping the Go toolchain cannot reintroduce the skew. x/tools is deliberately left at v0.47.0. Forcing it to v0.49.0 also pulls x/net, x/crypto, x/text and x/mod forward, and x/net is a direct dependency that ships in the binary; the lint toolchain should not move it. - build-image/Dockerfile no longer installs faillint. - The lint target invokes `go tool faillint`. - Adds 364 KB of vendored source: 13 x/tools packages, faillint's analyzer and dmitri.shuralyov.com/go/generated. Lint stays hermetic: `go tool faillint` was verified to run with GOPROXY=off against vendor/, so the build image needs no module cache. `go mod tidy` and `go mod vendor` are idempotent, so `make mod-check` passes. No CHANGELOG entry: build-image and lint tooling changes carry none, matching the Go 1.27 bump in #7807. Signed-off-by: Friedrich Gonzalez <1517449+friedrichg@users.noreply.github.com>
SungJin1212
approved these changes
Aug 27, 2026
This was referenced Aug 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does:
Alternative to #7815, not a supplement. Both fix the same breakage and only one should land. SungJin1212 diagnosed the problem there and the diagnosis is correct; this PR disagrees only about the mechanism. #7815 force-upgrades
golang.org/x/toolsinside a throwaway module in the Dockerfile; this declares faillint as atooldependency so the version comes from our own module graph.The problem:
go install github.com/fatih/faillint@v1.15.0resolves faillint's owngo.mod, so it builds againstgolang.org/x/toolsv0.30.0, whose decoder stops at pkgbits V2. Go 1.27 writes V4, so faillint fails withinternal error: package "net/http" without types was imported from .... Go 1.24 through 1.26 all wrote V2, which is why the stale pin cost nothing for three releases. faillint has had no upstream commit since 2025-03, so its pin will never advance on its own and every future pkgbits increment breaks it again.Declaring faillint as a
tooldependency lets MVS pick x/tools from the main module, which already requires v0.47.0 (declares V4, and carries the corrected unified reader from CL 765504). The skew becomes structurally impossible rather than a version number someone must remember to bump in a Dockerfile whenever the Go base image moves. This is the same mechanism the Go project used for its own vendored x/tools in golang/go#49159.x/tools is deliberately left at v0.47.0. Forcing v0.49.0 also drags x/net, x/crypto, x/text and x/mod forward, and x/net is a direct dependency that ships in the binary; lint tooling should not move it.
Cost: 364 KB of vendored source (13 x/tools packages, faillint's analyzer, and
dmitri.shuralyov.com/go/generated).build-image/Dockerfileloses a step, andmake lintcallsgo tool faillint.Verified on Go 1.27.0: all 8 faillint checks pass; a control run (
-paths context) still reports violations and exits 3, so the checks are not passing vacuously;go build -tags "netgo slicelabels" ./...is clean;go mod tidyandgo mod vendorare idempotent, somake mod-checkpasses. Lint stays hermetic:go tool faillintwas verified withGOPROXY=offagainstvendor/, so the build image still needs no module cache.Note
Makefilehas a second instance of this bug class:make modernizerunsgolang.org/x/tools/gopls/...@v0.22.0, which is safe on Go 1.27 only because that pin happens to postdate the V4 decode fixes. Left alone here.Which issue(s) this PR fixes:
N/A
Checklist
lintCI job exercises it.CHANGELOG.mdupdated - n/a, build-image and lint tooling changes carry no entry, matching Upgrade golang to 1.27.0 and golangci-lint to 2.13.1 #7807docs/configuration/v1-guarantees.mdupdated if this PR introduces experimental flags - n/a, no new flagsAI usage disclosure
Per §3 of
GENAI_POLICY.md: the investigation behind this change and the text of this description were substantially AI-assisted (Claude Code). Per §1, I verified the claims myself: I confirmed the vendored x/tools v0.47.0 declares V4 and has the corrected reader, reproduced the old failure on Go 1.27 ingolang:1.27.0-trixie, and ran the faillint suite plus the control case locally on Go 1.27.0.