From f869ff95a12756de97827b4afd93763f9661f144 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Mon, 8 Jun 2026 14:19:11 +0900 Subject: [PATCH] all: apply modernisers Signed-off-by: Ophestra --- check/absolute.go | 4 +-- cmd/earlyinit/modprobe.go | 4 +-- cmd/hakurei/json.go | 11 +++--- cmd/mbf/internal/pkgserver/search.go | 2 +- cmd/sharefs/fuse.go | 4 +-- command/parse.go | 4 +-- container/container.go | 7 ++-- container/dispatcher_test.go | 2 -- container/errors.go | 14 ++++---- container/init_test.go | 16 ++++----- ext/ext_test.go | 2 +- hst/fs.go | 13 +++---- hst/fs_test.go | 4 +-- hst/fsephemeral.go | 7 +--- internal/dbus/address.go | 4 +-- internal/lockedfile/transform_test.go | 2 +- internal/outcome/finalise.go | 3 +- internal/outcome/hsu.go | 10 +++--- internal/outcome/process.go | 6 ++-- internal/outcome/shim.go | 4 +-- internal/pipewire/pod.go | 8 ++--- internal/pkg/pkg.go | 36 +++++++++++-------- internal/report/report.go | 3 +- internal/rosa/azalea/evaluate.go | 11 +++--- internal/rosa/azalea/evaluate_test.go | 2 +- internal/rosa/report.go | 5 ++- internal/rosa/state.go | 2 +- internal/store/store_test.go | 4 +-- internal/stub/errors.go | 7 ++-- internal/system/dbus.go | 6 ++-- internal/wayland/wayland.go | 6 ++-- ldd/exec_test.go | 4 +-- message/message.go | 52 ++++++++++++++++++--------- test/internal/sandbox/assert.go | 16 ++++----- vfs/mountinfo.go | 2 +- 35 files changed, 146 insertions(+), 141 deletions(-) diff --git a/check/absolute.go b/check/absolute.go index 4df3c59b..1a050d06 100644 --- a/check/absolute.go +++ b/check/absolute.go @@ -20,8 +20,8 @@ func (e AbsoluteError) Error() string { } func (e AbsoluteError) Is(target error) bool { - var ce AbsoluteError - if !errors.As(target, &ce) { + ce, ok := errors.AsType[AbsoluteError](target) + if !ok { return errors.Is(target, syscall.EINVAL) } return e == ce diff --git a/cmd/earlyinit/modprobe.go b/cmd/earlyinit/modprobe.go index 5a9868d4..8addf973 100644 --- a/cmd/earlyinit/modprobe.go +++ b/cmd/earlyinit/modprobe.go @@ -57,8 +57,8 @@ func dispatchModprobe( continue } - var exitError *exec.ExitError - if !errors.As(err, &exitError) || exitError == nil { + exitError, ok := errors.AsType[*exec.ExitError](err) + if !ok || exitError == nil { r.Dispatch(report.Degraded, "invoke modprobe", err) continue } diff --git a/cmd/hakurei/json.go b/cmd/hakurei/json.go index 30eb4334..d0d978d3 100644 --- a/cmd/hakurei/json.go +++ b/cmd/hakurei/json.go @@ -7,7 +7,8 @@ import ( "strconv" ) -// decodeJSON decodes json from r and stores it in v. A non-nil error results in a call to fatal. +// decodeJSON decodes json from r and stores it in v. A non-nil error results in +// a call to fatal. func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any) { err := json.NewDecoder(r).Decode(v) if err == nil { @@ -47,14 +48,14 @@ func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any) { } if err := encoder.Encode(v); err != nil { - var marshalerError *json.MarshalerError - if errors.As(err, &marshalerError) && marshalerError != nil { + if e, ok := errors.AsType[*json.MarshalerError](err); ok && e != nil { // this likely indicates an implementation error in hst - fatal("cannot encode json for " + marshalerError.Type.String() + ": " + marshalerError.Err.Error()) + fatal("cannot encode json for " + e.Type.String() + ": " + e.Err.Error()) return } - // UnsupportedTypeError, UnsupportedValueError: incorrect usage, does not need to be handled + // UnsupportedTypeError, UnsupportedValueError: incorrect usage, does + // not need to be handled fatal("cannot write json: " + err.Error()) } } diff --git a/cmd/mbf/internal/pkgserver/search.go b/cmd/mbf/internal/pkgserver/search.go index 5756512f..15947804 100644 --- a/cmd/mbf/internal/pkgserver/search.go +++ b/cmd/mbf/internal/pkgserver/search.go @@ -74,7 +74,7 @@ func (s *searchCache) clean() { } func indexsum(in [][]int) int { sum := 0 - for i := 0; i < len(in); i++ { + for i := range in { sum += in[i][1] - in[i][0] } return sum diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go index c9855eb7..5dfbf385 100644 --- a/cmd/sharefs/fuse.go +++ b/cmd/sharefs/fuse.go @@ -508,8 +508,8 @@ func _main(s ...string) (exitCode int) { if !z.AllowOrphan { if err := z.Wait(); err != nil { - var exitError *exec.ExitError - if !errors.As(err, &exitError) || exitError == nil { + exitError, ok := errors.AsType[*exec.ExitError](err) + if !ok || exitError == nil { log.Println(err) return 5 } diff --git a/command/parse.go b/command/parse.go index 8e21433c..1a3f2ce3 100644 --- a/command/parse.go +++ b/command/parse.go @@ -91,8 +91,8 @@ func (n *node) MustParse(arguments []string, handleError func(error)) { case ErrEmptyTree: os.Exit(1) default: - var flagError FlagError - if !errors.As(err, &flagError) { // returned by HandlerFunc + flagError, ok := errors.AsType[FlagError](err) + if !ok { // returned by HandlerFunc handleError(err) os.Exit(1) } diff --git a/container/container.go b/container/container.go index 8af77315..3571d04a 100644 --- a/container/container.go +++ b/container/container.go @@ -154,11 +154,8 @@ func (e *StartError) Error() string { return e.Step } - { - var syscallError *os.SyscallError - if errors.As(e.Err, &syscallError) && syscallError != nil { - return e.Step + " " + syscallError.Error() - } + if se, ok := errors.AsType[*os.SyscallError](e.Err); ok && se != nil { + return e.Step + " " + se.Error() } return e.Step + ": " + e.Err.Error() diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go index 49631854..242af1bf 100644 --- a/container/dispatcher_test.go +++ b/container/dispatcher_test.go @@ -235,8 +235,6 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { }) } -func sliceAddr[S any](s []S) *[]S { return &s } - func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile { f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr} // check happens in Close, and cleanup is not guaranteed to run, so relying diff --git a/container/errors.go b/container/errors.go index 5a67bb4c..053bdeb7 100644 --- a/container/errors.go +++ b/container/errors.go @@ -46,9 +46,8 @@ func messageFromError(err error) (m string, ok bool) { // While this is usable for pointer errors, such use should be avoided as nil // check is omitted. func messagePrefix[T error](prefix string, err error) (string, bool) { - var targetError T - if errors.As(err, &targetError) { - return prefix + targetError.Error(), true + if e, ok := errors.AsType[T](err); ok { + return prefix + e.Error(), true } return zeroString, false } @@ -58,9 +57,8 @@ func messagePrefixP[V any, T interface { *V error }](prefix string, err error) (string, bool) { - var targetError T - if errors.As(err, &targetError) && targetError != nil { - return prefix + targetError.Error(), true + if e, ok := errors.AsType[T](err); ok && e != nil { + return prefix + e.Error(), true } return zeroString, false } @@ -109,8 +107,8 @@ func optionalErrorUnwrap(err error) error { // errnoFallback returns the concrete errno from an error, or a [os.PathError] fallback. func errnoFallback(op, path string, err error) (syscall.Errno, *os.PathError) { - var errno syscall.Errno - if !errors.As(err, &errno) { + errno, ok := errors.AsType[syscall.Errno](err) + if !ok { return 0, &os.PathError{Op: op, Path: path, Err: err} } return errno, nil diff --git a/container/init_test.go b/container/init_test.go index 23d0a7b3..fe0e627a 100644 --- a/container/init_test.go +++ b/container/init_test.go @@ -95,7 +95,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -123,7 +123,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -152,7 +152,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -182,7 +182,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -213,7 +213,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -245,7 +245,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -279,7 +279,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, @@ -315,7 +315,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 16, Gid: 1 << 15, Hostname: "hakurei-check", - Ops: (*Ops)(sliceAddr(make(Ops, 1))), + Ops: new(make(Ops, 1)), SeccompRules: make([]std.NativeRule, 0), SeccompPresets: std.PresetStrict, RetainSession: true, diff --git a/ext/ext_test.go b/ext/ext_test.go index a93a1b52..74d825cd 100644 --- a/ext/ext_test.go +++ b/ext/ext_test.go @@ -39,7 +39,7 @@ func TestSyscall(t *testing.T) { t.Errorf("Unmarshal: %v, want %v", got, tc.want) } }) - if errors.As(tc.err, new(ext.SyscallNameError)) { + if _, ok := errors.AsType[ext.SyscallNameError](tc.err); ok { return } diff --git a/hst/fs.go b/hst/fs.go index 13645d1a..cb35f925 100644 --- a/hst/fs.go +++ b/hst/fs.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "reflect" + "strings" "hakurei.app/check" ) @@ -78,17 +79,17 @@ type FSImplError struct{ Value FilesystemConfig } func (f FSImplError) Error() string { implType := reflect.TypeOf(f.Value) - var name string - for implType != nil && implType.Kind() == reflect.Ptr { - name += "*" + var buf strings.Builder + for implType != nil && implType.Kind() == reflect.Pointer { + buf.WriteByte('*') implType = implType.Elem() } if implType != nil { - name += implType.Name() + buf.WriteString(implType.Name()) } else { - name += "nil" + buf.WriteString("nil") } - return fmt.Sprintf("implementation %s not supported", name) + return "implementation " + buf.String() + " not supported" } // FilesystemConfigJSON is the [json] adapter for [FilesystemConfig]. diff --git a/hst/fs_test.go b/hst/fs_test.go index 94d44078..a88970b7 100644 --- a/hst/fs_test.go +++ b/hst/fs_test.go @@ -103,7 +103,7 @@ func TestFilesystemConfigJSON(t *testing.T) { t.Run("marshal", func(t *testing.T) { t.Parallel() wantErr := tc.wantErr - if errors.As(wantErr, new(hst.FSTypeError)) { + if _, ok := errors.AsType[hst.FSTypeError](wantErr); ok { // for unsupported implementation tc wantErr = hst.FSImplError{Value: stubFS{"cat"}} } @@ -139,7 +139,7 @@ func TestFilesystemConfigJSON(t *testing.T) { t.Run("unmarshal", func(t *testing.T) { t.Parallel() if tc.data == "\x00" && tc.sData == "\x00" { - if errors.As(tc.wantErr, new(hst.FSImplError)) { + if _, ok := errors.AsType[hst.FSImplError](tc.wantErr); ok { // this error is only returned on marshal return } diff --git a/hst/fsephemeral.go b/hst/fsephemeral.go index 9da79003..d1c01bca 100644 --- a/hst/fsephemeral.go +++ b/hst/fsephemeral.go @@ -43,18 +43,13 @@ func (e *FSEphemeral) Apply(z *ApplyState) { return } - size := e.Size - if size < 0 { - size = 0 - } - perm := e.Perm if perm == 0 { perm = fsEphemeralDefaultPerm } if e.Write { - z.Tmpfs(e.Target, size, perm) + z.Tmpfs(e.Target, max(e.Size, 0), perm) } else { z.Readonly(e.Target, perm) } diff --git a/internal/dbus/address.go b/internal/dbus/address.go index edee7e20..4afea9e1 100644 --- a/internal/dbus/address.go +++ b/internal/dbus/address.go @@ -80,7 +80,7 @@ func unescapeValue(v []byte) (val []byte, errno ParseError) { continue } - if ib := bytes.IndexByte([]byte("-_/.\\*"), b); ib != -1 { // - // _/.\* + if found := bytes.Contains([]byte("-_/.\\*"), []byte{b}); found { // - // _/.\* goto opt } else if b >= '0' && b <= '9' { // 0-9 goto opt @@ -101,7 +101,7 @@ func unescapeValue(v []byte) (val []byte, errno ParseError) { break } if c, err := hex.Decode(val[i:i+1], v[iu+1:iu+3]); err != nil { - if errors.As(err, new(hex.InvalidByteError)) { + if _, ok := errors.AsType[hex.InvalidByteError](err); ok { errno = ErrBadValHexByte break } diff --git a/internal/lockedfile/transform_test.go b/internal/lockedfile/transform_test.go index 1394ada7..95807493 100644 --- a/internal/lockedfile/transform_test.go +++ b/internal/lockedfile/transform_test.go @@ -40,7 +40,7 @@ func TestTransform(t *testing.T) { const maxChunkWords = 8 << 10 buf := make([]byte, 2*maxChunkWords*8) - for i := uint64(0); i < 2*maxChunkWords; i++ { + for i := range uint64(2 * maxChunkWords) { binary.LittleEndian.PutUint64(buf[i*8:], i) } if err := lockedfile.Write(path, bytes.NewReader(buf[:8]), 0666); err != nil { diff --git a/internal/outcome/finalise.go b/internal/outcome/finalise.go index d74c648c..4049b8d3 100644 --- a/internal/outcome/finalise.go +++ b/internal/outcome/finalise.go @@ -58,8 +58,7 @@ func (k *outcome) finalise( supp := make([]string, len(config.Groups)) for i, name := range config.Groups { if gid, err := k.lookupGroupId(name); err != nil { - var unknownGroupError user.UnknownGroupError - if errors.As(err, &unknownGroupError) { + if unknownGroupError, ok := errors.AsType[user.UnknownGroupError](err); ok { return newWithMessageError(fmt.Sprintf("unknown group %q", name), unknownGroupError) } else { return &hst.AppError{Step: "look up group by name", Err: err, Msg: err.Error()} diff --git a/internal/outcome/hsu.go b/internal/outcome/hsu.go index 118fd681..ecb616c0 100644 --- a/internal/outcome/hsu.go +++ b/internal/outcome/hsu.go @@ -51,18 +51,16 @@ func (h *Hsu) ID() (int, error) { cmd.Stderr = os.Stderr // pass through fatal messages cmd.Env = make([]string, 0) cmd.Dir = fhs.Root - var ( - p []byte - exitError *exec.ExitError - ) - + var p []byte const step = "obtain uid from hsu" if p, h.idErr = h.k.cmdOutput(cmd); h.idErr == nil { h.id, h.idErr = strconv.Atoi(string(p)) if h.idErr != nil { h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"} } - } else if errors.As(h.idErr, &exitError) && exitError != nil && exitError.ExitCode() == 1 { + } else if exitError, ok := errors.AsType[*exec.ExitError](h.idErr); ok && + exitError != nil && + exitError.ExitCode() == 1 { // hsu prints an error message in this case h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess} } else if errors.Is(h.idErr, os.ErrNotExist) { diff --git a/internal/outcome/process.go b/internal/outcome/process.go index 67851edc..614b22fc 100644 --- a/internal/outcome/process.go +++ b/internal/outcome/process.go @@ -328,11 +328,11 @@ func (k *outcome) main(msg message.Msg, identifierFd int) { } if err := k.sys.Revert((*system.Criteria)(&ec)); err != nil { - var joinError interface { + joinError, ok := errors.AsType[interface { Unwrap() []error error - } - if !errors.As(err, &joinError) || joinError == nil { + }](err) + if !ok || joinError == nil { perror(err, "revert system setup") } else { for _, v := range joinError.Unwrap() { diff --git a/internal/outcome/shim.go b/internal/outcome/shim.go index b2074928..6e039b65 100644 --- a/internal/outcome/shim.go +++ b/internal/outcome/shim.go @@ -390,8 +390,8 @@ func shimEntrypoint(k syscallDispatcher) { if err := k.containerWait(z); err != nil { sp.destroy() - var exitError *exec.ExitError - if !errors.As(err, &exitError) { + exitError, ok := errors.AsType[*exec.ExitError](err) + if !ok { if errors.Is(err, context.Canceled) { k.exit(hst.ExitCancel) } diff --git a/internal/pipewire/pod.go b/internal/pipewire/pod.go index 7cfafc87..e085af3d 100644 --- a/internal/pipewire/pod.go +++ b/internal/pipewire/pod.go @@ -176,8 +176,8 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) { case reflect.Struct: data = SPA_TYPE_Struct.append(data) var err error - for i := 0; i < v.NumField(); i++ { - data, err = marshalValueAppend(data, v.Field(i)) + for _, field := range v.Fields() { + data, err = marshalValueAppend(data, field) if err != nil { return data, err } @@ -370,8 +370,8 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error { } var fieldWireSize Word - for i := 0; i < v.NumField(); i++ { - if err := unmarshalValue(data, v.Field(i), &fieldWireSize); err != nil { + for _, field := range v.Fields() { + if err := unmarshalValue(data, field, &fieldWireSize); err != nil { return err } // bounds check completed in successful call to unmarshalValue diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go index e90bb72c..7b4c9637 100644 --- a/internal/pkg/pkg.go +++ b/internal/pkg/pkg.go @@ -238,8 +238,8 @@ func (t *TContext) destroy(errP *error) { if chmodErr != nil || removeErr != nil { *errP = errors.Join(*errP, chmodErr, removeErr) } else if errors.Is(*errP, os.ErrExist) { - var linkError *os.LinkError - if errors.As(*errP, &linkError) && linkError != nil && + if linkError, ok := errors.AsType[*os.LinkError](*errP); ok && + linkError != nil && linkError.Op == "rename" { // two artifacts may be backed by the same file *errP = nil @@ -974,36 +974,42 @@ func (e *ScrubError) Unwrap() []error { // Error returns a multi-line representation of [ScrubError]. func (e *ScrubError) Error() string { var segments []string + var buf strings.Builder + if len(e.ChecksumMismatches) > 0 { - s := "checksum mismatches:\n" + buf.Reset() + buf.WriteString("checksum mismatches:\n") for _, m := range e.ChecksumMismatches { - s += m.Error() + "\n" + buf.WriteString(m.Error() + "\n") } - segments = append(segments, s) + segments = append(segments, buf.String()) } if len(e.DanglingIdentifiers) > 0 { - s := "dangling identifiers:\n" + buf.Reset() + buf.WriteString("dangling identifiers:\n") for _, id := range e.DanglingIdentifiers { - s += Encode(id) + "\n" + buf.WriteString(Encode(id) + "\n") } - segments = append(segments, s) + segments = append(segments, buf.String()) } if len(e.DanglingStatus) > 0 { - s := "dangling status:\n" + buf.Reset() + buf.WriteString("dangling status:\n") for _, id := range e.DanglingStatus { - s += Encode(id) + "\n" + buf.WriteString(Encode(id) + "\n") } - segments = append(segments, s) + segments = append(segments, buf.String()) } if len(e.Errs) > 0 { - s := "errors during scrub:\n" + buf.Reset() + buf.WriteString("errors during scrub:\n") for pathname, errs := range e.errs { - s += " " + pathname.Value() + ":\n" + buf.WriteString(" " + pathname.Value() + ":\n") for _, err := range errs { - s += " " + err.Error() + "\n" + buf.WriteString(" " + err.Error() + "\n") } } - segments = append(segments, s) + segments = append(segments, buf.String()) } return strings.Join(segments, "\n") } diff --git a/internal/report/report.go b/internal/report/report.go index cbac1c34..c418c709 100644 --- a/internal/report/report.go +++ b/internal/report/report.go @@ -102,8 +102,7 @@ func (e Error) MarshalJSON() (data []byte, err error) { v.Severity = e.Severity } - var re RepresentableError - if errors.As(e.Err, &re) { + if re, ok := errors.AsType[RepresentableError](e.Err); ok { v.Err, err = json.Marshal(re) } else { v.Err, err = json.Marshal(e.Err.Error()) diff --git a/internal/rosa/azalea/evaluate.go b/internal/rosa/azalea/evaluate.go index 32c4f066..044e6826 100644 --- a/internal/rosa/azalea/evaluate.go +++ b/internal/rosa/azalea/evaluate.go @@ -6,6 +6,7 @@ import ( "maps" "reflect" "slices" + "strings" "unique" ) @@ -107,8 +108,8 @@ func (e TypeError) Error() string { } func (e TypeError) Is(err error) bool { - var v TypeError - return errors.As(err, &v) && + v, ok := errors.AsType[TypeError](err) + return ok && e.Asserted == v.Asserted && e.Concrete == v.Concrete } @@ -233,14 +234,14 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool { return evaluateAny(d, s, e[0], rp) } } - var v string + var v strings.Builder for i := range e { var _r string if evaluate(d, s, e[i], &_r) { - v += _r + v.WriteString(_r) } } - store(rp, v) + store(rp, v.String()) return true case Array: diff --git a/internal/rosa/azalea/evaluate_test.go b/internal/rosa/azalea/evaluate_test.go index 801b07a3..4a6c2f56 100644 --- a/internal/rosa/azalea/evaluate_test.go +++ b/internal/rosa/azalea/evaluate_test.go @@ -214,7 +214,7 @@ func TestEvaluate(t *testing.T) { } var errEquals bool - if errors.As(err, new(TypeError)) { + if _, ok := errors.AsType[TypeError](err); ok { errEquals = errors.Is(err, tc.err) } else { errEquals = reflect.DeepEqual(err, tc.err) diff --git a/internal/rosa/report.go b/internal/rosa/report.go index 54f60fb3..a97ff8e8 100644 --- a/internal/rosa/report.go +++ b/internal/rosa/report.go @@ -212,11 +212,10 @@ func (r *Report) HandleAccess(errP *error) func() { *errP = err } - var runtimeError interface { + if runtimeError, ok := errors.AsType[interface { Addr() uintptr runtime.Error - } - if errors.As(*errP, &runtimeError) { + }](*errP); ok { offset := int(runtimeError.Addr() - uintptr(unsafe.Pointer(unsafe.SliceData(r.data)))) // best effort for fragile uintptr if offset >= 0 { diff --git a/internal/rosa/state.go b/internal/rosa/state.go index feb06f82..8f9aba6d 100644 --- a/internal/rosa/state.go +++ b/internal/rosa/state.go @@ -1063,7 +1063,7 @@ func (ctx *evalContext) pf( checksum, ok := kc.(string) if !ok { err = azalea.TypeError{ - Concrete: reflect.TypeOf(checksum), + Concrete: reflect.TypeOf(kc), Asserted: reflect.TypeFor[string](), } return diff --git a/internal/store/store_test.go b/internal/store/store_test.go index 2210f543..cdaad24e 100644 --- a/internal/store/store_test.go +++ b/internal/store/store_test.go @@ -29,7 +29,7 @@ func TestStoreBigLock(t *testing.T) { { s := store.New(check.MustAbs(t.TempDir()).Append("state")) - for i := 0; i < 2; i++ { // check once behaviour + for range 2 { // check once behaviour if unlock, err := bigLock(s); err != nil { t.Fatalf("bigLock: error = %v", err) } else { @@ -43,7 +43,7 @@ func TestStoreBigLock(t *testing.T) { wantErr := &hst.AppError{Step: "create state store directory", Err: &os.PathError{Op: "mkdir", Path: "/proc/nonexistent", Err: syscall.ENOENT}} - for i := 0; i < 2; i++ { // check once behaviour + for range 2 { // check once behaviour if _, err := bigLock(store.New(check.MustAbs("/proc/nonexistent"))); !reflect.DeepEqual(err, wantErr) { t.Errorf("bigLock: error = %#v, want %#v", err, wantErr) } diff --git a/internal/stub/errors.go b/internal/stub/errors.go index c89149be..560bde6e 100644 --- a/internal/stub/errors.go +++ b/internal/stub/errors.go @@ -20,9 +20,6 @@ func (e UniqueError) Error() string { } func (e UniqueError) Is(target error) bool { - var u UniqueError - if !errors.As(target, &u) { - return false - } - return e == u + u, ok := errors.AsType[UniqueError](target) + return ok && e == u } diff --git a/internal/system/dbus.go b/internal/system/dbus.go index 70acdbdb..a6587ed5 100644 --- a/internal/system/dbus.go +++ b/internal/system/dbus.go @@ -172,12 +172,12 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) { return a, syscall.ENOMEM } - if i := bytes.IndexByte(p, '\n'); i == -1 { + if before, after, ok := bytes.Cut(p, []byte{'\n'}); !ok { n, _ := s.buf.Write(p) s.n += n return a + n, nil } else { - n, _ := s.buf.Write(p[:i]) + n, _ := s.buf.Write(before) s.n += n + 1 v := s.buf.String() @@ -190,7 +190,7 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) { } s.buf.Reset() - return s.write(p[i+1:], a+n+1) + return s.write(after, a+n+1) } } diff --git a/internal/wayland/wayland.go b/internal/wayland/wayland.go index 544f5cc9..1b5d5b64 100644 --- a/internal/wayland/wayland.go +++ b/internal/wayland/wayland.go @@ -130,13 +130,11 @@ func (e *Error) Error() string { return e.withPrefix("cannot connect to " + e.Host) case RCleanup: - var pathError *os.PathError - if errors.As(e.Errno, &pathError) && pathError != nil { + if pathError, ok := errors.AsType[*os.PathError](e.Errno); ok && pathError != nil { return pathError.Error() } - var errno syscall.Errno - if errors.As(e.Errno, &errno) && errno != 0 { + if errno, ok := errors.AsType[syscall.Errno](e.Errno); ok && errno != 0 { return "cannot close wayland close_fd pipe: " + errno.Error() } diff --git a/ldd/exec_test.go b/ldd/exec_test.go index b24b30e4..4621d335 100644 --- a/ldd/exec_test.go +++ b/ldd/exec_test.go @@ -20,8 +20,8 @@ func TestExec(t *testing.T) { _, err := ldd.Resolve(t.Context(), nil, check.MustAbs("/proc/nonexistent")) - var exitError *exec.ExitError - if !errors.As(err, &exitError) { + exitError, ok := errors.AsType[*exec.ExitError](err) + if !ok { t.Fatalf("Exec: error has incorrect concrete type: %#v", err) } diff --git a/message/message.go b/message/message.go index aa4870f9..3bb223a1 100644 --- a/message/message.go +++ b/message/message.go @@ -1,4 +1,5 @@ -// Package message provides interfaces and a base implementation for extended reporting on top of [log.Logger] +// Package message provides interfaces and a base implementation for extended +// reporting on top of [log.Logger] package message import ( @@ -15,10 +16,11 @@ type Error interface { error } -// GetMessage returns whether an error implements [Error], and the message if it does. +// GetMessage returns whether an error implements [Error], and the message if +// it does. func GetMessage(err error) (string, bool) { - var e Error - if !errors.As(err, &e) || e == nil { + e, ok := errors.AsType[Error](err) + if !ok || e == nil { return "", false } return e.Message(), true @@ -29,30 +31,43 @@ type Msg interface { // GetLogger returns the address of the underlying [log.Logger]. GetLogger() *log.Logger - // IsVerbose atomically loads and returns whether [Msg] has verbose logging enabled. + // IsVerbose atomically loads and returns whether [Msg] has verbose logging + // enabled. IsVerbose() bool - // SwapVerbose atomically stores a new verbose state and returns the previous value held by [Msg]. + // SwapVerbose atomically stores a new verbose state and returns the + // previous value held by [Msg]. SwapVerbose(verbose bool) bool - // Verbose passes its argument to the Println method of the underlying [log.Logger] if IsVerbose returns true. + // Verbose passes its argument to the Println method of the underlying + // [log.Logger] if IsVerbose returns true. Verbose(v ...any) - // Verbosef passes its argument to the Printf method of the underlying [log.Logger] if IsVerbose returns true. + // Verbosef passes its argument to the Printf method of the underlying + // [log.Logger] if IsVerbose returns true. Verbosef(format string, v ...any) - // Suspend causes the embedded [Suspendable] to withhold writes to its downstream [io.Writer]. - // Suspend returns false and is a noop if called between calls to Suspend and Resume. + // Suspend causes the embedded [Suspendable] to withhold writes to its + // downstream [io.Writer]. + // + // Suspend returns false and is a noop if called between calls to Suspend + // and Resume. Suspend() bool - // Resume dumps the entire buffer held by the embedded [Suspendable] and stops withholding future writes. + // Resume dumps the entire buffer held by the embedded [Suspendable] and + // stops withholding future writes. + // // Resume returns false and is a noop if a call to Suspend does not precede it. Resume() bool - // BeforeExit runs implementation-specific cleanup code, and optionally prints warnings. + // BeforeExit runs implementation-specific cleanup code, and optionally + // prints warnings. + // // BeforeExit is called before [os.Exit]. BeforeExit() } // defaultMsg is the default implementation of the [Msg] interface. -// The zero value is not safe for use. Callers should use the [New] function instead. +// +// The zero value is not safe for use. Callers should use the [New] function +// instead. type defaultMsg struct { verbose atomic.Bool @@ -61,8 +76,9 @@ type defaultMsg struct { } // New initialises a downstream [log.Logger] for a new [Msg]. -// The [log.Logger] should no longer be configured after [New] returns. -// If downstream is nil, a new logger is initialised in its place. +// +// The [log.Logger] should no longer be configured after [New] returns. If +// downstream is nil, a new logger is initialised in its place. func New(downstream *log.Logger) Msg { if downstream == nil { downstream = log.New(log.Writer(), "container: ", 0) @@ -94,7 +110,8 @@ func (msg *defaultMsg) Verbosef(format string, v ...any) { func (msg *defaultMsg) Resume() bool { resumed, dropped, _, err := msg.Suspendable.Resume() if err != nil { - // probably going to result in an error as well, so this message is as good as unreachable + // probably going to result in an error as well, so this message is as + // good as unreachable msg.logger.Printf("cannot dump buffer on resume: %v", err) } if resumed && dropped > 0 { @@ -103,7 +120,8 @@ func (msg *defaultMsg) Resume() bool { return resumed } -// BeforeExit prints a message if called between calls to [Suspendable.Suspend] and Resume. +// BeforeExit prints a message if called between calls to [Suspendable.Suspend] +// and Resume. func (msg *defaultMsg) BeforeExit() { if msg.Resume() { msg.logger.Printf("beforeExit reached on suspended output") diff --git a/test/internal/sandbox/assert.go b/test/internal/sandbox/assert.go index 343c1586..e6fe926b 100644 --- a/test/internal/sandbox/assert.go +++ b/test/internal/sandbox/assert.go @@ -1,11 +1,11 @@ //go:build testtool -/* -Package sandbox provides utilities for checking sandbox outcome. - -This package must never be used outside integration tests, there is a much better native implementation of mountinfo -in the public sandbox/vfs package. Files in this package are excluded by the build system to prevent accidental misuse. -*/ +// Package sandbox provides utilities for checking sandbox outcome. +// +// This package must never be used outside integration tests, there is a much +// better native implementation of mountinfo in the public sandbox/vfs package. +// Files in this package are excluded by the build system to prevent accidental +// misuse. package sandbox import ( @@ -204,8 +204,8 @@ func MustCheckFilter(pid int, want string) { return } - var perr *ptraceError - if !errors.As(err, &perr) { + perr, ok := errors.AsType[*ptraceError](err) + if !ok { fatalf("%s", err) } switch perr.op { diff --git a/vfs/mountinfo.go b/vfs/mountinfo.go index 77f6a35d..3c9e65ca 100644 --- a/vfs/mountinfo.go +++ b/vfs/mountinfo.go @@ -103,7 +103,7 @@ type ( // Flags interprets VfsOptstr and returns the resulting flags and unmatched options. func (e *MountInfoEntry) Flags() (flags uintptr, unmatched []string) { - for _, s := range strings.Split(e.VfsOptstr, ",") { + for s := range strings.SplitSeq(e.VfsOptstr, ",") { switch s { case "rw": case "ro":