Skip to content

Enforce-readiness: three clean, type-resolved linters (bytesbufferstring, mapdeletecheck, ioutildeprecated) have zero production [Content truncated due to length] #45629

Description

@github-actions

Summary

The registry has grown to 49 analyzers (cmd/linters/main.go), but the CI enforcement set in .github/workflows/cgo.yml (LINTER_FLAGS, lines 1208 and 1211) still lists only 20. Three of the newest analyzers are already built to the same enforcement bar as the linters that are enforced — type-resolved package identity, internal/nolint suppression, internal/filecheck.IsTestFile test-skip, and (for the two with autofix) analysistest.RunWithSuggestedFixes golden coverage — and each currently has zero production violations under the default build. They are ready to enforce:

Analyzer main.go Kind Autofix RWSF golden Prod violations
bytesbufferstring :73 simplification yes yes 0
ioutildeprecated :90 deprecation no (advisory) n/a 0
mapdeletecheck :95 simplification yes yes 0

Without CI enforcement these are dead weight in the registry — they can silently regress (e.g. a copied-in string(buf.Bytes()) or a resurrected io/ioutil import) with nothing to catch it. Adding them locks in the coverage the same way sprintfint, stringsindexcontains, stringscountcontains, tolowerequalfold, and fprintlnsprintf (all style/simplification linters) are already enforced.

Evidence per linter

bytesbufferstring — flags string(buf.Bytes()) on a bytes.Buffer value receiver, suggesting buf.String().

  • Package/type identity is exact and type-resolved: isBytesBufferValue checks *types.Named with obj.Pkg().Path() == "bytes" && obj.Name() == "Buffer" (bytesbufferstring.go:117-124) — no syntactic name match.
  • Deliberately excludes *bytes.Buffer to keep the rewrite semantics-preserving (nil pointer would panic on .Bytes() but return "<nil>" on .String()), documented at :83-89. The value-only restriction is also self-consistent with addressability, since Bytes()/String() are pointer-receiver methods.
  • nolint (:33) + IsTestFile (:60); autofix verified by RunWithSuggestedFixes with a .golden (bytesbufferstring_test.go:15).
  • Grep of pkg/ (excluding _test.go/testdata) surfaces no production string(x.Bytes()) site.

ioutildeprecated — flags calls to deprecated io/ioutil functions (advisory only, no autofix).

mapdeletecheck — flags if _, ok := m[k]; ok { delete(m, k) }, suggesting bare delete(m, k).

  • Fully type-resolved: verifies the ok condition resolves to the same object as the init assignment (Uses/Defs, :71-74), the delete ident is the builtin (*types.Builtin, :93-94), the RHS is a *types.Map (:161-166), and the delete's map+key are the same entities as the index expression via a structural sameExpr (:102-106, :173-206). Function-call maps/keys are conservatively skipped (sameExpr has no *ast.CallExpr case), so no side-effect-reordering false positive.
  • The rewrite is unconditionally sound: delete is a no-op for absent keys and safe on nil maps, and the removed ok var is scoped to the if (no else, single-stmt body).
  • nolint (:33) + IsTestFile (:44); autofix verified by RunWithSuggestedFixes with a .golden (mapdeletecheck_test.go:15).
  • Of 24 if _, ok := ...]; ok { sites in production pkg/, none has a delete-only body; all 61 production delete( calls are unconditional or in unrelated contexts.
Why enforce now

Recommendation

Add -bytesbufferstring -ioutildeprecated -mapdeletecheck to LINTER_FLAGS in .github/workflows/cgo.yml — the default run (:1208) at minimum; optionally the wasm run (:1211) too, though its package subset makes it lower-value here.

Validation checklist

Effort: trivial — a 3-flag CI edit, no code changes, guarded by the checklist.

Generated by 🤖 Sergo - Serena Go Expert · 383.9 AIC · ⌖ 14.1 AIC · ⊞ 5.8K ·

  • expires on Jul 21, 2026, 8:51 PM UTC-08:00

Metadata

Metadata

Labels

cookieIssue Monster Loves Cookies!sergo

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions