Skip to content

Migrate errors.As to errors.AsType[T]#5304

Open
pietern wants to merge 7 commits into
mainfrom
go1.26-errors-astype
Open

Migrate errors.As to errors.AsType[T]#5304
pietern wants to merge 7 commits into
mainfrom
go1.26-errors-astype

Conversation

@pietern
Copy link
Copy Markdown
Contributor

@pietern pietern commented May 21, 2026

Stacked on top of #5302.

Go 1.26 adds the generic, compile-time-checked errors.AsType[T]. Migrates the 75 call sites and adds a forbidigo rule. One //nolint exception where the target type is dynamic.

This pull request and its description were written by Isaac.

pietern added 6 commits May 21, 2026 20:24
Bump Go to `go1.26.0` / `toolchain go1.26.3` across all four modules. This
cleans up an inconsistency: `go.mod`, `tools/task/go.mod`, and
`bundle/internal/tf/codegen/go.mod` were sitting at `go 1.25.8` while
`tools/go.mod` had drifted back to `go 1.25.0`. All four are now in sync.

Release notes: https://go.dev/doc/go1.26

Co-authored-by: Isaac
Bumping the `go` directive to 1.26.0 unlocks two modernize analyzers that
were silent on 1.25:

  * stditerators - prefer reflect.Type.Fields()/Methods() and
    reflect.Value.Fields()/Methods() over the classic
    NumField()/Field(i) loop pattern.
  * newexpr - replace local `*T` helpers like `func intPtr(v int) *int
    { return &v }` (and their callers) with Go 1.26's `new(expr)`.

This commit is the verbatim output of `golangci-lint run --fix ./...`,
applied at the same time as the toolchain bump so CI doesn't fail the
moment the bump lands.

A few `field := field` style redeclarations the fixer leaves behind are
harmless (the loop variable is fresh per-iteration since Go 1.22). Leaving
those for a follow-up cleanup rather than expanding the diff here.

Co-authored-by: Isaac
Follow-up to the previous commit, which the previous commit message
deferred. Two cosmetic clean-ups:

1. Remove 14 redundant `x := x` redeclarations the modernize fixer left
   inside `for x := range t.Fields()` (or `.Methods()`) loops. The loop
   variable is already fresh per-iteration since Go 1.22, so the shadow
   was a no-op kept only to preserve the variable name from the old
   `field := t.Field(i)` pattern.

2. Remove dead `*Ptr` helper functions whose call sites were inlined to
   `new(expr)`. The fixer added `//go:fix inline` directives and rewrote
   the bodies to `return new(v)`, leaving the functions themselves with
   zero callers (except `int64Ptr`, where `new(700)` would yield `*int`
   instead of `*int64`; here we rewrite the 20 callers to
   `new(int64(N))` and drop the helper too).

  * bundle/docsgen/nodes_test.go: drop strPtr
  * libs/apps/runlocal/spec_test.go: drop stringPtr
  * libs/structs/structaccess/convert_test.go: drop stringPtr, intPtr,
    float64Ptr, boolPtr
  * cmd/pipelines/history_test.go: rewrite int64Ptr callers, drop helper

Co-authored-by: Isaac
Go 1.26 introduces errors.AsType[T error](err error) (T, bool): a generic,
type-safe, faster alternative to errors.As(err, &target) that removes the
need to declare a zero-valued target variable just to pass its address.

This commit only adds the rule; lint will fail on the 70+ existing call
sites. The follow-up commit migrates them.

Co-authored-by: Isaac
Go 1.26's errors.AsType[T] is a generic, type-safe replacement for the
pattern of declaring a zero-valued target var and passing &target to
errors.As. The generic form returns (T, bool) directly and is also faster
because the type check happens at compile time.

libs/errs/aggregate.go retains errors.As with a nolint directive: its
As(target any) method forwards a dynamic type that cannot be expressed as
a generic type parameter.

Co-authored-by: Isaac
@pietern pietern temporarily deployed to test-trigger-is May 21, 2026 19:09 — with GitHub Actions Inactive
@pietern pietern temporarily deployed to test-trigger-is May 21, 2026 19:09 — with GitHub Actions Inactive
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

eng-dev-ecosystem-bot commented May 21, 2026

Commit: 967269c

Run: 26273709409

Base automatically changed from bump-go1.26 to main May 21, 2026 20:46
@pietern pietern temporarily deployed to test-trigger-is May 22, 2026 07:08 — with GitHub Actions Inactive
@pietern pietern temporarily deployed to test-trigger-is May 22, 2026 07:08 — with GitHub Actions Inactive
Comment thread .golangci.yaml
- pattern: 'sync\.Once\b($|[^FV])'
msg: Use sync.OnceFunc, sync.OnceValue, or sync.OnceValues instead.
- pattern: 'errors\.As\b'
msg: 'Use errors.AsType[T](err) for type-safe error unwrapping (Go 1.26+). errors.As remains available but the generic form removes the need for a target variable.'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
msg: 'Use errors.AsType[T](err) for type-safe error unwrapping (Go 1.26+). errors.As remains available but the generic form removes the need for a target variable.'
msg: 'Use errors.AsType[T](err) for type-safe error unwrapping (Go 1.26+).'

rule forbids errors.As so saying it remains available is confusing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants