[tools] go/analysis/passes/errorsas: modernize As -> AsType[T]

1 view
Skip to first unread message

Alan Donovan (Gerrit)

unread,
Oct 7, 2025, 5:23:14 PM (15 hours ago) Oct 7
to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go LUCI, Robert Findley, Austin Clements, golang-co...@googlegroups.com

Alan Donovan submitted the change with unreviewed changes

Unreviewed changes

5 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: go/analysis/passes/modernize/modernize_test.go
Insertions: 2, Deletions: 2.

@@ -24,8 +24,8 @@
RunWithSuggestedFixes(t, TestData(), modernize.AnyAnalyzer, "any")
}

-func TestErrorsAs(t *testing.T) {
- RunWithSuggestedFixes(t, TestData(), goplsexport.ErrorsAsModernizer, "errorsastype/...")
+func TestErrorsAsType(t *testing.T) {
+ RunWithSuggestedFixes(t, TestData(), goplsexport.ErrorsAsTypeModernizer, "errorsastype/...")
}

func TestFmtAppendf(t *testing.T) {
@@ -36,8 +36,8 @@
RunWithSuggestedFixes(t, TestData(), modernize.ForVarAnalyzer, "forvar")
}

-func TestIterators(t *testing.T) {
- RunWithSuggestedFixes(t, TestData(), goplsexport.IteratorsModernizer, "iterators")
+func TestStdIterators(t *testing.T) {
+ RunWithSuggestedFixes(t, TestData(), goplsexport.StdIteratorsModernizer, "stditerators")
}

func TestMapsLoop(t *testing.T) {
```
```
The name of the file: gopls/internal/settings/analysis.go
Insertions: 1, Deletions: 1.

@@ -251,10 +251,10 @@
{analyzer: modernize.AnyAnalyzer, severity: protocol.SeverityHint},
{analyzer: modernize.AppendClippedAnalyzer, severity: protocol.SeverityHint, nonDefault: true}, // not nil-preserving
{analyzer: modernize.BLoopAnalyzer, severity: protocol.SeverityHint},
- {analyzer: goplsexport.ErrorsAsModernizer, severity: protocol.SeverityHint},
+ {analyzer: goplsexport.ErrorsAsTypeModernizer, severity: protocol.SeverityHint},
{analyzer: modernize.FmtAppendfAnalyzer, severity: protocol.SeverityHint},
{analyzer: modernize.ForVarAnalyzer, severity: protocol.SeverityHint},
- {analyzer: goplsexport.IteratorsModernizer, severity: protocol.SeverityHint},
+ {analyzer: goplsexport.StdIteratorsModernizer, severity: protocol.SeverityHint},
{analyzer: modernize.MapsLoopAnalyzer, severity: protocol.SeverityHint},
{analyzer: modernize.MinMaxAnalyzer, severity: protocol.SeverityHint},
{analyzer: modernize.NewExprAnalyzer, severity: protocol.SeverityHint},
```
```
The name of the file: internal/goplsexport/export.go
Insertions: 2, Deletions: 2.

@@ -9,6 +9,6 @@
import "golang.org/x/tools/go/analysis"

var (
- ErrorsAsModernizer *analysis.Analyzer // = modernize.errorsasAnalyzer
- IteratorsModernizer *analysis.Analyzer // = modernize.iteratorsAnalyzer
+ ErrorsAsTypeModernizer *analysis.Analyzer // = modernize.errorsastypeAnalyzer
+ StdIteratorsModernizer *analysis.Analyzer // = modernize.stditeratorsAnalyer
)
```
```
The name of the file: go/analysis/passes/modernize/errorsastype.go
Insertions: 23, Deletions: 3.

@@ -22,7 +22,7 @@
"golang.org/x/tools/internal/typesinternal/typeindex"
)

-var errorsasAnalyzer = &analysis.Analyzer{
+var errorsastypeAnalyzer = &analysis.Analyzer{
Name: "errorsastype",
Doc: analysisinternal.MustExtractDoc(doc, "errorsastype"),
URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#errorsastype",
@@ -32,7 +32,7 @@

func init() {
// Export to gopls until this is a published modernizer.
- goplsexport.ErrorsAsModernizer = errorsasAnalyzer
+ goplsexport.ErrorsAsTypeModernizer = errorsastypeAnalyzer
}

// errorsastype offers a fix to replace error.As with the newer
@@ -62,6 +62,19 @@
// detects actual mistakes in the use of errors.As. This logic does
// not belong in errorsas because the problems it fixes are merely
// stylistic.
+//
+// TODO(adonovan): support more cases:
+//
+// - Negative cases
+// var myerr E
+// if !errors.As(err, &myerr) { ... }
+// =>
+// myerr, ok := errors.AsType[E](err)
+// if !ok { ... }
+//
+// - if myerr := new(E); errors.As(err, myerr); { ... }
+//
+// - if errors.As(err, myerr) && othercond { ... }
func errorsastype(pass *analysis.Pass) (any, error) {
skipGenerated(pass)

@@ -98,9 +111,16 @@
}

// Format the type as valid Go syntax.
- // TODO(adonovan): FileQualifier needs to respect
+ // TODO(adonovan): fix: FileQualifier needs to respect
// visibility at the current point, and either fail
// or edit the imports as needed.
+ // TODO(adonovan): fix: TypeString is not a sound way
+ // to print types as Go syntax as it does not respect
+ // symbol visibility, etc. We need something loosely
+ // integrated with FileQualifier that accumulates
+ // import edits, and may fail (e.g. for unexported
+ // type or field names from other packages).
+ // See https://go.dev/issues/75604.
qual := typesinternal.FileQualifier(file, pass.Pkg)
errtype := types.TypeString(v.Type(), qual)

```

Change information

Commit message:
go/analysis/passes/modernize: errorsastype: errors.As -> AsType[T]

This CL adds a modernizer that replaces simple uses of
errors.As such as:

var myerr *MyErr
if errors.As(err, &myerr) {
handle(myerr)
}

with the less error-prone generic [errors.AsType] function,
introduced in Go 1.26:

if myerr, ok := errors.AsType[*MyErr](err); ok {
handle(myerr)
}

Also, redo the existing errorsas vet check (for actual bugs)
to take advantage of newer analysis features.

Fixes golang/go#75692
Updates golang/go#51945
Change-Id: I56bd5370449daeacedf5634e46c2a29697dcbf19
Reviewed-by: Robert Findley <rfin...@google.com>
Files:
  • M go/analysis/passes/errorsas/errorsas.go
  • M go/analysis/passes/errorsas/errorsas_test.go
  • A go/analysis/passes/errorsas/main.go
  • M go/analysis/passes/modernize/doc.go
  • A go/analysis/passes/modernize/errorsastype.go
  • M go/analysis/passes/modernize/modernize_test.go
  • A go/analysis/passes/modernize/testdata/src/errorsastype/dotimport/a.go
  • A go/analysis/passes/modernize/testdata/src/errorsastype/dotimport/a.go.golden
  • A go/analysis/passes/modernize/testdata/src/errorsastype/errorsastype.go
  • A go/analysis/passes/modernize/testdata/src/errorsastype/errorsastype.go.golden
  • M gopls/doc/analyzers.md
  • M gopls/internal/doc/api.json
  • M gopls/internal/settings/analysis.go
  • M internal/goplsexport/export.go
Change size: L
Delta: 14 files changed, 477 insertions(+), 39 deletions(-)
Branch: refs/heads/master
Submit Requirements:
  • requirement satisfiedCode-Review: +2 by Robert Findley
  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I56bd5370449daeacedf5634e46c2a29697dcbf19
Gerrit-Change-Number: 708895
Gerrit-PatchSet: 9
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-CC: Austin Clements <aus...@google.com>
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages