Browse Source

interface{} -> any now that Elvish requires Go 1.18.

Qi Xiao 2 years ago
parent
commit
51e4d97568
100 changed files with 383 additions and 383 deletions
  1. 1 1
      pkg/buildinfo/buildinfo.go
  2. 1 1
      pkg/cli/app.go
  3. 3 3
      pkg/cli/clitest/apptest.go
  4. 1 1
      pkg/cli/loop.go
  5. 2 2
      pkg/cli/modes/navigation_fs_test.go
  6. 1 1
      pkg/cli/term/buffer_builder.go
  7. 4 4
      pkg/cli/tk/utils_test.go
  8. 1 1
      pkg/daemon/client.go
  9. 1 1
      pkg/diag/show_error.go
  10. 4 4
      pkg/edit/binding_map.go
  11. 1 1
      pkg/edit/buffer_builtins.go
  12. 5 5
      pkg/edit/builtins.go
  13. 1 1
      pkg/edit/command_api.go
  14. 1 1
      pkg/edit/complete/complete.go
  15. 1 1
      pkg/edit/complete/complete_test.go
  16. 1 1
      pkg/edit/complete/completers.go
  17. 2 2
      pkg/edit/complete/generators.go
  18. 1 1
      pkg/edit/complete/node_path.go
  19. 8 8
      pkg/edit/complete_getopt.go
  20. 14 14
      pkg/edit/completion.go
  21. 2 2
      pkg/edit/completion_test.go
  22. 2 2
      pkg/edit/config_api.go
  23. 1 1
      pkg/edit/config_api_test.go
  24. 2 2
      pkg/edit/editor.go
  25. 1 1
      pkg/edit/histwalk.go
  26. 1 1
      pkg/edit/instant.go
  27. 2 2
      pkg/edit/key_binding.go
  28. 4 4
      pkg/edit/listing.go
  29. 6 6
      pkg/edit/listing_custom.go
  30. 1 1
      pkg/edit/minibuf.go
  31. 4 4
      pkg/edit/navigation.go
  32. 3 3
      pkg/edit/prompt.go
  33. 1 1
      pkg/edit/prompt_test.go
  34. 5 5
      pkg/edit/state_api.go
  35. 1 1
      pkg/edit/store_api.go
  36. 7 7
      pkg/edit/testutils_test.go
  37. 2 2
      pkg/edit/vars.go
  38. 1 1
      pkg/eval/builtin_fn_cmd.go
  39. 1 1
      pkg/eval/builtin_fn_cmd_unix.go
  40. 1 1
      pkg/eval/builtin_fn_cmd_windows.go
  41. 9 9
      pkg/eval/builtin_fn_container.go
  42. 1 1
      pkg/eval/builtin_fn_debug.go
  43. 1 1
      pkg/eval/builtin_fn_env.go
  44. 9 9
      pkg/eval/builtin_fn_flow.go
  45. 1 1
      pkg/eval/builtin_fn_fs.go
  46. 18 18
      pkg/eval/builtin_fn_io.go
  47. 9 9
      pkg/eval/builtin_fn_misc.go
  48. 1 1
      pkg/eval/builtin_fn_num.go
  49. 1 1
      pkg/eval/builtin_fn_num_test.go
  50. 7 7
      pkg/eval/builtin_fn_pred.go
  51. 4 4
      pkg/eval/builtin_fn_str.go
  52. 14 14
      pkg/eval/builtin_fn_stream.go
  53. 4 4
      pkg/eval/builtin_fn_styled.go
  54. 1 1
      pkg/eval/builtin_ns.go
  55. 3 3
      pkg/eval/builtin_special.go
  56. 2 2
      pkg/eval/builtin_special_test.go
  57. 3 3
      pkg/eval/callable.go
  58. 3 3
      pkg/eval/closure.go
  59. 6 6
      pkg/eval/compile_effect.go
  60. 2 2
      pkg/eval/compile_lvalue.go
  61. 34 34
      pkg/eval/compile_value.go
  62. 2 2
      pkg/eval/compiler.go
  63. 5 5
      pkg/eval/eval.go
  64. 2 2
      pkg/eval/eval_test.go
  65. 8 8
      pkg/eval/evaltest/evaltest.go
  66. 1 1
      pkg/eval/exception.go
  67. 2 2
      pkg/eval/external_cmd.go
  68. 7 7
      pkg/eval/frame.go
  69. 5 5
      pkg/eval/glob.go
  70. 7 7
      pkg/eval/go_fn.go
  71. 5 5
      pkg/eval/go_fn_test.go
  72. 1 1
      pkg/eval/node_utils.go
  73. 5 5
      pkg/eval/ns.go
  74. 2 2
      pkg/eval/options.go
  75. 1 1
      pkg/eval/options_test.go
  76. 1 1
      pkg/eval/plugin_gccgo.go
  77. 16 16
      pkg/eval/port.go
  78. 1 1
      pkg/eval/purely_eval.go
  79. 2 2
      pkg/eval/pwd.go
  80. 2 2
      pkg/eval/vals/aliased_types.go
  81. 4 4
      pkg/eval/vals/assoc.go
  82. 1 1
      pkg/eval/vals/assoc_test.go
  83. 1 1
      pkg/eval/vals/bool.go
  84. 4 4
      pkg/eval/vals/concat.go
  85. 2 2
      pkg/eval/vals/concat_test.go
  86. 10 10
      pkg/eval/vals/conversion.go
  87. 16 16
      pkg/eval/vals/conversion_test.go
  88. 2 2
      pkg/eval/vals/dissoc.go
  89. 1 1
      pkg/eval/vals/dissoc_test.go
  90. 2 2
      pkg/eval/vals/equal.go
  91. 1 1
      pkg/eval/vals/equal_test.go
  92. 1 1
      pkg/eval/vals/feed.go
  93. 3 3
      pkg/eval/vals/feed_test.go
  94. 4 4
      pkg/eval/vals/has_key.go
  95. 2 2
      pkg/eval/vals/has_key_test.go
  96. 1 1
      pkg/eval/vals/hash.go
  97. 7 7
      pkg/eval/vals/index.go
  98. 2 2
      pkg/eval/vals/index_list.go
  99. 2 2
      pkg/eval/vals/index_string.go
  100. 7 7
      pkg/eval/vals/iterate.go

+ 1 - 1
pkg/buildinfo/buildinfo.go

@@ -78,7 +78,7 @@ func (p *Program) Run(fds [3]*os.File, _ []string) error {
 	return nil
 }
 
-func mustToJSON(v interface{}) string {
+func mustToJSON(v any) string {
 	b, err := json.Marshal(v)
 	if err != nil {
 		panic(err)

+ 1 - 1
pkg/cli/app.go

@@ -382,7 +382,7 @@ func distributeHeight(widgets []tk.Widget, width, height int) ([]int, int) {
 	return heights, focus
 }
 
-func hasFocus(w interface{}) bool {
+func hasFocus(w any) bool {
 	if f, ok := w.(interface{ Focus() bool }); ok {
 		return f.Focus()
 	}

+ 3 - 3
pkg/cli/clitest/apptest.go

@@ -76,18 +76,18 @@ func (f *Fixture) Stop() {
 
 // MakeBuffer is a helper for building a buffer. It is equivalent to
 // term.NewBufferBuilder(width of terminal).MarkLines(args...).Buffer().
-func (f *Fixture) MakeBuffer(args ...interface{}) *term.Buffer {
+func (f *Fixture) MakeBuffer(args ...any) *term.Buffer {
 	return term.NewBufferBuilder(f.width).MarkLines(args...).Buffer()
 }
 
 // TestTTY is equivalent to f.TTY.TestBuffer(f.MakeBuffer(args...)).
-func (f *Fixture) TestTTY(t *testing.T, args ...interface{}) {
+func (f *Fixture) TestTTY(t *testing.T, args ...any) {
 	t.Helper()
 	f.TTY.TestBuffer(t, f.MakeBuffer(args...))
 }
 
 // TestTTYNotes is equivalent to f.TTY.TestNotesBuffer(f.MakeBuffer(args...)).
-func (f *Fixture) TestTTYNotes(t *testing.T, args ...interface{}) {
+func (f *Fixture) TestTTYNotes(t *testing.T, args ...any) {
 	t.Helper()
 	f.TTY.TestNotesBuffer(t, f.MakeBuffer(args...))
 }

+ 1 - 1
pkg/cli/loop.go

@@ -26,7 +26,7 @@ type loopReturn struct {
 }
 
 // A placeholder type for events.
-type event interface{}
+type event any
 
 // Callback for redrawing the editor UI to the terminal.
 type redrawCb func(flag redrawFlag)

+ 2 - 2
pkg/cli/modes/navigation_fs_test.go

@@ -63,7 +63,7 @@ func (c *testCursor) Descend(name string) error {
 }
 
 func getFile(root testutil.Dir, path []string) (NavigationFile, error) {
-	var f interface{} = root
+	var f any = root
 	for _, p := range path {
 		d, ok := f.(testutil.Dir)
 		if !ok {
@@ -91,7 +91,7 @@ func getDirFile(root testutil.Dir, path []string) (NavigationFile, error) {
 
 type testFile struct {
 	name string
-	data interface{}
+	data any
 }
 
 func (f testFile) Name() string { return f.name }

+ 1 - 1
pkg/cli/term/buffer_builder.go

@@ -125,7 +125,7 @@ var DotHere = struct{ x struct{} }{}
 
 // MarkLines is like calling WriteStyled with ui.MarkLines(args...), but accepts
 // an additional special parameter DotHere to mark the position of the dot.
-func (bb *BufferBuilder) MarkLines(args ...interface{}) *BufferBuilder {
+func (bb *BufferBuilder) MarkLines(args ...any) *BufferBuilder {
 	for i, arg := range args {
 		if arg == DotHere {
 			return bb.WriteStyled(ui.MarkLines(args[:i]...)).

+ 4 - 4
pkg/cli/tk/utils_test.go

@@ -41,7 +41,7 @@ type handleTest struct {
 	Event  term.Event
 	Events []term.Event
 
-	WantNewState  interface{}
+	WantNewState  any
 	WantUnhandled bool
 }
 
@@ -84,15 +84,15 @@ func testHandle(t *testing.T, tests []handleTest) {
 	}
 }
 
-func getState(v interface{}) interface{} {
+func getState(v any) any {
 	return reflectState(v).Interface()
 }
 
-func setState(v, state interface{}) {
+func setState(v, state any) {
 	reflectState(v).Set(reflect.ValueOf(state))
 }
 
-func reflectState(v interface{}) reflect.Value {
+func reflectState(v any) reflect.Value {
 	rv := reflect.ValueOf(v)
 	if rv.Kind() == reflect.Ptr {
 		rv = reflect.Indirect(rv)

+ 1 - 1
pkg/daemon/client.go

@@ -56,7 +56,7 @@ func (c *client) Close() error {
 	return c.ResetConn()
 }
 
-func (c *client) call(f string, req, res interface{}) error {
+func (c *client) call(f string, req, res any) error {
 	c.waits.Add(1)
 	defer c.waits.Done()
 

+ 1 - 1
pkg/diag/show_error.go

@@ -21,6 +21,6 @@ func Complain(w io.Writer, msg string) {
 }
 
 // Complainf is like Complain, but accepts a format string and arguments.
-func Complainf(w io.Writer, format string, args ...interface{}) {
+func Complainf(w io.Writer, format string, args ...any) {
 	Complain(w, fmt.Sprintf(format, args...))
 }

+ 4 - 4
pkg/edit/binding_map.go

@@ -41,7 +41,7 @@ func (bt bindingsMap) Repr(indent int) string {
 }
 
 // Index converts the index to ui.Key and uses the Index of the inner Map.
-func (bt bindingsMap) Index(index interface{}) (interface{}, error) {
+func (bt bindingsMap) Index(index any) (any, error) {
 	key, err := toKey(index)
 	if err != nil {
 		return nil, err
@@ -49,7 +49,7 @@ func (bt bindingsMap) Index(index interface{}) (interface{}, error) {
 	return vals.Index(bt.Map, key)
 }
 
-func (bt bindingsMap) HasKey(k interface{}) bool {
+func (bt bindingsMap) HasKey(k any) bool {
 	_, ok := bt.Map.Index(k)
 	return ok
 }
@@ -64,7 +64,7 @@ func (bt bindingsMap) GetKey(k ui.Key) eval.Callable {
 
 // Assoc converts the index to ui.Key, ensures that the value is CallableValue,
 // uses the Assoc of the inner Map and converts the result to a BindingTable.
-func (bt bindingsMap) Assoc(k, v interface{}) (interface{}, error) {
+func (bt bindingsMap) Assoc(k, v any) (any, error) {
 	key, err := toKey(k)
 	if err != nil {
 		return nil, err
@@ -79,7 +79,7 @@ func (bt bindingsMap) Assoc(k, v interface{}) (interface{}, error) {
 
 // Dissoc converts the key to ui.Key and calls the Dissoc method of the inner
 // map.
-func (bt bindingsMap) Dissoc(k interface{}) interface{} {
+func (bt bindingsMap) Dissoc(k any) any {
 	key, err := toKey(k)
 	if err != nil {
 		// Key is invalid; dissoc is no-op.

+ 1 - 1
pkg/edit/buffer_builtins.go

@@ -13,7 +13,7 @@ import (
 )
 
 func initBufferBuiltins(app cli.App, nb eval.NsBuilder) {
-	m := make(map[string]interface{})
+	m := make(map[string]any)
 	for name, fn := range bufferBuiltinsData {
 		// Make a lexically scoped copy of fn.
 		fn := fn

+ 5 - 5
pkg/edit/builtins.go

@@ -131,7 +131,7 @@ func insertRaw(app cli.App, tty cli.TTY) {
 
 var errMustBeKeyOrString = errors.New("must be key or string")
 
-func toKey(v interface{}) (ui.Key, error) {
+func toKey(v any) (ui.Key, error) {
 	switch v := v.(type) {
 	case ui.Key:
 		return v, nil
@@ -157,7 +157,7 @@ func toKey(v interface{}) (ui.Key, error) {
 // If called while the editor is inactive, the message will be queued, and shown
 // once the editor becomes active.
 
-func notify(app cli.App, x interface{}) error {
+func notify(app cli.App, x any) error {
 	// TODO: De-duplicate with the implementation of the styled builtin.
 	var t ui.Text
 	switch x := x.(type) {
@@ -240,7 +240,7 @@ func wordify(fm *eval.Frame, code string) error {
 }
 
 func initTTYBuiltins(app cli.App, tty cli.TTY, nb eval.NsBuilder) {
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"-dump-buf":  func() string { return dumpBuf(tty) },
 		"insert-raw": func() { insertRaw(app, tty) },
 		"clear":      func() { clear(app, tty) },
@@ -248,12 +248,12 @@ func initTTYBuiltins(app cli.App, tty cli.TTY, nb eval.NsBuilder) {
 }
 
 func initMiscBuiltins(app cli.App, nb eval.NsBuilder) {
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"binding-table":  makeBindingMap,
 		"close-mode":     func() { closeMode(app) },
 		"end-of-history": func() { endOfHistory(app) },
 		"key":            toKey,
-		"notify":         func(x interface{}) error { return notify(app, x) },
+		"notify":         func(x any) error { return notify(app, x) },
 		"redraw":         func(opts redrawOpts) { redraw(app, opts) },
 		"return-line":    app.CommitCode,
 		"return-eof":     app.CommitEOF,

+ 1 - 1
pkg/edit/command_api.go

@@ -27,7 +27,7 @@ func initCommandAPI(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 	nb.AddNs("command",
 		eval.BuildNsNamed("edit:command").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() {
 					w := modes.NewStub(modes.StubSpec{
 						Bindings: bindings,

+ 1 - 1
pkg/edit/complete/complete.go

@@ -59,7 +59,7 @@ type PureEvaler interface {
 	EachSpecial(func(special string))
 	EachNs(func(string))
 	EachVariableInNs(string, func(string))
-	PurelyEvalPrimary(pn *parse.Primary) interface{}
+	PurelyEvalPrimary(pn *parse.Primary) any
 	PurelyEvalCompound(*parse.Compound) (string, bool)
 	PurelyEvalPartialCompound(*parse.Compound, int) (string, bool)
 }

+ 1 - 1
pkg/edit/complete/complete_test.go

@@ -48,7 +48,7 @@ func (ev testEvaler) PurelyEvalCompound(cn *parse.Compound) (string, bool) {
 	return (*eval.Evaler)(nil).PurelyEvalCompound(cn)
 }
 
-func (ev testEvaler) PurelyEvalPrimary(pn *parse.Primary) interface{} {
+func (ev testEvaler) PurelyEvalPrimary(pn *parse.Primary) any {
 	return (*eval.Evaler)(nil).PurelyEvalPrimary(pn)
 }
 

+ 1 - 1
pkg/edit/complete/completers.go

@@ -93,7 +93,7 @@ func completeCommand(np nodePath, cfg Config) (*context, []RawItem, error) {
 // $a[<Tab> is supported, but $a[x][<Tab> is not.
 func completeIndex(np nodePath, cfg Config) (*context, []RawItem, error) {
 	ev := cfg.PureEvaler
-	generateForEmpty := func(v interface{}, pos int) (*context, []RawItem, error) {
+	generateForEmpty := func(v any, pos int) (*context, []RawItem, error) {
 		ctx := &context{"index", "", parse.Bareword, range0(pos)}
 		return ctx, generateIndices(v), nil
 	}

+ 2 - 2
pkg/edit/complete/generators.go

@@ -170,9 +170,9 @@ func generateFileNames(seed string, onlyExecutable bool) ([]RawItem, error) {
 	return items, nil
 }
 
-func generateIndices(v interface{}) []RawItem {
+func generateIndices(v any) []RawItem {
 	var items []RawItem
-	vals.IterateKeys(v, func(k interface{}) bool {
+	vals.IterateKeys(v, func(k any) bool {
 		if kstring, ok := k.(string); ok {
 			items = append(items, PlainItem(kstring))
 		}

+ 1 - 1
pkg/edit/complete/node_path.go

@@ -80,7 +80,7 @@ type storeMatcher struct {
 	typ reflect.Type
 }
 
-func store(p interface{}) nodesMatcher {
+func store(p any) nodesMatcher {
 	dst := reflect.ValueOf(p).Elem()
 	return storeMatcher{dst, dst.Type()}
 }

+ 8 - 8
pkg/edit/complete_getopt.go

@@ -94,7 +94,7 @@ import (
 //
 // @cf flag:parse-getopt
 
-func completeGetopt(fm *eval.Frame, vArgs, vOpts, vArgHandlers interface{}) error {
+func completeGetopt(fm *eval.Frame, vArgs, vOpts, vArgHandlers any) error {
 	args, err := parseGetoptArgs(vArgs)
 	if err != nil {
 		return err
@@ -134,7 +134,7 @@ func completeGetopt(fm *eval.Frame, vArgs, vOpts, vArgHandlers interface{}) erro
 		}
 		return out.Put(c)
 	}
-	call := func(fn eval.Callable, args ...interface{}) error {
+	call := func(fn eval.Callable, args ...any) error {
 		return fn.Call(fm, args, eval.NoOpts)
 	}
 
@@ -196,10 +196,10 @@ func completeGetopt(fm *eval.Frame, vArgs, vOpts, vArgHandlers interface{}) erro
 
 // TODO(xiaq): Simplify most of the parsing below with reflection.
 
-func parseGetoptArgs(v interface{}) ([]string, error) {
+func parseGetoptArgs(v any) ([]string, error) {
 	var args []string
 	var err error
-	errIterate := vals.Iterate(v, func(v interface{}) bool {
+	errIterate := vals.Iterate(v, func(v any) bool {
 		arg, ok := v.(string)
 		if !ok {
 			err = fmt.Errorf("arg should be string, got %s", vals.Kind(v))
@@ -221,13 +221,13 @@ type parsedOptSpecs struct {
 	argGenerator map[*getopt.OptionSpec]eval.Callable
 }
 
-func parseGetoptOptSpecs(v interface{}) (parsedOptSpecs, error) {
+func parseGetoptOptSpecs(v any) (parsedOptSpecs, error) {
 	result := parsedOptSpecs{
 		nil, map[*getopt.OptionSpec]string{},
 		map[*getopt.OptionSpec]string{}, map[*getopt.OptionSpec]eval.Callable{}}
 
 	var err error
-	errIterate := vals.Iterate(v, func(v interface{}) bool {
+	errIterate := vals.Iterate(v, func(v any) bool {
 		m, ok := v.(vals.Map)
 		if !ok {
 			err = fmt.Errorf("opt should be map, got %s", vals.Kind(v))
@@ -343,11 +343,11 @@ func parseGetoptOptSpecs(v interface{}) (parsedOptSpecs, error) {
 	return result, err
 }
 
-func parseGetoptArgHandlers(v interface{}) ([]eval.Callable, bool, error) {
+func parseGetoptArgHandlers(v any) ([]eval.Callable, bool, error) {
 	var argHandlers []eval.Callable
 	var variadic bool
 	var err error
-	errIterate := vals.Iterate(v, func(v interface{}) bool {
+	errIterate := vals.Iterate(v, func(v any) bool {
 		sv, ok := v.(string)
 		if ok {
 			if sv == "..." {

+ 14 - 14
pkg/edit/completion.go

@@ -91,7 +91,7 @@ import (
 
 type complexCandidateOpts struct {
 	CodeSuffix string
-	Display    interface{}
+	Display    any
 }
 
 func (*complexCandidateOpts) SetDefaultOptions() {}
@@ -245,7 +245,7 @@ func initCompletion(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 	generateForSudo := func(args []string) ([]complete.RawItem, error) {
 		return complete.GenerateForSudo(cfg(), args)
 	}
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"complete-filename": wrapArgGenerator(complete.GenerateFileNames),
 		"complete-getopt":   completeGetopt,
 		"complete-sudo":     wrapArgGenerator(generateForSudo),
@@ -262,7 +262,7 @@ func initCompletion(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 				"binding":       bindingVar,
 				"matcher":       matcherMapVar,
 			}).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"accept":      func() { listingAccept(app) },
 				"smart-start": func() { completionStart(app, bindings, cfg(), true) },
 				"start":       func() { completionStart(app, bindings, cfg(), false) },
@@ -278,7 +278,7 @@ func initCompletion(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 // A wrapper type implementing Elvish value methods.
 type complexItem complete.ComplexItem
 
-func (c complexItem) Index(k interface{}) (interface{}, bool) {
+func (c complexItem) Index(k any) (any, bool) {
 	switch k {
 	case "stem":
 		return c.Stem, true
@@ -290,13 +290,13 @@ func (c complexItem) Index(k interface{}) (interface{}, bool) {
 	return nil, false
 }
 
-func (c complexItem) IterateKeys(f func(interface{}) bool) {
+func (c complexItem) IterateKeys(f func(any) bool) {
 	vals.Feed(f, "stem", "code-suffix", "display")
 }
 
 func (c complexItem) Kind() string { return "map" }
 
-func (c complexItem) Equal(a interface{}) bool {
+func (c complexItem) Equal(a any) bool {
 	rhs, ok := a.(complexItem)
 	return ok && c.Stem == rhs.Stem &&
 		c.CodeSuffix == rhs.CodeSuffix && reflect.DeepEqual(c.Display, rhs.Display)
@@ -328,7 +328,7 @@ func wrapArgGenerator(gen complete.ArgGenerator) wrappedArgGenerator {
 		}
 		out := fm.ValueOutput()
 		for _, rawItem := range rawItems {
-			var v interface{}
+			var v any
 			switch rawItem := rawItem.(type) {
 			case complete.ComplexItem:
 				v = complexItem(rawItem)
@@ -389,14 +389,14 @@ func wrapMatcher(m matcher) wrappedMatcher {
 			if opts.IgnoreCase {
 				seed = strings.ToLower(seed)
 			}
-			inputs(func(v interface{}) {
+			inputs(func(v any) {
 				if errOut != nil {
 					return
 				}
 				errOut = out.Put(m(strings.ToLower(vals.ToString(v)), seed))
 			})
 		} else {
-			inputs(func(v interface{}) {
+			inputs(func(v any) {
 				if errOut != nil {
 					return
 				}
@@ -418,7 +418,7 @@ func adaptMatcherMap(nt notifier, ev *eval.Evaler, m vals.Map) complete.Filterer
 		if matcher == nil {
 			return complete.FilterPrefix(ctxName, seed, rawItems)
 		}
-		input := make(chan interface{})
+		input := make(chan any)
 		stopInputFeeder := make(chan struct{})
 		defer close(stopInputFeeder)
 		// Feed a string representing all raw candidates to the input channel.
@@ -441,7 +441,7 @@ func adaptMatcherMap(nt notifier, ev *eval.Evaler, m vals.Map) complete.Filterer
 		}
 
 		err = ev.Call(matcher,
-			eval.CallCfg{Args: []interface{}{seed}, From: "[editor matcher]"},
+			eval.CallCfg{Args: []any{seed}, From: "[editor matcher]"},
 			eval.EvalCfg{Ports: []*eval.Port{
 				// TODO: Supply the Chan component of port 2.
 				{Chan: input, File: eval.DevNull}, port1, {File: os.Stderr}}})
@@ -475,7 +475,7 @@ func adaptArgGeneratorMap(ev *eval.Evaler, m vals.Map) complete.ArgGenerator {
 		if gen == nil {
 			return complete.GenerateFileNames(args)
 		}
-		argValues := make([]interface{}, len(args))
+		argValues := make([]any, len(args))
 		for i, arg := range args {
 			argValues[i] = arg
 		}
@@ -486,7 +486,7 @@ func adaptArgGeneratorMap(ev *eval.Evaler, m vals.Map) complete.ArgGenerator {
 			defer outputMutex.Unlock()
 			output = append(output, item)
 		}
-		valueCb := func(ch <-chan interface{}) {
+		valueCb := func(ch <-chan any) {
 			for v := range ch {
 				switch v := v.(type) {
 				case string:
@@ -562,7 +562,7 @@ func (pe pureEvaler) EachVariableInNs(ns string, f func(string)) {
 	eachVariableInTop(pe.ev.Builtin(), pe.ev.Global(), ns, f)
 }
 
-func (pe pureEvaler) PurelyEvalPrimary(pn *parse.Primary) interface{} {
+func (pe pureEvaler) PurelyEvalPrimary(pn *parse.Primary) any {
 	return pe.ev.PurelyEvalPrimary(pn)
 }
 

+ 2 - 2
pkg/edit/completion_test.go

@@ -184,7 +184,7 @@ func TestBuiltinMatchers(t *testing.T) {
 		`var @substr = (edit:match-substr ab [ab abc cab acb ba [ab] [a b] [b a]])`,
 		`var @subseq = (edit:match-subseq ab [ab abc cab acb ba [ab] [a b] [b a]])`,
 	)
-	testGlobals(t, f.Evaler, map[string]interface{}{
+	testGlobals(t, f.Evaler, map[string]any{
 		"prefix": vals.MakeList(true, true, false, false, false, false, false, false),
 		"substr": vals.MakeList(true, true, true, false, false, true, false, false),
 		"subseq": vals.MakeList(true, true, true, true, false, true, true, false),
@@ -204,7 +204,7 @@ func TestBuiltinMatchers_Options(t *testing.T) {
 		`var @c = (edit:match-prefix &smart-case  ab [abc aBc Abc])`,
 		`var @d = (edit:match-prefix &smart-case  aB [abc aBc AbC])`,
 	)
-	testGlobals(t, f.Evaler, map[string]interface{}{
+	testGlobals(t, f.Evaler, map[string]any{
 		"a": vals.MakeList(true, true, true),
 		"b": vals.MakeList(true, true, true),
 		"c": vals.MakeList(true, true, true),

+ 2 - 2
pkg/edit/config_api.go

@@ -98,7 +98,7 @@ func initGlobalBindings(appSpec *cli.AppSpec, nt notifier, ev *eval.Evaler, nb e
 	nb.AddVar("global-binding", bindingVar)
 }
 
-func callHooks(ev *eval.Evaler, name string, hook vals.List, args ...interface{}) {
+func callHooks(ev *eval.Evaler, name string, hook vals.List, args ...any) {
 	if hook.Len() == 0 {
 		return
 	}
@@ -126,7 +126,7 @@ func callHooks(ev *eval.Evaler, name string, hook vals.List, args ...interface{}
 	}
 }
 
-func callFilters(ev *eval.Evaler, name string, filters vals.List, args ...interface{}) bool {
+func callFilters(ev *eval.Evaler, name string, filters vals.List, args ...any) bool {
 	if filters.Len() == 0 {
 		return true
 	}

+ 1 - 1
pkg/edit/config_api_test.go

@@ -38,7 +38,7 @@ func TestAfterReadline(t *testing.T) {
 	feedInput(f.TTYCtrl, "test code\n")
 	f.Wait()
 
-	testGlobals(t, f.Evaler, map[string]interface{}{
+	testGlobals(t, f.Evaler, map[string]any{
 		"called":      1,
 		"called-with": "test code",
 	})

+ 2 - 2
pkg/edit/editor.go

@@ -36,7 +36,7 @@ type Editor struct {
 // the *Editor type; functions may take a notifier instead of *Editor argument
 // to make it clear that they do not depend on other parts of *Editor.
 type notifier interface {
-	notifyf(format string, args ...interface{})
+	notifyf(format string, args ...any)
 	notifyError(ctx string, e error)
 }
 
@@ -132,7 +132,7 @@ func (ed *Editor) Ns() *eval.Ns {
 	return ed.ns
 }
 
-func (ed *Editor) notifyf(format string, args ...interface{}) {
+func (ed *Editor) notifyf(format string, args ...any) {
 	ed.app.Notify(ui.T(fmt.Sprintf(format, args...)))
 }
 

+ 1 - 1
pkg/edit/histwalk.go

@@ -43,7 +43,7 @@ func initHistWalk(ed *Editor, ev *eval.Evaler, hs *histStore, nb eval.NsBuilder)
 	nb.AddNs("history",
 		eval.BuildNsNamed("edit:history").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() { notifyError(app, histwalkStart(app, hs, bindings)) },
 				"up":    func() { notifyError(app, histwalkDo(app, modes.Histwalk.Prev)) },
 

+ 1 - 1
pkg/edit/instant.go

@@ -27,7 +27,7 @@ func initInstant(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 	nb.AddNs("-instant",
 		eval.BuildNsNamed("edit:-instant").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() { instantStart(ed.app, ev, bindings) },
 			}))
 }

+ 2 - 2
pkg/edit/key_binding.go

@@ -60,7 +60,7 @@ func indexLayeredBindings(k ui.Key, maps ...bindingsMap) eval.Callable {
 
 var bindingSource = parse.Source{Name: "[editor binding]"}
 
-func callWithNotifyPorts(nt notifier, ev *eval.Evaler, f eval.Callable, args ...interface{}) {
+func callWithNotifyPorts(nt notifier, ev *eval.Evaler, f eval.Callable, args ...any) {
 	notifyPort, cleanup := makeNotifyPort(nt)
 	defer cleanup()
 
@@ -73,7 +73,7 @@ func callWithNotifyPorts(nt notifier, ev *eval.Evaler, f eval.Callable, args ...
 }
 
 func makeNotifyPort(nt notifier) (*eval.Port, func()) {
-	ch := make(chan interface{})
+	ch := make(chan any)
 	r, w, err := os.Pipe()
 	if err != nil {
 		panic(err)

+ 4 - 4
pkg/edit/listing.go

@@ -20,7 +20,7 @@ func initListings(ed *Editor, ev *eval.Evaler, st storedefs.Store, histStore his
 	nb.AddNs("listing",
 		eval.BuildNsNamed("edit:listing").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"accept":     func() { listingAccept(app) },
 				"up":         func() { listingUp(app) },
 				"down":       func() { listingDown(app) },
@@ -28,7 +28,7 @@ func initListings(ed *Editor, ev *eval.Evaler, st storedefs.Store, histStore his
 				"down-cycle": func() { listingDownCycle(app) },
 				"page-up":    func() { listingPageUp(app) },
 				"page-down":  func() { listingPageDown(app) },
-				"start-custom": func(fm *eval.Frame, opts customListingOpts, items interface{}) {
+				"start-custom": func(fm *eval.Frame, opts customListingOpts, items any) {
 					listingStartCustom(ed, fm, opts, items)
 				},
 			}))
@@ -56,7 +56,7 @@ func initHistlist(ed *Editor, ev *eval.Evaler, histStore histutil.Store, commonB
 	nb.AddNs("histlist",
 		eval.BuildNsNamed("edit:histlist").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() {
 					w, err := modes.NewHistlist(ed.app, modes.HistlistSpec{
 						Bindings: bindings,
@@ -221,7 +221,7 @@ func listingRefilter(app cli.App) {
 
 func adaptToIterateString(variable vars.Var) func(func(string)) {
 	return func(f func(s string)) {
-		vals.Iterate(variable.Get(), func(v interface{}) bool {
+		vals.Iterate(variable.Get(), func(v any) bool {
 			f(vals.ToString(v))
 			return true
 		})

+ 6 - 6
pkg/edit/listing_custom.go

@@ -29,7 +29,7 @@ func (*customListingOpts) SetDefaultOptions() {}
 //
 // Starts a custom listing addon.
 
-func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, items interface{}) {
+func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, items any) {
 	var bindings tk.Bindings
 	if opts.Binding.Map != nil {
 		bindings = newMapBindings(ed, fm.Evaler, vars.FromPtr(&opts.Binding))
@@ -44,7 +44,7 @@ func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, item
 				defer itemsMutex.Unlock()
 				items = append(items, item)
 			}
-			valuesCb := func(ch <-chan interface{}) {
+			valuesCb := func(ch <-chan any) {
 				for v := range ch {
 					if item, itemOk := getListingItem(v); itemOk {
 						collect(item)
@@ -64,7 +64,7 @@ func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, item
 					}
 				}
 			}
-			f := func(fm *eval.Frame) error { return fn.Call(fm, []interface{}{q}, eval.NoOpts) }
+			f := func(fm *eval.Frame) error { return fn.Call(fm, []any{q}, eval.NoOpts) }
 			err := fm.PipeOutput(f, valuesCb, bytesCb)
 			// TODO(xiaq): Report the error.
 			_ = err
@@ -73,7 +73,7 @@ func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, item
 	} else {
 		getItems = func(q string) []modes.ListingItem {
 			convertedItems := []modes.ListingItem{}
-			vals.Iterate(items, func(v interface{}) bool {
+			vals.Iterate(items, func(v any) bool {
 				toFilter, toFilterOk := getToFilter(v)
 				item, itemOk := getListingItem(v)
 				if toFilterOk && itemOk && strings.Contains(toFilter, q) {
@@ -107,13 +107,13 @@ func listingStartCustom(ed *Editor, fm *eval.Frame, opts customListingOpts, item
 	startMode(ed.app, w, err)
 }
 
-func getToFilter(v interface{}) (string, bool) {
+func getToFilter(v any) (string, bool) {
 	toFilterValue, _ := vals.Index(v, "to-filter")
 	toFilter, toFilterOk := toFilterValue.(string)
 	return toFilter, toFilterOk
 }
 
-func getListingItem(v interface{}) (item modes.ListingItem, ok bool) {
+func getListingItem(v any) (item modes.ListingItem, ok bool) {
 	toAcceptValue, _ := vals.Index(v, "to-accept")
 	toAccept, toAcceptOk := toAcceptValue.(string)
 	toShowValue, _ := vals.Index(v, "to-show")

+ 1 - 1
pkg/edit/minibuf.go

@@ -13,7 +13,7 @@ func initMinibuf(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 	nb.AddNs("minibuf",
 		eval.BuildNsNamed("edit:minibuf").
 			AddVar("binding", bindingVar).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() { minibufStart(ed, ev, bindings) },
 			}))
 }

+ 4 - 4
pkg/edit/navigation.go

@@ -79,12 +79,12 @@ func navInsertSelectedAndQuit(app cli.App) {
 // A list of 3 integers, used for specifying the width ratio of the 3 columns in
 // navigation mode.
 
-func convertNavWidthRatio(v interface{}) [3]int {
+func convertNavWidthRatio(v any) [3]int {
 	var (
 		numbers []int
 		hasErr  bool
 	)
-	vals.Iterate(v, func(elem interface{}) bool {
+	vals.Iterate(v, func(elem any) bool {
 		var i int
 		err := vals.ScanToGo(elem, &i)
 		if err != nil {
@@ -108,7 +108,7 @@ func initNavigation(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 	bindings := newMapBindings(ed, ev, bindingVar)
 	widthRatioVar := newListVar(vals.MakeList(1.0, 3.0, 4.0))
 
-	selectedFileVar := vars.FromGet(func() interface{} {
+	selectedFileVar := vars.FromGet(func() any {
 		if w, ok := activeNavigation(ed.app); ok {
 			return w.SelectedName()
 		}
@@ -123,7 +123,7 @@ func initNavigation(ed *Editor, ev *eval.Evaler, nb eval.NsBuilder) {
 				"binding":     bindingVar,
 				"width-ratio": widthRatioVar,
 			}).
-			AddGoFns(map[string]interface{}{
+			AddGoFns(map[string]any{
 				"start": func() {
 					w, err := modes.NewNavigation(app, modes.NavigationSpec{
 						Bindings: bindings,

+ 3 - 3
pkg/edit/prompt.go

@@ -127,12 +127,12 @@ func defaultStaleTransform(original ui.Text) ui.Text {
 
 // Calls a function with the given arguments and closed input, and concatenates
 // its outputs to a styled text. Used to call prompts and stale transformers.
-func callForStyledText(nt notifier, ev *eval.Evaler, ctx string, fn eval.Callable, args ...interface{}) ui.Text {
+func callForStyledText(nt notifier, ev *eval.Evaler, ctx string, fn eval.Callable, args ...any) ui.Text {
 	var (
 		result      ui.Text
 		resultMutex sync.Mutex
 	)
-	add := func(v interface{}) {
+	add := func(v any) {
 		resultMutex.Lock()
 		defer resultMutex.Unlock()
 		newResult, err := result.Concat(v)
@@ -144,7 +144,7 @@ func callForStyledText(nt notifier, ev *eval.Evaler, ctx string, fn eval.Callabl
 	}
 
 	// Value outputs are concatenated.
-	valuesCb := func(ch <-chan interface{}) {
+	valuesCb := func(ch <-chan any) {
 		for v := range ch {
 			add(v)
 		}

+ 1 - 1
pkg/edit/prompt_test.go

@@ -126,7 +126,7 @@ func TestRPromptPersistent_False(t *testing.T) {
 	)
 }
 
-func testRPromptPersistent(t *testing.T, code string, finalBuf ...interface{}) {
+func testRPromptPersistent(t *testing.T, code string, finalBuf ...any) {
 	f := setup(t, rc(`set edit:rprompt = { put RRR }`, code))
 
 	// Make sure that the UI has stabilized before hitting Enter.

+ 5 - 5
pkg/edit/state_api.go

@@ -62,12 +62,12 @@ func initStateAPI(app cli.App, nb eval.NsBuilder) {
 	// State API always operates on the root CodeArea widget
 	codeArea := app.ActiveWidget().(tk.CodeArea)
 
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"insert-at-dot": func(s string) { insertAtDot(app, s) },
 		"replace-input": func(s string) { replaceInput(app, s) },
 	})
 
-	setDot := func(v interface{}) error {
+	setDot := func(v any) error {
 		var dot int
 		err := vals.ScanToGo(v, &dot)
 		if err != nil {
@@ -78,12 +78,12 @@ func initStateAPI(app cli.App, nb eval.NsBuilder) {
 		})
 		return nil
 	}
-	getDot := func() interface{} {
+	getDot := func() any {
 		return vals.FromGo(codeArea.CopyState().Buffer.Dot)
 	}
 	nb.AddVar("-dot", vars.FromSetGet(setDot, getDot))
 
-	setCurrentCommand := func(v interface{}) error {
+	setCurrentCommand := func(v any) error {
 		var content string
 		err := vals.ScanToGo(v, &content)
 		if err != nil {
@@ -92,7 +92,7 @@ func initStateAPI(app cli.App, nb eval.NsBuilder) {
 		replaceInput(app, content)
 		return nil
 	}
-	getCurrentCommand := func() interface{} {
+	getCurrentCommand := func() any {
 		return vals.FromGo(codeArea.CopyState().Buffer.Content)
 	}
 	nb.AddVar("current-command", vars.FromSetGet(setCurrentCommand, getCurrentCommand))

+ 1 - 1
pkg/edit/store_api.go

@@ -125,7 +125,7 @@ func insertLastWord(app cli.App, histStore histutil.Store) error {
 }
 
 func initStoreAPI(app cli.App, nb eval.NsBuilder, fuser histutil.Store) {
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"command-history": func(fm *eval.Frame, opts cmdhistOpt) error {
 			return commandHistory(opts, fuser, fm.ValueOutput())
 		},

+ 7 - 7
pkg/edit/testutils_test.go

@@ -36,7 +36,7 @@ func rc(codes ...string) func(*fixture) {
 	return func(f *fixture) { evals(f.Evaler, codes...) }
 }
 
-func assign(name string, val interface{}) func(*fixture) {
+func assign(name string, val any) func(*fixture) {
 	return func(f *fixture) {
 		f.Evaler.ExtendGlobal(eval.BuildNs().AddVar("temp", vars.NewReadOnly(val)))
 		evals(f.Evaler, "set "+name+" = $temp")
@@ -84,16 +84,16 @@ func (f *fixture) Wait() (string, error) {
 	return <-f.codeCh, <-f.errCh
 }
 
-func (f *fixture) MakeBuffer(args ...interface{}) *term.Buffer {
+func (f *fixture) MakeBuffer(args ...any) *term.Buffer {
 	return term.NewBufferBuilder(f.width).MarkLines(args...).Buffer()
 }
 
-func (f *fixture) TestTTY(t *testing.T, args ...interface{}) {
+func (f *fixture) TestTTY(t *testing.T, args ...any) {
 	t.Helper()
 	f.TTYCtrl.TestBuffer(t, f.MakeBuffer(args...))
 }
 
-func (f *fixture) TestTTYNotes(t *testing.T, args ...interface{}) {
+func (f *fixture) TestTTYNotes(t *testing.T, args ...any) {
 	t.Helper()
 	f.TTYCtrl.TestNotesBuffer(t, f.MakeBuffer(args...))
 }
@@ -119,19 +119,19 @@ func evals(ev *eval.Evaler, codes ...string) {
 	}
 }
 
-func getGlobal(ev *eval.Evaler, name string) interface{} {
+func getGlobal(ev *eval.Evaler, name string) any {
 	v, _ := ev.Global().Index(name)
 	return v
 }
 
-func testGlobals(t *testing.T, ev *eval.Evaler, wantVals map[string]interface{}) {
+func testGlobals(t *testing.T, ev *eval.Evaler, wantVals map[string]any) {
 	t.Helper()
 	for name, wantVal := range wantVals {
 		testGlobal(t, ev, name, wantVal)
 	}
 }
 
-func testGlobal(t *testing.T, ev *eval.Evaler, name string, wantVal interface{}) {
+func testGlobal(t *testing.T, ev *eval.Evaler, name string, wantVal any) {
 	t.Helper()
 	if val := getGlobal(ev, name); !vals.Equal(val, wantVal) {
 		t.Errorf("$%s = %s, want %s",

+ 2 - 2
pkg/edit/vars.go

@@ -10,7 +10,7 @@ import (
 )
 
 func initVarsAPI(ed *Editor, nb eval.NsBuilder) {
-	nb.AddGoFns(map[string]interface{}{
+	nb.AddGoFns(map[string]any{
 		"add-var":  addVar,
 		"add-vars": addVars,
 	})
@@ -88,7 +88,7 @@ func initVarsAPI(ed *Editor, nb eval.NsBuilder) {
 // }
 // ```
 
-func addVar(fm *eval.Frame, name string, val interface{}) error {
+func addVar(fm *eval.Frame, name string, val any) error {
 	if !isUnqualified(name) {
 		return errs.BadValue{
 			What:  "name argument to edit:add-var",

+ 1 - 1
pkg/eval/builtin_fn_cmd.go

@@ -12,7 +12,7 @@ import (
 // TODO(xiaq): Document "fg".
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		// Command resolution
 		"external":        external,
 		"has-external":    hasExternal,

+ 1 - 1
pkg/eval/builtin_fn_cmd_unix.go

@@ -35,7 +35,7 @@ var ErrNotInSameProcessGroup = errors.New("not in the same process group")
 // Reference to syscall.Exec. Can be overridden in tests.
 var syscallExec = syscall.Exec
 
-func execFn(fm *Frame, args ...interface{}) error {
+func execFn(fm *Frame, args ...any) error {
 	var argstrings []string
 	if len(args) == 0 {
 		argstrings = []string{"elvish"}

+ 1 - 1
pkg/eval/builtin_fn_cmd_windows.go

@@ -4,7 +4,7 @@ import "errors"
 
 var errNotSupportedOnWindows = errors.New("not supported on Windows")
 
-func execFn(...interface{}) error {
+func execFn(...any) error {
 	return errNotSupportedOnWindows
 }
 

+ 9 - 9
pkg/eval/builtin_fn_container.go

@@ -12,7 +12,7 @@ import (
 // Lists and maps.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"ns": nsFn,
 
 		"make-map": makeMap,
@@ -88,7 +88,7 @@ func nsFn(m vals.Map) (*Ns, error) {
 func makeMap(input Inputs) (vals.Map, error) {
 	m := vals.EmptyMap
 	var errMakeMap error
-	input(func(v interface{}) {
+	input(func(v any) {
 		if errMakeMap != nil {
 			return
 		}
@@ -144,7 +144,7 @@ func makeMap(input Inputs) (vals.Map, error) {
 //
 // @cf dissoc
 
-func assoc(a, k, v interface{}) (interface{}, error) {
+func assoc(a, k, v any) (any, error) {
 	return vals.Assoc(a, k, v)
 }
 
@@ -168,7 +168,7 @@ var errCannotDissoc = errors.New("cannot dissoc")
 //
 // @cf assoc
 
-func dissoc(a, k interface{}) (interface{}, error) {
+func dissoc(a, k any) (any, error) {
 	a2 := vals.Dissoc(a, k)
 	if a2 == nil {
 		return nil, errCannotDissoc
@@ -211,7 +211,7 @@ func dissoc(a, k interface{}) (interface{}, error) {
 // ▶ $false
 // ```
 
-func hasValue(container, value interface{}) (bool, error) {
+func hasValue(container, value any) (bool, error) {
 	switch container := container.(type) {
 	case vals.Map:
 		for it := container.Iterator(); it.HasElem(); it.Next() {
@@ -223,7 +223,7 @@ func hasValue(container, value interface{}) (bool, error) {
 		return false, nil
 	default:
 		var found bool
-		err := vals.Iterate(container, func(v interface{}) bool {
+		err := vals.Iterate(container, func(v any) bool {
 			found = (v == value)
 			return !found
 		})
@@ -279,7 +279,7 @@ func hasValue(container, value interface{}) (bool, error) {
 // ▶ $false
 // ```
 
-func hasKey(container, key interface{}) bool {
+func hasKey(container, key any) bool {
 	return vals.HasKey(container, key)
 }
 
@@ -302,10 +302,10 @@ func hasKey(container, key interface{}) bool {
 //
 // Note that there is no guaranteed order for the keys of a map.
 
-func keys(fm *Frame, v interface{}) error {
+func keys(fm *Frame, v any) error {
 	out := fm.ValueOutput()
 	var errPut error
-	errIterate := vals.IterateKeys(v, func(k interface{}) bool {
+	errIterate := vals.IterateKeys(v, func(k any) bool {
 		errPut = out.Put(k)
 		return errPut == nil
 	})

+ 1 - 1
pkg/eval/builtin_fn_debug.go

@@ -8,7 +8,7 @@ import (
 )
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"src":    src,
 		"-gc":    _gc,
 		"-stack": _stack,

+ 1 - 1
pkg/eval/builtin_fn_env.go

@@ -45,7 +45,7 @@ var ErrNonExistentEnvVar = errors.New("non-existent environment variable")
 // @cf has-env get-env set-env
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"has-env":   hasEnv,
 		"get-env":   getEnv,
 		"set-env":   os.Setenv,

+ 9 - 9
pkg/eval/builtin_fn_flow.go

@@ -14,7 +14,7 @@ import (
 // TODO(xiaq): Document "multi-error".
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"run-parallel": runParallel,
 		// Exception and control
 		"fail":        fail,
@@ -128,12 +128,12 @@ func runParallel(fm *Frame, functions ...Callable) error {
 func each(fm *Frame, f Callable, inputs Inputs) error {
 	broken := false
 	var err error
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if broken {
 			return
 		}
 		newFm := fm.Fork("closure of each")
-		ex := f.Call(newFm, []interface{}{v}, NoOpts)
+		ex := f.Call(newFm, []any{v}, NoOpts)
 		newFm.Close()
 
 		if ex != nil {
@@ -197,7 +197,7 @@ func peach(fm *Frame, f Callable, inputs Inputs) error {
 	var errMu sync.Mutex
 	var err error
 
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if atomic.LoadInt32(&broken) != 0 {
 			return
 		}
@@ -205,7 +205,7 @@ func peach(fm *Frame, f Callable, inputs Inputs) error {
 		go func() {
 			newFm := fm.Fork("closure of peach")
 			newFm.ports[0] = DummyInputPort
-			ex := f.Call(newFm, []interface{}{v}, NoOpts)
+			ex := f.Call(newFm, []any{v}, NoOpts)
 			newFm.Close()
 
 			if ex != nil {
@@ -229,7 +229,7 @@ func peach(fm *Frame, f Callable, inputs Inputs) error {
 }
 
 // FailError is an error returned by the "fail" command.
-type FailError struct{ Content interface{} }
+type FailError struct{ Content any }
 
 // Error returns the string representation of the cause.
 func (e FailError) Error() string { return vals.ToString(e.Content) }
@@ -241,8 +241,8 @@ type failFields struct{ e FailError }
 
 func (failFields) IsStructMap() {}
 
-func (f failFields) Type() string         { return "fail" }
-func (f failFields) Content() interface{} { return f.e.Content }
+func (f failFields) Type() string { return "fail" }
+func (f failFields) Content() any { return f.e.Content }
 
 //elvdoc:fn fail
 //
@@ -269,7 +269,7 @@ func (f failFields) Content() interface{} { return f.e.Content }
 //     fail ?(f)
 // ```
 
-func fail(v interface{}) error {
+func fail(v any) error {
 	if e, ok := v.(error); ok {
 		// MAYBE TODO: if v is an exception, attach a "rethrown" stack trace,
 		// like Java

+ 1 - 1
pkg/eval/builtin_fn_fs.go

@@ -8,7 +8,7 @@ import (
 // Filesystem commands.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		// Directory
 		"cd": cd,
 

+ 18 - 18
pkg/eval/builtin_fn_io.go

@@ -18,7 +18,7 @@ import (
 // Input and output.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		// Value output
 		"put":    put,
 		"repeat": repeat,
@@ -84,7 +84,7 @@ func init() {
 // [C](https://manpages.debian.org/stretch/manpages-dev/puts.3.en.html) and
 // [Ruby](https://ruby-doc.org/core-2.2.2/IO.html#method-i-puts) as `puts`.
 
-func put(fm *Frame, args ...interface{}) error {
+func put(fm *Frame, args ...any) error {
 	out := fm.ValueOutput()
 	for _, a := range args {
 		err := out.Put(a)
@@ -114,7 +114,7 @@ func put(fm *Frame, args ...interface{}) error {
 //
 // Etymology: [Clojure](https://clojuredocs.org/clojure.core/repeat).
 
-func repeat(fm *Frame, n int, v interface{}) error {
+func repeat(fm *Frame, n int, v any) error {
 	out := fm.ValueOutput()
 	for i := 0; i < n; i++ {
 		err := out.Put(v)
@@ -229,7 +229,7 @@ type printOpts struct{ Sep string }
 
 func (o *printOpts) SetDefaultOptions() { o.Sep = " " }
 
-func print(fm *Frame, opts printOpts, args ...interface{}) error {
+func print(fm *Frame, opts printOpts, args ...any) error {
 	out := fm.ByteOutput()
 	for i, arg := range args {
 		if i > 0 {
@@ -324,8 +324,8 @@ func print(fm *Frame, opts printOpts, args ...interface{}) error {
 //
 // @cf print echo pprint repr
 
-func printf(fm *Frame, template string, args ...interface{}) error {
-	wrappedArgs := make([]interface{}, len(args))
+func printf(fm *Frame, template string, args ...any) error {
+	wrappedArgs := make([]any, len(args))
 	for i, arg := range args {
 		wrappedArgs[i] = formatter{arg}
 	}
@@ -335,7 +335,7 @@ func printf(fm *Frame, template string, args ...interface{}) error {
 }
 
 type formatter struct {
-	wrapped interface{}
+	wrapped any
 }
 
 func (f formatter) Format(state fmt.State, r rune) {
@@ -377,7 +377,7 @@ func (f formatter) Format(state fmt.State, r rune) {
 
 // Writes to State using the flag it stores, but with a potentially different
 // verb and value.
-func writeFmt(state fmt.State, v rune, val interface{}) {
+func writeFmt(state fmt.State, v rune, val any) {
 	// Reconstruct the verb string.
 	var sb strings.Builder
 	sb.WriteRune('%')
@@ -425,7 +425,7 @@ func writeFmt(state fmt.State, v rune, val interface{}) {
 //
 // Etymology: Bourne sh.
 
-func echo(fm *Frame, opts printOpts, args ...interface{}) error {
+func echo(fm *Frame, opts printOpts, args ...any) error {
 	err := print(fm, opts, args...)
 	if err != nil {
 		return err
@@ -461,7 +461,7 @@ func echo(fm *Frame, opts printOpts, args ...interface{}) error {
 //
 // @cf repr
 
-func pprint(fm *Frame, args ...interface{}) error {
+func pprint(fm *Frame, args ...any) error {
 	out := fm.ByteOutput()
 	for _, arg := range args {
 		_, err := out.WriteString(vals.Repr(arg, 0))
@@ -494,7 +494,7 @@ func pprint(fm *Frame, args ...interface{}) error {
 //
 // Etymology: [Python](https://docs.python.org/3/library/functions.html#repr).
 
-func repr(fm *Frame, args ...interface{}) error {
+func repr(fm *Frame, args ...any) error {
 	out := fm.ByteOutput()
 	for i, arg := range args {
 		if i > 0 {
@@ -720,7 +720,7 @@ func fromJSON(fm *Frame) error {
 
 	dec := json.NewDecoder(in)
 	for {
-		var v interface{}
+		var v any
 		err := dec.Decode(&v)
 		if err != nil {
 			if err == io.EOF {
@@ -740,13 +740,13 @@ func fromJSON(fm *Frame) error {
 }
 
 // Converts a interface{} that results from json.Unmarshal to an Elvish value.
-func fromJSONInterface(v interface{}) (interface{}, error) {
+func fromJSONInterface(v any) (any, error) {
 	switch v := v.(type) {
 	case nil, bool, string:
 		return v, nil
 	case float64:
 		return v, nil
-	case []interface{}:
+	case []any:
 		vec := vals.EmptyList
 		for _, elem := range v {
 			converted, err := fromJSONInterface(elem)
@@ -756,7 +756,7 @@ func fromJSONInterface(v interface{}) (interface{}, error) {
 			vec = vec.Conj(converted)
 		}
 		return vec, nil
-	case map[string]interface{}:
+	case map[string]any:
 		m := vals.EmptyMap
 		for key, val := range v {
 			convertedVal, err := fromJSONInterface(val)
@@ -848,7 +848,7 @@ func toLines(fm *Frame, inputs Inputs) error {
 	out := fm.ByteOutput()
 	var errOut error
 
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errOut != nil {
 			return
 		}
@@ -888,7 +888,7 @@ func toTerminated(fm *Frame, terminator string, inputs Inputs) error {
 
 	out := fm.ByteOutput()
 	var errOut error
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errOut != nil {
 			return
 		}
@@ -920,7 +920,7 @@ func toJSON(fm *Frame, inputs Inputs) error {
 	encoder := json.NewEncoder(fm.ByteOutput())
 
 	var errEncode error
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errEncode != nil {
 			return
 		}

+ 9 - 9
pkg/eval/builtin_fn_misc.go

@@ -26,7 +26,7 @@ var (
 // Builtins that have not been put into their own groups go here.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"nop":        nop,
 		"kind-of":    kindOf,
 		"constantly": constantly,
@@ -69,7 +69,7 @@ func init() {
 // Etymology: Various languages, in particular NOP in
 // [assembly languages](https://en.wikipedia.org/wiki/NOP).
 
-func nop(opts RawOptions, args ...interface{}) {
+func nop(opts RawOptions, args ...any) {
 	// Do nothing
 }
 
@@ -90,7 +90,7 @@ func nop(opts RawOptions, args ...interface{}) {
 //
 // The terminology and definition of "kind" is subject to change.
 
-func kindOf(fm *Frame, args ...interface{}) error {
+func kindOf(fm *Frame, args ...any) error {
 	out := fm.ValueOutput()
 	for _, a := range args {
 		err := out.Put(vals.Kind(a))
@@ -134,7 +134,7 @@ func kindOf(fm *Frame, args ...interface{}) error {
 //
 // Etymology: [Clojure](https://clojuredocs.org/clojure.core/constantly).
 
-func constantly(args ...interface{}) Callable {
+func constantly(args ...any) Callable {
 	// TODO(xiaq): Repr of this function is not right.
 	return NewGoFn(
 		"created by constantly",
@@ -171,11 +171,11 @@ func constantly(args ...interface{}) Callable {
 // ```
 
 func call(fm *Frame, fn Callable, argsVal vals.List, optsVal vals.Map) error {
-	args := make([]interface{}, 0, argsVal.Len())
+	args := make([]any, 0, argsVal.Len())
 	for it := argsVal.Iterator(); it.HasElem(); it.Next() {
 		args = append(args, it.Elem())
 	}
-	opts := make(map[string]interface{}, optsVal.Len())
+	opts := make(map[string]any, optsVal.Len())
 	for it := optsVal.Iterator(); it.HasElem(); it.Next() {
 		k, v := it.Elem()
 		ks, ok := k.(string)
@@ -310,7 +310,7 @@ func eval(fm *Frame, opts evalOpts, code string) error {
 	newNs, exc := fm.Eval(src, nil, ns)
 	if opts.OnEnd != nil {
 		newFm := fm.Fork("on-end callback of eval")
-		errCb := opts.OnEnd.Call(newFm, []interface{}{newNs}, NoOpts)
+		errCb := opts.OnEnd.Call(newFm, []any{newNs}, NoOpts)
 		if exc == nil {
 			return errCb
 		}
@@ -459,7 +459,7 @@ var TimeAfter = func(fm *Frame, d time.Duration) <-chan time.Time {
 // [tty 8], line 1: sleep -1
 // ```
 
-func sleep(fm *Frame, duration interface{}) error {
+func sleep(fm *Frame, duration any) error {
 	var f float64
 	var d time.Duration
 
@@ -534,7 +534,7 @@ func timeCmd(fm *Frame, opts timeOpt, f Callable) error {
 	dt := t1.Sub(t0)
 	if opts.OnEnd != nil {
 		newFm := fm.Fork("on-end callback of time")
-		errCb := opts.OnEnd.Call(newFm, []interface{}{dt.Seconds()}, NoOpts)
+		errCb := opts.OnEnd.Call(newFm, []any{dt.Seconds()}, NoOpts)
 		if err == nil {
 			err = errCb
 		}

+ 1 - 1
pkg/eval/builtin_fn_num.go

@@ -27,7 +27,7 @@ import (
 // ```
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		// Constructor
 		"float64":   toFloat64,
 		"num":       num,

+ 1 - 1
pkg/eval/builtin_fn_num_test.go

@@ -253,7 +253,7 @@ func bigRat(s string) *big.Rat {
 	return z
 }
 
-func args(vs ...interface{}) string {
+func args(vs ...any) string {
 	s := make([]string, len(vs))
 	for i, v := range vs {
 		s[i] = vals.ToString(v)

+ 7 - 7
pkg/eval/builtin_fn_pred.go

@@ -40,7 +40,7 @@ import (
 // @cf not
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"bool":    vals.Bool,
 		"not":     not,
 		"is":      is,
@@ -76,7 +76,7 @@ func init() {
 //
 // @cf bool
 
-func not(v interface{}) bool {
+func not(v any) bool {
 	return !vals.Bool(v)
 }
 
@@ -106,7 +106,7 @@ func not(v interface{}) bool {
 //
 // Etymology: [Python](https://docs.python.org/3/reference/expressions.html#is).
 
-func is(args ...interface{}) bool {
+func is(args ...any) bool {
 	for i := 0; i+1 < len(args); i++ {
 		if args[i] != args[i+1] {
 			return false
@@ -145,7 +145,7 @@ func is(args ...interface{}) bool {
 //
 // Etymology: [Perl](https://perldoc.perl.org/perlop.html#Equality-Operators).
 
-func eq(args ...interface{}) bool {
+func eq(args ...any) bool {
 	for i := 0; i+1 < len(args); i++ {
 		if !vals.Equal(args[i], args[i+1]) {
 			return false
@@ -174,7 +174,7 @@ func eq(args ...interface{}) bool {
 //
 // @cf eq
 
-func notEq(args ...interface{}) bool {
+func notEq(args ...any) bool {
 	for i := 0; i+1 < len(args); i++ {
 		if vals.Equal(args[i], args[i+1]) {
 			return false
@@ -232,7 +232,7 @@ var ErrUncomparable = errs.BadValue{
 	What:  `inputs to "compare" or "order"`,
 	Valid: "comparable values", Actual: "uncomparable values"}
 
-func compare(fm *Frame, a, b interface{}) (int, error) {
+func compare(fm *Frame, a, b any) (int, error) {
 	switch cmp(a, b) {
 	case less:
 		return -1, nil
@@ -254,7 +254,7 @@ const (
 	uncomparable
 )
 
-func cmp(a, b interface{}) ordering {
+func cmp(a, b any) ordering {
 	switch a := a.(type) {
 	case int, *big.Int, *big.Rat, float64:
 		switch b.(type) {

+ 4 - 4
pkg/eval/builtin_fn_str.go

@@ -58,7 +58,7 @@ var ErrInputOfEawkMustBeString = errors.New("input of eawk must be string")
 // TODO(xiaq): Document -override-wcswidth.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"<s":  func(a, b string) bool { return a < b },
 		"<=s": func(a, b string) bool { return a <= b },
 		"==s": func(a, b string) bool { return a == b },
@@ -92,7 +92,7 @@ func init() {
 // ▶ '[&k=v]'
 // ```
 
-func toString(fm *Frame, args ...interface{}) error {
+func toString(fm *Frame, args ...any) error {
 	out := fm.ValueOutput()
 	for _, a := range args {
 		err := out.Put(vals.ToString(a))
@@ -194,7 +194,7 @@ var eawkWordSep = regexp.MustCompile("[ \t]+")
 func eawk(fm *Frame, f Callable, inputs Inputs) error {
 	broken := false
 	var err error
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if broken {
 			return
 		}
@@ -204,7 +204,7 @@ func eawk(fm *Frame, f Callable, inputs Inputs) error {
 			err = ErrInputOfEawkMustBeString
 			return
 		}
-		args := []interface{}{line}
+		args := []any{line}
 		for _, field := range eawkWordSep.Split(strings.Trim(line, " \t"), -1) {
 			args = append(args, field)
 		}

+ 14 - 14
pkg/eval/builtin_fn_stream.go

@@ -11,7 +11,7 @@ import (
 // Stream manipulation.
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"all": all,
 		"one": one,
 
@@ -112,7 +112,7 @@ func init() {
 func all(fm *Frame, inputs Inputs) error {
 	out := fm.ValueOutput()
 	var errOut error
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errOut != nil {
 			return
 		}
@@ -136,9 +136,9 @@ func all(fm *Frame, inputs Inputs) error {
 // @cf all
 
 func one(fm *Frame, inputs Inputs) error {
-	var val interface{}
+	var val any
 	n := 0
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if n == 0 {
 			val = v
 		}
@@ -182,7 +182,7 @@ func take(fm *Frame, n int, inputs Inputs) error {
 	out := fm.ValueOutput()
 	var errOut error
 	i := 0
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errOut != nil {
 			return
 		}
@@ -228,7 +228,7 @@ func drop(fm *Frame, n int, inputs Inputs) error {
 	out := fm.ValueOutput()
 	var errOut error
 	i := 0
-	inputs(func(v interface{}) {
+	inputs(func(v any) {
 		if errOut != nil {
 			return
 		}
@@ -264,12 +264,12 @@ func drop(fm *Frame, n int, inputs Inputs) error {
 // The count implementation uses a custom varargs based implementation rather
 // than the more common `Inputs` API (see pkg/eval/go_fn.go) because this
 // allows the implementation to be O(1) for the common cases rather than O(n).
-func count(fm *Frame, args ...interface{}) (int, error) {
+func count(fm *Frame, args ...any) (int, error) {
 	var n int
 	switch nargs := len(args); nargs {
 	case 0:
 		// Count inputs.
-		fm.IterateInputs(func(interface{}) {
+		fm.IterateInputs(func(any) {
 			n++
 		})
 	case 1:
@@ -278,7 +278,7 @@ func count(fm *Frame, args ...interface{}) (int, error) {
 		if len := vals.Len(v); len >= 0 {
 			n = len
 		} else {
-			err := vals.Iterate(v, func(interface{}) bool {
+			err := vals.Iterate(v, func(any) bool {
 				n++
 				return true
 			})
@@ -370,8 +370,8 @@ type orderOptions struct {
 func (opt *orderOptions) SetDefaultOptions() {}
 
 func order(fm *Frame, opts orderOptions, inputs Inputs) error {
-	var values []interface{}
-	inputs(func(v interface{}) { values = append(values, v) })
+	var values []any
+	inputs(func(v any) { values = append(values, v) })
 
 	var errSort error
 	var lessFn func(i, j int) bool
@@ -380,11 +380,11 @@ func order(fm *Frame, opts orderOptions, inputs Inputs) error {
 			if errSort != nil {
 				return true
 			}
-			var args []interface{}
+			var args []any
 			if opts.Reverse {
-				args = []interface{}{values[j], values[i]}
+				args = []any{values[j], values[i]}
 			} else {
-				args = []interface{}{values[i], values[j]}
+				args = []any{values[i], values[j]}
 			}
 			outputs, err := fm.CaptureOutput(func(fm *Frame) error {
 				return opts.LessThan.Call(fm, args, NoOpts)

+ 4 - 4
pkg/eval/builtin_fn_styled.go

@@ -12,7 +12,7 @@ import (
 var errStyledSegmentArgType = errors.New("argument to styled-segment must be a string or a styled segment")
 
 func init() {
-	addBuiltinFns(map[string]interface{}{
+	addBuiltinFns(map[string]any{
 		"styled-segment": styledSegment,
 		"styled":         styled,
 	})
@@ -46,7 +46,7 @@ func init() {
 // Turns a string or ui.Segment into a new ui.Segment with the attributes
 // from the supplied options applied to it. If the input is already a Segment its
 // attributes are copied and modified.
-func styledSegment(options RawOptions, input interface{}) (*ui.Segment, error) {
+func styledSegment(options RawOptions, input any) (*ui.Segment, error) {
 	var text string
 	var style ui.Style
 
@@ -132,7 +132,7 @@ func styledSegment(options RawOptions, input interface{}) (*ui.Segment, error) {
 // put $s[0] $s[1]
 // ```
 
-func styled(fm *Frame, input interface{}, stylings ...interface{}) (ui.Text, error) {
+func styled(fm *Frame, input any, stylings ...any) (ui.Text, error) {
 	var text ui.Text
 
 	switch input := input.(type) {
@@ -160,7 +160,7 @@ func styled(fm *Frame, input interface{}, stylings ...interface{}) (ui.Text, err
 		case Callable:
 			for i, seg := range text {
 				vs, err := fm.CaptureOutput(func(fm *Frame) error {
-					return styling.Call(fm, []interface{}{seg}, NoOpts)
+					return styling.Call(fm, []any{seg}, NoOpts)
 				})
 				if err != nil {
 					return nil, err

+ 1 - 1
pkg/eval/builtin_ns.go

@@ -115,6 +115,6 @@ var builtinNs = BuildNsNamed("").AddVars(map[string]vars.Var{
 	"paths":     vars.NewEnvListVar("PATH"),
 })
 
-func addBuiltinFns(fns map[string]interface{}) {
+func addBuiltinFns(fns map[string]any) {
 	builtinNs.AddGoFns(fns)
 }

+ 3 - 3
pkg/eval/builtin_special.go

@@ -198,7 +198,7 @@ func (op *delElemOp) Range() diag.Ranging {
 }
 
 func (op *delElemOp) exec(fm *Frame) Exception {
-	var indices []interface{}
+	var indices []any
 	for _, indexOp := range op.indexOps {
 		indexValues, exc := indexOp.exec(fm)
 		if exc != nil {
@@ -436,7 +436,7 @@ type andOrOp struct {
 }
 
 func (op *andOrOp) exec(fm *Frame) Exception {
-	var lastValue interface{} = vals.Bool(op.init)
+	var lastValue any = vals.Bool(op.init)
 	out := fm.ValueOutput()
 	for _, argOp := range op.argOps {
 		values, exc := argOp.exec(fm)
@@ -632,7 +632,7 @@ func (op *forOp) exec(fm *Frame) Exception {
 
 	iterated := false
 	var errElement error
-	errIterate := vals.Iterate(iterable, func(v interface{}) bool {
+	errIterate := vals.Iterate(iterable, func(v any) bool {
 		iterated = true
 		err := variable.Set(v)
 		if err != nil {

+ 2 - 2
pkg/eval/builtin_special_test.go

@@ -172,9 +172,9 @@ var errBadVar = errors.New("bad var")
 
 type badVar struct{ allowedSets int }
 
-func (v *badVar) Get() interface{} { return nil }
+func (v *badVar) Get() any { return nil }
 
-func (v *badVar) Set(interface{}) error {
+func (v *badVar) Set(any) error {
 	if v.allowedSets == 0 {
 		return errBadVar
 	}

+ 3 - 3
pkg/eval/callable.go

@@ -3,12 +3,12 @@ package eval
 // Callable wraps the Call method.
 type Callable interface {
 	// Call calls the receiver in a Frame with arguments and options.
-	Call(fm *Frame, args []interface{}, opts map[string]interface{}) error
+	Call(fm *Frame, args []any, opts map[string]any) error
 }
 
 var (
 	// NoArgs is an empty argument list. It can be used as an argument to Call.
-	NoArgs = []interface{}{}
+	NoArgs = []any{}
 	// NoOpts is an empty option map. It can be used as an argument to Call.
-	NoOpts = map[string]interface{}{}
+	NoOpts = map[string]any{}
 )

+ 3 - 3
pkg/eval/closure.go

@@ -22,7 +22,7 @@ type Closure struct {
 	// The index of the rest argument. -1 if there is no rest argument.
 	RestArg     int
 	OptNames    []string
-	OptDefaults []interface{}
+	OptDefaults []any
 	SrcMeta     parse.Source
 	DefRange    diag.Ranging
 	op          effectOp
@@ -38,7 +38,7 @@ func (*Closure) Kind() string {
 }
 
 // Equal compares by address.
-func (c *Closure) Equal(rhs interface{}) bool {
+func (c *Closure) Equal(rhs any) bool {
 	return c == rhs
 }
 
@@ -53,7 +53,7 @@ func (c *Closure) Repr(int) string {
 }
 
 // Call calls a closure.
-func (c *Closure) Call(fm *Frame, args []interface{}, opts map[string]interface{}) error {
+func (c *Closure) Call(fm *Frame, args []any, opts map[string]any) error {
 	// Check number of arguments.
 	if c.RestArg != -1 {
 		if len(args) < len(c.ArgNames)-1 {

+ 6 - 6
pkg/eval/compile_effect.go

@@ -102,7 +102,7 @@ func (op *pipelineOp) exec(fm *Frame) Exception {
 			if e != nil {
 				return fm.errorpf(op, "failed to create pipe: %s", e)
 			}
-			ch := make(chan interface{}, pipelineChanBufferSize)
+			ch := make(chan any, pipelineChanBufferSize)
 			sendStop := make(chan struct{})
 			sendError := new(error)
 			readerGone := new(int32)
@@ -264,7 +264,7 @@ func (op *formOp) exec(fm *Frame) (errRet Exception) {
 		// There is a temporary assignment.
 		// Save variables.
 		var saveVars []vars.Var
-		var saveVals []interface{}
+		var saveVals []any
 		for _, lv := range op.tempLValues {
 			variable, err := derefLValue(fm, lv)
 			if err != nil {
@@ -338,7 +338,7 @@ func (op *formOp) exec(fm *Frame) (errRet Exception) {
 		return fm.errorp(cmd.headOp, err)
 	}
 
-	var args []interface{}
+	var args []any
 	for _, argOp := range cmd.argOps {
 		moreArgs, exc := argOp.exec(fm)
 		if exc != nil {
@@ -348,8 +348,8 @@ func (op *formOp) exec(fm *Frame) (errRet Exception) {
 	}
 
 	// TODO(xiaq): This conversion should be avoided.
-	convertedOpts := make(map[string]interface{})
-	exc := cmd.optsOp.exec(fm, func(k, v interface{}) Exception {
+	convertedOpts := make(map[string]any)
+	exc := cmd.optsOp.exec(fm, func(k, v any) Exception {
 		if ks, ok := k.(string); ok {
 			convertedOpts[ks] = v
 			return nil
@@ -389,7 +389,7 @@ func evalForCommand(fm *Frame, op valuesOp, what string) (Callable, error) {
 		Actual: vals.ReprPlain(value)})
 }
 
-func allTrue(vs []interface{}) bool {
+func allTrue(vs []any) bool {
 	for _, v := range vs {
 		if !vals.Bool(v) {
 			return false

+ 2 - 2
pkg/eval/compile_lvalue.go

@@ -167,7 +167,7 @@ func (op *assignOp) exec(fm *Frame) Exception {
 	return nil
 }
 
-func set(fm *Frame, r diag.Ranger, temp bool, variable vars.Var, value interface{}) Exception {
+func set(fm *Frame, r diag.Ranger, temp bool, variable vars.Var, value any) Exception {
 	if temp {
 		saved := variable.Get()
 		err := variable.Set(value)
@@ -207,7 +207,7 @@ func derefLValue(fm *Frame, lv lvalue) (vars.Var, error) {
 	if len(lv.indexOps) == 0 {
 		return variable, nil
 	}
-	indices := make([]interface{}, len(lv.indexOps))
+	indices := make([]any, len(lv.indexOps))
 	for i, op := range lv.indexOps {
 		values, exc := op.exec(fm)
 		if exc != nil {

+ 34 - 34
pkg/eval/compile_value.go

@@ -17,7 +17,7 @@ import (
 // An operation that produces values.
 type valuesOp interface {
 	diag.Ranger
-	exec(*Frame) ([]interface{}, Exception)
+	exec(*Frame) ([]any, Exception)
 }
 
 var outputCaptureBufferSize = 16
@@ -44,12 +44,12 @@ func (cp *compiler) compoundOp(n *parse.Compound) valuesOp {
 
 type loneTildeOp struct{ diag.Ranging }
 
-func (op loneTildeOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op loneTildeOp) exec(fm *Frame) ([]any, Exception) {
 	home, err := fsutil.GetHome("")
 	if err != nil {
 		return nil, fm.errorp(op, err)
 	}
-	return []interface{}{home}, nil
+	return []any{home}, nil
 }
 
 func (cp *compiler) compoundOps(ns []*parse.Compound) []valuesOp {
@@ -66,7 +66,7 @@ type compoundOp struct {
 	subops []valuesOp
 }
 
-func (op compoundOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op compoundOp) exec(fm *Frame) ([]any, Exception) {
 	// Accumulator.
 	vs, exc := op.subops[0].exec(fm)
 	if exc != nil {
@@ -85,7 +85,7 @@ func (op compoundOp) exec(fm *Frame) ([]interface{}, Exception) {
 		}
 	}
 	if op.tilde {
-		newvs := make([]interface{}, len(vs))
+		newvs := make([]any, len(vs))
 		for i, v := range vs {
 			tilded, err := doTilde(v)
 			if err != nil {
@@ -103,7 +103,7 @@ func (op compoundOp) exec(fm *Frame) ([]interface{}, Exception) {
 		}
 	}
 	if hasGlob {
-		newvs := make([]interface{}, 0, len(vs))
+		newvs := make([]any, 0, len(vs))
 		for _, v := range vs {
 			if gp, ok := v.(globPattern); ok {
 				results, err := doGlob(gp, fm.Interrupts())
@@ -120,8 +120,8 @@ func (op compoundOp) exec(fm *Frame) ([]interface{}, Exception) {
 	return vs, nil
 }
 
-func outerProduct(vs []interface{}, us []interface{}, f func(interface{}, interface{}) (interface{}, error)) ([]interface{}, error) {
-	ws := make([]interface{}, len(vs)*len(us))
+func outerProduct(vs []any, us []any, f func(any, any) (any, error)) ([]any, error) {
+	ws := make([]any, len(vs)*len(us))
 	nu := len(us)
 	for i, v := range vs {
 		for j, u := range us {
@@ -141,7 +141,7 @@ var (
 	ErrCannotDetermineUsername = errors.New("cannot determine user name from glob pattern")
 )
 
-func doTilde(v interface{}) (interface{}, error) {
+func doTilde(v any) (any, error) {
 	switch v := v.(type) {
 	case string:
 		s := v
@@ -226,7 +226,7 @@ type indexingOp struct {
 	indexOps []valuesOp
 }
 
-func (op *indexingOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op *indexingOp) exec(fm *Frame) ([]any, Exception) {
 	vs, exc := op.headOp.exec(fm)
 	if exc != nil {
 		return nil, exc
@@ -236,7 +236,7 @@ func (op *indexingOp) exec(fm *Frame) ([]interface{}, Exception) {
 		if exc != nil {
 			return nil, exc
 		}
-		newvs := make([]interface{}, 0, len(vs)*len(indices))
+		newvs := make([]any, 0, len(vs)*len(indices))
 		for _, v := range vs {
 			for _, index := range indices {
 				result, err := vals.Index(v, index)
@@ -267,7 +267,7 @@ func (cp *compiler) primaryOp(n *parse.Primary) valuesOp {
 		if err != nil {
 			cp.errorpf(n, "%s", err)
 		}
-		vs := []interface{}{
+		vs := []any{
 			globPattern{Pattern: glob.Pattern{Segments: []glob.Segment{seg}, DirOverride: ""},
 				Flags: 0, Buts: nil, TypeCb: nil}}
 		return literalValues(n, vs...)
@@ -307,7 +307,7 @@ type variableOp struct {
 	ref     *varRef
 }
 
-func (op variableOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op variableOp) exec(fm *Frame) ([]any, Exception) {
 	variable := deref(fm, op.ref)
 	if variable == nil {
 		return nil, fm.errorpf(op, "variable $%s not found", op.qname)
@@ -317,7 +317,7 @@ func (op variableOp) exec(fm *Frame) ([]interface{}, Exception) {
 		vs, err := vals.Collect(value)
 		return vs, fm.errorp(op, err)
 	}
-	return []interface{}{value}, nil
+	return []any{value}, nil
 }
 
 type listOp struct {
@@ -325,7 +325,7 @@ type listOp struct {
 	subops []valuesOp
 }
 
-func (op listOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op listOp) exec(fm *Frame) ([]any, Exception) {
 	list := vals.EmptyList
 	for _, subop := range op.subops {
 		moreValues, exc := subop.exec(fm)
@@ -336,7 +336,7 @@ func (op listOp) exec(fm *Frame) ([]interface{}, Exception) {
 			list = list.Conj(moreValue)
 		}
 	}
-	return []interface{}{list}, nil
+	return []any{list}, nil
 }
 
 type exceptionCaptureOp struct {
@@ -344,12 +344,12 @@ type exceptionCaptureOp struct {
 	subop effectOp
 }
 
-func (op exceptionCaptureOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op exceptionCaptureOp) exec(fm *Frame) ([]any, Exception) {
 	exc := op.subop.exec(fm)
 	if exc == nil {
-		return []interface{}{OK}, nil
+		return []any{OK}, nil
 	}
-	return []interface{}{exc}, nil
+	return []any{exc}, nil
 }
 
 type outputCaptureOp struct {
@@ -357,7 +357,7 @@ type outputCaptureOp struct {
 	subop effectOp
 }
 
-func (op outputCaptureOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op outputCaptureOp) exec(fm *Frame) ([]any, Exception) {
 	outPort, collect, err := CapturePort()
 	if err != nil {
 		return nil, fm.errorp(op, err)
@@ -444,7 +444,7 @@ type lambdaOp struct {
 	srcMeta       parse.Source
 }
 
-func (op *lambdaOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op *lambdaOp) exec(fm *Frame) ([]any, Exception) {
 	capture := &Ns{
 		make([]vars.Var, len(op.capture.infos)),
 		make([]staticVarInfo, len(op.capture.infos))}
@@ -457,7 +457,7 @@ func (op *lambdaOp) exec(fm *Frame) ([]interface{}, Exception) {
 			capture.infos[i] = fm.up.infos[info.index]
 		}
 	}
-	optDefaults := make([]interface{}, len(op.optDefaultOps))
+	optDefaults := make([]any, len(op.optDefaultOps))
 	for i, op := range op.optDefaultOps {
 		defaultValue, err := evalForValue(fm, op, "option default value")
 		if err != nil {
@@ -465,7 +465,7 @@ func (op *lambdaOp) exec(fm *Frame) ([]interface{}, Exception) {
 		}
 		optDefaults[i] = defaultValue
 	}
-	return []interface{}{&Closure{op.argNames, op.restArg, op.optNames, optDefaults, op.srcMeta, op.Range(), op.subop, op.newLocal, capture}}, nil
+	return []any{&Closure{op.argNames, op.restArg, op.optNames, optDefaults, op.srcMeta, op.Range(), op.subop, op.newLocal, capture}}, nil
 }
 
 type mapOp struct {
@@ -473,16 +473,16 @@ type mapOp struct {
 	pairsOp *mapPairsOp
 }
 
-func (op mapOp) exec(fm *Frame) ([]interface{}, Exception) {
+func (op mapOp) exec(fm *Frame) ([]any, Exception) {
 	m := vals.EmptyMap
-	exc := op.pairsOp.exec(fm, func(k, v interface{}) Exception {
+	exc := op.pairsOp.exec(fm, func(k, v any) Exception {
 		m = m.Assoc(k, v)
 		return nil
 	})
 	if exc != nil {
 		return nil, exc
 	}
-	return []interface{}{m}, nil
+	return []any{m}, nil
 }
 
 func (cp *compiler) mapPairs(pairs []*parse.MapPair) *mapPairsOp {
@@ -510,7 +510,7 @@ type mapPairsOp struct {
 	ends      []int
 }
 
-func (op *mapPairsOp) exec(fm *Frame, f func(k, v interface{}) Exception) Exception {
+func (op *mapPairsOp) exec(fm *Frame, f func(k, v any) Exception) Exception {
 	for i := range op.keysOps {
 		keys, exc := op.keysOps[i].exec(fm)
 		if exc != nil {
@@ -536,14 +536,14 @@ func (op *mapPairsOp) exec(fm *Frame, f func(k, v interface{}) Exception) Except
 
 type literalValuesOp struct {
 	diag.Ranging
-	values []interface{}
+	values []any
 }
 
-func (op literalValuesOp) exec(*Frame) ([]interface{}, Exception) {
+func (op literalValuesOp) exec(*Frame) ([]any, Exception) {
 	return op.values, nil
 }
 
-func literalValues(r diag.Ranger, vs ...interface{}) valuesOp {
+func literalValues(r diag.Ranger, vs ...any) valuesOp {
 	return literalValuesOp{r.Range(), vs}
 }
 
@@ -552,8 +552,8 @@ type seqValuesOp struct {
 	subops []valuesOp
 }
 
-func (op seqValuesOp) exec(fm *Frame) ([]interface{}, Exception) {
-	var values []interface{}
+func (op seqValuesOp) exec(fm *Frame) ([]any, Exception) {
+	var values []any
 	for _, subop := range op.subops {
 		moreValues, exc := subop.exec(fm)
 		if exc != nil {
@@ -566,9 +566,9 @@ func (op seqValuesOp) exec(fm *Frame) ([]interface{}, Exception) {
 
 type nopValuesOp struct{ diag.Ranging }
 
-func (nopValuesOp) exec(fm *Frame) ([]interface{}, Exception) { return nil, nil }
+func (nopValuesOp) exec(fm *Frame) ([]any, Exception) { return nil, nil }
 
-func evalForValue(fm *Frame, op valuesOp, what string) (interface{}, Exception) {
+func evalForValue(fm *Frame, op valuesOp, what string) (any, Exception) {
 	values, exc := op.exec(fm)
 	if exc != nil {
 		return nil, exc

+ 2 - 2
pkg/eval/compiler.go

@@ -83,7 +83,7 @@ func (op nsOp) prepare(fm *Frame) (*Ns, func() Exception) {
 
 const compilationErrorType = "compilation error"
 
-func (cp *compiler) errorpf(r diag.Ranger, format string, args ...interface{}) {
+func (cp *compiler) errorpf(r diag.Ranger, format string, args ...any) {
 	// The panic is caught by the recover in compile above.
 	panic(&diag.Error{
 		Type:    compilationErrorType,
@@ -93,7 +93,7 @@ func (cp *compiler) errorpf(r diag.Ranger, format string, args ...interface{}) {
 
 // GetCompilationError returns a *diag.Error if the given value is a compilation
 // error. Otherwise it returns nil.
-func GetCompilationError(e interface{}) *diag.Error {
+func GetCompilationError(e any) *diag.Error {
 	if e, ok := e.(*diag.Error); ok && e.Type == compilationErrorType {
 		return e
 	}

+ 5 - 5
pkg/eval/eval.go

@@ -172,8 +172,8 @@ func NewEvaler() *Evaler {
 		AddVar("notify-bg-job-success",
 			vars.FromPtrWithMutex(&ev.notifyBgJobSuccess, &ev.mu)).
 		AddVar("num-bg-jobs",
-			vars.FromGet(func() interface{} { return strconv.Itoa(ev.getNumBgJobs()) })).
-		AddVar("args", vars.FromGet(func() interface{} { return ev.Args })))
+			vars.FromGet(func() any { return strconv.Itoa(ev.getNumBgJobs()) })).
+		AddVar("args", vars.FromGet(func() any { return ev.Args })))
 
 	// Install the "builtin" module after extension is complete.
 	ev.modules["builtin"] = ev.builtin
@@ -185,7 +185,7 @@ func adaptChdirHook(name string, ev *Evaler, pfns *vals.List) func(string) {
 	return func(path string) {
 		ports, cleanup := PortsFromStdFiles(ev.ValuePrefix())
 		defer cleanup()
-		callCfg := CallCfg{Args: []interface{}{path}, From: "[hook " + name + "]"}
+		callCfg := CallCfg{Args: []any{path}, From: "[hook " + name + "]"}
 		evalCfg := EvalCfg{Ports: ports[:]}
 		for it := (*pfns).Iterator(); it.HasElem(); it.Next() {
 			fn, ok := it.Elem().(Callable)
@@ -406,9 +406,9 @@ func (ev *Evaler) Eval(src parse.Source, cfg EvalCfg) error {
 // CallCfg keeps configuration for the (*Evaler).Call method.
 type CallCfg struct {
 	// Arguments to pass to the the function.
-	Args []interface{}
+	Args []any
 	// Options to pass to the function.
-	Opts map[string]interface{}
+	Opts map[string]any
 	// The name of the internal source that is calling the function.
 	From string
 }

+ 2 - 2
pkg/eval/eval_test.go

@@ -117,8 +117,8 @@ func TestCall(t *testing.T) {
 	passedOpt := "opt value"
 	ev.Call(fn,
 		CallCfg{
-			Args: []interface{}{passedArg},
-			Opts: map[string]interface{}{"opt": passedOpt},
+			Args: []any{passedArg},
+			Opts: map[string]any{"opt": passedOpt},
 			From: "[TestCall]"},
 		EvalCfg{})
 

+ 8 - 8
pkg/eval/evaltest/evaltest.go

@@ -39,7 +39,7 @@ type Case struct {
 }
 
 type result struct {
-	ValueOut  []interface{}
+	ValueOut  []any
 	BytesOut  []byte
 	StderrOut []byte
 
@@ -89,7 +89,7 @@ func (c Case) Passes(f func(t *testing.T)) Case {
 
 // Puts returns an altered Case that requires the source code to produce the
 // specified values in the value channel when evaluated.
-func (c Case) Puts(vs ...interface{}) Case {
+func (c Case) Puts(vs ...any) Case {
 	c.want.ValueOut = vs
 	return c
 }
@@ -220,11 +220,11 @@ func evalAndCollect(t *testing.T, ev *eval.Evaler, texts []string) result {
 
 // Like eval.CapturePort, but captures values and bytes separately. Also panics
 // if it cannot create a pipe.
-func capturePort() (*eval.Port, func() ([]interface{}, []byte)) {
-	var values []interface{}
+func capturePort() (*eval.Port, func() ([]any, []byte)) {
+	var values []any
 	var bytes []byte
 	port, done, err := eval.PipePort(
-		func(ch <-chan interface{}) {
+		func(ch <-chan any) {
 			for v := range ch {
 				values = append(values, v)
 			}
@@ -235,13 +235,13 @@ func capturePort() (*eval.Port, func() ([]interface{}, []byte)) {
 	if err != nil {
 		panic(err)
 	}
-	return port, func() ([]interface{}, []byte) {
+	return port, func() ([]any, []byte) {
 		done()
 		return values, bytes
 	}
 }
 
-func matchOut(want, got []interface{}) bool {
+func matchOut(want, got []any) bool {
 	if len(got) != len(want) {
 		return false
 	}
@@ -253,7 +253,7 @@ func matchOut(want, got []interface{}) bool {
 	return true
 }
 
-func match(got, want interface{}) bool {
+func match(got, want any) bool {
 	switch got := got.(type) {
 	case float64:
 		// Special-case float64 to correctly handle NaN and support

+ 1 - 1
pkg/eval/exception.go

@@ -124,7 +124,7 @@ func (exc *exception) Repr(indent int) string {
 }
 
 // Equal compares by address.
-func (exc *exception) Equal(rhs interface{}) bool {
+func (exc *exception) Equal(rhs any) bool {
 	return exc == rhs
 }
 

+ 2 - 2
pkg/eval/external_cmd.go

@@ -41,7 +41,7 @@ func (e externalCmd) Kind() string {
 	return "fn"
 }
 
-func (e externalCmd) Equal(a interface{}) bool {
+func (e externalCmd) Equal(a any) bool {
 	return e == a
 }
 
@@ -54,7 +54,7 @@ func (e externalCmd) Repr(int) string {
 }
 
 // Call calls an external command.
-func (e externalCmd) Call(fm *Frame, argVals []interface{}, opts map[string]interface{}) error {
+func (e externalCmd) Call(fm *Frame, argVals []any, opts map[string]any) error {
 	if len(opts) > 0 {
 		return ErrExternalCmdOpts
 	}

+ 7 - 7
pkg/eval/frame.go

@@ -87,7 +87,7 @@ func (fm *Frame) Close() error {
 }
 
 // InputChan returns a channel from which input can be read.
-func (fm *Frame) InputChan() chan interface{} {
+func (fm *Frame) InputChan() chan any {
 	return fm.ports[0].Chan
 }
 
@@ -113,9 +113,9 @@ func (fm *Frame) ErrorFile() *os.File {
 }
 
 // IterateInputs calls the passed function for each input element.
-func (fm *Frame) IterateInputs(f func(interface{})) {
+func (fm *Frame) IterateInputs(f func(any)) {
 	var wg sync.WaitGroup
-	inputs := make(chan interface{})
+	inputs := make(chan any)
 
 	wg.Add(2)
 	go func() {
@@ -138,7 +138,7 @@ func (fm *Frame) IterateInputs(f func(interface{})) {
 	}
 }
 
-func linesToChan(r io.Reader, ch chan<- interface{}) {
+func linesToChan(r io.Reader, ch chan<- any) {
 	filein := bufio.NewReader(r)
 	for {
 		line, err := filein.ReadString('\n')
@@ -179,7 +179,7 @@ func (fm *Frame) forkWithOutput(name string, p *Port) *Frame {
 }
 
 // CaptureOutput captures the output of a given callback that operates on a Frame.
-func (fm *Frame) CaptureOutput(f func(*Frame) error) ([]interface{}, error) {
+func (fm *Frame) CaptureOutput(f func(*Frame) error) ([]any, error) {
 	outPort, collect, err := CapturePort()
 	if err != nil {
 		return nil, err
@@ -189,7 +189,7 @@ func (fm *Frame) CaptureOutput(f func(*Frame) error) ([]interface{}, error) {
 }
 
 // PipeOutput calls a callback with output piped to the given output handlers.
-func (fm *Frame) PipeOutput(f func(*Frame) error, vCb func(<-chan interface{}), bCb func(*os.File)) error {
+func (fm *Frame) PipeOutput(f func(*Frame) error, vCb func(<-chan any), bCb func(*os.File)) error {
 	outPort, done, err := PipePort(vCb, bCb)
 	if err != nil {
 		return err
@@ -223,7 +223,7 @@ func (fm *Frame) errorp(r diag.Ranger, e error) Exception {
 }
 
 // Returns an Exception with specified range and error text.
-func (fm *Frame) errorpf(r diag.Ranger, format string, args ...interface{}) Exception {
+func (fm *Frame) errorpf(r diag.Ranger, format string, args ...any) Exception {
 	return fm.errorp(r, fmt.Errorf(format, args...))
 }
 

+ 5 - 5
pkg/eval/glob.go

@@ -65,7 +65,7 @@ var runeMatchers = map[string]func(rune) bool{
 
 func (gp globPattern) Kind() string { return "glob-pattern" }
 
-func (gp globPattern) Index(k interface{}) (interface{}, error) {
+func (gp globPattern) Index(k any) (any, error) {
 	modifierv, ok := k.(string)
 	if !ok {
 		return nil, ErrModifierMustBeString
@@ -132,7 +132,7 @@ func (gp globPattern) Index(k interface{}) (interface{}, error) {
 	return gp, nil
 }
 
-func (gp globPattern) Concat(v interface{}) (interface{}, error) {
+func (gp globPattern) Concat(v any) (any, error) {
 	switch rhs := v.(type) {
 	case string:
 		gp.append(stringToSegments(rhs)...)
@@ -155,7 +155,7 @@ func (gp globPattern) Concat(v interface{}) (interface{}, error) {
 	return nil, vals.ErrConcatNotImplemented
 }
 
-func (gp globPattern) RConcat(v interface{}) (interface{}, error) {
+func (gp globPattern) RConcat(v any) (any, error) {
 	switch lhs := v.(type) {
 	case string:
 		segs := stringToSegments(lhs)
@@ -228,13 +228,13 @@ func stringToSegments(s string) []glob.Segment {
 	return segs
 }
 
-func doGlob(gp globPattern, abort <-chan struct{}) ([]interface{}, error) {
+func doGlob(gp globPattern, abort <-chan struct{}) ([]any, error) {
 	but := make(map[string]struct{})
 	for _, s := range gp.Buts {
 		but[s] = struct{}{}
 	}
 
-	vs := make([]interface{}, 0)
+	vs := make([]any, 0)
 	if !gp.Glob(func(pathInfo glob.PathInfo) bool {
 		select {
 		case <-abort:

+ 7 - 7
pkg/eval/go_fn.go

@@ -36,7 +36,7 @@ func (e WrongArgType) Unwrap() error {
 
 type goFn struct {
 	name string
-	impl interface{}
+	impl any
 
 	// Type information of impl.
 
@@ -63,7 +63,7 @@ type optionsPtr interface {
 // Inputs is the type that the last parameter of a Go-native function can take.
 // When that is the case, it is a callback to get inputs. See the doc of GoFn
 // for details.
-type Inputs func(func(interface{}))
+type Inputs func(func(any))
 
 var (
 	frameType      = reflect.TypeOf((*Frame)(nil))
@@ -107,7 +107,7 @@ var (
 // If the last return value has nominal type error and is not nil, it is turned
 // into an exception and no return value is written. If the last return value is
 // a nil error, it is ignored.
-func NewGoFn(name string, impl interface{}) Callable {
+func NewGoFn(name string, impl any) Callable {
 	implType := reflect.TypeOf(impl)
 	b := &goFn{name: name, impl: impl}
 
@@ -149,7 +149,7 @@ func (*goFn) Kind() string {
 }
 
 // Equal compares identity.
-func (b *goFn) Equal(rhs interface{}) bool {
+func (b *goFn) Equal(rhs any) bool {
 	return b == rhs
 }
 
@@ -168,7 +168,7 @@ func (b *goFn) Repr(int) string {
 var errorType = reflect.TypeOf((*error)(nil)).Elem()
 
 // Call calls the implementation using reflection.
-func (b *goFn) Call(f *Frame, args []interface{}, opts map[string]interface{}) error {
+func (b *goFn) Call(f *Frame, args []any, opts map[string]any) error {
 	if b.variadicArg != nil {
 		if len(args) < len(b.normalArgs) {
 			return errs.ArityMismatch{What: "arguments",
@@ -233,9 +233,9 @@ func (b *goFn) Call(f *Frame, args []interface{}, opts map[string]interface{}) e
 			if !vals.CanIterate(iterable) {
 				return fmt.Errorf("%s cannot be iterated", vals.Kind(iterable))
 			}
-			inputs = func(f func(interface{})) {
+			inputs = func(f func(any)) {
 				// CanIterate(iterable) is true
-				_ = vals.Iterate(iterable, func(v interface{}) bool {
+				_ = vals.Iterate(iterable, func(v any) bool {
 					f(v)
 					return true
 				})

+ 5 - 5
pkg/eval/go_fn_test.go

@@ -148,20 +148,20 @@ func TestGoFn_RawOptions(t *testing.T) {
 	)
 }
 
-func f(body interface{}) func(*Evaler) {
+func f(body any) func(*Evaler) {
 	return func(ev *Evaler) {
 		ev.ExtendGlobal(BuildNs().AddGoFn("f", body))
 	}
 }
 
-func testInputs(t *testing.T, wantValues ...interface{}) func(Inputs) {
+func testInputs(t *testing.T, wantValues ...any) func(Inputs) {
 	return func(i Inputs) {
 		t.Helper()
-		var values []interface{}
-		i(func(x interface{}) {
+		var values []any
+		i(func(x any) {
 			values = append(values, x)
 		})
-		wantValues := []interface{}{"foo", "bar"}
+		wantValues := []any{"foo", "bar"}
 		if !reflect.DeepEqual(values, wantValues) {
 			t.Errorf("Inputs parameter didn't get supplied inputs")
 		}

+ 1 - 1
pkg/eval/node_utils.go

@@ -17,7 +17,7 @@ func stringLiteralOrError(cp *compiler, n *parse.Compound, what string) string {
 }
 
 type errorpfer interface {
-	errorpf(r diag.Ranger, fmt string, args ...interface{})
+	errorpf(r diag.Ranger, fmt string, args ...any)
 }
 
 // argsWalker is used by builtin special forms to implement argument parsing.

+ 5 - 5
pkg/eval/ns.go

@@ -81,7 +81,7 @@ func (ns *Ns) Hash() uint32 {
 }
 
 // Equal returns whether rhs has the same identity as ns.
-func (ns *Ns) Equal(rhs interface{}) bool {
+func (ns *Ns) Equal(rhs any) bool {
 	if ns2, ok := rhs.(*Ns); ok {
 		return ns == ns2
 	}
@@ -96,7 +96,7 @@ func (ns *Ns) Repr(int) string {
 // Index looks up a variable with the given name, and returns its value if it
 // exists. This is only used for introspection from Elvish code; for
 // introspection from Go code, use IndexName.
-func (ns *Ns) Index(k interface{}) (interface{}, bool) {
+func (ns *Ns) Index(k any) (any, bool) {
 	if ks, ok := k.(string); ok {
 		variable := ns.IndexString(ks)
 		if variable == nil {
@@ -128,7 +128,7 @@ func (ns *Ns) lookup(k string) (staticVarInfo, int) {
 }
 
 // IterateKeys produces the names of all the variables in this Ns.
-func (ns *Ns) IterateKeys(f func(interface{}) bool) {
+func (ns *Ns) IterateKeys(f func(any) bool) {
 	for _, info := range ns.infos {
 		if info.deleted {
 			continue
@@ -210,12 +210,12 @@ func (nb NsBuilder) AddNs(name string, v Nser) NsBuilder {
 }
 
 // AddGoFn adds a Go function. The resulting variable will be read-only.
-func (nb NsBuilder) AddGoFn(name string, impl interface{}) NsBuilder {
+func (nb NsBuilder) AddGoFn(name string, impl any) NsBuilder {
 	return nb.AddFn(name, NewGoFn(nb.prefix+name, impl))
 }
 
 // AddGoFns adds Go functions. The resulting variables will be read-only.
-func (nb NsBuilder) AddGoFns(fns map[string]interface{}) NsBuilder {
+func (nb NsBuilder) AddGoFns(fns map[string]any) NsBuilder {
 	for name, impl := range fns {
 		nb.AddGoFn(name, impl)
 	}

+ 2 - 2
pkg/eval/options.go

@@ -20,7 +20,7 @@ func (e UnknownOption) Error() string {
 // RawOptions is the type of an argument a Go-native function can take to
 // declare that it wants to parse options itself. See the doc of NewGoFn for
 // details.
-type RawOptions map[string]interface{}
+type RawOptions map[string]any
 
 // Takes a raw option map and a pointer to a struct, and populate the struct
 // with options. A field named FieldName corresponds to the option named
@@ -29,7 +29,7 @@ type RawOptions map[string]interface{}
 //
 // Similar to vals.ScanMapToGo, but requires rawOpts to contain a subset of keys
 // supported by the struct.
-func scanOptions(rawOpts RawOptions, ptr interface{}) error {
+func scanOptions(rawOpts RawOptions, ptr any) error {
 	_, keyIdx := vals.StructFieldsInfo(reflect.TypeOf(ptr).Elem())
 	structValue := reflect.ValueOf(ptr).Elem()
 	for k, v := range rawOpts {

+ 1 - 1
pkg/eval/options_test.go

@@ -17,7 +17,7 @@ func (o opts) Equal(p opts) bool { return o == p }
 
 func TestScanOptions(t *testing.T) {
 	// A wrapper of ScanOptions, to make it easier to test
-	wrapper := func(src RawOptions, dstInit interface{}) (interface{}, error) {
+	wrapper := func(src RawOptions, dstInit any) (any, error) {
 		ptr := reflect.New(reflect.TypeOf(dstInit))
 		ptr.Elem().Set(reflect.ValueOf(dstInit))
 		err := scanOptions(src, ptr.Interface())

+ 1 - 1
pkg/eval/plugin_gccgo.go

@@ -12,6 +12,6 @@ func pluginOpen(name string) (pluginStub, error) {
 	return pluginStub{}, errPluginNotImplemented
 }
 
-func (pluginStub) Lookup(symName string) (interface{}, error) {
+func (pluginStub) Lookup(symName string) (any, error) {
 	return nil, errPluginNotImplemented
 }

+ 16 - 16
pkg/eval/port.go

@@ -16,7 +16,7 @@ import (
 // Port conveys data stream. It always consists of a byte band and a channel band.
 type Port struct {
 	File      *os.File
-	Chan      chan interface{}
+	Chan      chan any
 	closeFile bool
 	closeChan bool
 
@@ -84,14 +84,14 @@ var (
 	DummyPorts = []*Port{DummyInputPort, DummyOutputPort, DummyOutputPort}
 )
 
-func getClosedChan() chan interface{} {
-	ch := make(chan interface{})
+func getClosedChan() chan any {
+	ch := make(chan any)
 	close(ch)
 	return ch
 }
 
-func getBlackholeChan() chan interface{} {
-	ch := make(chan interface{})
+func getBlackholeChan() chan any {
+	ch := make(chan any)
 	go func() {
 		for range ch {
 		}
@@ -112,12 +112,12 @@ func getDevNull() *os.File {
 // piped. The supplied functions are called on a separate goroutine with the
 // read ends of the value and byte components of the port. It also returns a
 // function to clean up the port and wait for the callbacks to finish.
-func PipePort(vCb func(<-chan interface{}), bCb func(*os.File)) (*Port, func(), error) {
+func PipePort(vCb func(<-chan any), bCb func(*os.File)) (*Port, func(), error) {
 	r, w, err := os.Pipe()
 	if err != nil {
 		return nil, nil, err
 	}
-	ch := make(chan interface{}, outputCaptureBufferSize)
+	ch := make(chan any, outputCaptureBufferSize)
 
 	var wg sync.WaitGroup
 	wg.Add(2)
@@ -142,11 +142,11 @@ func PipePort(vCb func(<-chan interface{}), bCb func(*os.File)) (*Port, func(),
 // CapturePort returns an output *Port whose value and byte components are
 // both connected to an internal pipe that saves the output. It also returns a
 // function to call to obtain the captured output.
-func CapturePort() (*Port, func() []interface{}, error) {
-	vs := []interface{}{}
+func CapturePort() (*Port, func() []any, error) {
+	vs := []any{}
 	var m sync.Mutex
 	port, done, err := PipePort(
-		func(ch <-chan interface{}) {
+		func(ch <-chan any) {
 			for v := range ch {
 				m.Lock()
 				vs = append(vs, v)
@@ -174,7 +174,7 @@ func CapturePort() (*Port, func() []interface{}, error) {
 	if err != nil {
 		return nil, nil, err
 	}
-	return port, func() []interface{} {
+	return port, func() []any {
 		done()
 		return vs
 	}, nil
@@ -191,7 +191,7 @@ func StringCapturePort() (*Port, func() []string, error) {
 		lines = append(lines, line)
 	}
 	port, done, err := PipePort(
-		func(ch <-chan interface{}) {
+		func(ch <-chan any) {
 			for v := range ch {
 				addLine("▶ " + vals.ToString(v))
 			}
@@ -227,7 +227,7 @@ const filePortChanSize = 32
 // each value to the file, prepending with a prefix. It also returns a cleanup
 // function, which should be called when the *Port is no longer needed.
 func FilePort(f *os.File, valuePrefix string) (*Port, func()) {
-	ch := make(chan interface{}, filePortChanSize)
+	ch := make(chan any, filePortChanSize)
 	relayDone := make(chan struct{})
 	go func() {
 		for v := range ch {
@@ -267,16 +267,16 @@ func PortsFromFiles(files [3]*os.File, prefix string) ([]*Port, func()) {
 // for the back-chanel signal that the reader of the channel has gone.
 type ValueOutput interface {
 	// Outputs a value. Returns errs.ReaderGone if the reader is gone.
-	Put(v interface{}) error
+	Put(v any) error
 }
 
 type valueOutput struct {
-	data      chan<- interface{}
+	data      chan<- any
 	sendStop  <-chan struct{}
 	sendError *error
 }
 
-func (vo valueOutput) Put(v interface{}) error {
+func (vo valueOutput) Put(v any) error {
 	select {
 	case vo.data <- v:
 		return nil

+ 1 - 1
pkg/eval/purely_eval.go

@@ -59,7 +59,7 @@ func (ev *Evaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (strin
 // If this cannot be done, it returns nil.
 //
 // Currently, only string literals and variables with no @ can be evaluated.
-func (ev *Evaler) PurelyEvalPrimary(pn *parse.Primary) interface{} {
+func (ev *Evaler) PurelyEvalPrimary(pn *parse.Primary) any {
 	switch pn.Type {
 	case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted:
 		return pn.Value

+ 2 - 2
pkg/eval/pwd.go

@@ -23,7 +23,7 @@ var Getwd func() (string, error) = os.Getwd
 
 // Get returns the current working directory. It returns "/unknown/pwd" when
 // it cannot be determined.
-func (pwdVar) Get() interface{} {
+func (pwdVar) Get() any {
 	pwd, err := Getwd()
 	if err != nil {
 		// This should really use the path separator appropriate for the
@@ -36,7 +36,7 @@ func (pwdVar) Get() interface{} {
 }
 
 // Set changes the current working directory.
-func (pwd pwdVar) Set(v interface{}) error {
+func (pwd pwdVar) Set(v any) error {
 	path, ok := v.(string)
 	if !ok {
 		return vars.ErrPathMustBeString

+ 2 - 2
pkg/eval/vals/aliased_types.go

@@ -17,7 +17,7 @@ type List = vector.Vector
 var EmptyList = vector.Empty
 
 // MakeList creates a new List from values.
-func MakeList(vs ...interface{}) vector.Vector {
+func MakeList(vs ...any) vector.Vector {
 	vec := vector.Empty
 	for _, v := range vs {
 		vec = vec.Conj(v)
@@ -42,7 +42,7 @@ var EmptyMap = hashmap.New(Equal, Hash)
 
 // MakeMap creates a map from arguments that are alternately keys and values. It
 // panics if the number of arguments is odd.
-func MakeMap(a ...interface{}) hashmap.Map {
+func MakeMap(a ...any) hashmap.Map {
 	if len(a)%2 == 1 {
 		panic("odd number of arguments to MakeMap")
 	}

+ 4 - 4
pkg/eval/vals/assoc.go

@@ -8,7 +8,7 @@ import (
 type Assocer interface {
 	// Assoc returns a slightly modified version of the receiver with key k
 	// associated with value v.
-	Assoc(k, v interface{}) (interface{}, error)
+	Assoc(k, v any) (any, error)
 }
 
 var (
@@ -21,7 +21,7 @@ var (
 // the container, in which the key associated with the value. It is implemented
 // for the builtin type string, List and Map types, StructMap types, and types
 // satisfying the Assocer interface. For other types, it returns an error.
-func Assoc(a, k, v interface{}) (interface{}, error) {
+func Assoc(a, k, v any) (any, error) {
 	switch a := a.(type) {
 	case string:
 		return assocString(a, k, v)
@@ -35,7 +35,7 @@ func Assoc(a, k, v interface{}) (interface{}, error) {
 	return nil, errAssocUnsupported
 }
 
-func assocString(s string, k, v interface{}) (interface{}, error) {
+func assocString(s string, k, v any) (any, error) {
 	i, j, err := convertStringIndex(k, s)
 	if err != nil {
 		return nil, err
@@ -47,7 +47,7 @@ func assocString(s string, k, v interface{}) (interface{}, error) {
 	return s[:i] + repl + s[j:], nil
 }
 
-func assocList(l List, k, v interface{}) (interface{}, error) {
+func assocList(l List, k, v any) (any, error) {
 	index, err := ConvertListIndex(k, l.Len())
 	if err != nil {
 		return nil, err

+ 1 - 1
pkg/eval/vals/assoc_test.go

@@ -12,7 +12,7 @@ type customAssocer struct{}
 
 var errCustomAssoc = errors.New("custom assoc error")
 
-func (a customAssocer) Assoc(k, v interface{}) (interface{}, error) {
+func (a customAssocer) Assoc(k, v any) (any, error) {
 	return "custom result", errCustomAssoc
 }
 

+ 1 - 1
pkg/eval/vals/bool.go

@@ -9,7 +9,7 @@ type Booler interface {
 // Bool converts a value to bool. It is implemented for nil, the builtin bool
 // type, and types implementing the Booler interface. For all other values, it
 // returns true.
-func Bool(v interface{}) bool {
+func Bool(v any) bool {
 	switch v := v.(type) {
 	case nil:
 		return false

+ 4 - 4
pkg/eval/vals/concat.go

@@ -11,12 +11,12 @@ type Concatter interface {
 	// Concat concatenates the receiver with another value, the receiver being
 	// the left operand. If concatenation is not supported for the given value,
 	// the method can return the special error type ErrCatNotImplemented.
-	Concat(v interface{}) (interface{}, error)
+	Concat(v any) (any, error)
 }
 
 // RConcatter wraps the RConcat method. See Concat for how it is used.
 type RConcatter interface {
-	RConcat(v interface{}) (interface{}, error)
+	RConcat(v any) (any, error)
 }
 
 // ErrConcatNotImplemented is a special error value used to signal that
@@ -37,7 +37,7 @@ func (err cannotConcat) Error() string {
 // lhs.Concat(rhs). If lhs doesn't implement the interface or returned
 // ErrConcatNotImplemented, it then calls rhs.RConcat(lhs). If all attempts
 // fail, it returns nil and an error.
-func Concat(lhs, rhs interface{}) (interface{}, error) {
+func Concat(lhs, rhs any) (any, error) {
 	if v, ok := tryConcatBuiltins(lhs, rhs); ok {
 		return v, nil
 	}
@@ -59,7 +59,7 @@ func Concat(lhs, rhs interface{}) (interface{}, error) {
 	return nil, cannotConcat{Kind(lhs), Kind(rhs)}
 }
 
-func tryConcatBuiltins(lhs, rhs interface{}) (interface{}, bool) {
+func tryConcatBuiltins(lhs, rhs any) (any, bool) {
 	switch lhs := lhs.(type) {
 	case string, int, *big.Int, *big.Rat, float64:
 		switch rhs := rhs.(type) {

+ 2 - 2
pkg/eval/vals/concat_test.go

@@ -15,7 +15,7 @@ type concatter struct{}
 
 var errBadFloat64 = errors.New("float64 is bad")
 
-func (concatter) Concat(rhs interface{}) (interface{}, error) {
+func (concatter) Concat(rhs any) (any, error) {
 	switch rhs := rhs.(type) {
 	case string:
 		return "concatter " + rhs, nil
@@ -29,7 +29,7 @@ func (concatter) Concat(rhs interface{}) (interface{}, error) {
 // An implementation of RConcatter that accepts all types.
 type rconcatter struct{}
 
-func (rconcatter) RConcat(lhs interface{}) (interface{}, error) {
+func (rconcatter) RConcat(lhs any) (any, error) {
 	return "rconcatter", nil
 }
 

+ 10 - 10
pkg/eval/vals/conversion.go

@@ -69,7 +69,7 @@ var (
 // conversion, and returns an error if the conversion fails. In other cases,
 // this function just tries to perform "*ptr = src" via reflection and returns
 // an error if the assignment can't be done.
-func ScanToGo(src interface{}, ptr interface{}) error {
+func ScanToGo(src any, ptr any) error {
 	switch ptr := ptr.(type) {
 	case *int:
 		i, err := elvToInt(src)
@@ -116,7 +116,7 @@ func ScanToGo(src interface{}, ptr interface{}) error {
 	}
 }
 
-func elvToInt(arg interface{}) (int, error) {
+func elvToInt(arg any) (int, error) {
 	switch arg := arg.(type) {
 	case int:
 		return arg, nil
@@ -131,7 +131,7 @@ func elvToInt(arg interface{}) (int, error) {
 	}
 }
 
-func elvToNum(arg interface{}) (Num, error) {
+func elvToNum(arg any) (Num, error) {
 	switch arg := arg.(type) {
 	case int, *big.Int, *big.Rat, float64:
 		return arg, nil
@@ -146,7 +146,7 @@ func elvToNum(arg interface{}) (Num, error) {
 	}
 }
 
-func elvToRune(arg interface{}) (rune, error) {
+func elvToRune(arg any) (rune, error) {
 	ss, ok := arg.(string)
 	if !ok {
 		return -1, errMustBeString
@@ -164,7 +164,7 @@ func elvToRune(arg interface{}) (rune, error) {
 
 // ScanListToGo converts a List to a slice, using ScanToGo to convert each
 // element.
-func ScanListToGo(src List, ptr interface{}) error {
+func ScanListToGo(src List, ptr any) error {
 	n := src.Len()
 	values := reflect.MakeSlice(reflect.TypeOf(ptr).Elem(), n, n)
 	i := 0
@@ -181,16 +181,16 @@ func ScanListToGo(src List, ptr interface{}) error {
 
 // Optional wraps the last pointer passed to ScanListElementsToGo, to indicate
 // that it is optional.
-func Optional(ptr interface{}) interface{} { return optional{ptr} }
+func Optional(ptr any) any { return optional{ptr} }
 
-type optional struct{ ptr interface{} }
+type optional struct{ ptr any }
 
 // ScanListElementsToGo unpacks elements from a list, storing the each element
 // in the given pointers with ScanToGo.
 //
 // The last pointer may be wrapped with Optional to indicate that it is
 // optional.
-func ScanListElementsToGo(src List, ptrs ...interface{}) error {
+func ScanListElementsToGo(src List, ptrs ...any) error {
 	if o, ok := ptrs[len(ptrs)-1].(optional); ok {
 		switch src.Len() {
 		case len(ptrs) - 1:
@@ -222,7 +222,7 @@ func ScanListElementsToGo(src List, ptrs ...interface{}) error {
 //
 // The map may contains keys that don't correspond to struct fields, and it
 // doesn't have to contain all keys that correspond to struct fields.
-func ScanMapToGo(src Map, ptr interface{}) error {
+func ScanMapToGo(src Map, ptr any) error {
 	// Iterate over the struct keys instead of the map: since extra keys are
 	// allowed, the map may be very big, while the size of the struct is bound.
 	keys, _ := StructFieldsInfo(reflect.TypeOf(ptr).Elem())
@@ -283,7 +283,7 @@ func makeStructFieldsInfo(t reflect.Type) structFieldsInfo {
 //
 // Exact numbers are normalized to the smallest types that can hold them, and
 // runes are converted to strings. Values of other types are returned unchanged.
-func FromGo(a interface{}) interface{} {
+func FromGo(a any) any {
 	switch a := a.(type) {
 	case *big.Int:
 		return NormalizeBigInt(a)

+ 16 - 16
pkg/eval/vals/conversion_test.go

@@ -17,7 +17,7 @@ func TestScanToGo_ConcreteTypeDst(t *testing.T) {
 	// A wrapper around ScanToGo, to make it easier to test. Instead of
 	// supplying a pointer to the destination, an initial value to the
 	// destination is supplied and the result is returned.
-	scanToGo := func(src interface{}, dstInit interface{}) (interface{}, error) {
+	scanToGo := func(src any, dstInit any) (any, error) {
 		ptr := reflect.New(TypeOf(dstInit))
 		err := ScanToGo(src, ptr.Interface())
 		return ptr.Elem().Interface(), err
@@ -56,7 +56,7 @@ func TestScanToGo_ConcreteTypeDst(t *testing.T) {
 }
 
 func TestScanToGo_NumDst(t *testing.T) {
-	scanToGo := func(src interface{}) (Num, error) {
+	scanToGo := func(src any) (Num, error) {
 		var n Num
 		err := ScanToGo(src, &n)
 		return n, err
@@ -80,7 +80,7 @@ func TestScanToGo_NumDst(t *testing.T) {
 }
 
 func TestScanToGo_InterfaceDst(t *testing.T) {
-	scanToGo := func(src interface{}) (interface{}, error) {
+	scanToGo := func(src any) (any, error) {
 		var l List
 		err := ScanToGo(src, &l)
 		return l, err
@@ -102,7 +102,7 @@ func TestScanToGo_ErrorsWithNonPointerDst(t *testing.T) {
 
 func TestScanListToGo(t *testing.T) {
 	// A wrapper around ScanListToGo, to make it easier to test.
-	scanListToGo := func(src List, dstInit interface{}) (interface{}, error) {
+	scanListToGo := func(src List, dstInit any) (any, error) {
 		ptr := reflect.New(TypeOf(dstInit))
 		ptr.Elem().Set(reflect.ValueOf(dstInit))
 		err := ScanListToGo(src, ptr.Interface())
@@ -119,8 +119,8 @@ func TestScanListToGo(t *testing.T) {
 
 func TestScanListElementsToGo(t *testing.T) {
 	// A wrapper around ScanListElementsToGo, to make it easier to test.
-	scanListElementsToGo := func(src List, inits ...interface{}) ([]interface{}, error) {
-		ptrs := make([]interface{}, len(inits))
+	scanListElementsToGo := func(src List, inits ...any) ([]any, error) {
+		ptrs := make([]any, len(inits))
 		for i, init := range inits {
 			if o, ok := init.(optional); ok {
 				// Wrapping the init value with Optional translates to wrapping
@@ -131,7 +131,7 @@ func TestScanListElementsToGo(t *testing.T) {
 			}
 		}
 		err := ScanListElementsToGo(src, ptrs...)
-		vals := make([]interface{}, len(ptrs))
+		vals := make([]any, len(ptrs))
 		for i, ptr := range ptrs {
 			if o, ok := ptr.(optional); ok {
 				vals[i] = reflect.ValueOf(o.ptr).Elem().Interface()
@@ -143,17 +143,17 @@ func TestScanListElementsToGo(t *testing.T) {
 	}
 
 	Test(t, Fn("ScanListElementsToGo", scanListElementsToGo), Table{
-		Args(MakeList("1", "2"), 0, 0).Rets([]interface{}{1, 2}),
-		Args(MakeList("1", "2"), "", "").Rets([]interface{}{"1", "2"}),
-		Args(MakeList("1", "2"), 0, Optional(0)).Rets([]interface{}{1, 2}),
-		Args(MakeList("1"), 0, Optional(0)).Rets([]interface{}{1, 0}),
+		Args(MakeList("1", "2"), 0, 0).Rets([]any{1, 2}),
+		Args(MakeList("1", "2"), "", "").Rets([]any{"1", "2"}),
+		Args(MakeList("1", "2"), 0, Optional(0)).Rets([]any{1, 2}),
+		Args(MakeList("1"), 0, Optional(0)).Rets([]any{1, 0}),
 
-		Args(MakeList("a"), 0).Rets([]interface{}{0},
+		Args(MakeList("a"), 0).Rets([]any{0},
 			cannotParseAs{"integer", "a"}),
-		Args(MakeList("1"), 0, 0).Rets([]interface{}{0, 0},
+		Args(MakeList("1"), 0, 0).Rets([]any{0, 0},
 			errs.ArityMismatch{What: "list elements",
 				ValidLow: 2, ValidHigh: 2, Actual: 1}),
-		Args(MakeList("1"), 0, 0, Optional(0)).Rets([]interface{}{0, 0, 0},
+		Args(MakeList("1"), 0, 0, Optional(0)).Rets([]any{0, 0, 0},
 			errs.ArityMismatch{What: "list elements",
 				ValidLow: 2, ValidHigh: 3, Actual: 1}),
 	})
@@ -161,7 +161,7 @@ func TestScanListElementsToGo(t *testing.T) {
 
 type aStruct struct {
 	Foo int
-	bar interface{}
+	bar any
 }
 
 // Equal is required by cmp.Diff, since aStruct contains unexported fields.
@@ -169,7 +169,7 @@ func (a aStruct) Equal(b aStruct) bool { return a == b }
 
 func TestScanMapToGo(t *testing.T) {
 	// A wrapper around ScanMapToGo, to make it easier to test.
-	scanMapToGo := func(src Map, dstInit interface{}) (interface{}, error) {
+	scanMapToGo := func(src Map, dstInit any) (any, error) {
 		ptr := reflect.New(TypeOf(dstInit))
 		ptr.Elem().Set(reflect.ValueOf(dstInit))
 		err := ScanMapToGo(src, ptr.Interface())

+ 2 - 2
pkg/eval/vals/dissoc.go

@@ -4,14 +4,14 @@ package vals
 type Dissocer interface {
 	// Dissoc returns a slightly modified version of the receiver with key k
 	// dissociated with any value.
-	Dissoc(k interface{}) interface{}
+	Dissoc(k any) any
 }
 
 // Dissoc takes a container and a key, and returns a modified version of the
 // container, with the given key dissociated with any value. It is implemented
 // for the Map type and types satisfying the Dissocer interface. For other
 // types, it returns nil.
-func Dissoc(a, k interface{}) interface{} {
+func Dissoc(a, k any) any {
 	switch a := a.(type) {
 	case Map:
 		return a.Dissoc(k)

+ 1 - 1
pkg/eval/vals/dissoc_test.go

@@ -8,7 +8,7 @@ import (
 
 type dissocer struct{}
 
-func (dissocer) Dissoc(interface{}) interface{} { return "custom ret" }
+func (dissocer) Dissoc(any) any { return "custom ret" }
 
 func TestDissoc(t *testing.T) {
 	Test(t, Fn("Dissoc", Dissoc), Table{

+ 2 - 2
pkg/eval/vals/equal.go

@@ -9,14 +9,14 @@ import (
 type Equaler interface {
 	// Equal compares the receiver to another value. Two equal values must have
 	// the same hash code.
-	Equal(other interface{}) bool
+	Equal(other any) bool
 }
 
 // Equal returns whether two values are equal. It is implemented for the builtin
 // types bool and string, the File, List, Map types, StructMap types, and types
 // satisfying the Equaler interface. For other types, it uses reflect.DeepEqual
 // to compare the two values.
-func Equal(x, y interface{}) bool {
+func Equal(x, y any) bool {
 	switch x := x.(type) {
 	case nil:
 		return x == y

+ 1 - 1
pkg/eval/vals/equal_test.go

@@ -10,7 +10,7 @@ import (
 
 type customEqualer struct{ ret bool }
 
-func (c customEqualer) Equal(interface{}) bool { return c.ret }
+func (c customEqualer) Equal(any) bool { return c.ret }
 
 type customStruct struct{ a, b string }
 

+ 1 - 1
pkg/eval/vals/feed.go

@@ -2,7 +2,7 @@ package vals
 
 // Feed calls the function with given values, breaking earlier if the function
 // returns false.
-func Feed(f func(interface{}) bool, values ...interface{}) {
+func Feed(f func(any) bool, values ...any) {
 	for _, value := range values {
 		if !f(value) {
 			break

+ 3 - 3
pkg/eval/vals/feed_test.go

@@ -6,14 +6,14 @@ import (
 )
 
 func TestFeed(t *testing.T) {
-	var fed []interface{}
+	var fed []any
 
-	Feed(func(x interface{}) bool {
+	Feed(func(x any) bool {
 		fed = append(fed, x)
 		return x != 10
 	}, 1, 2, 3, 10, 11, 12, 13)
 
-	wantFed := []interface{}{1, 2, 3, 10}
+	wantFed := []any{1, 2, 3, 10}
 	if !reflect.DeepEqual(fed, wantFed) {
 		t.Errorf("Fed %v, want %v", fed, wantFed)
 	}

+ 4 - 4
pkg/eval/vals/has_key.go

@@ -10,7 +10,7 @@ import (
 type HasKeyer interface {
 	// HasKey returns whether the receiver has the given argument as a valid
 	// key.
-	HasKey(interface{}) bool
+	HasKey(any) bool
 }
 
 // HasKey returns whether a container has a key. It is implemented for the Map
@@ -18,7 +18,7 @@ type HasKeyer interface {
 // back to iterating keys using IterateKeys, and if that fails, it falls back to
 // calling Len and checking if key is a valid numeric or slice index. Otherwise
 // it returns false.
-func HasKey(container, key interface{}) bool {
+func HasKey(container, key any) bool {
 	switch container := container.(type) {
 	case HasKeyer:
 		return container.HasKey(key)
@@ -30,7 +30,7 @@ func HasKey(container, key interface{}) bool {
 		return hasKeyStructMap(container.Fields(), key)
 	default:
 		var found bool
-		err := IterateKeys(container, func(k interface{}) bool {
+		err := IterateKeys(container, func(k any) bool {
 			if key == k {
 				found = true
 			}
@@ -49,7 +49,7 @@ func HasKey(container, key interface{}) bool {
 	}
 }
 
-func hasKeyStructMap(m StructMap, k interface{}) bool {
+func hasKeyStructMap(m StructMap, k any) bool {
 	kstring, ok := k.(string)
 	if !ok || kstring == "" {
 		return false

+ 2 - 2
pkg/eval/vals/has_key_test.go

@@ -6,9 +6,9 @@ import (
 	. "src.elv.sh/pkg/tt"
 )
 
-type hasKeyer struct{ key interface{} }
+type hasKeyer struct{ key any }
 
-func (h hasKeyer) HasKey(k interface{}) bool { return k == h.key }
+func (h hasKeyer) HasKey(k any) bool { return k == h.key }
 
 func TestHasKey(t *testing.T) {
 	Test(t, Fn("HasKey", HasKey), Table{

+ 1 - 1
pkg/eval/vals/hash.go

@@ -18,7 +18,7 @@ type Hasher interface {
 // types bool and string, the File, List, Map types, StructMap types, and types
 // satisfying the Hasher interface. For other values, it returns 0 (which is OK
 // in terms of correctness).
-func Hash(v interface{}) uint32 {
+func Hash(v any) uint32 {
 	switch v := v.(type) {
 	case bool:
 		if v {

+ 7 - 7
pkg/eval/vals/index.go

@@ -10,24 +10,24 @@ import (
 type Indexer interface {
 	// Index retrieves the value corresponding to the specified key in the
 	// container. It returns the value (if any), and whether it actually exists.
-	Index(k interface{}) (v interface{}, ok bool)
+	Index(k any) (v any, ok bool)
 }
 
 // ErrIndexer wraps the Index method.
 type ErrIndexer interface {
 	// Index retrieves one value from the receiver at the specified index.
-	Index(k interface{}) (interface{}, error)
+	Index(k any) (any, error)
 }
 
 var errNotIndexable = errors.New("not indexable")
 
 type noSuchKeyError struct {
-	key interface{}
+	key any
 }
 
 // NoSuchKey returns an error indicating that a key is not found in a map-like
 // value.
-func NoSuchKey(k interface{}) error {
+func NoSuchKey(k any) error {
 	return noSuchKeyError{k}
 }
 
@@ -39,7 +39,7 @@ func (err noSuchKeyError) Error() string {
 // type string, *os.File, List, StructMap and PseudoStructMap types, and types
 // satisfying the ErrIndexer or Indexer interface (the Map type satisfies
 // Indexer). For other types, it returns a nil value and a non-nil error.
-func Index(a, k interface{}) (interface{}, error) {
+func Index(a, k any) (any, error) {
 	switch a := a.(type) {
 	case string:
 		return indexString(a, k)
@@ -64,7 +64,7 @@ func Index(a, k interface{}) (interface{}, error) {
 	}
 }
 
-func indexFile(f *os.File, k interface{}) (interface{}, error) {
+func indexFile(f *os.File, k any) (any, error) {
 	switch k {
 	case "fd":
 		return int(f.Fd()), nil
@@ -74,7 +74,7 @@ func indexFile(f *os.File, k interface{}) (interface{}, error) {
 	return nil, NoSuchKey(k)
 }
 
-func indexStructMap(a StructMap, k interface{}) (interface{}, error) {
+func indexStructMap(a StructMap, k any) (any, error) {
 	fieldName, ok := k.(string)
 	if !ok || fieldName == "" {
 		return nil, NoSuchKey(k)

+ 2 - 2
pkg/eval/vals/index_list.go

@@ -12,7 +12,7 @@ var (
 	errIndexMustBeInteger = errors.New("index must must be integer")
 )
 
-func indexList(l List, rawIndex interface{}) (interface{}, error) {
+func indexList(l List, rawIndex any) (any, error) {
 	index, err := ConvertListIndex(rawIndex, l.Len())
 	if err != nil {
 		return nil, err
@@ -53,7 +53,7 @@ func adjustAndCheckIndex(i, n int, includeN bool) (int, error) {
 
 // ConvertListIndex parses a list index, check whether it is valid, and returns
 // the converted structure.
-func ConvertListIndex(rawIndex interface{}, n int) (*ListIndex, error) {
+func ConvertListIndex(rawIndex any, n int) (*ListIndex, error) {
 	switch rawIndex := rawIndex.(type) {
 	case int:
 		index, err := adjustAndCheckIndex(rawIndex, n, false)

+ 2 - 2
pkg/eval/vals/index_string.go

@@ -7,7 +7,7 @@ import (
 
 var errIndexNotAtRuneBoundary = errors.New("index not at rune boundary")
 
-func indexString(s string, index interface{}) (string, error) {
+func indexString(s string, index any) (string, error) {
 	i, j, err := convertStringIndex(index, s)
 	if err != nil {
 		return "", err
@@ -15,7 +15,7 @@ func indexString(s string, index interface{}) (string, error) {
 	return s[i:j], nil
 }
 
-func convertStringIndex(rawIndex interface{}, s string) (int, int, error) {
+func convertStringIndex(rawIndex any, s string) (int, int, error) {
 	index, err := ConvertListIndex(rawIndex, len(s))
 	if err != nil {
 		return 0, 0, err

+ 7 - 7
pkg/eval/vals/iterate.go

@@ -4,7 +4,7 @@ package vals
 type Iterator interface {
 	// Iterate calls the passed function with each value within the receiver.
 	// The iteration is aborted if the function returns false.
-	Iterate(func(v interface{}) bool)
+	Iterate(func(v any) bool)
 }
 
 type cannotIterate struct{ kind string }
@@ -13,7 +13,7 @@ func (err cannotIterate) Error() string { return "cannot iterate " + err.kind }
 
 // CanIterate returns whether the value can be iterated. If CanIterate(v) is
 // true, calling Iterate(v, f) will not result in an error.
-func CanIterate(v interface{}) bool {
+func CanIterate(v any) bool {
 	switch v.(type) {
 	case Iterator, string, List:
 		return true
@@ -26,7 +26,7 @@ func CanIterate(v interface{}) bool {
 // implemented for the builtin type string, the List type, and types satisfying
 // the Iterator interface. For these types, it always returns a nil error. For
 // other types, it doesn't do anything and returns an error.
-func Iterate(v interface{}, f func(interface{}) bool) error {
+func Iterate(v any, f func(any) bool) error {
 	switch v := v.(type) {
 	case string:
 		for _, r := range v {
@@ -50,12 +50,12 @@ func Iterate(v interface{}, f func(interface{}) bool) error {
 }
 
 // Collect collects all elements of an iterable value into a slice.
-func Collect(it interface{}) ([]interface{}, error) {
-	var vs []interface{}
+func Collect(it any) ([]any, error) {
+	var vs []any
 	if len := Len(it); len >= 0 {
-		vs = make([]interface{}, 0, len)
+		vs = make([]any, 0, len)
 	}
-	err := Iterate(it, func(v interface{}) bool {
+	err := Iterate(it, func(v any) bool {
 		vs = append(vs, v)
 		return true
 	})

Some files were not shown because too many files changed in this diff