feat(error): name the callee/target in attempt to call/index errors#228
Merged
Conversation
Mirrors PUC-Lua by annotating :call, :get_field, :set_field, :get_table,
:set_table, and :self with a compile-time name_hint derived from the AST
(`{:global, name}`, `{:local, name}`, `{:upvalue, name}`, `{:field, name}`,
`{:method, name}`). The executor formats the hint into the runtime error
so messages now report the source name:
attempt to call a nil value (global 'foo')
attempt to index a nil value (local 't')
attempt to call a nil value (field 'bar')
Also fixes :set_field / :set_table to raise :index_non_table instead of
MatchError when the target isn't a table.
davydog187
commented
May 21, 2026
|
|
||
| test "call-nil error names a field" do | ||
| assert error_message("local t = {}\nt.bar()") =~ | ||
| "attempt to call a nil value (field 'bar')" |
Contributor
Author
There was a problem hiding this comment.
For the case where we're invoking functions and methods, it would be nice it if provided this information, i.e. I want to see that it was the t.bar() that failed (the 't' symbol is not mentioned in the current). Its definitely important to note which is nil as well (bar is nil, not t)
`t.bar()` where `bar` is nil now reports the receiver too:
attempt to call a nil value (field 'bar' on local 't')
attempt to call a nil value (method 'baz' on local 't')
Previously only the field/method name was named, leaving the receiver
symbol invisible -- so a user couldn't tell which `t` the failure
referred to in a script with several. Property and Index name_hints
now recurse into the table expression and tag a third element onto
`{:field, name, receiver}` / `{:method, name, receiver}`. The executor
formats the receiver with its own `local`/`global`/`upvalue` qualifier.
Anonymous receivers (e.g. `f().bar()`) emit the original 2-tuple form
and render with no receiver clause.
Also runs `mix format` over the rest of the prior commit's edits.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
:call,:get_field,:set_field,:get_table,:set_table, and:selfinstructions with a compile-timename_hintderived from the AST ({:global, name}/{:local, name}/{:upvalue, name}/{:field, name}/{:method, name}).:set_field/:set_tableto raise:index_non_tableinstead ofMatchErrorwhen the target isn't a table.Before
After
PUC-Lua recovers the same names via debug info threaded through bytecode; doing it at compile time is simpler here because the AST is still in scope when we emit the instruction.
Test plan
mix test test/lua/error_messages_test.exs— 36 tests including 10 new cases covering global/local/upvalue/field/method calls, set-side index, non-function/non-table targets, and the anonymous-callee (no-hint) case.mix test— full suite (1778 tests, 30 skipped) passes.iex -S mixsmoke test for each error path.