slicemakezerolength (69th linter): make()-only scope misses the more idiomatic var s []T nil-slice pattern
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 541
- Avg merge
- 5h 48m
- Merged PRs (30d)
- 773
Description
Problem
slicemakezerolength (added 2026-09-11 via PR #60310, the 69th registered analyzer) flags make([]T, 0) calls that precede an unconditional one-element-per-iteration range+append loop, suggesting capacity len(range-expr). Its entire detection surface requires the slice variable to originate from a two-arg make([]T, 0) call: zeroLengthSliceAssignment (pkg/linters/slicemakezerolength/slicemakezerolength.go:67-122) only matches an AssignStmt or DeclStmt whose right-hand value is a *ast.CallExpr resolving to the builtin make, and the DeclStmt branch additionally requires len(spec.Values) == 1, i.e. an explicit initializer.
Evidence
pkg/parser/content_extractor.go:169-180 has exactly the pattern this linter exists to catch:
```go
var normalizedValue []any
switch v := fieldValue.(type) {
case []string:
for _, s := range v {
normalizedValue = append(normalizedValue, s)
}
}
```
v is a []string (hasKnownRangeSize accepts string/slice/array/map underlying types) and the loop body is a single unconditional append (appendsOneElement accepts exactly this shape). The only reason this real production site passes undetected is that normalizedValue is declared with var normalizedValue []any, a zero-value nil slice with no initializer, instead of make([]any, 0). Because ValueSpec.Values is empty in that case, zeroLengthSliceAssignment returns false at the len(spec.Values) != 1 check before it ever inspects a make call.
Impact
var x []T is the idiomatic, more common Go spelling for exactly this initialize-then-append-in-a-known-size-loop shape (common Go style guidance prefers the nil-slice form over make([]T, 0) for a var that will only ever grow via append). A linter whose stated goal is finding capacity-preallocation opportunities but whose match rule only recognizes the less-idiomatic make([]T, 0) spelling will have a systematically low real-world hit rate: developers who already reach for the preferred spelling are entirely invisible to it.
Recommendation
Extend zeroLengthSliceAssignment to also accept a DeclStmt ValueSpec with zero Values (a bare var s []T where the type is an *ast.ArrayType with Len nil) as a starting state equivalent to make([]T, 0) — both begin as an empty, zero-capacity slice. Add a testdata case mirroring content_extractor.go (var s []T; for _, x := range known-size-expr { s = append(s, x) }) alongside the existing badZeroLengthNoCapacity case.
Validation checklist
- New testdata case for the bare var declaration produces a diagnostic.
- Existing make([]T, 0) and make([]T, 0x0) cases keep passing unchanged.
- A bare var s []T with no follow-on loop (mirroring goodWithoutGrowth) still produces no diagnostic.
Effort: small — one additional branch in zeroLengthSliceAssignment plus one testdata case.
> [!WARNING]
>
> Firewall blocked 1 domain
>
> The following domain was blocked by the firewall during workflow execution:
>
> - `api.anthropic.com`
>
> To allow these domains, add them to the `network.allowed` list in your workflow frontmatter:
>
> ```yaml
> network:
> allowed:
> - defaults
> - "api.anthropic.com"
> ```
>
> See [Network Configuration](https://github.github.com/gh-aw/reference/network/) for more information.
>
>
> Generated by [🤖 Sergo - Serena Go Expert](https://github.com/github/gh-aw/actions/runs/34671215893) · claude · agent · 202 AIC · ⌖ 7.68 AIC · ⊞ 6.8K · [◷](https://github.com/search?q=repo%3Agithub%2Fgh-aw+is%3Aissue+%22gh-aw-workflow-call-id%3A+github%2Fgh-aw%2Fsergo%22&type=issues)
> - [x] expires on Sep 18, 2026, 7:56 PM UTC-08:00
Contributor guide
Research direction
Start in pkg/linters/slicemakezerolength/slicemakezerolength.go, especially zeroLengthSliceAssignment around lines 67-122, then inspect the existing badZeroLengthNoCapacity and goodWithoutGrowth testdata cases. Add coverage for a bare var s []T followed by a known-size range and append, while preserving the existing make cases and no-growth behavior. Run the slicemakezerolength tests and confirm the new pattern produces a diagnostic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100