all: convert interface{} to any

Change-Id: I1f3b7cc8899c7707abb01e3d14807c37c3451382
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/449695
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/pkgsite/main.go b/cmd/pkgsite/main.go
index c273c82..29fd67e 100644
--- a/cmd/pkgsite/main.go
+++ b/cmd/pkgsite/main.go
@@ -294,7 +294,7 @@
 	return outPaths, cacheMods, nil
 }
 
-func die(format string, args ...interface{}) {
+func die(format string, args ...any) {
 	fmt.Fprintf(os.Stderr, format, args...)
 	fmt.Fprintln(os.Stderr)
 	os.Exit(1)
diff --git a/internal/database/benchmark_test.go b/internal/database/benchmark_test.go
index 29b2956..a0c5d17 100644
--- a/internal/database/benchmark_test.go
+++ b/internal/database/benchmark_test.go
@@ -27,7 +27,7 @@
 		b.Fatal(err)
 	}
 	const size = 15000
-	vals := make([]interface{}, size)
+	vals := make([]any, size)
 	for i := 0; i < size; i++ {
 		vals[i] = i + 1
 	}
@@ -54,13 +54,13 @@
 		if err != nil {
 			b.Fatal(err)
 		}
-		rows := make([][]interface{}, len(vals))
+		rows := make([][]any, len(vals))
 		for i, v := range vals {
-			rows[i] = []interface{}{v}
+			rows[i] = []any{v}
 		}
 		src := pgx.CopyFromRows(rows)
 		for i := 0; i < b.N; i++ {
-			err = conn.Raw(func(driverConn interface{}) error {
+			err = conn.Raw(func(driverConn any) error {
 				pgxConn := driverConn.(*stdlib.Conn).Conn()
 				_, err := pgxConn.CopyFrom(ctx, []string{"test_large_bulk"}, []string{"i"}, src)
 				return err
diff --git a/internal/database/copy.go b/internal/database/copy.go
index b564fd1..86244ea 100644
--- a/internal/database/copy.go
+++ b/internal/database/copy.go
@@ -94,7 +94,7 @@
 	if !db.InTransaction() {
 		return errors.New("not in a transaction")
 	}
-	return db.conn.Raw(func(c interface{}) error {
+	return db.conn.Raw(func(c any) error {
 		if w, ok := c.(*wrapConn); ok {
 			c = w.underlying
 		}
@@ -108,7 +108,7 @@
 
 // A RowItem is a row of values or an error.
 type RowItem struct {
-	Values []interface{}
+	Values []any
 	Err    error
 }
 
@@ -133,7 +133,7 @@
 }
 
 // Values implements CopyFromSource.Values.
-func (cs *chanCopySource) Values() ([]interface{}, error) {
+func (cs *chanCopySource) Values() ([]any, error) {
 	return cs.next.Values, cs.next.Err
 }
 
diff --git a/internal/database/copy_test.go b/internal/database/copy_test.go
index f96eff3..a878985 100644
--- a/internal/database/copy_test.go
+++ b/internal/database/copy_test.go
@@ -32,7 +32,7 @@
 			t.Fatal(err)
 		}
 	}
-	rows := [][]interface{}{
+	rows := [][]any{
 		{3, "baz"},
 		{4, "moo"},
 	}
@@ -63,7 +63,7 @@
 			t.Fatal(err)
 		}
 	}
-	rows := [][]interface{}{
+	rows := [][]any{
 		{3, "baz"}, // new row
 		{1, "moo"}, // replace "foo" with "moo"
 	}
@@ -103,7 +103,7 @@
 		t.Fatal(err)
 	}
 
-	rows := [][]interface{}{
+	rows := [][]any{
 		{13, "baz"}, // new row
 		{11, "moo"}, // replace "foo" with "moo"
 	}
@@ -138,7 +138,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	conn.Raw(func(c interface{}) error {
+	conn.Raw(func(c any) error {
 		if _, ok := c.(*stdlib.Conn); !ok {
 			t.Skip("skipping; DB driver not pgx")
 		}
diff --git a/internal/database/database.go b/internal/database/database.go
index b636375..3057163 100644
--- a/internal/database/database.go
+++ b/internal/database/database.go
@@ -87,7 +87,7 @@
 }
 
 // Exec executes a SQL statement and returns the number of rows it affected.
-func (db *DB) Exec(ctx context.Context, query string, args ...interface{}) (_ int64, err error) {
+func (db *DB) Exec(ctx context.Context, query string, args ...any) (_ int64, err error) {
 	defer logQuery(ctx, query, args, db.instanceID, db.IsRetryable())(&err)
 	res, err := db.execResult(ctx, query, args...)
 	if err != nil {
@@ -101,7 +101,7 @@
 }
 
 // execResult executes a SQL statement and returns a sql.Result.
-func (db *DB) execResult(ctx context.Context, query string, args ...interface{}) (res sql.Result, err error) {
+func (db *DB) execResult(ctx context.Context, query string, args ...any) (res sql.Result, err error) {
 	if db.tx != nil {
 		return db.tx.ExecContext(ctx, query, args...)
 	}
@@ -109,7 +109,7 @@
 }
 
 // Query runs the DB query.
-func (db *DB) Query(ctx context.Context, query string, args ...interface{}) (_ *sql.Rows, err error) {
+func (db *DB) Query(ctx context.Context, query string, args ...any) (_ *sql.Rows, err error) {
 	defer logQuery(ctx, query, args, db.instanceID, db.IsRetryable())(&err)
 	if db.tx != nil {
 		return db.tx.QueryContext(ctx, query, args...)
@@ -118,7 +118,7 @@
 }
 
 // QueryRow runs the query and returns a single row.
-func (db *DB) QueryRow(ctx context.Context, query string, args ...interface{}) *sql.Row {
+func (db *DB) QueryRow(ctx context.Context, query string, args ...any) *sql.Row {
 	defer logQuery(ctx, query, args, db.instanceID, db.IsRetryable())(nil)
 	start := time.Now()
 	defer func() {
@@ -144,7 +144,7 @@
 
 // RunQuery executes query, then calls f on each row. It stops when there are no
 // more rows or f returns a non-nil error.
-func (db *DB) RunQuery(ctx context.Context, query string, f func(*sql.Rows) error, params ...interface{}) error {
+func (db *DB) RunQuery(ctx context.Context, query string, f func(*sql.Rows) error, params ...any) error {
 	rows, err := db.Query(ctx, query, params...)
 	if err != nil {
 		return err
@@ -168,7 +168,7 @@
 // RunQueryIncrementally executes query, then calls f on each row. It fetches
 // rows in groups of size batchSize. It stops when there are no more rows, or
 // when f returns io.EOF.
-func (db *DB) RunQueryIncrementally(ctx context.Context, query string, batchSize int, f func(*sql.Rows) error, params ...interface{}) (err error) {
+func (db *DB) RunQueryIncrementally(ctx context.Context, query string, batchSize int, f func(*sql.Rows) error, params ...any) (err error) {
 	// Run in a transaction, because cursors require one.
 	return db.Transact(ctx, sql.LevelDefault, func(tx *DB) error {
 		// Declare a cursor and associate it with the query.
@@ -327,7 +327,7 @@
 // If conflictAction is not empty, it is appended to the statement.
 //
 // The query is executed using a PREPARE statement with the provided values.
-func (db *DB) BulkInsert(ctx context.Context, table string, columns []string, values []interface{}, conflictAction string) (err error) {
+func (db *DB) BulkInsert(ctx context.Context, table string, columns []string, values []any, conflictAction string) (err error) {
 	defer derrors.Wrap(&err, "DB.BulkInsert(ctx, %q, %v, [%d values], %q)",
 		table, columns, len(values), conflictAction)
 
@@ -338,7 +338,7 @@
 // In addition to the arguments of BulkInsert, it takes a list of columns to return and a function
 // to scan those columns. To get the returned values, provide a function that scans them as if
 // they were the selected columns of a query. See TestBulkInsert for an example.
-func (db *DB) BulkInsertReturning(ctx context.Context, table string, columns []string, values []interface{}, conflictAction string, returningColumns []string, scanFunc func(*sql.Rows) error) (err error) {
+func (db *DB) BulkInsertReturning(ctx context.Context, table string, columns []string, values []any, conflictAction string, returningColumns []string, scanFunc func(*sql.Rows) error) (err error) {
 	defer derrors.Wrap(&err, "DB.BulkInsertReturning(ctx, %q, %v, [%d values], %q, %v, scanFunc)",
 		table, columns, len(values), conflictAction, returningColumns)
 
@@ -352,18 +352,18 @@
 // conflicting columns is provided. An "ON CONFLICT (conflict_columns) DO
 // UPDATE" clause is added to the statement, with assignments "c=excluded.c" for
 // every column c.
-func (db *DB) BulkUpsert(ctx context.Context, table string, columns []string, values []interface{}, conflictColumns []string) error {
+func (db *DB) BulkUpsert(ctx context.Context, table string, columns []string, values []any, conflictColumns []string) error {
 	conflictAction := buildUpsertConflictAction(columns, conflictColumns)
 	return db.BulkInsert(ctx, table, columns, values, conflictAction)
 }
 
 // BulkUpsertReturning is like BulkInsertReturning, but performs an upsert like BulkUpsert.
-func (db *DB) BulkUpsertReturning(ctx context.Context, table string, columns []string, values []interface{}, conflictColumns, returningColumns []string, scanFunc func(*sql.Rows) error) error {
+func (db *DB) BulkUpsertReturning(ctx context.Context, table string, columns []string, values []any, conflictColumns, returningColumns []string, scanFunc func(*sql.Rows) error) error {
 	conflictAction := buildUpsertConflictAction(columns, conflictColumns)
 	return db.BulkInsertReturning(ctx, table, columns, values, conflictAction, returningColumns, scanFunc)
 }
 
-func (db *DB) bulkInsert(ctx context.Context, table string, columns, returningColumns []string, values []interface{}, conflictAction string, scanFunc func(*sql.Rows) error) (err error) {
+func (db *DB) bulkInsert(ctx context.Context, table string, columns, returningColumns []string, values []any, conflictAction string, scanFunc func(*sql.Rows) error) (err error) {
 	if remainder := len(values) % len(columns); remainder != 0 {
 		return fmt.Errorf("modulus of len(values) and len(columns) must be 0: got %d", remainder)
 	}
@@ -485,7 +485,7 @@
 //
 // Values contains one slice of values per column. (Note that this is unlike BulkInsert, which
 // takes a single slice of interleaved values.)
-func (db *DB) BulkUpdate(ctx context.Context, table string, columns, types []string, values [][]interface{}) (err error) {
+func (db *DB) BulkUpdate(ctx context.Context, table string, columns, types []string, values [][]any) (err error) {
 	defer derrors.Wrap(&err, "DB.BulkUpdate(ctx, tx, %q, %v, [%d values])",
 		table, columns, len(values))
 
@@ -507,7 +507,7 @@
 		if right > nRows {
 			right = nRows
 		}
-		var args []interface{}
+		var args []any
 		for _, vs := range values {
 			args = append(args, pq.Array(vs[left:right]))
 		}
@@ -543,7 +543,7 @@
 
 // Collect1 runs the query, which must select for a single column that can be
 // scanned into a value of type T, and returns a slice of the resulting values.
-func Collect1[T any](ctx context.Context, db *DB, query string, args ...interface{}) (ts []T, err error) {
+func Collect1[T any](ctx context.Context, db *DB, query string, args ...any) (ts []T, err error) {
 	defer derrors.WrapStack(&err, "Collect1(%q)", query)
 	err = db.RunQuery(ctx, query, func(rows *sql.Rows) error {
 		var t T
@@ -565,7 +565,7 @@
 	ptr *string
 }
 
-func (e emptyStringScanner) Scan(value interface{}) error {
+func (e emptyStringScanner) Scan(value any) error {
 	var ns sql.NullString
 	if err := ns.Scan(value); err != nil {
 		return err
diff --git a/internal/database/database_test.go b/internal/database/database_test.go
index e2ee75b..e48caf9 100644
--- a/internal/database/database_test.go
+++ b/internal/database/database_test.go
@@ -62,7 +62,7 @@
 	for _, test := range []struct {
 		name           string
 		columns        []string
-		values         []interface{}
+		values         []any
 		conflictAction string
 		wantErr        bool
 		wantCount      int
@@ -72,35 +72,35 @@
 
 			name:      "test-one-row",
 			columns:   []string{"colA"},
-			values:    []interface{}{"valueA"},
+			values:    []any{"valueA"},
 			wantCount: 1,
 		},
 		{
 
 			name:      "test-multiple-rows",
 			columns:   []string{"colA"},
-			values:    []interface{}{"valueA1", "valueA2", "valueA3"},
+			values:    []any{"valueA1", "valueA2", "valueA3"},
 			wantCount: 3,
 		},
 		{
 
 			name:    "test-invalid-column-name",
 			columns: []string{"invalid_col"},
-			values:  []interface{}{"valueA"},
+			values:  []any{"valueA"},
 			wantErr: true,
 		},
 		{
 
 			name:    "test-mismatch-num-cols-and-vals",
 			columns: []string{"colA", "colB"},
-			values:  []interface{}{"valueA1", "valueB1", "valueA2"},
+			values:  []any{"valueA1", "valueB1", "valueA2"},
 			wantErr: true,
 		},
 		{
 
 			name:         "insert-returning",
 			columns:      []string{"colA", "colB"},
-			values:       []interface{}{"valueA1", "valueB1", "valueA2", "valueB2"},
+			values:       []any{"valueA1", "valueB1", "valueA2", "valueB2"},
 			wantCount:    2,
 			wantReturned: []string{"valueA1", "valueA2"},
 		},
@@ -108,14 +108,14 @@
 
 			name:    "test-conflict",
 			columns: []string{"colA"},
-			values:  []interface{}{"valueA", "valueA"},
+			values:  []any{"valueA", "valueA"},
 			wantErr: true,
 		},
 		{
 
 			name:           "test-conflict-do-nothing",
 			columns:        []string{"colA"},
-			values:         []interface{}{"valueA", "valueA"},
+			values:         []any{"valueA", "valueA"},
 			conflictAction: OnConflictDoNothing,
 			wantCount:      1,
 		},
@@ -130,7 +130,7 @@
 			// which would truncate most tables in the database.
 			name:           "test-sql-injection",
 			columns:        []string{"colA"},
-			values:         []interface{}{fmt.Sprintf("''); TRUNCATE %s CASCADE;))", table)},
+			values:         []any{fmt.Sprintf("''); TRUNCATE %s CASCADE;))", table)},
 			conflictAction: OnConflictDoNothing,
 			wantCount:      1,
 		},
@@ -204,7 +204,7 @@
 		t.Fatal(err)
 	}
 	const size = 150001
-	vals := make([]interface{}, size)
+	vals := make([]any, size)
 	for i := 0; i < size; i++ {
 		vals[i] = i + 1
 	}
@@ -240,7 +240,7 @@
 	if _, err := testDB.Exec(ctx, `CREATE TEMPORARY TABLE test_replace (C1 int PRIMARY KEY, C2 int);`); err != nil {
 		t.Fatal(err)
 	}
-	for _, values := range [][]interface{}{
+	for _, values := range [][]any{
 		{2, 4, 4, 8},                 // First, insert some rows.
 		{1, -1, 2, -2, 3, -3, 4, -4}, // Then replace those rows while inserting others.
 	} {
@@ -250,7 +250,7 @@
 		if err != nil {
 			t.Fatal(err)
 		}
-		var got []interface{}
+		var got []any
 		err = testDB.RunQuery(ctx, `SELECT C1, C2 FROM test_replace ORDER BY C1`, func(rows *sql.Rows) error {
 			var a, b int
 			if err := rows.Scan(&a, &b); err != nil {
@@ -324,7 +324,7 @@
 	}()
 
 	cols := []string{"a", "b"}
-	var values []interface{}
+	var values []any
 	for i := 0; i < 50; i++ {
 		values = append(values, i, i)
 	}
@@ -336,7 +336,7 @@
 	}
 
 	// Update all even values of column a.
-	updateVals := make([][]interface{}, 2)
+	updateVals := make([][]any, 2)
 	for i := 0; i < len(values)/2; i += 2 {
 		updateVals[0] = append(updateVals[0], i)
 		updateVals[1] = append(updateVals[1], -i)
@@ -486,12 +486,12 @@
 		}
 	}
 
-	err = conn.Raw(func(c interface{}) error {
+	err = conn.Raw(func(c any) error {
 		stdConn, ok := c.(*stdlib.Conn)
 		if !ok {
 			t.Skip("DB driver is not pgx")
 		}
-		rows := [][]interface{}{{1}, {2}}
+		rows := [][]any{{1}, {2}}
 		_, err = stdConn.Conn().CopyFrom(ctx, []string{"test_copy"}, []string{"i"}, pgx.CopyFromRows(rows))
 		return err
 	})
diff --git a/internal/database/logging.go b/internal/database/logging.go
index a2f6260..dcb8c18 100644
--- a/internal/database/logging.go
+++ b/internal/database/logging.go
@@ -31,7 +31,7 @@
 	Error           string `json:",omitempty"`
 }
 
-func logQuery(ctx context.Context, query string, args []interface{}, instanceID string, retryable bool) func(*error) {
+func logQuery(ctx context.Context, query string, args []any, instanceID string, retryable bool) func(*error) {
 	if QueryLoggingDisabled {
 		return func(*error) {}
 	}
diff --git a/internal/database/reflect.go b/internal/database/reflect.go
index e057d06..2bfbd20 100644
--- a/internal/database/reflect.go
+++ b/internal/database/reflect.go
@@ -37,7 +37,7 @@
 //	    // use p
 //	    return nil
 //	})
-func StructScanner[T any]() func(p *T) []interface{} {
+func StructScanner[T any]() func(p *T) []any {
 	return structScannerForType[T]()
 }
 
@@ -46,7 +46,7 @@
 	kind reflect.Kind
 }
 
-func structScannerForType[T any]() func(p *T) []interface{} {
+func structScannerForType[T any]() func(p *T) []any {
 	var x T
 	t := reflect.TypeOf(x)
 	if t.Kind() != reflect.Struct {
@@ -62,9 +62,9 @@
 		}
 	}
 	// Return a function that gets pointers to the exported fields.
-	return func(p *T) []interface{} {
+	return func(p *T) []any {
 		v := reflect.ValueOf(p).Elem()
-		var ps []interface{}
+		var ps []any
 		for _, info := range fieldInfos {
 			p := v.Field(info.num).Addr().Interface()
 			switch info.kind {
@@ -87,7 +87,7 @@
 // value that can be passed to a Scan function. If the corresponding column is
 // nil, the variable will be set to nil. Otherwise, it will be set to a newly
 // allocated pointer to the column value.
-func NullPtr(p interface{}) nullPtr {
+func NullPtr(p any) nullPtr {
 	v := reflect.ValueOf(p)
 	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Ptr {
 		panic("NullPtr arg must be pointer to pointer")
@@ -100,7 +100,7 @@
 	ptr reflect.Value
 }
 
-func (n nullPtr) Scan(value interface{}) error {
+func (n nullPtr) Scan(value any) error {
 	// n.ptr is like a variable v of type **T
 	ntype := n.ptr.Elem().Type() // T
 	if value == nil {
@@ -126,7 +126,7 @@
 //	type Player struct { Name string; Score int }
 //	var players []Player
 //	err := db.CollectStructs(ctx, &players, "SELECT name, score FROM players")
-func CollectStructs[T any](ctx context.Context, db *DB, query string, args ...interface{}) ([]T, error) {
+func CollectStructs[T any](ctx context.Context, db *DB, query string, args ...any) ([]T, error) {
 	scanner := structScannerForType[T]()
 	var ts []T
 	err := db.RunQuery(ctx, query, func(rows *sql.Rows) error {
@@ -143,7 +143,7 @@
 	return ts, nil
 }
 
-func CollectStructPtrs[T any](ctx context.Context, db *DB, query string, args ...interface{}) ([]*T, error) {
+func CollectStructPtrs[T any](ctx context.Context, db *DB, query string, args ...any) ([]*T, error) {
 	scanner := structScannerForType[T]()
 	var ts []*T
 	err := db.RunQuery(ctx, query, func(rows *sql.Rows) error {
diff --git a/internal/database/reflect_test.go b/internal/database/reflect_test.go
index be570e4..2bb2f33 100644
--- a/internal/database/reflect_test.go
+++ b/internal/database/reflect_test.go
@@ -80,7 +80,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if err := testDB.BulkInsert(ctx, "structs", []string{"name", "score", "slice", "nullable", "bytes"}, []interface{}{
+	if err := testDB.BulkInsert(ctx, "structs", []string{"name", "score", "slice", "nullable", "bytes"}, []any{
 		"A", 1, pq.Array([]int64(nil)), 7, nil,
 		"B", 2, pq.Array([]int64{1, 2}), -8, []byte("abc"),
 		"C", 3, pq.Array([]int64{}), nil, []byte("def"),
diff --git a/internal/dcensus/debug.go b/internal/dcensus/debug.go
index fd6134a..4342f95 100644
--- a/internal/dcensus/debug.go
+++ b/internal/dcensus/debug.go
@@ -56,7 +56,7 @@
 	return buf.String()
 }
 
-func dumpAttributes(w io.Writer, m map[string]interface{}) {
+func dumpAttributes(w io.Writer, m map[string]any) {
 	for k, v := range m {
 		fmt.Fprintf(w, "  %q: %#v\n", k, v)
 	}
diff --git a/internal/derrors/derrors.go b/internal/derrors/derrors.go
index e9bf284..4702ae5 100644
--- a/internal/derrors/derrors.go
+++ b/internal/derrors/derrors.go
@@ -156,7 +156,7 @@
 // corresponding to the code is returned unwrapped.
 //
 // If code is http.StatusOK, it returns nil.
-func FromStatus(code int, format string, args ...interface{}) error {
+func FromStatus(code int, format string, args ...any) error {
 	if code == http.StatusOK {
 		return nil
 	}
@@ -215,7 +215,7 @@
 //
 // See Wrap for an equivalent function that allows
 // the result to be unwrapped.
-func Add(errp *error, format string, args ...interface{}) {
+func Add(errp *error, format string, args ...any) {
 	if *errp != nil {
 		*errp = fmt.Errorf("%s: %v", fmt.Sprintf(format, args...), *errp)
 	}
@@ -230,14 +230,14 @@
 //
 // See Add for an equivalent function that does not allow
 // the result to be unwrapped.
-func Wrap(errp *error, format string, args ...interface{}) {
+func Wrap(errp *error, format string, args ...any) {
 	if *errp != nil {
 		*errp = fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), *errp)
 	}
 }
 
 // WrapStack is like Wrap, but adds a stack trace if there isn't one already.
-func WrapStack(errp *error, format string, args ...interface{}) {
+func WrapStack(errp *error, format string, args ...any) {
 	if *errp != nil {
 		if se := (*StackError)(nil); !errors.As(*errp, &se) {
 			*errp = NewStackError(*errp)
@@ -273,7 +273,7 @@
 }
 
 // WrapAndReport calls Wrap followed by Report.
-func WrapAndReport(errp *error, format string, args ...interface{}) {
+func WrapAndReport(errp *error, format string, args ...any) {
 	Wrap(errp, format, args...)
 	if *errp != nil {
 		Report(*errp)
diff --git a/internal/fetch/fetch.go b/internal/fetch/fetch.go
index 6c8d34c..7432e3e 100644
--- a/internal/fetch/fetch.go
+++ b/internal/fetch/fetch.go
@@ -206,7 +206,7 @@
 	if err != nil {
 		return nil, nil, err
 	}
-	logf := func(format string, args ...interface{}) {
+	logf := func(format string, args ...any) {
 		log.Infof(ctx, format, args...)
 	}
 	d := licenses.NewDetectorFS(modulePath, v, contentDir, logf)
diff --git a/internal/fetch/helper_test.go b/internal/fetch/helper_test.go
index ccb7e5d..4768088 100644
--- a/internal/fetch/helper_test.go
+++ b/internal/fetch/helper_test.go
@@ -182,7 +182,7 @@
 		return got, nil
 	}
 
-	d := licenses.NewDetectorFS(modulePath, LocalVersion, os.DirFS(directory), func(format string, args ...interface{}) {
+	d := licenses.NewDetectorFS(modulePath, LocalVersion, os.DirFS(directory), func(format string, args ...any) {
 		log.Infof(ctx, format, args...)
 	})
 	return got, d
@@ -209,7 +209,7 @@
 			t.Fatal(err)
 		}
 	}
-	logf := func(format string, args ...interface{}) {
+	logf := func(format string, args ...any) {
 		log.Infof(ctx, format, args...)
 	}
 	return licenses.NewDetectorFS(modulePath, version, contentDir, logf)
diff --git a/internal/frontend/client.go b/internal/frontend/client.go
index afb2323..978c87b 100644
--- a/internal/frontend/client.go
+++ b/internal/frontend/client.go
@@ -90,7 +90,7 @@
 	return s.serveStats && r.FormValue("content") == "json"
 }
 
-func (s *Server) serveJSONPage(w http.ResponseWriter, r *http.Request, d interface{}) (err error) {
+func (s *Server) serveJSONPage(w http.ResponseWriter, r *http.Request, d any) (err error) {
 	defer derrors.Wrap(&err, "serveJSONPage(ctx, w, r)")
 	if !s.shouldServeJSON(r) {
 		return derrors.NotFound
diff --git a/internal/frontend/server.go b/internal/frontend/server.go
index 939a8f6..cd768a6 100644
--- a/internal/frontend/server.go
+++ b/internal/frontend/server.go
@@ -490,7 +490,7 @@
 	basePage
 	templateName    string
 	messageTemplate template.TrustedTemplate
-	MessageData     interface{}
+	MessageData     any
 }
 
 // PanicHandler returns an http.HandlerFunc that can be used in HTTP
@@ -643,7 +643,7 @@
 }
 
 // servePage is used to execute all templates for a *Server.
-func (s *Server) servePage(ctx context.Context, w http.ResponseWriter, templateName string, page interface{}) {
+func (s *Server) servePage(ctx context.Context, w http.ResponseWriter, templateName string, page any) {
 	defer middleware.ElapsedStat(ctx, "servePage")()
 
 	buf, err := s.renderPage(ctx, templateName, page)
@@ -659,7 +659,7 @@
 }
 
 // renderPage executes the given templateName with page.
-func (s *Server) renderPage(ctx context.Context, templateName string, page interface{}) ([]byte, error) {
+func (s *Server) renderPage(ctx context.Context, templateName string, page any) ([]byte, error) {
 	defer middleware.ElapsedStat(ctx, "renderPage")()
 
 	tmpl, err := s.findTemplate(templateName)
@@ -686,7 +686,7 @@
 	return tmpl, nil
 }
 
-func executeTemplate(ctx context.Context, templateName string, tmpl *template.Template, data interface{}) ([]byte, error) {
+func executeTemplate(ctx context.Context, templateName string, tmpl *template.Template, data any) ([]byte, error) {
 	var buf bytes.Buffer
 	if err := tmpl.Execute(&buf, data); err != nil {
 		log.Errorf(ctx, "Error executing page template %q: %v", templateName, err)
diff --git a/internal/frontend/server_test.go b/internal/frontend/server_test.go
index f156bc4..181be64 100644
--- a/internal/frontend/server_test.go
+++ b/internal/frontend/server_test.go
@@ -1568,7 +1568,7 @@
 	for _, c := range []struct {
 		name    string
 		subs    []string
-		typeval interface{}
+		typeval any
 	}{
 		{"badge", nil, badgePage{}},
 		// error.tmpl omitted because relies on an associated "message" template
diff --git a/internal/frontend/tabs.go b/internal/frontend/tabs.go
index aace156..bb081b5 100644
--- a/internal/frontend/tabs.go
+++ b/internal/frontend/tabs.go
@@ -78,7 +78,7 @@
 // handler.
 func fetchDetailsForUnit(ctx context.Context, r *http.Request, tab string, ds internal.DataSource, um *internal.UnitMeta,
 	requestedVersion string, bc internal.BuildContext,
-	getVulnEntries vulns.VulnEntriesFunc) (_ interface{}, err error) {
+	getVulnEntries vulns.VulnEntriesFunc) (_ any, err error) {
 	defer derrors.Wrap(&err, "fetchDetailsForUnit(r, %q, ds, um=%q,%q,%q)", tab, um.Path, um.ModulePath, um.Version)
 	switch tab {
 	case tabMain:
diff --git a/internal/frontend/unit.go b/internal/frontend/unit.go
index 79fce3b..e282d59 100644
--- a/internal/frontend/unit.go
+++ b/internal/frontend/unit.go
@@ -89,7 +89,7 @@
 	RedirectedFromPath string
 
 	// Details contains data specific to the type of page being rendered.
-	Details interface{}
+	Details any
 
 	// Vulns holds vulnerability information.
 	Vulns []vulns.Vuln
diff --git a/internal/godoc/codec/codec.go b/internal/godoc/codec/codec.go
index 6caf7c8..83ca3b9 100644
--- a/internal/godoc/codec/codec.go
+++ b/internal/godoc/codec/codec.go
@@ -19,19 +19,19 @@
 type Encoder struct {
 	buf      []byte
 	typeNums map[reflect.Type]int
-	seen     map[interface{}]uint64 // for references; see StartStruct
+	seen     map[any]uint64 // for references; see StartStruct
 }
 
 // NewEncoder returns an Encoder.
 func NewEncoder() *Encoder {
 	return &Encoder{
 		typeNums: map[reflect.Type]int{},
-		seen:     map[interface{}]uint64{},
+		seen:     map[any]uint64{},
 	}
 }
 
 // Encode encodes x.
-func (e *Encoder) Encode(x interface{}) (err error) {
+func (e *Encoder) Encode(x any) (err error) {
 	defer handlePanic(&err)
 	e.EncodeAny(x)
 	return nil
@@ -62,7 +62,7 @@
 	panic(codecError{err})
 }
 
-func failf(format string, args ...interface{}) {
+func failf(format string, args ...any) {
 	fail(fmt.Errorf(format, args...))
 }
 
@@ -82,7 +82,7 @@
 	buf       []byte
 	i         int
 	typeInfos []*typeInfo
-	refs      []interface{} // list of struct pointers, in the order seen
+	refs      []any // list of struct pointers, in the order seen
 }
 
 // NewDecoder returns a Decoder for the given bytes.
@@ -91,7 +91,7 @@
 }
 
 // Decode decodes a value encoded with Encoder.Encode.
-func (d *Decoder) Decode() (_ interface{}, err error) {
+func (d *Decoder) Decode() (_ any, err error) {
 	defer handlePanic(&err)
 	if d.typeInfos == nil {
 		d.decodeInitial()
@@ -347,7 +347,7 @@
 // StartStruct should be called before encoding a struct pointer. The isNil
 // argument says whether the pointer is nil. The p argument is the struct
 // pointer. If StartStruct returns false, encoding should not proceed.
-func (e *Encoder) StartStruct(isNil bool, p interface{}) bool {
+func (e *Encoder) StartStruct(isNil bool, p any) bool {
 	if isNil {
 		e.EncodeNil()
 		return false
@@ -370,7 +370,7 @@
 // false, decoding should not proceed. If it returns true and the second return
 // value is non-nil, it is a reference to a previous value and should be used
 // instead of proceeding with decoding.
-func (d *Decoder) StartStruct() (bool, interface{}) {
+func (d *Decoder) StartStruct() (bool, any) {
 	b := d.readByte()
 	switch b {
 	case nilCode: // do not set the pointer
@@ -388,7 +388,7 @@
 
 // StoreRef should be called by a struct decoder immediately after it allocates
 // a struct pointer.
-func (d *Decoder) StoreRef(p interface{}) {
+func (d *Decoder) StoreRef(p any) {
 	d.refs = append(d.refs, p)
 }
 
@@ -452,7 +452,7 @@
 
 // EncodeAny encodes a Go type. The type must have
 // been registered with Register.
-func (e *Encoder) EncodeAny(x interface{}) {
+func (e *Encoder) EncodeAny(x any) {
 	// Encode a nil interface value with a zero.
 	if x == nil {
 		e.writeByte(0)
@@ -477,7 +477,7 @@
 }
 
 // DecodeAny decodes a value encoded by EncodeAny.
-func (d *Decoder) DecodeAny() interface{} {
+func (d *Decoder) DecodeAny() any {
 	// If we're looking at a zero, this is a nil interface.
 	if d.curByte() == 0 {
 		d.readByte() // consume the byte
@@ -541,8 +541,8 @@
 }
 
 type (
-	encodeFunc func(*Encoder, interface{})
-	decodeFunc func(*Decoder) interface{}
+	encodeFunc func(*Encoder, any)
+	decodeFunc func(*Decoder) any
 )
 
 var (
@@ -551,7 +551,7 @@
 )
 
 // Register records the type of x for use by Encoders and Decoders.
-func Register(x interface{}, enc encodeFunc, dec decodeFunc) {
+func Register(x any, enc encodeFunc, dec decodeFunc) {
 	t := reflect.TypeOf(x)
 	tn := typeName(t)
 	if _, ok := typeInfosByName[tn]; ok {
@@ -578,26 +578,26 @@
 
 func init() {
 	Register(int64(0),
-		func(e *Encoder, x interface{}) { e.EncodeInt(x.(int64)) },
-		func(d *Decoder) interface{} { return d.DecodeInt() })
+		func(e *Encoder, x any) { e.EncodeInt(x.(int64)) },
+		func(d *Decoder) any { return d.DecodeInt() })
 	Register(uint64(0),
-		func(e *Encoder, x interface{}) { e.EncodeUint(x.(uint64)) },
-		func(d *Decoder) interface{} { return d.DecodeUint() })
+		func(e *Encoder, x any) { e.EncodeUint(x.(uint64)) },
+		func(d *Decoder) any { return d.DecodeUint() })
 	Register(int(0),
-		func(e *Encoder, x interface{}) { e.EncodeInt(int64(x.(int))) },
-		func(d *Decoder) interface{} { return int(d.DecodeInt()) })
+		func(e *Encoder, x any) { e.EncodeInt(int64(x.(int))) },
+		func(d *Decoder) any { return int(d.DecodeInt()) })
 	Register(float64(0),
-		func(e *Encoder, x interface{}) { e.EncodeFloat(x.(float64)) },
-		func(d *Decoder) interface{} { return d.DecodeFloat() })
+		func(e *Encoder, x any) { e.EncodeFloat(x.(float64)) },
+		func(d *Decoder) any { return d.DecodeFloat() })
 	Register(false,
-		func(e *Encoder, x interface{}) { e.EncodeBool(x.(bool)) },
-		func(d *Decoder) interface{} { return d.DecodeBool() })
+		func(e *Encoder, x any) { e.EncodeBool(x.(bool)) },
+		func(d *Decoder) any { return d.DecodeBool() })
 	Register("",
-		func(e *Encoder, x interface{}) { e.EncodeString(x.(string)) },
-		func(d *Decoder) interface{} { return d.DecodeString() })
+		func(e *Encoder, x any) { e.EncodeString(x.(string)) },
+		func(d *Decoder) any { return d.DecodeString() })
 	Register([]byte(nil),
-		func(e *Encoder, x interface{}) { e.EncodeBytes(x.([]byte)) },
-		func(d *Decoder) interface{} { return d.DecodeBytes() })
+		func(e *Encoder, x any) { e.EncodeBytes(x.([]byte)) },
+		func(d *Decoder) any { return d.DecodeBytes() })
 
 	for t := range typeInfosByType {
 		builtinTypes = append(builtinTypes, t)
diff --git a/internal/godoc/codec/codec_test.go b/internal/godoc/codec/codec_test.go
index c93f941..bd3bc43 100644
--- a/internal/godoc/codec/codec_test.go
+++ b/internal/godoc/codec/codec_test.go
@@ -92,13 +92,13 @@
 
 	d := NewDecoder(e.Bytes())
 	d.decodeInitial()
-	gots := []interface{}{
+	gots := []any{
 		d.DecodeBytes(),
 		d.DecodeString(),
 		d.DecodeBool(),
 		d.DecodeFloat(),
 	}
-	wants := []interface{}{by, s, b, f}
+	wants := []any{by, s, b, f}
 	if !cmp.Equal(gots, wants) {
 		t.Errorf("got %v, want %v", gots, wants)
 	}
@@ -128,7 +128,7 @@
 }
 
 func TestAny(t *testing.T) {
-	want := []interface{}{"bar", nil, 1, -5, 98.6, uint64(1 << 63), "Luke Luck likes lakes", true}
+	want := []any{"bar", nil, 1, -5, 98.6, uint64(1 << 63), "Luke Luck likes lakes", true}
 	e := NewEncoder()
 	for _, w := range want {
 		e.EncodeAny(w)
@@ -145,7 +145,7 @@
 }
 
 func TestEncodeDecode(t *testing.T) {
-	want := []interface{}{"bar", nil, 1, -5, 98.6, uint64(1 << 63), "Luke Luck likes lakes", true}
+	want := []any{"bar", nil, 1, -5, 98.6, uint64(1 << 63), "Luke Luck likes lakes", true}
 	e := NewEncoder()
 	for _, w := range want {
 		if err := e.Encode(w); err != nil {
@@ -194,7 +194,7 @@
 	}
 }
 
-func mustEncode(t *testing.T, x interface{}) []byte {
+func mustEncode(t *testing.T, x any) []byte {
 	t.Helper()
 	e := NewEncoder()
 	if err := e.Encode(x); err != nil {
@@ -215,7 +215,7 @@
 
 func TestSkip(t *testing.T) {
 	e := NewEncoder()
-	values := []interface{}{
+	values := []any{
 		1,
 		false,
 		"yes",
@@ -316,8 +316,8 @@
 
 func init() {
 	Register(&node{},
-		func(e *Encoder, x interface{}) { encode_node(e, x.(*node)) },
-		func(d *Decoder) interface{} {
+		func(e *Encoder, x any) { encode_node(e, x.(*node)) },
+		func(d *Decoder) any {
 			var x *node
 			decode_node(d, &x)
 			return x
diff --git a/internal/godoc/codec/generate.go b/internal/godoc/codec/generate.go
index 6011576..e5417c2 100644
--- a/internal/godoc/codec/generate.go
+++ b/internal/godoc/codec/generate.go
@@ -21,7 +21,7 @@
 // It generates code for the type of each given value, as well
 // as any types they depend on.
 // packageName is the name following the file's package declaration.
-func GenerateFile(filename, packageName string, values ...interface{}) error {
+func GenerateFile(filename, packageName string, values ...any) error {
 	if !strings.HasSuffix(filename, ".go") {
 		filename += ".go"
 	}
@@ -69,7 +69,7 @@
 	return m, nil
 }
 
-func generate(w io.Writer, packageName string, fieldNames map[string][]string, vs ...interface{}) error {
+func generate(w io.Writer, packageName string, fieldNames map[string][]string, vs ...any) error {
 	g := &generator{
 		pkg:        packageName,
 		done:       map[reflect.Type]bool{},
@@ -107,7 +107,7 @@
 	}
 	// The empty interface doesn't need any additional code. It's tricky to get
 	// its reflect.Type: we need to dereference the pointer type.
-	var iface interface{}
+	var iface any
 	g.done[reflect.TypeOf(&iface).Elem()] = true
 
 	src, err := g.generate()
@@ -330,7 +330,7 @@
 	}
 }
 
-func execute(tmpl *template.Template, data interface{}) ([]byte, error) {
+func execute(tmpl *template.Template, data any) ([]byte, error) {
 	var buf bytes.Buffer
 	if err := tmpl.Execute(&buf, data); err != nil {
 		return nil, err
@@ -474,8 +474,8 @@
 
 func init() {
   codec.Register(«$goName»(nil),
-    func(e *codec.Encoder, x interface{}) { encode_«$funcName»(e, x.(«$goName»)) },
-    func(d *codec.Decoder) interface{} { var x «$goName»; decode_«$funcName»(d, &x); return x })
+    func(e *codec.Encoder, x any) { encode_«$funcName»(e, x.(«$goName»)) },
+    func(d *codec.Decoder) any { var x «$goName»; decode_«$funcName»(d, &x); return x })
 }
 `
 
@@ -519,8 +519,8 @@
 
 func init() {
 	codec.Register(«$goName»(nil),
-	func(e *codec.Encoder, x interface{}) { encode_«$funcName»(e, x.(«$goName»)) },
-	func(d *codec.Decoder) interface{} { var x «$goName»; decode_«$funcName»(d, &x); return x })
+	func(e *codec.Encoder, x any) { encode_«$funcName»(e, x.(«$goName»)) },
+	func(d *codec.Decoder) any { var x «$goName»; decode_«$funcName»(d, &x); return x })
 }
 `
 
@@ -583,8 +583,8 @@
 
 func init() {
 	codec.Register(&«$goName»{},
-		func(e *codec.Encoder, x interface{}) { encode_«$funcName»(e, x.(*«$goName»)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_«$funcName»(e, x.(*«$goName»)) },
+		func(d *codec.Decoder) any {
 			var x *«$goName»
 			decode_«$funcName»(d, &x)
 			return x
diff --git a/internal/godoc/codec/generate_test.go b/internal/godoc/codec/generate_test.go
index 23df548..db7aade 100644
--- a/internal/godoc/codec/generate_test.go
+++ b/internal/godoc/codec/generate_test.go
@@ -23,7 +23,7 @@
 	var r io.Reader
 	g := &generator{pkg: "codec"}
 	for _, test := range []struct {
-		v    interface{}
+		v    any
 		want string
 	}{
 		{0, "int"},
@@ -49,7 +49,7 @@
 	testGenerate(t, "struct", ast.BasicLit{})
 }
 
-func testGenerate(t *testing.T, name string, x interface{}) {
+func testGenerate(t *testing.T, name string, x any) {
 	t.Helper()
 	var buf bytes.Buffer
 	if err := generate(&buf, "somepkg", nil, x); err != nil {
diff --git a/internal/godoc/codec/testdata/map.go b/internal/godoc/codec/testdata/map.go
index 939f5c3..1d2259f 100644
--- a/internal/godoc/codec/testdata/map.go
+++ b/internal/godoc/codec/testdata/map.go
@@ -41,6 +41,6 @@
 
 func init() {
 	codec.Register(map[string]bool(nil),
-		func(e *codec.Encoder, x interface{}) { encode_map_string_bool(e, x.(map[string]bool)) },
-		func(d *codec.Decoder) interface{} { var x map[string]bool; decode_map_string_bool(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_map_string_bool(e, x.(map[string]bool)) },
+		func(d *codec.Decoder) any { var x map[string]bool; decode_map_string_bool(d, &x); return x })
 }
diff --git a/internal/godoc/codec/testdata/slice.go b/internal/godoc/codec/testdata/slice.go
index e5381ca..d54078f 100644
--- a/internal/godoc/codec/testdata/slice.go
+++ b/internal/godoc/codec/testdata/slice.go
@@ -35,8 +35,8 @@
 
 func init() {
 	codec.Register([][]int(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_slice_int(e, x.([][]int)) },
-		func(d *codec.Decoder) interface{} { var x [][]int; decode_slice_slice_int(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_slice_int(e, x.([][]int)) },
+		func(d *codec.Decoder) any { var x [][]int; decode_slice_slice_int(d, &x); return x })
 }
 
 func encode_slice_int(e *codec.Encoder, s []int) {
@@ -64,6 +64,6 @@
 
 func init() {
 	codec.Register([]int(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_int(e, x.([]int)) },
-		func(d *codec.Decoder) interface{} { var x []int; decode_slice_int(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_int(e, x.([]int)) },
+		func(d *codec.Decoder) any { var x []int; decode_slice_int(d, &x); return x })
 }
diff --git a/internal/godoc/codec/testdata/struct.go b/internal/godoc/codec/testdata/struct.go
index d27d9ad..0ea3c62 100644
--- a/internal/godoc/codec/testdata/struct.go
+++ b/internal/godoc/codec/testdata/struct.go
@@ -65,8 +65,8 @@
 
 func init() {
 	codec.Register(&ast.BasicLit{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BasicLit
 			decode_ast_BasicLit(d, &x)
 			return x
diff --git a/internal/godoc/dochtml/dochtml.go b/internal/godoc/dochtml/dochtml.go
index 404b81b..95348bb 100644
--- a/internal/godoc/dochtml/dochtml.go
+++ b/internal/godoc/dochtml/dochtml.go
@@ -226,7 +226,7 @@
 }
 
 // renderInfo returns the functions and data needed to render the doc.
-func renderInfo(ctx context.Context, fset *token.FileSet, p *doc.Package, opt RenderOptions) (map[string]interface{}, templateData, func() []render.Link) {
+func renderInfo(ctx context.Context, fset *token.FileSet, p *doc.Package, opt RenderOptions) (map[string]any, templateData, func() []render.Link) {
 	// Make a copy to avoid modifying caller's *doc.Package.
 	p2 := *p
 	p = &p2
@@ -276,7 +276,7 @@
 	sinceVersion := func(name string) safehtml.HTML {
 		return safehtml.HTMLEscaped(opt.SinceVersionFunc(name))
 	}
-	funcs := map[string]interface{}{
+	funcs := map[string]any{
 		"render_short_synopsis":    r.ShortSynopsis,
 		"render_synopsis":          r.Synopsis,
 		"render_doc":               r.DocHTML,
@@ -300,7 +300,7 @@
 
 // executeToHTMLWithLimit executes tmpl on data and returns the result as a safehtml.HTML.
 // It returns an error if the size of the result exceeds limit.
-func executeToHTMLWithLimit(tmpl *template.Template, data interface{}, limit int64) (safehtml.HTML, error) {
+func executeToHTMLWithLimit(tmpl *template.Template, data any, limit int64) (safehtml.HTML, error) {
 	buf := &limitBuffer{B: new(bytes.Buffer), Remain: limit}
 	err := tmpl.Execute(buf, data)
 	if buf.Remain < 0 {
@@ -341,7 +341,7 @@
 
 // Code returns an printer.CommentedNode if ex.Comments is non-nil,
 // otherwise it returns ex.Code as is.
-func (ex *example) Code() interface{} {
+func (ex *example) Code() any {
 	if len(ex.Comments) > 0 {
 		return &printer.CommentedNode{Node: ex.Example.Code, Comments: ex.Comments}
 	}
diff --git a/internal/godoc/dochtml/internal/render/idents.go b/internal/godoc/dochtml/internal/render/idents.go
index 3e7642d..2d6f689 100644
--- a/internal/godoc/dochtml/internal/render/idents.go
+++ b/internal/godoc/dochtml/internal/render/idents.go
@@ -78,7 +78,7 @@
 	pkgIDs map[string]map[string]bool // map[name]map[topLevelID]bool
 
 	// topLevelDecls is the set of all AST declarations for the this package.
-	topLevelDecls map[interface{}]bool // map[T]bool where T is *ast.FuncDecl | *ast.GenDecl | *ast.TypeSpec | *ast.ValueSpec
+	topLevelDecls map[any]bool // map[T]bool where T is *ast.FuncDecl | *ast.GenDecl | *ast.TypeSpec | *ast.ValueSpec
 }
 
 // newPackageIDs returns a packageIDs that collects all top-level identifiers
@@ -88,7 +88,7 @@
 		name:          pkg.Name,
 		impPaths:      make(map[string]string),
 		pkgIDs:        make(map[string]map[string]bool),
-		topLevelDecls: make(map[interface{}]bool),
+		topLevelDecls: make(map[any]bool),
 	}
 
 	// Collect top-level declaration IDs for pkg and related packages.
diff --git a/internal/godoc/dochtml/internal/render/linkify.go b/internal/godoc/dochtml/internal/render/linkify.go
index a08e63d..5ee5bf5 100644
--- a/internal/godoc/dochtml/internal/render/linkify.go
+++ b/internal/godoc/dochtml/internal/render/linkify.go
@@ -306,7 +306,7 @@
 	return safe.HTMLConcat(hs...)
 }
 
-func badType(x interface{}) safe.HTML {
+func badType(x any) safe.HTML {
 	return safe.HTMLEscaped(fmt.Sprintf("bad type %T", x))
 }
 
@@ -548,7 +548,7 @@
 	return safe.HTMLConcat(htmls...)
 }
 
-func ExecuteToHTML(tmpl *template.Template, data interface{}) safe.HTML {
+func ExecuteToHTML(tmpl *template.Template, data any) safe.HTML {
 	h, err := tmpl.ExecuteToHTML(data)
 	if err != nil {
 		return safe.HTMLEscaped("[" + err.Error() + "]")
diff --git a/internal/godoc/dochtml/internal/render/testdata/os.go b/internal/godoc/dochtml/internal/render/testdata/os.go
index 1d237c2..3371b0f 100644
--- a/internal/godoc/dochtml/internal/render/testdata/os.go
+++ b/internal/godoc/dochtml/internal/render/testdata/os.go
@@ -33,7 +33,6 @@
 //		log.Fatal(err)
 //	}
 //	fmt.Printf("read %d bytes: %q\n", count, data[:count])
-//
 package os
 
 import (
@@ -489,7 +488,7 @@
 // Sys returns system-dependent exit information about
 // the process. Convert it to the appropriate underlying
 // type, such as syscall.WaitStatus on Unix, to access its contents.
-func (p *ProcessState) Sys() interface{} {
+func (p *ProcessState) Sys() any {
 	return nil
 }
 
@@ -498,7 +497,7 @@
 // type, such as *syscall.Rusage on Unix, to access its contents.
 // (On Unix, *syscall.Rusage matches struct rusage as defined in the
 // getrusage(2) manual page.)
-func (p *ProcessState) SysUsage() interface{} {
+func (p *ProcessState) SysUsage() any {
 	return nil
 }
 
diff --git a/internal/godoc/dochtml/template.go b/internal/godoc/dochtml/template.go
index ca6ce03..9e81ff3 100644
--- a/internal/godoc/dochtml/template.go
+++ b/internal/godoc/dochtml/template.go
@@ -42,8 +42,8 @@
 	})
 }
 
-var tmpl = map[string]interface{}{
-	"ternary": func(q, a, b interface{}) interface{} {
+var tmpl = map[string]any{
+	"ternary": func(q, a, b any) any {
 		v := reflect.ValueOf(q)
 		vz := reflect.New(v.Type()).Elem()
 		if reflect.DeepEqual(v.Interface(), vz.Interface()) {
@@ -60,7 +60,7 @@
 	"render_decl":              (*render.Renderer)(nil).DeclHTML,
 	"render_code":              (*render.Renderer)(nil).CodeHTML,
 	"file_link":                func() string { return "" },
-	"source_link":              func(string, interface{}) string { return "" },
+	"source_link":              func(string, any) string { return "" },
 	"since_version":            func(string) safehtml.HTML { return safehtml.HTML{} },
 	"play_url":                 func(*doc.Example) string { return "" },
 	"safe_id":                  render.SafeGoID,
diff --git a/internal/godoc/encode.go b/internal/godoc/encode.go
index b91871a..0c76e90 100644
--- a/internal/godoc/encode.go
+++ b/internal/godoc/encode.go
@@ -124,4 +124,4 @@
 //go:generate go run gen_ast.go
 
 // Used by the gen program to generate encodings for unexported types.
-var TypesToGenerate = []interface{}{&encPackage{}}
+var TypesToGenerate = []any{&encPackage{}}
diff --git a/internal/godoc/encode_ast.gen.go b/internal/godoc/encode_ast.gen.go
index 27d3906..4cf1521 100644
--- a/internal/godoc/encode_ast.gen.go
+++ b/internal/godoc/encode_ast.gen.go
@@ -65,8 +65,8 @@
 
 func init() {
 	codec.Register(&ast.ArrayType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ArrayType(e, x.(*ast.ArrayType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ArrayType(e, x.(*ast.ArrayType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ArrayType
 			decode_ast_ArrayType(d, &x)
 			return x
@@ -132,8 +132,8 @@
 
 func init() {
 	codec.Register(&ast.AssignStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_AssignStmt(e, x.(*ast.AssignStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_AssignStmt(e, x.(*ast.AssignStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.AssignStmt
 			decode_ast_AssignStmt(d, &x)
 			return x
@@ -187,8 +187,8 @@
 
 func init() {
 	codec.Register(&ast.BadDecl{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BadDecl(e, x.(*ast.BadDecl)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BadDecl(e, x.(*ast.BadDecl)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BadDecl
 			decode_ast_BadDecl(d, &x)
 			return x
@@ -242,8 +242,8 @@
 
 func init() {
 	codec.Register(&ast.BadExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BadExpr(e, x.(*ast.BadExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BadExpr(e, x.(*ast.BadExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BadExpr
 			decode_ast_BadExpr(d, &x)
 			return x
@@ -297,8 +297,8 @@
 
 func init() {
 	codec.Register(&ast.BadStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BadStmt(e, x.(*ast.BadStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BadStmt(e, x.(*ast.BadStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BadStmt
 			decode_ast_BadStmt(d, &x)
 			return x
@@ -358,8 +358,8 @@
 
 func init() {
 	codec.Register(&ast.BasicLit{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BasicLit
 			decode_ast_BasicLit(d, &x)
 			return x
@@ -425,8 +425,8 @@
 
 func init() {
 	codec.Register(&ast.BinaryExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BinaryExpr(e, x.(*ast.BinaryExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BinaryExpr(e, x.(*ast.BinaryExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BinaryExpr
 			decode_ast_BinaryExpr(d, &x)
 			return x
@@ -486,8 +486,8 @@
 
 func init() {
 	codec.Register(&ast.BlockStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BlockStmt(e, x.(*ast.BlockStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BlockStmt(e, x.(*ast.BlockStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BlockStmt
 			decode_ast_BlockStmt(d, &x)
 			return x
@@ -547,8 +547,8 @@
 
 func init() {
 	codec.Register(&ast.BranchStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_BranchStmt(e, x.(*ast.BranchStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_BranchStmt(e, x.(*ast.BranchStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.BranchStmt
 			decode_ast_BranchStmt(d, &x)
 			return x
@@ -620,8 +620,8 @@
 
 func init() {
 	codec.Register(&ast.CallExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_CallExpr(e, x.(*ast.CallExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_CallExpr(e, x.(*ast.CallExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.CallExpr
 			decode_ast_CallExpr(d, &x)
 			return x
@@ -687,8 +687,8 @@
 
 func init() {
 	codec.Register(&ast.CaseClause{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_CaseClause(e, x.(*ast.CaseClause)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_CaseClause(e, x.(*ast.CaseClause)) },
+		func(d *codec.Decoder) any {
 			var x *ast.CaseClause
 			decode_ast_CaseClause(d, &x)
 			return x
@@ -754,8 +754,8 @@
 
 func init() {
 	codec.Register(&ast.ChanType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ChanType(e, x.(*ast.ChanType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ChanType(e, x.(*ast.ChanType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ChanType
 			decode_ast_ChanType(d, &x)
 			return x
@@ -821,8 +821,8 @@
 
 func init() {
 	codec.Register(&ast.CommClause{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_CommClause(e, x.(*ast.CommClause)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_CommClause(e, x.(*ast.CommClause)) },
+		func(d *codec.Decoder) any {
 			var x *ast.CommClause
 			decode_ast_CommClause(d, &x)
 			return x
@@ -870,8 +870,8 @@
 
 func init() {
 	codec.Register(&ast.CommentGroup{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_CommentGroup(e, x.(*ast.CommentGroup)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_CommentGroup(e, x.(*ast.CommentGroup)) },
+		func(d *codec.Decoder) any {
 			var x *ast.CommentGroup
 			decode_ast_CommentGroup(d, &x)
 			return x
@@ -925,8 +925,8 @@
 
 func init() {
 	codec.Register(&ast.Comment{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Comment(e, x.(*ast.Comment)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Comment(e, x.(*ast.Comment)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Comment
 			decode_ast_Comment(d, &x)
 			return x
@@ -998,8 +998,8 @@
 
 func init() {
 	codec.Register(&ast.CompositeLit{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_CompositeLit(e, x.(*ast.CompositeLit)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_CompositeLit(e, x.(*ast.CompositeLit)) },
+		func(d *codec.Decoder) any {
 			var x *ast.CompositeLit
 			decode_ast_CompositeLit(d, &x)
 			return x
@@ -1047,8 +1047,8 @@
 
 func init() {
 	codec.Register(&ast.DeclStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_DeclStmt(e, x.(*ast.DeclStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_DeclStmt(e, x.(*ast.DeclStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.DeclStmt
 			decode_ast_DeclStmt(d, &x)
 			return x
@@ -1102,8 +1102,8 @@
 
 func init() {
 	codec.Register(&ast.DeferStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_DeferStmt(e, x.(*ast.DeferStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_DeferStmt(e, x.(*ast.DeferStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.DeferStmt
 			decode_ast_DeferStmt(d, &x)
 			return x
@@ -1157,8 +1157,8 @@
 
 func init() {
 	codec.Register(&ast.Ellipsis{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Ellipsis(e, x.(*ast.Ellipsis)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Ellipsis(e, x.(*ast.Ellipsis)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Ellipsis
 			decode_ast_Ellipsis(d, &x)
 			return x
@@ -1212,8 +1212,8 @@
 
 func init() {
 	codec.Register(&ast.EmptyStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_EmptyStmt(e, x.(*ast.EmptyStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_EmptyStmt(e, x.(*ast.EmptyStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.EmptyStmt
 			decode_ast_EmptyStmt(d, &x)
 			return x
@@ -1261,8 +1261,8 @@
 
 func init() {
 	codec.Register(&ast.ExprStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ExprStmt(e, x.(*ast.ExprStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ExprStmt(e, x.(*ast.ExprStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ExprStmt
 			decode_ast_ExprStmt(d, &x)
 			return x
@@ -1322,8 +1322,8 @@
 
 func init() {
 	codec.Register(&ast.FieldList{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_FieldList(e, x.(*ast.FieldList)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_FieldList(e, x.(*ast.FieldList)) },
+		func(d *codec.Decoder) any {
 			var x *ast.FieldList
 			decode_ast_FieldList(d, &x)
 			return x
@@ -1395,8 +1395,8 @@
 
 func init() {
 	codec.Register(&ast.Field{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Field(e, x.(*ast.Field)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Field(e, x.(*ast.Field)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Field
 			decode_ast_Field(d, &x)
 			return x
@@ -1468,8 +1468,8 @@
 
 func init() {
 	codec.Register(&ast.ForStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ForStmt(e, x.(*ast.ForStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ForStmt(e, x.(*ast.ForStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ForStmt
 			decode_ast_ForStmt(d, &x)
 			return x
@@ -1541,8 +1541,8 @@
 
 func init() {
 	codec.Register(&ast.FuncDecl{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_FuncDecl(e, x.(*ast.FuncDecl)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_FuncDecl(e, x.(*ast.FuncDecl)) },
+		func(d *codec.Decoder) any {
 			var x *ast.FuncDecl
 			decode_ast_FuncDecl(d, &x)
 			return x
@@ -1596,8 +1596,8 @@
 
 func init() {
 	codec.Register(&ast.FuncLit{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_FuncLit(e, x.(*ast.FuncLit)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_FuncLit(e, x.(*ast.FuncLit)) },
+		func(d *codec.Decoder) any {
 			var x *ast.FuncLit
 			decode_ast_FuncLit(d, &x)
 			return x
@@ -1663,8 +1663,8 @@
 
 func init() {
 	codec.Register(&ast.FuncType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_FuncType(e, x.(*ast.FuncType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_FuncType(e, x.(*ast.FuncType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.FuncType
 			decode_ast_FuncType(d, &x)
 			return x
@@ -1742,8 +1742,8 @@
 
 func init() {
 	codec.Register(&ast.GenDecl{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_GenDecl(e, x.(*ast.GenDecl)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_GenDecl(e, x.(*ast.GenDecl)) },
+		func(d *codec.Decoder) any {
 			var x *ast.GenDecl
 			decode_ast_GenDecl(d, &x)
 			return x
@@ -1797,8 +1797,8 @@
 
 func init() {
 	codec.Register(&ast.GoStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_GoStmt(e, x.(*ast.GoStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_GoStmt(e, x.(*ast.GoStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.GoStmt
 			decode_ast_GoStmt(d, &x)
 			return x
@@ -1858,8 +1858,8 @@
 
 func init() {
 	codec.Register(&ast.Ident{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Ident(e, x.(*ast.Ident)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Ident(e, x.(*ast.Ident)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Ident
 			decode_ast_Ident(d, &x)
 			return x
@@ -1931,8 +1931,8 @@
 
 func init() {
 	codec.Register(&ast.IfStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_IfStmt(e, x.(*ast.IfStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_IfStmt(e, x.(*ast.IfStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.IfStmt
 			decode_ast_IfStmt(d, &x)
 			return x
@@ -2004,8 +2004,8 @@
 
 func init() {
 	codec.Register(&ast.ImportSpec{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ImportSpec(e, x.(*ast.ImportSpec)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ImportSpec(e, x.(*ast.ImportSpec)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ImportSpec
 			decode_ast_ImportSpec(d, &x)
 			return x
@@ -2065,8 +2065,8 @@
 
 func init() {
 	codec.Register(&ast.IncDecStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_IncDecStmt(e, x.(*ast.IncDecStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_IncDecStmt(e, x.(*ast.IncDecStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.IncDecStmt
 			decode_ast_IncDecStmt(d, &x)
 			return x
@@ -2132,8 +2132,8 @@
 
 func init() {
 	codec.Register(&ast.IndexExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_IndexExpr(e, x.(*ast.IndexExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_IndexExpr(e, x.(*ast.IndexExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.IndexExpr
 			decode_ast_IndexExpr(d, &x)
 			return x
@@ -2199,8 +2199,8 @@
 
 func init() {
 	codec.Register(&ast.IndexListExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_IndexListExpr(e, x.(*ast.IndexListExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_IndexListExpr(e, x.(*ast.IndexListExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.IndexListExpr
 			decode_ast_IndexListExpr(d, &x)
 			return x
@@ -2260,8 +2260,8 @@
 
 func init() {
 	codec.Register(&ast.InterfaceType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_InterfaceType(e, x.(*ast.InterfaceType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_InterfaceType(e, x.(*ast.InterfaceType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.InterfaceType
 			decode_ast_InterfaceType(d, &x)
 			return x
@@ -2321,8 +2321,8 @@
 
 func init() {
 	codec.Register(&ast.KeyValueExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_KeyValueExpr(e, x.(*ast.KeyValueExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_KeyValueExpr(e, x.(*ast.KeyValueExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.KeyValueExpr
 			decode_ast_KeyValueExpr(d, &x)
 			return x
@@ -2382,8 +2382,8 @@
 
 func init() {
 	codec.Register(&ast.LabeledStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_LabeledStmt(e, x.(*ast.LabeledStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_LabeledStmt(e, x.(*ast.LabeledStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.LabeledStmt
 			decode_ast_LabeledStmt(d, &x)
 			return x
@@ -2443,8 +2443,8 @@
 
 func init() {
 	codec.Register(&ast.MapType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_MapType(e, x.(*ast.MapType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_MapType(e, x.(*ast.MapType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.MapType
 			decode_ast_MapType(d, &x)
 			return x
@@ -2504,8 +2504,8 @@
 
 func init() {
 	codec.Register(&ast.ParenExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ParenExpr(e, x.(*ast.ParenExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ParenExpr(e, x.(*ast.ParenExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ParenExpr
 			decode_ast_ParenExpr(d, &x)
 			return x
@@ -2589,8 +2589,8 @@
 
 func init() {
 	codec.Register(&ast.RangeStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_RangeStmt(e, x.(*ast.RangeStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_RangeStmt(e, x.(*ast.RangeStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.RangeStmt
 			decode_ast_RangeStmt(d, &x)
 			return x
@@ -2644,8 +2644,8 @@
 
 func init() {
 	codec.Register(&ast.ReturnStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ReturnStmt(e, x.(*ast.ReturnStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ReturnStmt(e, x.(*ast.ReturnStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ReturnStmt
 			decode_ast_ReturnStmt(d, &x)
 			return x
@@ -2699,8 +2699,8 @@
 
 func init() {
 	codec.Register(&ast.Scope{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Scope(e, x.(*ast.Scope)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Scope(e, x.(*ast.Scope)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Scope
 			decode_ast_Scope(d, &x)
 			return x
@@ -2754,8 +2754,8 @@
 
 func init() {
 	codec.Register(&ast.SelectStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_SelectStmt(e, x.(*ast.SelectStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_SelectStmt(e, x.(*ast.SelectStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.SelectStmt
 			decode_ast_SelectStmt(d, &x)
 			return x
@@ -2809,8 +2809,8 @@
 
 func init() {
 	codec.Register(&ast.SelectorExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_SelectorExpr(e, x.(*ast.SelectorExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_SelectorExpr(e, x.(*ast.SelectorExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.SelectorExpr
 			decode_ast_SelectorExpr(d, &x)
 			return x
@@ -2870,8 +2870,8 @@
 
 func init() {
 	codec.Register(&ast.SendStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_SendStmt(e, x.(*ast.SendStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_SendStmt(e, x.(*ast.SendStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.SendStmt
 			decode_ast_SendStmt(d, &x)
 			return x
@@ -2955,8 +2955,8 @@
 
 func init() {
 	codec.Register(&ast.SliceExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_SliceExpr(e, x.(*ast.SliceExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_SliceExpr(e, x.(*ast.SliceExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.SliceExpr
 			decode_ast_SliceExpr(d, &x)
 			return x
@@ -3010,8 +3010,8 @@
 
 func init() {
 	codec.Register(&ast.StarExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_StarExpr(e, x.(*ast.StarExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_StarExpr(e, x.(*ast.StarExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.StarExpr
 			decode_ast_StarExpr(d, &x)
 			return x
@@ -3071,8 +3071,8 @@
 
 func init() {
 	codec.Register(&ast.StructType{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_StructType(e, x.(*ast.StructType)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_StructType(e, x.(*ast.StructType)) },
+		func(d *codec.Decoder) any {
 			var x *ast.StructType
 			decode_ast_StructType(d, &x)
 			return x
@@ -3138,8 +3138,8 @@
 
 func init() {
 	codec.Register(&ast.SwitchStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_SwitchStmt(e, x.(*ast.SwitchStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_SwitchStmt(e, x.(*ast.SwitchStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.SwitchStmt
 			decode_ast_SwitchStmt(d, &x)
 			return x
@@ -3205,8 +3205,8 @@
 
 func init() {
 	codec.Register(&ast.TypeAssertExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_TypeAssertExpr(e, x.(*ast.TypeAssertExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_TypeAssertExpr(e, x.(*ast.TypeAssertExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.TypeAssertExpr
 			decode_ast_TypeAssertExpr(d, &x)
 			return x
@@ -3284,8 +3284,8 @@
 
 func init() {
 	codec.Register(&ast.TypeSpec{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_TypeSpec(e, x.(*ast.TypeSpec)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_TypeSpec(e, x.(*ast.TypeSpec)) },
+		func(d *codec.Decoder) any {
 			var x *ast.TypeSpec
 			decode_ast_TypeSpec(d, &x)
 			return x
@@ -3351,8 +3351,8 @@
 
 func init() {
 	codec.Register(&ast.TypeSwitchStmt{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_TypeSwitchStmt(e, x.(*ast.TypeSwitchStmt)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_TypeSwitchStmt(e, x.(*ast.TypeSwitchStmt)) },
+		func(d *codec.Decoder) any {
 			var x *ast.TypeSwitchStmt
 			decode_ast_TypeSwitchStmt(d, &x)
 			return x
@@ -3412,8 +3412,8 @@
 
 func init() {
 	codec.Register(&ast.UnaryExpr{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_UnaryExpr(e, x.(*ast.UnaryExpr)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_UnaryExpr(e, x.(*ast.UnaryExpr)) },
+		func(d *codec.Decoder) any {
 			var x *ast.UnaryExpr
 			decode_ast_UnaryExpr(d, &x)
 			return x
@@ -3485,8 +3485,8 @@
 
 func init() {
 	codec.Register(&ast.ValueSpec{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_ValueSpec(e, x.(*ast.ValueSpec)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_ValueSpec(e, x.(*ast.ValueSpec)) },
+		func(d *codec.Decoder) any {
 			var x *ast.ValueSpec
 			decode_ast_ValueSpec(d, &x)
 			return x
@@ -3541,8 +3541,8 @@
 
 func init() {
 	codec.Register(&encPackage{},
-		func(e *codec.Encoder, x interface{}) { encode_encPackage(e, x.(*encPackage)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_encPackage(e, x.(*encPackage)) },
+		func(d *codec.Decoder) any {
 			var x *encPackage
 			decode_encPackage(d, &x)
 			return x
@@ -3574,8 +3574,8 @@
 
 func init() {
 	codec.Register([]ast.Expr(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Expr(e, x.([]ast.Expr)) },
-		func(d *codec.Decoder) interface{} { var x []ast.Expr; decode_slice_ast_Expr(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Expr(e, x.([]ast.Expr)) },
+		func(d *codec.Decoder) any { var x []ast.Expr; decode_slice_ast_Expr(d, &x); return x })
 }
 
 func encode_slice_ast_Stmt(e *codec.Encoder, s []ast.Stmt) {
@@ -3603,8 +3603,8 @@
 
 func init() {
 	codec.Register([]ast.Stmt(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Stmt(e, x.([]ast.Stmt)) },
-		func(d *codec.Decoder) interface{} { var x []ast.Stmt; decode_slice_ast_Stmt(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Stmt(e, x.([]ast.Stmt)) },
+		func(d *codec.Decoder) any { var x []ast.Stmt; decode_slice_ast_Stmt(d, &x); return x })
 }
 
 func encode_slice_ast_Comment(e *codec.Encoder, s []*ast.Comment) {
@@ -3632,8 +3632,8 @@
 
 func init() {
 	codec.Register([]*ast.Comment(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Comment(e, x.([]*ast.Comment)) },
-		func(d *codec.Decoder) interface{} { var x []*ast.Comment; decode_slice_ast_Comment(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Comment(e, x.([]*ast.Comment)) },
+		func(d *codec.Decoder) any { var x []*ast.Comment; decode_slice_ast_Comment(d, &x); return x })
 }
 
 func encode_slice_ast_Field(e *codec.Encoder, s []*ast.Field) {
@@ -3661,8 +3661,8 @@
 
 func init() {
 	codec.Register([]*ast.Field(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Field(e, x.([]*ast.Field)) },
-		func(d *codec.Decoder) interface{} { var x []*ast.Field; decode_slice_ast_Field(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Field(e, x.([]*ast.Field)) },
+		func(d *codec.Decoder) any { var x []*ast.Field; decode_slice_ast_Field(d, &x); return x })
 }
 
 func encode_slice_ast_Ident(e *codec.Encoder, s []*ast.Ident) {
@@ -3690,8 +3690,8 @@
 
 func init() {
 	codec.Register([]*ast.Ident(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Ident(e, x.([]*ast.Ident)) },
-		func(d *codec.Decoder) interface{} { var x []*ast.Ident; decode_slice_ast_Ident(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Ident(e, x.([]*ast.Ident)) },
+		func(d *codec.Decoder) any { var x []*ast.Ident; decode_slice_ast_Ident(d, &x); return x })
 }
 
 func encode_slice_ast_Spec(e *codec.Encoder, s []ast.Spec) {
@@ -3719,8 +3719,8 @@
 
 func init() {
 	codec.Register([]ast.Spec(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Spec(e, x.([]ast.Spec)) },
-		func(d *codec.Decoder) interface{} { var x []ast.Spec; decode_slice_ast_Spec(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Spec(e, x.([]ast.Spec)) },
+		func(d *codec.Decoder) any { var x []ast.Spec; decode_slice_ast_Spec(d, &x); return x })
 }
 
 // Fields of ast_Object: Kind Name Decl Data Type
@@ -3788,8 +3788,8 @@
 
 func init() {
 	codec.Register(&ast.Object{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_Object(e, x.(*ast.Object)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_Object(e, x.(*ast.Object)) },
+		func(d *codec.Decoder) any {
 			var x *ast.Object
 			decode_ast_Object(d, &x)
 			return x
@@ -3827,8 +3827,8 @@
 
 func init() {
 	codec.Register(map[string]*ast.Object(nil),
-		func(e *codec.Encoder, x interface{}) { encode_map_string_ast_Object(e, x.(map[string]*ast.Object)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_map_string_ast_Object(e, x.(map[string]*ast.Object)) },
+		func(d *codec.Decoder) any {
 			var x map[string]*ast.Object
 			decode_map_string_ast_Object(d, &x)
 			return x
@@ -3860,8 +3860,8 @@
 
 func init() {
 	codec.Register([]*File(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_File(e, x.([]*File)) },
-		func(d *codec.Decoder) interface{} { var x []*File; decode_slice_File(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_File(e, x.([]*File)) },
+		func(d *codec.Decoder) any { var x []*File; decode_slice_File(d, &x); return x })
 }
 
 func encode_map_string_bool(e *codec.Encoder, m map[string]bool) {
@@ -3895,8 +3895,8 @@
 
 func init() {
 	codec.Register(map[string]bool(nil),
-		func(e *codec.Encoder, x interface{}) { encode_map_string_bool(e, x.(map[string]bool)) },
-		func(d *codec.Decoder) interface{} { var x map[string]bool; decode_map_string_bool(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_map_string_bool(e, x.(map[string]bool)) },
+		func(d *codec.Decoder) any { var x map[string]bool; decode_map_string_bool(d, &x); return x })
 }
 
 // Fields of File: Name AST
@@ -3946,8 +3946,8 @@
 
 func init() {
 	codec.Register(&File{},
-		func(e *codec.Encoder, x interface{}) { encode_File(e, x.(*File)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_File(e, x.(*File)) },
+		func(d *codec.Decoder) any {
 			var x *File
 			decode_File(d, &x)
 			return x
@@ -4037,8 +4037,8 @@
 
 func init() {
 	codec.Register(&ast.File{},
-		func(e *codec.Encoder, x interface{}) { encode_ast_File(e, x.(*ast.File)) },
-		func(d *codec.Decoder) interface{} {
+		func(e *codec.Encoder, x any) { encode_ast_File(e, x.(*ast.File)) },
+		func(d *codec.Decoder) any {
 			var x *ast.File
 			decode_ast_File(d, &x)
 			return x
@@ -4070,8 +4070,8 @@
 
 func init() {
 	codec.Register([]ast.Decl(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_Decl(e, x.([]ast.Decl)) },
-		func(d *codec.Decoder) interface{} { var x []ast.Decl; decode_slice_ast_Decl(d, &x); return x })
+		func(e *codec.Encoder, x any) { encode_slice_ast_Decl(e, x.([]ast.Decl)) },
+		func(d *codec.Decoder) any { var x []ast.Decl; decode_slice_ast_Decl(d, &x); return x })
 }
 
 func encode_slice_ast_ImportSpec(e *codec.Encoder, s []*ast.ImportSpec) {
@@ -4099,12 +4099,8 @@
 
 func init() {
 	codec.Register([]*ast.ImportSpec(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_ImportSpec(e, x.([]*ast.ImportSpec)) },
-		func(d *codec.Decoder) interface{} {
-			var x []*ast.ImportSpec
-			decode_slice_ast_ImportSpec(d, &x)
-			return x
-		})
+		func(e *codec.Encoder, x any) { encode_slice_ast_ImportSpec(e, x.([]*ast.ImportSpec)) },
+		func(d *codec.Decoder) any { var x []*ast.ImportSpec; decode_slice_ast_ImportSpec(d, &x); return x })
 }
 
 func encode_slice_ast_CommentGroup(e *codec.Encoder, s []*ast.CommentGroup) {
@@ -4132,10 +4128,6 @@
 
 func init() {
 	codec.Register([]*ast.CommentGroup(nil),
-		func(e *codec.Encoder, x interface{}) { encode_slice_ast_CommentGroup(e, x.([]*ast.CommentGroup)) },
-		func(d *codec.Decoder) interface{} {
-			var x []*ast.CommentGroup
-			decode_slice_ast_CommentGroup(d, &x)
-			return x
-		})
+		func(e *codec.Encoder, x any) { encode_slice_ast_CommentGroup(e, x.([]*ast.CommentGroup)) },
+		func(d *codec.Decoder) any { var x []*ast.CommentGroup; decode_slice_ast_CommentGroup(d, &x); return x })
 }
diff --git a/internal/godoc/encode_test.go b/internal/godoc/encode_test.go
index 77d0c04..b6fb8c7 100644
--- a/internal/godoc/encode_test.go
+++ b/internal/godoc/encode_test.go
@@ -159,9 +159,9 @@
 
 func printNode(w io.Writer, root ast.Node) error {
 	var err error
-	seen := map[interface{}]int{}
+	seen := map[any]int{}
 
-	pr := func(format string, args ...interface{}) {
+	pr := func(format string, args ...any) {
 		if err == nil {
 			_, err = fmt.Fprintf(w, format, args...)
 		}
@@ -173,8 +173,8 @@
 		}
 	}
 
-	var prValue func(interface{}, int)
-	prValue = func(x interface{}, depth int) {
+	var prValue func(any, int)
+	prValue = func(x any, depth int) {
 		indent(depth)
 		if x == nil || reflect.ValueOf(x).IsNil() {
 			pr("nil\n")
diff --git a/internal/godoc/gen_ast.go b/internal/godoc/gen_ast.go
index b01d049..d0a80b8 100644
--- a/internal/godoc/gen_ast.go
+++ b/internal/godoc/gen_ast.go
@@ -17,7 +17,7 @@
 )
 
 func main() {
-	types := []interface{}{
+	types := []any{
 		ast.ArrayType{},
 		ast.AssignStmt{},
 		ast.BadDecl{},
diff --git a/internal/licenses/gen_exceptions.go b/internal/licenses/gen_exceptions.go
index a9ca7ab..b97b1de 100644
--- a/internal/licenses/gen_exceptions.go
+++ b/internal/licenses/gen_exceptions.go
@@ -203,13 +203,13 @@
 	return out
 }
 
-// templateList returns xs, but it flattens any nested []interface{} into the main list.
+// templateList returns xs, but it flattens any nested []any into the main list.
 // Called from templates as "list", to pass multiple arguments to templates.
-func templateList(xs ...interface{}) []interface{} {
-	var list []interface{}
+func templateList(xs ...any) []any {
+	var list []any
 	for _, x := range xs {
 		switch x := x.(type) {
-		case []interface{}:
+		case []any:
 			list = append(list, x...)
 		default:
 			list = append(list, x)
diff --git a/internal/licenses/licenses.go b/internal/licenses/licenses.go
index 4a947726..aecbba7 100644
--- a/internal/licenses/licenses.go
+++ b/internal/licenses/licenses.go
@@ -315,7 +315,7 @@
 	modulePath     string
 	version        string
 	fsys           fs.FS
-	logf           func(string, ...interface{})
+	logf           func(string, ...any)
 	moduleRedist   bool
 	moduleLicenses []*License // licenses at module root directory, or list from exceptions
 	allLicenses    []*License
@@ -326,7 +326,7 @@
 // zr should be the zip file for that module and version.
 // logf is for logging; if nil, no logging is done.
 // Deprecated: use NewDetectorFS.
-func NewDetector(modulePath, version string, zr *zip.Reader, logf func(string, ...interface{})) *Detector {
+func NewDetector(modulePath, version string, zr *zip.Reader, logf func(string, ...any)) *Detector {
 	sub, err := fs.Sub(zr, modulePath+"@"+version)
 	// This should only fail if the prefix is not a valid path, which shouldn't be possible.
 	if err != nil && logf != nil {
@@ -338,9 +338,9 @@
 // NewDetectorFS returns a Detector for the given module and version.
 // fsys should represent the content directory of the module (not the zip root).
 // logf is for logging; if nil, no logging is done.
-func NewDetectorFS(modulePath, version string, fsys fs.FS, logf func(string, ...interface{})) *Detector {
+func NewDetectorFS(modulePath, version string, fsys fs.FS, logf func(string, ...any)) *Detector {
 	if logf == nil {
-		logf = func(string, ...interface{}) {}
+		logf = func(string, ...any) {}
 	}
 	d := &Detector{
 		modulePath: modulePath,
@@ -552,9 +552,9 @@
 // DetectFile return the set of license types for the given file contents. It
 // also returns the licensecheck coverage information. The filename is used
 // solely for logging.
-func DetectFile(contents []byte, filename string, logf func(string, ...interface{})) ([]string, licensecheck.Coverage) {
+func DetectFile(contents []byte, filename string, logf func(string, ...any)) ([]string, licensecheck.Coverage) {
 	if logf == nil {
-		logf = func(string, ...interface{}) {}
+		logf = func(string, ...any) {}
 	}
 	cov := scanner().Scan(contents)
 	if cov.Percent < float64(coverageThreshold) {
diff --git a/internal/log/log.go b/internal/log/log.go
index 5bad139..ea38b9b 100644
--- a/internal/log/log.go
+++ b/internal/log/log.go
@@ -22,7 +22,7 @@
 var (
 	mu     sync.Mutex
 	logger interface {
-		log(context.Context, logging.Severity, interface{})
+		log(context.Context, logging.Severity, any)
 	} = stdlibLogger{}
 
 	// currentLevel holds current log level.
@@ -74,7 +74,7 @@
 	sdlogger *logging.Logger
 }
 
-func (l *stackdriverLogger) log(ctx context.Context, s logging.Severity, payload interface{}) {
+func (l *stackdriverLogger) log(ctx context.Context, s logging.Severity, payload any) {
 	// Convert errors to strings, or they may serialize as the empty JSON object.
 	if err, ok := payload.(error); ok {
 		payload = err.Error()
@@ -109,7 +109,7 @@
 	}
 }
 
-func (stdlibLogger) log(ctx context.Context, s logging.Severity, payload interface{}) {
+func (stdlibLogger) log(ctx context.Context, s logging.Severity, payload any) {
 	var extras []string
 	traceID, _ := ctx.Value(traceIDKey{}).(string) // if not present, traceID is ""
 	if traceID != "" {
@@ -161,54 +161,54 @@
 }
 
 // Infof logs a formatted string at the Info level.
-func Infof(ctx context.Context, format string, args ...interface{}) {
+func Infof(ctx context.Context, format string, args ...any) {
 	logf(ctx, logging.Info, format, args)
 }
 
 // Warningf logs a formatted string at the Warning level.
-func Warningf(ctx context.Context, format string, args ...interface{}) {
+func Warningf(ctx context.Context, format string, args ...any) {
 	logf(ctx, logging.Warning, format, args)
 }
 
 // Errorf logs a formatted string at the Error level.
-func Errorf(ctx context.Context, format string, args ...interface{}) {
+func Errorf(ctx context.Context, format string, args ...any) {
 	logf(ctx, logging.Error, format, args)
 }
 
 // Debugf logs a formatted string at the Debug level.
-func Debugf(ctx context.Context, format string, args ...interface{}) {
+func Debugf(ctx context.Context, format string, args ...any) {
 	logf(ctx, logging.Debug, format, args)
 }
 
 // Fatalf logs formatted string at the Critical level followed by exiting the program.
-func Fatalf(ctx context.Context, format string, args ...interface{}) {
+func Fatalf(ctx context.Context, format string, args ...any) {
 	logf(ctx, logging.Critical, format, args)
 	die()
 }
 
-func logf(ctx context.Context, s logging.Severity, format string, args []interface{}) {
+func logf(ctx context.Context, s logging.Severity, format string, args []any) {
 	doLog(ctx, s, fmt.Sprintf(format, args...))
 }
 
 // Info logs arg, which can be a string or a struct, at the Info level.
-func Info(ctx context.Context, arg interface{}) { doLog(ctx, logging.Info, arg) }
+func Info(ctx context.Context, arg any) { doLog(ctx, logging.Info, arg) }
 
 // Warning logs arg, which can be a string or a struct, at the Warning level.
-func Warning(ctx context.Context, arg interface{}) { doLog(ctx, logging.Warning, arg) }
+func Warning(ctx context.Context, arg any) { doLog(ctx, logging.Warning, arg) }
 
 // Error logs arg, which can be a string or a struct, at the Error level.
-func Error(ctx context.Context, arg interface{}) { doLog(ctx, logging.Error, arg) }
+func Error(ctx context.Context, arg any) { doLog(ctx, logging.Error, arg) }
 
 // Debug logs arg, which can be a string or a struct, at the Debug level.
-func Debug(ctx context.Context, arg interface{}) { doLog(ctx, logging.Debug, arg) }
+func Debug(ctx context.Context, arg any) { doLog(ctx, logging.Debug, arg) }
 
 // Fatal logs arg, which can be a string or a struct, at the Critical level followed by exiting the program.
-func Fatal(ctx context.Context, arg interface{}) {
+func Fatal(ctx context.Context, arg any) {
 	doLog(ctx, logging.Critical, arg)
 	die()
 }
 
-func doLog(ctx context.Context, s logging.Severity, payload interface{}) {
+func doLog(ctx context.Context, s logging.Severity, payload any) {
 	if getLevel() > s {
 		return
 	}
diff --git a/internal/log/log_test.go b/internal/log/log_test.go
index 459c12e..d655875 100644
--- a/internal/log/log_test.go
+++ b/internal/log/log_test.go
@@ -59,7 +59,7 @@
 
 	tests := []struct {
 		name     string
-		logFunc  func(context.Context, interface{})
+		logFunc  func(context.Context, any)
 		logMsg   string
 		expected bool
 	}{
@@ -93,7 +93,7 @@
 
 	tests := []struct {
 		name    string
-		logFunc func(context.Context, interface{})
+		logFunc func(context.Context, any)
 		logMsg  string
 	}{
 		{name: "debug", logFunc: Debug, logMsg: debugMsg},
@@ -118,6 +118,6 @@
 	logs string
 }
 
-func (l *mockLogger) log(ctx context.Context, s logging.Severity, payload interface{}) {
+func (l *mockLogger) log(ctx context.Context, s logging.Severity, payload any) {
 	l.logs += fmt.Sprintf("%s: %+v", s, payload)
 }
diff --git a/internal/middleware/experiment.go b/internal/middleware/experiment.go
index 2789a84..7d88a9c 100644
--- a/internal/middleware/experiment.go
+++ b/internal/middleware/experiment.go
@@ -48,7 +48,7 @@
 	e := &Experimenter{
 		p: poller.New(
 			initial,
-			func(ctx context.Context) (interface{}, error) {
+			func(ctx context.Context) (any, error) {
 				return getter(ctx)
 			},
 			func(err error) {
diff --git a/internal/middleware/quota_test.go b/internal/middleware/quota_test.go
index c31a96e..f2b03a8 100644
--- a/internal/middleware/quota_test.go
+++ b/internal/middleware/quota_test.go
@@ -17,7 +17,7 @@
 func TestIPKey(t *testing.T) {
 	for _, test := range []struct {
 		in   string
-		want interface{}
+		want any
 	}{
 		{"", ""},
 		{"1.2.3", ""},
diff --git a/internal/middleware/requestlog.go b/internal/middleware/requestlog.go
index cf70f91..2aa948b 100644
--- a/internal/middleware/requestlog.go
+++ b/internal/middleware/requestlog.go
@@ -86,7 +86,7 @@
 			Status:  translateStatus(w2.status),
 			Latency: time.Since(start),
 		},
-		Payload: map[string]interface{}{
+		Payload: map[string]any{
 			"requestType": "request end",
 			"isRobot":     isRobot(r.Header.Get("User-Agent")),
 		},
diff --git a/internal/middleware/stats.go b/internal/middleware/stats.go
index c333d9d..1a93987 100644
--- a/internal/middleware/stats.go
+++ b/internal/middleware/stats.go
@@ -31,19 +31,19 @@
 
 // SetStat sets a stat named key in the current context. If key already has a
 // value, the old and new value are both stored in a slice.
-func SetStat(ctx context.Context, key string, value interface{}) {
+func SetStat(ctx context.Context, key string, value any) {
 	x := ctx.Value(statsKey{})
 	if x == nil {
 		return
 	}
-	m := x.(map[string]interface{})
+	m := x.(map[string]any)
 	v, ok := m[key]
 	if !ok {
 		m[key] = value
-	} else if s, ok := v.([]interface{}); ok {
+	} else if s, ok := v.([]any); ok {
 		m[key] = append(s, value)
 	} else {
-		m[key] = []interface{}{v, value}
+		m[key] = []any{v, value}
 	}
 }
 
@@ -76,7 +76,7 @@
 	Hash              uint64 // hash of page contents
 	Size              int    // total size of data written
 	StatusCode        int    // HTTP status
-	Other             map[string]interface{}
+	Other             map[string]any
 }
 
 func newStatsResponseWriter() *statsResponseWriter {
@@ -84,7 +84,7 @@
 		header: http.Header{},
 		start:  time.Now(),
 		hasher: fnv.New64a(),
-		stats:  PageStats{Other: map[string]interface{}{}},
+		stats:  PageStats{Other: map[string]any{}},
 	}
 }
 
diff --git a/internal/middleware/stats_test.go b/internal/middleware/stats_test.go
index 3370474..74b6170 100644
--- a/internal/middleware/stats_test.go
+++ b/internal/middleware/stats_test.go
@@ -54,9 +54,9 @@
 		StatusCode: code,
 		Size:       len(data),
 		Hash:       h.Sum64(),
-		Other: map[string]interface{}{
+		Other: map[string]any{
 			// JSON unmarshals all numbers into float64s.
-			"a": []interface{}{float64(1), float64(3)},
+			"a": []any{float64(1), float64(3)},
 			"b": float64(2),
 		},
 	}
diff --git a/internal/poller/poller.go b/internal/poller/poller.go
index 19ab64c..42b654c 100644
--- a/internal/poller/poller.go
+++ b/internal/poller/poller.go
@@ -12,7 +12,7 @@
 )
 
 // A Getter returns a value.
-type Getter func(context.Context) (interface{}, error)
+type Getter func(context.Context) (any, error)
 
 // A Poller maintains a current value, and refreshes it by periodically
 // polling for a new value.
@@ -20,13 +20,13 @@
 	getter  Getter
 	onError func(error)
 	mu      sync.Mutex
-	current interface{}
+	current any
 }
 
 // New creates a new poller with an initial value. The getter is invoked
 // to obtain updated values. Errors returned from the getter are passed
 // to onError.
-func New(initial interface{}, getter Getter, onError func(error)) *Poller {
+func New(initial any, getter Getter, onError func(error)) *Poller {
 	return &Poller{
 		getter:  getter,
 		onError: onError,
@@ -69,7 +69,7 @@
 // Current returns the current value. Initially, this is the value passed to New.
 // After each successful poll, the value is updated.
 // If a poll fails, the value remains unchanged.
-func (p *Poller) Current() interface{} {
+func (p *Poller) Current() any {
 	p.mu.Lock()
 	defer p.mu.Unlock()
 	return p.current
diff --git a/internal/poller/poller_test.go b/internal/poller/poller_test.go
index 5a2afc1..31bd5c0 100644
--- a/internal/poller/poller_test.go
+++ b/internal/poller/poller_test.go
@@ -25,7 +25,7 @@
 	)
 
 	cur := -1
-	getter := func(context.Context) (interface{}, error) {
+	getter := func(context.Context) (any, error) {
 		// Even: success; odd: failure.
 		cur++
 		if cur%2 == 0 {
diff --git a/internal/postgres/details.go b/internal/postgres/details.go
index 490e937..0e67d42 100644
--- a/internal/postgres/details.go
+++ b/internal/postgres/details.go
@@ -162,10 +162,10 @@
 
 // jsonbScanner scans a jsonb value into a Go value.
 type jsonbScanner struct {
-	ptr interface{} // a pointer to a Go struct or other JSON-serializable value
+	ptr any // a pointer to a Go struct or other JSON-serializable value
 }
 
-func (s jsonbScanner) Scan(value interface{}) (err error) {
+func (s jsonbScanner) Scan(value any) (err error) {
 	defer derrors.Wrap(&err, "jsonbScanner(%+v)", value)
 
 	vptr := reflect.ValueOf(s.ptr)
@@ -190,7 +190,7 @@
 }
 
 // scanModuleInfo constructs an *internal.ModuleInfo from the given scanner.
-func scanModuleInfo(scan func(dest ...interface{}) error) (*internal.ModuleInfo, error) {
+func scanModuleInfo(scan func(dest ...any) error) (*internal.ModuleInfo, error) {
 	var mi internal.ModuleInfo
 	if err := scan(&mi.ModulePath, &mi.Version, &mi.CommitTime,
 		&mi.IsRedistributable, &mi.HasGoMod, jsonbScanner{&mi.SourceInfo}); err != nil {
diff --git a/internal/postgres/insert_module.go b/internal/postgres/insert_module.go
index d61f811..f8813d6 100644
--- a/internal/postgres/insert_module.go
+++ b/internal/postgres/insert_module.go
@@ -275,7 +275,7 @@
 	ctx, span := trace.StartSpan(ctx, "insertLicenses")
 	defer span.End()
 	defer derrors.WrapStack(&err, "insertLicenses(ctx, %q, %q)", m.ModulePath, m.Version)
-	var licenseValues []interface{}
+	var licenseValues []any
 	for _, l := range m.Licenses {
 		covJSON, err := json.Marshal(l.Coverage)
 		if err != nil {
@@ -312,7 +312,7 @@
 		return err
 	}
 
-	var values []interface{}
+	var values []any
 	for _, u := range m.Units {
 		for _, i := range u.Imports {
 			values = append(values, u.Path, m.ModulePath, i)
@@ -348,7 +348,7 @@
 	}
 	var (
 		paths         []string
-		unitValues    []interface{}
+		unitValues    []any
 		pathToReadme  = map[string]*internal.Readme{}
 		pathToImports = map[string][]string{}
 		pathIDToPath  = map[int]string{}
@@ -447,7 +447,7 @@
 	return s
 }
 
-func insertUnits(ctx context.Context, db *database.DB, unitValues []interface{}) (pathIDToUnitID map[int]int, err error) {
+func insertUnits(ctx context.Context, db *database.DB, unitValues []any) (pathIDToUnitID map[int]int, err error) {
 	defer derrors.WrapAndReport(&err, "insertUnits")
 
 	// Insert data into the units table.
@@ -465,9 +465,9 @@
 
 	// Check to see if any rows have the same path_id and module_id.
 	// For golang/go#43899.
-	conflictingValues := map[[2]interface{}]bool{}
+	conflictingValues := map[[2]any]bool{}
 	for i := 0; i < len(unitValues); i += len(unitCols) {
-		key := [2]interface{}{unitValues[i], unitValues[i+1]}
+		key := [2]any{unitValues[i], unitValues[i+1]}
 		if conflictingValues[key] {
 			log.Errorf(ctx, "insertUnits: %v occurs twice", key)
 		} else {
@@ -506,7 +506,7 @@
 					if doc.GOOS == "" || doc.GOARCH == "" {
 						ch <- database.RowItem{Err: errors.New("empty GOOS or GOARCH")}
 					}
-					ch <- database.RowItem{Values: []interface{}{unitID, doc.GOOS, doc.GOARCH, doc.Synopsis, doc.Source}}
+					ch <- database.RowItem{Values: []any{unitID, doc.GOOS, doc.GOARCH, doc.Synopsis, doc.Source}}
 				}
 			}
 			close(ch)
@@ -580,7 +580,7 @@
 		return err
 	}
 
-	var importValues []interface{}
+	var importValues []any
 	for _, pkgPath := range paths {
 		imports, ok := pathToImports[pkgPath]
 		if !ok {
@@ -605,7 +605,7 @@
 	pathToReadme map[string]*internal.Readme) (err error) {
 	defer derrors.WrapStack(&err, "insertReadmes")
 
-	var readmeValues []interface{}
+	var readmeValues []any
 	for _, path := range paths {
 		readme, ok := pathToReadme[path]
 		if !ok {
diff --git a/internal/postgres/insert_symbol_history.go b/internal/postgres/insert_symbol_history.go
index 0b68758..9f0005f 100644
--- a/internal/postgres/insert_symbol_history.go
+++ b/internal/postgres/insert_symbol_history.go
@@ -39,7 +39,7 @@
 			return err
 		}
 		for _, doc := range docIDToDoc {
-			var values []interface{}
+			var values []any
 			builds := []internal.BuildContext{{GOOS: doc.GOOS, GOARCH: doc.GOARCH}}
 			if doc.GOOS == internal.All {
 				builds = internal.BuildContexts
@@ -126,10 +126,10 @@
 	return x != nil, nil
 }
 
-func appendSymbolHistoryRow(sm *internal.SymbolMeta, values []interface{},
+func appendSymbolHistoryRow(sm *internal.SymbolMeta, values []any,
 	packagePath, modulePath, ver string, build internal.BuildContext,
 	pathToID, symToID map[string]int,
-	pathToPkgsymID map[string]map[packageSymbol]int) (_ []interface{}, err error) {
+	pathToPkgsymID map[string]map[packageSymbol]int) (_ []any, err error) {
 	defer derrors.WrapStack(&err, "appendSymbolHistoryRow(%q, %q, %q, %q)", sm.Name, packagePath, modulePath, ver)
 	symbolID := symToID[sm.Name]
 	if symbolID == 0 {
diff --git a/internal/postgres/path.go b/internal/postgres/path.go
index cf106ca..9b2edf3 100644
--- a/internal/postgres/path.go
+++ b/internal/postgres/path.go
@@ -135,7 +135,7 @@
 	}
 
 	// Insert any unit paths that we don't already have.
-	var values []interface{}
+	var values []any
 	for _, v := range paths {
 		if _, ok := pathToID[v]; !ok {
 			values = append(values, v)
diff --git a/internal/postgres/postgres.go b/internal/postgres/postgres.go
index 4728e89..d56f08c 100644
--- a/internal/postgres/postgres.go
+++ b/internal/postgres/postgres.go
@@ -42,7 +42,7 @@
 func newdb(db *database.DB, bypass bool) *DB {
 	p := poller.New(
 		[]string(nil),
-		func(ctx context.Context) (interface{}, error) {
+		func(ctx context.Context) (any, error) {
 			return getExcludedPrefixes(ctx, db)
 		},
 		func(err error) {
diff --git a/internal/postgres/requeue.go b/internal/postgres/requeue.go
index b1b1d52..618ad0e 100644
--- a/internal/postgres/requeue.go
+++ b/internal/postgres/requeue.go
@@ -174,7 +174,7 @@
 
 	collect := func(rows *sql.Rows) error {
 		// Scan the last two columns separately; they are in the query only for sorting.
-		scan := func(dests ...interface{}) error {
+		scan := func(dests ...any) error {
 			var npkg int
 			return rows.Scan(append(dests, &npkg)...)
 		}
diff --git a/internal/postgres/search.go b/internal/postgres/search.go
index 369c656..baf1e6c 100644
--- a/internal/postgres/search.go
+++ b/internal/postgres/search.go
@@ -927,7 +927,7 @@
 	if _, err := db.Exec(ctx, createTableQuery); err != nil {
 		return fmt.Errorf("CREATE TABLE: %v", err)
 	}
-	var values []interface{}
+	var values []any
 	i := 0
 	for p, c := range counts {
 		if i >= limit {
diff --git a/internal/postgres/symbol.go b/internal/postgres/symbol.go
index 6f53505..4424083 100644
--- a/internal/postgres/symbol.go
+++ b/internal/postgres/symbol.go
@@ -121,7 +121,7 @@
 	// documentation IDs.
 	// Keep track of which rows already exist in documentation_symbols using
 	// gotDocIDToPkgsymIDs.
-	var documentationIDs []interface{}
+	var documentationIDs []any
 	for docID := range docIDToPkgsymIDs {
 		documentationIDs = append(documentationIDs, docID)
 	}
@@ -168,7 +168,7 @@
 		docIDs = append(docIDs, docID)
 	}
 	sort.Ints(docIDs)
-	var values []interface{}
+	var values []any
 	for _, docID := range docIDs {
 		gotSet := gotDocIDToPkgsymIDs[docID]
 		for pkgsymID := range docIDToPkgsymIDs[docID] {
@@ -269,7 +269,7 @@
 	}
 	sort.Strings(paths)
 
-	var packageSymbols []interface{}
+	var packageSymbols []any
 	for _, path := range paths {
 		docs := pathToDocIDToDoc[path]
 		pathID := pathToID[path]
@@ -363,7 +363,7 @@
 		return nil, err
 	}
 
-	var values []interface{}
+	var values []any
 	for _, name := range names {
 		if _, ok := nameToID[name]; !ok {
 			values = append(values, name)
diff --git a/internal/postgres/symbolsearch.go b/internal/postgres/symbolsearch.go
index c2b96a1..478a3ab 100644
--- a/internal/postgres/symbolsearch.go
+++ b/internal/postgres/symbolsearch.go
@@ -316,7 +316,7 @@
 }
 
 func runSymbolSearch(ctx context.Context, ddb *database.DB,
-	st search.SearchType, q string, limit int, args ...interface{}) (results []*SearchResult, err error) {
+	st search.SearchType, q string, limit int, args ...any) (results []*SearchResult, err error) {
 	defer derrors.Wrap(&err, "runSymbolSearch(ctx, ddb, %q, %q, %d, %v)", st, q, limit, args)
 	defer middleware.ElapsedStat(ctx, fmt.Sprintf("%s-runSymbolSearch", st))()
 
@@ -342,7 +342,7 @@
 		return nil
 	}
 	query := search.SymbolQuery(st)
-	args = append([]interface{}{q, limit}, args...)
+	args = append([]any{q, limit}, args...)
 	if err := ddb.RunQuery(ctx, query, collect, args...); err != nil {
 		return nil, err
 	}
diff --git a/internal/postgres/unit.go b/internal/postgres/unit.go
index 234990c..e961358 100644
--- a/internal/postgres/unit.go
+++ b/internal/postgres/unit.go
@@ -503,7 +503,7 @@
 		u internal.Unit
 	)
 	u.BuildContexts = bcs
-	var goos, goarch interface{}
+	var goos, goarch any
 	if bcMatched.GOOS != "" {
 		goos = bcMatched.GOOS
 		goarch = bcMatched.GOARCH
diff --git a/internal/postgres/versionstate.go b/internal/postgres/versionstate.go
index 2ccaa02..12f5389 100644
--- a/internal/postgres/versionstate.go
+++ b/internal/postgres/versionstate.go
@@ -43,7 +43,7 @@
 }
 
 func insertIndexVersions(ctx context.Context, ddb *database.DB, versions []*internal.IndexVersion, conflictAction string) (err error) {
-	var vals []interface{}
+	var vals []any
 	for _, v := range versions {
 		vals = append(vals,
 			v.Path,
@@ -237,7 +237,7 @@
 	sort.Slice(packageVersionStates, func(i, j int) bool {
 		return packageVersionStates[i].PackagePath < packageVersionStates[j].PackagePath
 	})
-	var vals []interface{}
+	var vals []any
 	for _, pvs := range packageVersionStates {
 		vals = append(vals, pvs.PackagePath, pvs.ModulePath, pvs.Version, pvs.Status, pvs.Error)
 	}
@@ -299,7 +299,7 @@
 
 // scanModuleVersionState constructs an *internal.ModuleModuleVersionState from the given
 // scanner. It expects columns to be in the order of moduleVersionStateColumns.
-func scanModuleVersionState(scan func(dest ...interface{}) error) (*internal.ModuleVersionState, error) {
+func scanModuleVersionState(scan func(dest ...any) error) (*internal.ModuleVersionState, error) {
 	var (
 		v               internal.ModuleVersionState
 		indexTimestamp  pq.NullTime
@@ -333,7 +333,7 @@
 // queryModuleVersionStates executes a query for ModuleModuleVersionState rows. It expects the
 // given queryFormat be a format specifier with exactly one argument: a %s verb
 // for the query columns.
-func (db *DB) queryModuleVersionStates(ctx context.Context, queryFormat string, args ...interface{}) ([]*internal.ModuleVersionState, error) {
+func (db *DB) queryModuleVersionStates(ctx context.Context, queryFormat string, args ...any) ([]*internal.ModuleVersionState, error) {
 	query := fmt.Sprintf(queryFormat, moduleVersionStateColumns)
 	rows, err := db.db.Query(ctx, query, args...)
 	if err != nil {
diff --git a/internal/symbol/generate.go b/internal/symbol/generate.go
index 3fd4e0d..9e1c2de 100644
--- a/internal/symbol/generate.go
+++ b/internal/symbol/generate.go
@@ -332,7 +332,7 @@
 // emitf is the same as
 // https://go.googlesource.com/go/+/refs/tags/go1.16.6/src/cmd/api/goapi.go#997,
 // except verbose mode is removed.
-func (w *Walker) emitf(format string, args ...interface{}) {
+func (w *Walker) emitf(format string, args ...any) {
 	f := strings.Join(w.scope, ", ") + ", " + fmt.Sprintf(format, args...)
 	if strings.Contains(f, "\n") {
 		panic("feature contains newlines: " + f)
diff --git a/internal/worker/pages.go b/internal/worker/pages.go
index 02fbb2f..8e6d4b7 100644
--- a/internal/worker/pages.go
+++ b/internal/worker/pages.go
@@ -213,7 +213,7 @@
 	return strings.ToUpper(e[:1]) + e[1:]
 }
 
-func renderPage(ctx context.Context, w http.ResponseWriter, page interface{}, tmpl *template.Template) (err error) {
+func renderPage(ctx context.Context, w http.ResponseWriter, page any, tmpl *template.Template) (err error) {
 	defer derrors.Wrap(&err, "renderPage")
 	var buf bytes.Buffer
 	if err := tmpl.Execute(&buf, page); err != nil {
diff --git a/internal/worker/server.go b/internal/worker/server.go
index e6b07ad..e6af6ce 100644
--- a/internal/worker/server.go
+++ b/internal/worker/server.go
@@ -106,7 +106,7 @@
 	}
 
 	// Update information about DB locks, etc. every few seconds.
-	p := poller.New(&postgres.UserInfo{}, func(ctx context.Context) (interface{}, error) {
+	p := poller.New(&postgres.UserInfo{}, func(ctx context.Context) (any, error) {
 		return scfg.DB.GetUserInfo(ctx, "worker")
 	}, func(err error) { log.Error(context.Background(), err) })
 	p.Start(context.Background(), 10*time.Second)
@@ -769,7 +769,7 @@
 // percentage computes the truncated percentage of x/y.
 // It returns 0 if y is 0.
 // x and y can be any int or uint type.
-func percentage(x, y interface{}) int {
+func percentage(x, y any) int {
 	denom := toUint64(y)
 	if denom == 0 {
 		return 0
@@ -777,7 +777,7 @@
 	return int(toUint64(x) * 100 / denom)
 }
 
-func toUint64(n interface{}) uint64 {
+func toUint64(n any) uint64 {
 	v := reflect.ValueOf(n)
 	switch v.Kind() {
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
diff --git a/internal/xcontext/xcontext.go b/internal/xcontext/xcontext.go
index ff8ed4e..641dfe5 100644
--- a/internal/xcontext/xcontext.go
+++ b/internal/xcontext/xcontext.go
@@ -17,7 +17,7 @@
 
 type detachedContext struct{ parent context.Context }
 
-func (v detachedContext) Deadline() (time.Time, bool)       { return time.Time{}, false }
-func (v detachedContext) Done() <-chan struct{}             { return nil }
-func (v detachedContext) Err() error                        { return nil }
-func (v detachedContext) Value(key interface{}) interface{} { return v.parent.Value(key) }
+func (v detachedContext) Deadline() (time.Time, bool) { return time.Time{}, false }
+func (v detachedContext) Done() <-chan struct{}       { return nil }
+func (v detachedContext) Err() error                  { return nil }
+func (v detachedContext) Value(key any) any           { return v.parent.Value(key) }
diff --git a/tests/screentest/testcases.txt b/tests/screentest/testcases.txt
index 0fc092f..9ae1b04 100644
--- a/tests/screentest/testcases.txt
+++ b/tests/screentest/testcases.txt
@@ -3,7 +3,7 @@
 {{with .Token}}header Authorization: Bearer {{.}}{{end}}
 {{with .QuotaBypass}}header X-Go-Discovery-Auth-Bypass-Quota: {{.}}{{end}}
 output tests/screentest/testdata
-# Prevent dynamic readme bages from rendering
+# Prevent dynamic readme badges from rendering
 block https://codecov.io/* https://travis-ci.com/*
 
 {{$ready := "[role='treeitem'][aria-selected='true']"}}