]> Cypherpunks repositories - gostls13.git/commitdiff
all: replace calls to errors.As with errors.AsType
authorJulien Cretel <jub0bsinthecloud@gmail.com>
Wed, 1 Oct 2025 20:08:18 +0000 (20:08 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 13 Oct 2025 17:12:48 +0000 (10:12 -0700)
This change replaces most occurrences (in code as well as in comments) of
errors.As with errors.AsType. It leaves the errors package and vendored
code untouched.

Change-Id: I3bde73f318a0b408bdb8f5a251494af15a13118a
GitHub-Last-Rev: 8aaaa36a5a12d2a6a90c6d51680464e1a3115139
GitHub-Pull-Request: golang/go#75698
Reviewed-on: https://go-review.googlesource.com/c/go/+/708495
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
58 files changed:
src/cmd/compile/internal/types2/api_test.go
src/cmd/go/internal/base/path.go
src/cmd/go/internal/doc/pkgsite.go
src/cmd/go/internal/fmtcmd/fmt.go
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/modget/get.go
src/cmd/go/internal/modget/query.go
src/cmd/go/internal/modload/build.go
src/cmd/go/internal/modload/buildlist.go
src/cmd/go/internal/modload/edit.go
src/cmd/go/internal/modload/import.go
src/cmd/go/internal/modload/list.go
src/cmd/go/internal/modload/load.go
src/cmd/go/internal/modload/modfile.go
src/cmd/go/internal/modload/query.go
src/cmd/go/internal/test/test.go
src/cmd/go/internal/test/testflag.go
src/cmd/go/internal/vcweb/vcstest/vcstest_test.go
src/cmd/go/internal/vcweb/vcweb.go
src/cmd/go/internal/version/version.go
src/cmd/go/internal/vet/vetflag.go
src/cmd/go/internal/work/build.go
src/cmd/go/internal/work/exec.go
src/cmd/internal/bootstrap_test/experiment_toolid_test.go
src/cmd/internal/robustio/robustio_darwin.go
src/cmd/internal/robustio/robustio_flaky.go
src/cmd/internal/robustio/robustio_windows.go
src/cmd/internal/script/engine.go
src/cmd/internal/script/scripttest/scripttest.go
src/cmd/link/link_test.go
src/crypto/tls/conn.go
src/crypto/tls/handshake_server.go
src/crypto/tls/handshake_server_test.go
src/crypto/tls/quic.go
src/crypto/tls/quic_test.go
src/debug/buildinfo/buildinfo.go
src/encoding/json/jsontext/coder_test.go
src/encoding/json/jsontext/fuzz_test.go
src/encoding/json/jsontext/state.go
src/encoding/json/v2/errors.go
src/encoding/json/v2/example_test.go
src/go/types/api_test.go
src/internal/runtime/wasitest/testdata/tcpecho.go
src/internal/testenv/testenv_unix.go
src/io/fs/readdir_test.go
src/log/log_test.go
src/log/slog/logger_test.go
src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go
src/net/http/h2_error_test.go
src/net/lookup_test.go
src/os/exec/exec_test.go
src/os/os_test.go
src/runtime/pprof/proto_windows.go
src/testing/fstest/testfs.go
src/testing/fstest/testfs_test.go
src/text/template/exec_test.go
src/text/template/funcs.go

index 0d3c8b8e3e5e0f692cad03dc144a4664c7e897e3..4b7012e6c45e9f96a94a5763a126c0d5ea48b306 100644 (file)
@@ -2468,8 +2468,8 @@ func TestInstantiateErrors(t *testing.T) {
                        t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
                }
 
-               var argErr *ArgumentError
-               if !errors.As(err, &argErr) {
+               argErr, ok := errors.AsType[*ArgumentError](err)
+               if !ok {
                        t.Fatalf("Instantiate(%v, %v): error is not an *ArgumentError", T, test.targs)
                }
 
@@ -2484,8 +2484,8 @@ func TestArgumentErrorUnwrapping(t *testing.T) {
                Index: 1,
                Err:   Error{Msg: "test"},
        }
-       var e Error
-       if !errors.As(err, &e) {
+       e, ok := errors.AsType[Error](err)
+       if !ok {
                t.Fatalf("error %v does not wrap types.Error", err)
        }
        if e.Msg != "test" {
index 5bb7bc3bde63e263270c4ed7e95cfb84bf290be3..a7577f62e768985806601f42f5f36980e150c4fb 100644 (file)
@@ -55,8 +55,7 @@ func sameFile(path1, path2 string) bool {
 
 // ShortPathError rewrites the path in err using base.ShortPath, if err is a wrapped PathError.
 func ShortPathError(err error) error {
-       var pe *fs.PathError
-       if errors.As(err, &pe) {
+       if pe, ok := errors.AsType[*fs.PathError](err); ok {
                pe.Path = ShortPath(pe.Path)
        }
        return err
index 06289ac4fc9a8a69d01eea063e8457a167b25c13..c173167b6329a4f193776e397d205bb1b88208cf 100644 (file)
@@ -81,8 +81,7 @@ func doPkgsite(urlPath, fragment string) error {
        cmd.Stderr = os.Stderr
 
        if err := cmd.Run(); err != nil {
-               var ee *exec.ExitError
-               if errors.As(err, &ee) {
+               if ee, ok := errors.AsType[*exec.ExitError](err); ok {
                        // Exit with the same exit status as pkgsite to avoid
                        // printing of "exit status" error messages.
                        // Any relevant messages have already been printed
index 62b22f6bcfa4079e418ab816b5448d156af91b09..83fba9661a66fcd3f51908c48c0b8a9e9476ed53 100644 (file)
@@ -68,11 +68,10 @@ func runFmt(ctx context.Context, cmd *base.Command, args []string) {
                        continue
                }
                if pkg.Error != nil {
-                       var nogo *load.NoGoError
-                       var embed *load.EmbedError
-                       if (errors.As(pkg.Error, &nogo) || errors.As(pkg.Error, &embed)) && len(pkg.InternalAllGoFiles()) > 0 {
-                               // Skip this error, as we will format
-                               // all files regardless.
+                       if _, ok := errors.AsType[*load.NoGoError](pkg.Error); ok {
+                               // Skip this error, as we will format all files regardless.
+                       } else if  _, ok := errors.AsType[*load.EmbedError](pkg.Error); ok && len(pkg.InternalAllGoFiles()) > 0 {
+                               // Skip this error, as we will format all files regardless.
                        } else {
                                base.Errorf("%v", pkg.Error)
                                continue
index 135d7579d65dffabd6f2a68c2034970c05da77f5..a894affc8440668e15b7d303562f3505aef71518 100644 (file)
@@ -290,8 +290,8 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
 
        // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
        // The latter is more specific about the cause.
-       var nogoErr *build.NoGoError
-       if errors.As(err, &nogoErr) {
+       nogoErr, ok := errors.AsType[*build.NoGoError](err)
+       if ok {
                if p.Dir == "" && nogoErr.Dir != "" {
                        p.Dir = nogoErr.Dir
                }
index d8b1f83bf1d132522f1d90b7b087a4bd299e8e09..5017f878ed3647e6a26699fbbcb3d9da86a7a05f 100644 (file)
@@ -1294,15 +1294,13 @@ func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPack
                        continue
                }
 
-               var (
-                       importMissing *modload.ImportMissingError
-                       ambiguous     *modload.AmbiguousImportError
-               )
-               if !errors.As(err, &importMissing) && !errors.As(err, &ambiguous) {
-                       // The package, which is a dependency of something we care about, has some
-                       // problem that we can't resolve with a version change.
-                       // Leave the error for the final LoadPackages call.
-                       continue
+               if _, ok := errors.AsType[*modload.ImportMissingError](err); !ok {
+                       if _, ok := errors.AsType[*modload.AmbiguousImportError](err); !ok {
+                               // The package, which is a dependency of something we care about, has some
+                               // problem that we can't resolve with a version change.
+                               // Leave the error for the final LoadPackages call.
+                               continue
+                       }
                }
 
                path := pkgPath
@@ -1674,7 +1672,7 @@ func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []strin
                                }
 
                                base.SetExitStatus(1)
-                               if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) {
+                               if ambiguousErr, ok := errors.AsType[*modload.AmbiguousImportError](err); ok {
                                        for _, m := range ambiguousErr.Modules {
                                                relevantMods[m] |= hasPkg
                                        }
@@ -1717,7 +1715,7 @@ func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []strin
                i := i
                r.work.Add(func() {
                        err := modload.CheckRetractions(ctx, retractions[i].m)
-                       if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) {
+                       if _, ok := errors.AsType[*modload.ModuleRetractedError](err); ok {
                                retractions[i].message = err.Error()
                        }
                })
@@ -1994,8 +1992,8 @@ func (r *resolver) updateBuildList(ctx context.Context, additions []module.Versi
                        toolchain.SwitchOrFatal(ctx, err)
                }
 
-               var constraint *modload.ConstraintError
-               if !errors.As(err, &constraint) {
+               constraint, ok := errors.AsType[*modload.ConstraintError](err)
+               if !ok {
                        base.Fatal(err)
                }
 
@@ -2066,8 +2064,11 @@ func reqsFromGoMod(f *modfile.File) []module.Version {
 // does not exist at the requested version, either because the module does not
 // exist at all or because it does not include that specific version.
 func isNoSuchModuleVersion(err error) bool {
-       var noMatch *modload.NoMatchingVersionError
-       return errors.Is(err, os.ErrNotExist) || errors.As(err, &noMatch)
+       if errors.Is(err, os.ErrNotExist) {
+               return true
+       }
+       _, ok := errors.AsType[*modload.NoMatchingVersionError](err)
+       return ok
 }
 
 // isNoSuchPackageVersion reports whether err indicates that the requested
@@ -2075,8 +2076,11 @@ func isNoSuchModuleVersion(err error) bool {
 // that could contain it exists at that version, or because every such module
 // that does exist does not actually contain the package.
 func isNoSuchPackageVersion(err error) bool {
-       var noPackage *modload.PackageNotInModuleError
-       return isNoSuchModuleVersion(err) || errors.As(err, &noPackage)
+       if isNoSuchModuleVersion(err) {
+               return true
+       }
+       _, ok := errors.AsType[*modload.PackageNotInModuleError](err)
+       return ok
 }
 
 // workspace represents the set of modules in a workspace.
index db09947293c6dc831b72a7d8020f7bf1dfd4fb2e..59f3023ffc4f41950cda76c892a8b2d49a53da26 100644 (file)
@@ -283,7 +283,7 @@ func reportError(q *query, err error) {
        // If err already mentions all of the relevant parts of q, just log err to
        // reduce stutter. Otherwise, log both q and err.
        //
-       // TODO(bcmills): Use errors.As to unpack these errors instead of parsing
+       // TODO(bcmills): Use errors.AsType to unpack these errors instead of parsing
        // strings with regular expressions.
 
        if !utf8.ValidString(q.pattern) || !utf8.ValidString(q.version) {
index cb168d58a227bc0a7f1d513bc43d8de35f5d565b..a8ab82d1ecb2461267e8cb0cfb957231a18d2ea6 100644 (file)
@@ -129,11 +129,10 @@ func addUpdate(ctx context.Context, m *modinfo.ModulePublic) {
        }
 
        info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed)
-       var noVersionErr *NoMatchingVersionError
-       if errors.Is(err, ErrDisallowed) ||
+       if _, ok := errors.AsType[*NoMatchingVersionError](err); ok ||
                errors.Is(err, fs.ErrNotExist) ||
-               errors.As(err, &noVersionErr) {
-               // Ignore "not found" and "no matching version" errors.
+               errors.Is(err, ErrDisallowed) {
+               // Ignore "no matching version" and "not found" errors.
                // This means the proxy has no matching version or no versions at all.
                //
                // Ignore "disallowed" errors. This means the current version is
@@ -238,10 +237,10 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
        }
 
        err := CheckRetractions(ctx, module.Version{Path: m.Path, Version: m.Version})
-       var noVersionErr *NoMatchingVersionError
-       var retractErr *ModuleRetractedError
-       if err == nil || errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
-               // Ignore "not found" and "no matching version" errors.
+       if err == nil {
+               return
+       } else if _, ok := errors.AsType[*NoMatchingVersionError](err); ok || errors.Is(err, fs.ErrNotExist) {
+               // Ignore "no matching version" and "not found" errors.
                // This means the proxy has no matching version or no versions at all.
                //
                // We should report other errors though. An attacker that controls the
@@ -250,7 +249,7 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
                // hide versions, since the "list" and "latest" endpoints are not
                // authenticated.
                return
-       } else if errors.As(err, &retractErr) {
+       } else if retractErr, ok := errors.AsType[*ModuleRetractedError](err); ok {
                if len(retractErr.Rationale) == 0 {
                        m.Retracted = []string{"retracted by module author"}
                } else {
@@ -265,9 +264,8 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
 // author. m.Error is set if there's an error loading deprecation information.
 func addDeprecation(ctx context.Context, m *modinfo.ModulePublic) {
        deprecation, err := CheckDeprecation(ctx, module.Version{Path: m.Path, Version: m.Version})
-       var noVersionErr *NoMatchingVersionError
-       if errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
-               // Ignore "not found" and "no matching version" errors.
+       if _, ok := errors.AsType[*NoMatchingVersionError](err); ok || errors.Is(err, fs.ErrNotExist) {
+               // Ignore "no matching version" and "not found" errors.
                // This means the proxy has no matching version or no versions at all.
                //
                // We should report other errors though. An attacker that controls the
index 086626042c95b7555f5b42580caf1f6d895dc68c..cf64ee1dc210f90ce50717f4627d31923b343251 100644 (file)
@@ -922,7 +922,7 @@ func tidyPrunedRoots(ctx context.Context, mainModule module.Version, old *Requir
                        q.Add(func() {
                                skipModFile := true
                                _, _, _, _, err := importFromModules(ctx, pkg.path, tidy, nil, skipModFile)
-                               if aie := (*AmbiguousImportError)(nil); errors.As(err, &aie) {
+                               if _, ok := errors.AsType[*AmbiguousImportError](err); ok {
                                        disambiguateRoot.Store(pkg.mod, true)
                                }
                        })
index 153c21a90cc423092ced743c8510454b8bed3964..96d864545d042afac3e9fd7ef4ee0bd4de0e0eb1 100644 (file)
@@ -226,8 +226,10 @@ func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade, mustSel
                // conflict we discover from one or more of the original roots.
                mg, upgradedRoots, err := extendGraph(ctx, rootPruning, roots, selectedRoot)
                if err != nil {
-                       var tooNew *gover.TooNewError
-                       if mg == nil || errors.As(err, &tooNew) {
+                       if mg == nil {
+                               return orig, false, err
+                       }
+                       if _, ok := errors.AsType[*gover.TooNewError](err); ok {
                                return orig, false, err
                        }
                        // We're about to walk the entire extended module graph, so we will find
index 83e7e037117a4d5de6d6be21c6e3ea8ca4105484..392fe3edd77b52c0049ec93d42c4c0c33421c2aa 100644 (file)
@@ -410,7 +410,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
 
                        root, isLocal, err := fetch(ctx, m)
                        if err != nil {
-                               if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
+                               if _, ok := errors.AsType[*sumMissingError](err); ok {
                                        // We are missing a sum needed to fetch a module in the build list.
                                        // We can't verify that the package is unique, and we may not find
                                        // the package at all. Keep checking other modules to decide which
@@ -549,7 +549,7 @@ func queryImport(ctx context.Context, path string, rs *Requirements) (module.Ver
        for _, m := range mods {
                root, isLocal, err := fetch(ctx, m)
                if err != nil {
-                       if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
+                       if _, ok := errors.AsType[*sumMissingError](err); ok {
                                return module.Version{}, &ImportMissingSumError{importPath: path}
                        }
                        return module.Version{}, err
index b66e73a112cedd2730a9554408772c8b2c2462bc..803bab49ae96bbccf950d4c334eadbd6107e8580 100644 (file)
@@ -305,13 +305,11 @@ func listModules(ctx context.Context, rs *Requirements, args []string, mode List
 // modinfoError wraps an error to create an error message in
 // modinfo.ModuleError with minimal redundancy.
 func modinfoError(path, vers string, err error) *modinfo.ModuleError {
-       var nerr *NoMatchingVersionError
-       var merr *module.ModuleError
-       if errors.As(err, &nerr) {
+       if _, ok := errors.AsType[*NoMatchingVersionError](err); ok {
                // NoMatchingVersionError contains the query, so we don't mention the
                // query again in ModuleError.
                err = &module.ModuleError{Path: path, Err: err}
-       } else if !errors.As(err, &merr) {
+       } else if _, ok := errors.AsType[*module.ModuleError](err); !ok {
                // If the error does not contain path and version, wrap it in a
                // module.ModuleError.
                err = &module.ModuleError{Path: path, Version: vers, Err: err}
index 413de8148fb79e8d94045a21bbca17a8de347933..0d661eb2e7b0be016438a774b1a178dbff55220d 100644 (file)
@@ -1304,7 +1304,7 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
                }
 
                // Add importer information to checksum errors.
-               if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
+               if sumErr, ok := errors.AsType[*ImportMissingSumError](pkg.err); ok {
                        if importer := pkg.stack; importer != nil {
                                sumErr.importer = importer.path
                                sumErr.importerVersion = importer.mod.Version
@@ -1312,7 +1312,7 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
                        }
                }
 
-               if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) && stdErr.isStd {
+               if stdErr, ok := errors.AsType[*ImportMissingError](pkg.err); ok && stdErr.isStd {
                        // Add importer go version information to import errors of standard
                        // library packages arising from newer releases.
                        if importer := pkg.stack; importer != nil {
@@ -1384,7 +1384,7 @@ func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err err
        var maxTooNew *gover.TooNewError
        for _, pkg := range ld.pkgs {
                if pkg.err != nil {
-                       if tooNew := (*gover.TooNewError)(nil); errors.As(pkg.err, &tooNew) {
+                       if tooNew, ok := errors.AsType[*gover.TooNewError](pkg.err); ok {
                                if maxTooNew == nil || gover.Compare(tooNew.GoVersion, maxTooNew.GoVersion) > 0 {
                                        maxTooNew = tooNew
                                }
@@ -1573,7 +1573,7 @@ func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[mod
                        // we should only add the missing import once.
                        continue
                }
-               if !errors.As(pkg.err, new(*ImportMissingError)) {
+               if _, ok := errors.AsType[*ImportMissingError](pkg.err); !ok {
                        // Leave other errors for Import or load.Packages to report.
                        continue
                }
@@ -1584,8 +1584,7 @@ func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[mod
                        var err error
                        mod, err = queryImport(ctx, pkg.path, ld.requirements)
                        if err != nil {
-                               var ime *ImportMissingError
-                               if errors.As(err, &ime) {
+                               if ime, ok := errors.AsType[*ImportMissingError](err); ok {
                                        for curstack := pkg.stack; curstack != nil; curstack = curstack.stack {
                                                if LoaderState.MainModules.Contains(curstack.mod.Path) {
                                                        ime.ImportingMainModule = curstack.mod
@@ -1625,7 +1624,7 @@ func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[mod
                maxTooNewPkg *loadPkg
        )
        for _, pm := range pkgMods {
-               if tooNew := (*gover.TooNewError)(nil); errors.As(pm.pkg.err, &tooNew) {
+               if tooNew, ok := errors.AsType[*gover.TooNewError](pm.pkg.err); ok {
                        if maxTooNew == nil || gover.Compare(tooNew.GoVersion, maxTooNew.GoVersion) > 0 {
                                maxTooNew = tooNew
                                maxTooNewPkg = pm.pkg
@@ -1771,8 +1770,7 @@ func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (ch
                        // full module graph.
                        m, _, _, _, err := importFromModules(ctx, path, ld.requirements, nil, ld.skipImportModFiles)
                        if err != nil {
-                               var missing *ImportMissingError
-                               if errors.As(err, &missing) && ld.ResolveMissingImports {
+                               if _, ok := errors.AsType[*ImportMissingError](err); ok && ld.ResolveMissingImports {
                                        // This package isn't provided by any selected module.
                                        // If we can find it, it will be a new root dependency.
                                        m, err = queryImport(ctx, path, ld.requirements)
@@ -2196,14 +2194,14 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements,
                        // module that previously provided the package to a version that no
                        // longer does, or to a version for which the module source code (but
                        // not the go.mod file in isolation) has a checksum error.
-                       if missing := (*ImportMissingError)(nil); errors.As(mismatch.err, &missing) {
+                       if _, ok := errors.AsType[*ImportMissingError](mismatch.err); ok {
                                selected := module.Version{
                                        Path:    pkg.mod.Path,
                                        Version: mg.Selected(pkg.mod.Path),
                                }
                                ld.error(fmt.Errorf("%s loaded from %v,\n\tbut go %s would fail to locate it in %s", pkg.stackText(), pkg.mod, compatVersion, selected))
                        } else {
-                               if ambiguous := (*AmbiguousImportError)(nil); errors.As(mismatch.err, &ambiguous) {
+                               if _, ok := errors.AsType[*AmbiguousImportError](mismatch.err); ok {
                                        // TODO: Is this check needed?
                                }
                                ld.error(fmt.Errorf("%s loaded from %v,\n\tbut go %s would fail to locate it:\n\t%v", pkg.stackText(), pkg.mod, compatVersion, mismatch.err))
index fa2348d97baf25e26e2aaf5f9d5952847f0b6b65..3fdbdc7010b993dad49b4a6bd62f847992324aa4 100644 (file)
@@ -76,8 +76,7 @@ func ReadModFile(gomod string, fix modfile.VersionFixer) (data []byte, f *modfil
 }
 
 func shortPathErrorList(err error) error {
-       var el modfile.ErrorList
-       if errors.As(err, &el) {
+       if el, ok := errors.AsType[modfile.ErrorList](err); ok {
                for i := range el {
                        el[i].Filename = base.ShortPath(el[i].Filename)
                }
@@ -175,12 +174,15 @@ func (e *excludedError) Is(err error) bool { return err == ErrDisallowed }
 // its author.
 func CheckRetractions(ctx context.Context, m module.Version) (err error) {
        defer func() {
-               if retractErr := (*ModuleRetractedError)(nil); err == nil || errors.As(err, &retractErr) {
+               if err == nil {
+                       return
+               }
+               if _, ok := errors.AsType[*ModuleRetractedError](err); ok {
                        return
                }
                // Attribute the error to the version being checked, not the version from
                // which the retractions were to be loaded.
-               if mErr := (*module.ModuleError)(nil); errors.As(err, &mErr) {
+               if mErr, ok := errors.AsType[*module.ModuleError](err); ok {
                        err = mErr.Err
                }
                err = &retractionLoadingError{m: m, err: err}
index 94ee8bc955918cf54cb7caacfd85a8e584825e20..b37a244fbbacddb356d45e1bfa8cc2f58c8a448f 100644 (file)
@@ -932,7 +932,7 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod
                                if notExistErr == nil {
                                        notExistErr = rErr
                                }
-                       } else if iv := (*module.InvalidVersionError)(nil); errors.As(rErr, &iv) {
+                       } else if _, ok := errors.AsType[*module.InvalidVersionError](rErr); ok {
                                if invalidVersion == nil {
                                        invalidVersion = rErr
                                }
index e667bd64f7997f796c8054f1edbddcc58663f462..e225929add20c2c692e2062ec5d67afe9e648b66 100644 (file)
@@ -1741,8 +1741,7 @@ func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action)
                } else if errors.Is(err, exec.ErrWaitDelay) {
                        fmt.Fprintf(cmd.Stdout, "*** Test I/O incomplete %v after exiting.\n", cmd.WaitDelay)
                }
-               var ee *exec.ExitError
-               if len(out) == 0 || !errors.As(err, &ee) || !ee.Exited() {
+               if ee, ok := errors.AsType[*exec.ExitError](err); !ok || !ee.Exited() || len(out) == 0 {
                        // If there was no test output, print the exit status so that the reason
                        // for failure is clear.
                        fmt.Fprintf(cmd.Stdout, "%s\n", err)
index fc2b22cb56a9ee4f35923a2ab3b77814dde6de08..d6891a1d0b955b8827f3aed5169112dcf7363740 100644 (file)
@@ -261,7 +261,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
                        break
                }
 
-               if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) {
+               if nf, ok := errors.AsType[cmdflag.NonFlagError](err); ok {
                        if !inPkgList && packageNames != nil {
                                // We already saw the package list previously, and this argument is not
                                // a flag, so it â€” and everything after it â€” must be either a value for
@@ -296,7 +296,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
                        inPkgList = false
                }
 
-               if nd := (cmdflag.FlagNotDefinedError{}); errors.As(err, &nd) {
+               if nd, ok := errors.AsType[cmdflag.FlagNotDefinedError](err); ok {
                        // This is a flag we do not know. We must assume that any args we see
                        // after this might be flag arguments, not package names, so make
                        // packageNames non-nil to indicate that the package list is complete.
index 67234ac20d462871700a138fb5be57fb6380ee11..6a6a0eee57ce851b4ae17d00459e727f839fb0de 100644 (file)
@@ -155,10 +155,10 @@ func TestScripts(t *testing.T) {
                                t.Log(buf)
                        }
                        if err != nil {
-                               if notInstalled := (vcweb.ServerNotInstalledError{}); errors.As(err, &notInstalled) || errors.Is(err, exec.ErrNotFound) {
+                               if _, ok := errors.AsType[vcweb.ServerNotInstalledError](err); ok || errors.Is(err, exec.ErrNotFound) {
                                        t.Skip(err)
                                }
-                               if skip := (vcweb.SkipError{}); errors.As(err, &skip) {
+                               if skip, ok := errors.AsType[vcweb.SkipError](err); ok {
                                        if skip.Msg == "" {
                                                t.Skip("SKIP")
                                        } else {
index b81ff5e63de72aeb1e20a71e38a1b37a6f1e4f4e..4b4e127bb042e086d34e9bd81a712aa7ca7d2003 100644 (file)
@@ -244,9 +244,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
        })
        if err != nil {
                s.logger.Print(err)
-               if notFound := (ScriptNotFoundError{}); errors.As(err, &notFound) {
+               if _, ok := errors.AsType[ScriptNotFoundError](err); ok {
                        http.NotFound(w, req)
-               } else if notInstalled := (ServerNotInstalledError{}); errors.As(err, &notInstalled) || errors.Is(err, exec.ErrNotFound) {
+               } else if _, ok := errors.AsType[ServerNotInstalledError](err); ok || errors.Is(err, exec.ErrNotFound) {
                        http.Error(w, err.Error(), http.StatusNotImplemented)
                } else {
                        http.Error(w, err.Error(), http.StatusInternalServerError)
index c26dd42b4e1a085fe90afabf1b889fb15a10c439..781bc080e89fe4f412d0baae8278d4d63d97bb7e 100644 (file)
@@ -168,7 +168,7 @@ func scanFile(file string, info fs.FileInfo, mustPrint bool) bool {
        bi, err := buildinfo.ReadFile(file)
        if err != nil {
                if mustPrint {
-                       if pathErr := (*os.PathError)(nil); errors.As(err, &pathErr) && filepath.Clean(pathErr.Path) == filepath.Clean(file) {
+                       if pathErr, ok := errors.AsType[*os.PathError](err); ok && filepath.Clean(pathErr.Path) == filepath.Clean(file) {
                                fmt.Fprintf(os.Stderr, "%v\n", file)
                        } else {
                                // Skip errors for non-Go binaries.
index 7ebd8c9bfd19eb8aca34c87af94ff07e6fc1103c..7342b99d6e36bb45341c4d955d3dc2219f9343e0 100644 (file)
@@ -160,7 +160,7 @@ func toolFlags(cmd *base.Command, args []string) (passToTool, packageNames []str
                        break
                }
 
-               if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) {
+               if _, ok := errors.AsType[cmdflag.NonFlagError](err); ok {
                        // Everything from here on out â€” including the argument we just consumed â€”
                        // must be a package name.
                        packageNames = args
index adc98f93138007e3f8c8436951302d8739f7f255..fdb483d46f21d957ec2239af5007c9c6714d5325 100644 (file)
@@ -705,7 +705,7 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) {
                                continue
                        }
                        haveErrors = true
-                       if missingErr := (*modload.ImportMissingError)(nil); !errors.As(pkg.Error, &missingErr) {
+                       if _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
                                allMissingErrors = false
                                break
                        }
index fa6ddce24bed3caf56c2b1db33ec4577d682d8a5..703b4367db31ef18ccdf572447bfbb325ea9524c 100644 (file)
@@ -169,9 +169,10 @@ func (b *Builder) Do(ctx context.Context, root *Action) {
                                        a.Package.Incomplete = true
                                }
                        } else {
-                               var ipe load.ImportPathError
-                               if a.Package != nil && (!errors.As(err, &ipe) || ipe.ImportPath() != a.Package.ImportPath) {
-                                       err = fmt.Errorf("%s: %v", a.Package.ImportPath, err)
+                               if a.Package != nil {
+                                       if ipe, ok := errors.AsType[load.ImportPathError](err); !ok || ipe.ImportPath() != a.Package.ImportPath {
+                                               err = fmt.Errorf("%s: %v", a.Package.ImportPath, err)
+                                       }
                                }
                                sh := b.Shell(a)
                                sh.Errorf("%s", err)
index ff2379c8998c76247dd2c3da38debeb576ed5741..ca292b700861a916b238288def1075f62a658d2f 100644 (file)
@@ -97,7 +97,7 @@ func runCmd(t *testing.T, dir string, env []string, path string, args ...string)
        cmd.Env = env
        out, err := cmd.Output()
        if err != nil {
-               if ee := (*exec.ExitError)(nil); errors.As(err, &ee) {
+               if ee, ok := errors.AsType[*exec.ExitError](err); ok {
                        out = append(out, ee.Stderr...)
                }
                t.Fatalf("%s failed:\n%s\n%s", cmd, out, err)
index 99fd8ebc2fff18afa6764b3e8c2a0fd26caa9241..69ea2479308dea22447eb33b8fb6213ca2bc707f 100644 (file)
@@ -13,9 +13,6 @@ const errFileNotFound = syscall.ENOENT
 
 // isEphemeralError returns true if err may be resolved by waiting.
 func isEphemeralError(err error) bool {
-       var errno syscall.Errno
-       if errors.As(err, &errno) {
-               return errno == errFileNotFound
-       }
-       return false
+       errno, ok := errors.AsType[syscall.Errno](err)
+       return ok && errno == errFileNotFound
 }
index c56e36ca62412aae46a98f41f5a2d9ad5191fe8e..ec1a2daea6585221ad3644ef4d79906ec98eabd1 100644 (file)
@@ -31,8 +31,7 @@ func retry(f func() (err error, mayRetry bool)) error {
                        return err
                }
 
-               var errno syscall.Errno
-               if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) {
+               if errno, ok := errors.AsType[syscall.Errno](err); ok && (lowestErrno == 0 || errno < lowestErrno) {
                        bestErr = err
                        lowestErrno = errno
                } else if bestErr == nil {
index 687dcb66f83d15d0be4c7d45f4652a236afb2ac2..ad46ec5cfeb60148f2d4e027c0f4696426d4bdde 100644 (file)
@@ -14,8 +14,7 @@ const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND
 
 // isEphemeralError returns true if err may be resolved by waiting.
 func isEphemeralError(err error) bool {
-       var errno syscall.Errno
-       if errors.As(err, &errno) {
+       if errno, ok := errors.AsType[syscall.Errno](err); ok {
                switch errno {
                case syscall.ERROR_ACCESS_DENIED,
                        syscall.ERROR_FILE_NOT_FOUND,
index eb9344f6e2a1eb1cc2cee89cd0e46eb970df2529..4607868379488a751874f192ca161eee80de66d1 100644 (file)
@@ -185,7 +185,7 @@ func (e *Engine) Execute(s *State, file string, script *bufio.Reader, log io.Wri
 
        var lineno int
        lineErr := func(err error) error {
-               if errors.As(err, new(*CommandError)) {
+               if _, ok := errors.AsType[*CommandError](err); ok {
                        return err
                }
                return fmt.Errorf("%s:%d: %w", file, lineno, err)
@@ -283,7 +283,7 @@ func (e *Engine) Execute(s *State, file string, script *bufio.Reader, log io.Wri
                // Run the command.
                err = e.runCommand(s, cmd, impl)
                if err != nil {
-                       if stop := (stopError{}); errors.As(err, &stop) {
+                       if stop, ok := errors.AsType[stopError](err); ok {
                                // Since the 'stop' command halts execution of the entire script,
                                // log its message separately from the section in which it appears.
                                err = endSection(true)
@@ -607,13 +607,13 @@ func checkStatus(cmd *command, err error) error {
                return nil
        }
 
-       if s := (stopError{}); errors.As(err, &s) {
+       if _, ok := errors.AsType[stopError](err); ok {
                // This error originated in the Stop command.
                // Propagate it as-is.
                return cmdError(cmd, err)
        }
 
-       if w := (waitError{}); errors.As(err, &w) {
+       if _, ok := errors.AsType[waitError](err); ok {
                // This error was surfaced from a background process by a call to Wait.
                // Add a call frame for Wait itself, but ignore its "want" field.
                // (Wait itself cannot fail to wait on commands or else it would leak
index bace662a6722fdaf210d7bc0197d2e291a3d07ee..349201fd188c1b8d967846733bfa205cd2c74917 100644 (file)
@@ -89,7 +89,7 @@ func Run(t testing.TB, e *script.Engine, s *script.State, filename string, testS
                return e.Execute(s, filename, bufio.NewReader(testScript), log)
        }()
 
-       if skip := (skipError{}); errors.As(err, &skip) {
+       if skip, ok := errors.AsType[skipError](err); ok {
                if skip.msg == "" {
                        t.Skip("SKIP")
                } else {
index 0125ba8e0f56beaa678890426e0929bda12b34c2..31822d21f39d314a74f3e74f4c089ea581d48798 100644 (file)
@@ -1532,11 +1532,13 @@ func TestFlagS(t *testing.T) {
                }
                cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "nm", exe)
                out, err = cmd.CombinedOutput()
-               if err != nil && !errors.As(err, new(*exec.ExitError)) {
-                       // Error exit is fine as it may have no symbols.
-                       // On darwin we need to emit dynamic symbol references so it
-                       // actually has some symbols, and nm succeeds.
-                       t.Errorf("(mode=%s) go tool nm failed: %v\n%s", mode, err, out)
+               if err != nil {
+                       if _, ok := errors.AsType[*exec.ExitError](err); !ok {
+                               // Error exit is fine as it may have no symbols.
+                               // On darwin we need to emit dynamic symbol references so it
+                               // actually has some symbols, and nm succeeds.
+                               t.Errorf("(mode=%s) go tool nm failed: %v\n%s", mode, err, out)
+                       }
                }
                for _, s := range syms {
                        if bytes.Contains(out, []byte(s)) {
index 09dc9ea94c939f6f54cbc6e8bbf135e070f0e0f3..2de120a1329f873516242e2924d605ba6c7dffe5 100644 (file)
@@ -1578,9 +1578,9 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
                        // the handshake (RFC 9001, Section 5.7).
                        c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
                } else {
-                       var a alert
                        c.out.Lock()
-                       if !errors.As(c.out.err, &a) {
+                       a, ok := errors.AsType[alert](c.out.err)
+                       if !ok {
                                a = alertInternalError
                        }
                        c.out.Unlock()
index 088c66fadb2a4446453b6b8852966ad3006e47e1..a2cf176a86c0d872faa040e21e43bae37acca810 100644 (file)
@@ -965,10 +965,9 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
 
                chains, err := certs[0].Verify(opts)
                if err != nil {
-                       var errCertificateInvalid x509.CertificateInvalidError
-                       if errors.As(err, &x509.UnknownAuthorityError{}) {
+                       if _, ok := errors.AsType[x509.UnknownAuthorityError](err); ok {
                                c.sendAlert(alertUnknownCA)
-                       } else if errors.As(err, &errCertificateInvalid) && errCertificateInvalid.Reason == x509.Expired {
+                       } else if errCertificateInvalid, ok := errors.AsType[x509.CertificateInvalidError](err); ok && errCertificateInvalid.Reason == x509.Expired {
                                c.sendAlert(alertCertificateExpired)
                        } else {
                                c.sendAlert(alertBadCertificate)
index 941f2a3373feb97484fcf11760ac9fa3b1be40c3..43183db2a197705d9478a87d8ce56bfb96a6836b 100644 (file)
@@ -403,8 +403,7 @@ func TestAlertForwarding(t *testing.T) {
 
        err := Server(s, testConfig).Handshake()
        s.Close()
-       var opErr *net.OpError
-       if !errors.As(err, &opErr) || opErr.Err != error(alertUnknownCA) {
+       if opErr, ok := errors.AsType[*net.OpError](err); !ok || opErr.Err != error(alertUnknownCA) {
                t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA))
        }
 }
index 3be479eb12f0856df31a29c5e274b055bcd9595c..2ba2242b2d93d2159f905956aa601d95b86a6413 100644 (file)
@@ -362,12 +362,11 @@ func quicError(err error) error {
        if err == nil {
                return nil
        }
-       var ae AlertError
-       if errors.As(err, &ae) {
+       if _, ok := errors.AsType[AlertError](err); ok {
                return err
        }
-       var a alert
-       if !errors.As(err, &a) {
+       a, ok := errors.AsType[alert](err)
+       if !ok {
                a = alertInternalError
        }
        // Return an error wrapping the original error and an AlertError.
index f6e8c55d9d63e465b03412eef69e2daa1368d88a..5f4b2b7707d01e85224c2abc6a42fc9ad36cb1b3 100644 (file)
@@ -368,8 +368,7 @@ func TestQUICHandshakeError(t *testing.T) {
        if !errors.Is(err, AlertError(alertBadCertificate)) {
                t.Errorf("connection handshake terminated with error %q, want alertBadCertificate", err)
        }
-       var e *CertificateVerificationError
-       if !errors.As(err, &e) {
+       if _, ok := errors.AsType[*CertificateVerificationError](err); !ok {
                t.Errorf("connection handshake terminated with error %q, want CertificateVerificationError", err)
        }
 }
index 12e3b750d233a74af81937af579d94a8a91c32f2..d202d5050a2786df6a6e3672d12fb962dc3af98b 100644 (file)
@@ -67,7 +67,7 @@ const (
 // with module support.
 func ReadFile(name string) (info *BuildInfo, err error) {
        defer func() {
-               if pathErr := (*fs.PathError)(nil); errors.As(err, &pathErr) {
+               if _, ok := errors.AsType[*fs.PathError](err); ok {
                        err = fmt.Errorf("could not read Go build info: %w", err)
                } else if err != nil {
                        err = fmt.Errorf("could not read Go build info from %s: %w", name, err)
index 4a9efb3b8f97a568aea3df8689e25744c038e289..8602e3e7fff2860a565876feb041ad92a981937b 100644 (file)
@@ -486,7 +486,7 @@ func testCoderInterleaved(t *testing.T, where jsontest.CasePos, modeName string,
                                // Retry as a ReadToken call.
                                expectError := dec.PeekKind() == '}' || dec.PeekKind() == ']'
                                if expectError {
-                                       if !errors.As(err, new(*SyntacticError)) {
+                                       if _, ok := errors.AsType[*SyntacticError](err); !ok {
                                                t.Fatalf("%s: Decoder.ReadToken error is %T, want %T", where, err, new(SyntacticError))
                                        }
                                        tickTock = !tickTock
index 60d16b9e27805c1bc490e172a97b6139a933e746..3ad181d43416b890369443c0b8ca105b65d95ed7 100644 (file)
@@ -53,9 +53,10 @@ func FuzzCoder(f *testing.F) {
                        } else {
                                val, err := dec.ReadValue()
                                if err != nil {
-                                       expectError := dec.PeekKind() == '}' || dec.PeekKind() == ']'
-                                       if expectError && errors.As(err, new(*SyntacticError)) {
-                                               continue
+                                       if expectError := dec.PeekKind() == '}' || dec.PeekKind() == ']'; expectError {
+                                               if _, ok := errors.AsType[*SyntacticError](err); ok {
+                                                       continue
+                                               }
                                        }
                                        if err == io.EOF {
                                                break
index d214fd5190325e3855780e9ec6c843a48700d15e..538dfe32bfa9d2a812528b1c8cf04c6a45144b3f 100644 (file)
@@ -24,8 +24,7 @@ import (
 // The name of a duplicate JSON object member can be extracted as:
 //
 //     err := ...
-//     var serr jsontext.SyntacticError
-//     if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName {
+//     if serr, ok := errors.AsType[jsontext.SyntacticError](err); ok && serr.Err == jsontext.ErrDuplicateName {
 //             ptr := serr.JSONPointer // JSON pointer to duplicate name
 //             name := ptr.LastToken() // duplicate name itself
 //             ...
index 9485d7b527793cc875770dc36d74b886afa042fc..0f50d608c9ed27f348f32162b13b5ab294a1b756 100644 (file)
@@ -28,8 +28,7 @@ import (
 // The name of an unknown JSON object member can be extracted as:
 //
 //     err := ...
-//     var serr json.SemanticError
-//     if errors.As(err, &serr) && serr.Err == json.ErrUnknownName {
+//     if serr, ok := errors.AsType[json.SemanticError](err); ok && serr.Err == json.ErrUnknownName {
 //             ptr := serr.JSONPointer // JSON pointer to unknown name
 //             name := ptr.LastToken() // unknown name itself
 //             ...
index c6bf0a864d8385a9331f16c1335bfa0d2ae6846c..6d539bbd36b52934de1414fe78595d7d612a4ee8 100644 (file)
@@ -371,8 +371,7 @@ func Example_unknownMembers() {
        // Specifying RejectUnknownMembers causes Unmarshal
        // to reject the presence of any unknown members.
        err = json.Unmarshal([]byte(input), new(Color), json.RejectUnknownMembers(true))
-       var serr *json.SemanticError
-       if errors.As(err, &serr) && serr.Err == json.ErrUnknownName {
+       if serr, ok := errors.AsType[*json.SemanticError](err); ok && serr.Err == json.ErrUnknownName {
                fmt.Println("Unmarshal error:", serr.Err, strconv.Quote(serr.JSONPointer.LastToken()))
        }
 
index f7a98ae28061bba7f0bfce0b08687940a62082aa..2798b9e0c4eb473b9e4060778eefe535d44e1707 100644 (file)
@@ -2480,8 +2480,8 @@ func TestInstantiateErrors(t *testing.T) {
                        t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
                }
 
-               var argErr *ArgumentError
-               if !errors.As(err, &argErr) {
+               argErr, ok := errors.AsType[*ArgumentError](err)
+               if !ok {
                        t.Fatalf("Instantiate(%v, %v): error is not an *ArgumentError", T, test.targs)
                }
 
@@ -2496,8 +2496,8 @@ func TestArgumentErrorUnwrapping(t *testing.T) {
                Index: 1,
                Err:   Error{Msg: "test"},
        }
-       var e Error
-       if !errors.As(err, &e) {
+       e, ok := errors.AsType[Error](err)
+       if !ok {
                t.Fatalf("error %v does not wrap types.Error", err)
        }
        if e.Msg != "test" {
index 819e3526885642dc549ab275b5892d2f301fab26..6da56acba10a1cf5c03d97c832197eb5daba044e 100644 (file)
@@ -62,8 +62,7 @@ func findListener() (net.Listener, error) {
                l, err := net.FileListener(f)
                f.Close()
 
-               var se syscall.Errno
-               switch errors.As(err, &se); se {
+               switch se, _ := errors.AsType[syscall.Errno](err); se {
                case syscall.ENOTSOCK:
                        continue
                case syscall.EBADF:
index a629078842eadcbb904dd354fe5567ea8a28300f..22eeca220da017d6e03be7375ece51e9bb10186e 100644 (file)
@@ -21,8 +21,7 @@ func syscallIsNotSupported(err error) bool {
                return false
        }
 
-       var errno syscall.Errno
-       if errors.As(err, &errno) {
+       if errno, ok := errors.AsType[syscall.Errno](err); ok {
                switch errno {
                case syscall.EPERM, syscall.EROFS:
                        // User lacks permission: either the call requires root permission and the
index b89706b893afd2f3f616dc6279889fefb25e7239..b729bf27ac40acc76928ce2add85e536bee71a0c 100644 (file)
@@ -93,8 +93,8 @@ func TestFileInfoToDirEntry(t *testing.T) {
 }
 
 func errorPath(err error) string {
-       var perr *PathError
-       if !errors.As(err, &perr) {
+       perr, ok := errors.AsType[*PathError](err)
+       if !ok {
                return ""
        }
        return perr.Path
index 8cc05c5e647f953d0c8d7bb63e0da224e0a6c0fe..5d5d38cc10dbaea262ed15e0dd42fe2787a512f7 100644 (file)
@@ -272,8 +272,7 @@ func TestCallDepth(t *testing.T) {
                        cmd.Env = append(cmd.Environ(), envVar+"=1")
 
                        out, err := cmd.CombinedOutput()
-                       var exitErr *exec.ExitError
-                       if !errors.As(err, &exitErr) {
+                       if _, ok := errors.AsType[*exec.ExitError](err); !ok {
                                t.Fatalf("expected exec.ExitError: %v", err)
                        }
 
index bf645d9c4c63102dc6dd16a2773be664cf521428..edacef13a4d5188374dafa2fd868c537c8d6c0ed 100644 (file)
@@ -303,8 +303,7 @@ func TestCallDepthConnection(t *testing.T) {
                        cmd.Env = append(cmd.Environ(), envVar+"=1")
 
                        out, err := cmd.CombinedOutput()
-                       var exitErr *exec.ExitError
-                       if !errors.As(err, &exitErr) {
+                       if _, ok := errors.AsType[*exec.ExitError](err); !ok {
                                t.Fatalf("expected exec.ExitError: %v", err)
                        }
 
index 5e060a6b489bf9caad5abb6b6d38bb7776e04aaa..940fcccf7f2139749f9caf01c4670eb206488de4 100644 (file)
@@ -842,8 +842,7 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string, order hostLooku
        }
        p, server, err := r.lookup(ctx, arpa, dnsmessage.TypePTR, conf)
        if err != nil {
-               var dnsErr *DNSError
-               if errors.As(err, &dnsErr) && dnsErr.IsNotFound {
+               if dnsErr, ok := errors.AsType[*DNSError](err); ok && dnsErr.IsNotFound {
                        if order == hostLookupDNSFiles {
                                names := lookupStaticAddr(addr)
                                if len(names) > 0 {
index 826b4daba1e7fd71f4bb5cab97b161fca4108b49..fc1d40f18b6f9a75c9e5daf506991bd8bf6340b9 100644 (file)
@@ -2627,8 +2627,7 @@ func TestLongDNSNames(t *testing.T) {
                                }
 
                                expectedErr := DNSError{Err: errNoSuchHost.Error(), Name: v.req, IsNotFound: true}
-                               var dnsErr *DNSError
-                               errors.As(err, &dnsErr)
+                               dnsErr, _ := errors.AsType[*DNSError](err)
                                if dnsErr == nil || *dnsErr != expectedErr {
                                        t.Errorf("%v: Lookup%v: unexpected error: %v", i, testName, err)
                                }
@@ -2820,8 +2819,7 @@ func TestLookupOrderFilesNoSuchHost(t *testing.T) {
                }
 
                expectedErr := DNSError{Err: errNoSuchHost.Error(), Name: testName, IsNotFound: true}
-               var dnsErr *DNSError
-               errors.As(err, &dnsErr)
+               dnsErr, _ := errors.AsType[*DNSError](err)
                if dnsErr == nil || *dnsErr != expectedErr {
                        t.Errorf("Lookup%v: unexpected error: %v", v.name, err)
                }
@@ -2853,8 +2851,7 @@ func TestExtendedRCode(t *testing.T) {
 
        r := &Resolver{PreferGo: true, Dial: fake.DialContext}
        _, _, err := r.tryOneName(context.Background(), getSystemDNSConfig(), "go.dev.", dnsmessage.TypeA)
-       var dnsErr *DNSError
-       if !(errors.As(err, &dnsErr) && dnsErr.Err == errServerMisbehaving.Error()) {
+       if dnsErr, ok := errors.AsType[*DNSError](err); !ok || dnsErr.Err != errServerMisbehaving.Error() {
                t.Fatalf("r.tryOneName(): unexpected error: %v", err)
        }
 }
index 5e400683b415e7e47f501d8d845ca513caefe3b6..e71825451a8e32c489bf644790befda3942fbba2 100644 (file)
@@ -25,19 +25,18 @@ func (e externalStreamError) Error() string {
 }
 
 func TestStreamError(t *testing.T) {
-       var target externalStreamError
        streamErr := http2streamError(42, http2ErrCodeProtocol)
-       ok := errors.As(streamErr, &target)
+       extStreamErr, ok := errors.AsType[externalStreamError](streamErr)
        if !ok {
-               t.Fatalf("errors.As failed")
+               t.Fatalf("errors.AsType failed")
        }
-       if target.StreamID != streamErr.StreamID {
-               t.Errorf("got StreamID %v, expected %v", target.StreamID, streamErr.StreamID)
+       if extStreamErr.StreamID != streamErr.StreamID {
+               t.Errorf("got StreamID %v, expected %v", extStreamErr.StreamID, streamErr.StreamID)
        }
-       if target.Cause != streamErr.Cause {
-               t.Errorf("got Cause %v, expected %v", target.Cause, streamErr.Cause)
+       if extStreamErr.Cause != streamErr.Cause {
+               t.Errorf("got Cause %v, expected %v", extStreamErr.Cause, streamErr.Cause)
        }
-       if uint32(target.Code) != uint32(streamErr.Code) {
-               t.Errorf("got Code %v, expected %v", target.Code, streamErr.Code)
+       if uint32(extStreamErr.Code) != uint32(streamErr.Code) {
+               t.Errorf("got Code %v, expected %v", extStreamErr.Code, streamErr.Code)
        }
 }
index 514cbd098ae772a1628c72545fadd72b227c754b..2a774100a8ec676f52a59a59d655ec8e050250f0 100644 (file)
@@ -1420,8 +1420,8 @@ func testLookupNoData(t *testing.T, prefix string) {
                        return
                }
 
-               var dnsErr *DNSError
-               if errors.As(err, &dnsErr) {
+               dnsErr, ok := errors.AsType[*DNSError](err)
+               if ok {
                        succeeded := true
                        if !dnsErr.IsNotFound {
                                succeeded = false
@@ -1455,8 +1455,7 @@ func testLookupNoData(t *testing.T, prefix string) {
 func TestLookupPortNotFound(t *testing.T) {
        allResolvers(t, func(t *testing.T) {
                _, err := LookupPort("udp", "_-unknown-service-")
-               var dnsErr *DNSError
-               if !errors.As(err, &dnsErr) || !dnsErr.IsNotFound {
+               if dnsErr, ok := errors.AsType[*DNSError](err); !ok || !dnsErr.IsNotFound {
                        t.Fatalf("unexpected error: %v", err)
                }
        })
@@ -1475,8 +1474,7 @@ var tcpOnlyService = func() string {
 func TestLookupPortDifferentNetwork(t *testing.T) {
        allResolvers(t, func(t *testing.T) {
                _, err := LookupPort("udp", tcpOnlyService)
-               var dnsErr *DNSError
-               if !errors.As(err, &dnsErr) || !dnsErr.IsNotFound {
+               if dnsErr, ok := errors.AsType[*DNSError](err); !ok || !dnsErr.IsNotFound {
                        t.Fatalf("unexpected error: %v", err)
                }
        })
index 3bded3dea604fb20d67edecb76c72358591fbc5b..1decebdc222d235aeef052f06bc270346778e427 100644 (file)
@@ -1378,8 +1378,8 @@ func TestWaitInterrupt(t *testing.T) {
                // The child process should be reported as failed,
                // and the grandchild will exit (or die by SIGPIPE) once the
                // stderr pipe is closed.
-               if ee := new(*exec.ExitError); !errors.As(err, ee) {
-                       t.Errorf("Wait error = %v; want %T", err, *ee)
+               if ee, ok := errors.AsType[*exec.ExitError](err); !ok {
+                       t.Errorf("Wait error = %v; want %T", err, ee)
                }
        })
 
@@ -1423,8 +1423,8 @@ func TestWaitInterrupt(t *testing.T) {
 
                // This command ignores SIGINT, sleeping until it is killed.
                // Wait should return the usual error for a killed process.
-               if ee := new(*exec.ExitError); !errors.As(err, ee) {
-                       t.Errorf("Wait error = %v; want %T", err, *ee)
+               if ee, ok := errors.AsType[*exec.ExitError](err); !ok {
+                       t.Errorf("Wait error = %v; want %T", err, ee)
                }
        })
 
@@ -1471,7 +1471,7 @@ func TestWaitInterrupt(t *testing.T) {
                t.Logf("stderr:\n%s", cmd.Stderr)
                t.Logf("[%d] %v", cmd.Process.Pid, err)
 
-               if ee := new(*exec.ExitError); !errors.As(err, ee) {
+               if _, ok := errors.AsType[*exec.ExitError](err); !ok {
                        t.Errorf("Wait error = %v; want %v", err, ctx.Err())
                }
 
index 9f6eb13e1f96a9b62b34ec659d23132d5b3d6411..536734901baff61af9bebf80dcc1f2d816dda39b 100644 (file)
@@ -840,8 +840,7 @@ func TestReaddirOfFile(t *testing.T) {
        if err == nil {
                t.Error("Readdirnames succeeded; want non-nil error")
        }
-       var pe *PathError
-       if !errors.As(err, &pe) || pe.Path != f.Name() {
+       if pe, ok := errors.AsType[*PathError](err); !ok || pe.Path != f.Name() {
                t.Errorf("Readdirnames returned %q; want a PathError with path %q", err, f.Name())
        }
        if len(names) > 0 {
index f4dc44bd078eac0ba34608715bac1ac7c6117220..3118e8911e28ec8cc67f5e82518dfbcaac7f0ff3 100644 (file)
@@ -67,8 +67,7 @@ func readMainModuleMapping() (start, end uint64, exe, buildID string, err error)
 func createModuleSnapshot() (syscall.Handle, error) {
        for {
                snap, err := syscall.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE|windows.TH32CS_SNAPMODULE32, uint32(syscall.Getpid()))
-               var errno syscall.Errno
-               if err != nil && errors.As(err, &errno) && errno == windows.ERROR_BAD_LENGTH {
+               if errno, ok := errors.AsType[syscall.Errno](err); ok && errno == windows.ERROR_BAD_LENGTH {
                        // When CreateToolhelp32Snapshot(SNAPMODULE|SNAPMODULE32, ...) fails
                        // with ERROR_BAD_LENGTH then it should be retried until it succeeds.
                        continue
index 1fb84b892842cbff4123b6b49760f95d0f5bcb7e..72830a09a727bd2916c924cd91966ff0fb5a4083 100644 (file)
@@ -29,7 +29,7 @@ import (
 // The contents of fsys must not change concurrently with TestFS.
 //
 // If TestFS finds any misbehaviors, it returns either the first error or a
-// list of errors. Use [errors.Is] or [errors.As] to inspect.
+// list of errors. Use [errors.Is] or [errors.AsType] to inspect.
 //
 // Typical usage inside a test is:
 //
index d6d6d89b89fdaa83a3bbe056ac0cde0a149de106..e3d7f1ab44d7b76a278473f4cd1c1b73f9978b6c 100644 (file)
@@ -105,8 +105,12 @@ func TestTestFSWrappedErrors(t *testing.T) {
 
        // TestFS is expected to return a list of errors.
        // Enforce that the list can be extracted for browsing.
-       var errs interface{ Unwrap() []error }
-       if !errors.As(err, &errs) {
+       type wrapper interface{
+               error
+               Unwrap() []error
+       }
+       errs, ok := errors.AsType[wrapper](err)
+       if !ok {
                t.Errorf("caller should be able to extract the errors as a list: %#v", err)
        } else {
                for _, err := range errs.Unwrap() {
index 65440901a0b4ecd82ef090bd867284b0bf57066d..8665f3ad4987c2add0bc60d8a43e19e30d219a60 100644 (file)
@@ -1015,8 +1015,7 @@ func TestExecError_CustomError(t *testing.T) {
        var b bytes.Buffer
        err := tmpl.Execute(&b, nil)
 
-       var e *CustomError
-       if !errors.As(err, &e) {
+       if _, ok := errors.AsType[*CustomError](err); !ok {
                t.Fatalf("expected custom error; got %s", err)
        }
 }
index c28c3ea2002d212fbf2f5b243ddcb787d3d1a473..30b3243a5a841604d98e3e3cba50b6df3614d30a 100644 (file)
@@ -22,7 +22,7 @@ import (
 // return value evaluates to non-nil during execution, execution terminates and
 // Execute returns that error.
 //
-// Errors returned by Execute wrap the underlying error; call [errors.As] to
+// Errors returned by Execute wrap the underlying error; call [errors.AsType] to
 // unwrap them.
 //
 // When template execution invokes a function with an argument list, that list