Resolves the three name classes of 02-dsl-semantics.md §1 inside a spec block.
Inside a spec block a bare identifier is one of exactly three things, and the class is determined syntactically, never by inference:
| Syntax | Class | Rewrites to |
|---|---|---|
^name | Constant | Map.fetch!(constants, :name) |
name | Variable | Map.fetch!(state, :name) |
let name = … | Local | left alone; ordinary Elixir |
Why locals are over-approximated
A bare name that is neither a declared variable nor a constant may still be a
perfectly good local: a let pattern, a fn argument, a comprehension
generator, a case clause head. bound_names/1 collects every name bound
anywhere in the block, ignoring scope, and a read of a name in that set is
left alone.
Over-approximating is the deliberate direction to be wrong in. Missing a binding would turn working Elixir into a spurious "undeclared variable" error; including one too many only means a genuine typo is reported by Elixir's own compiler ("undefined variable") instead of by this one. The first is a regression, the second is a slightly worse message.
Summary
Functions
Every name bound anywhere in the AST, ignoring scope. See the module note on why this over-approximates.
The variable names bound by a pattern. A pinned name is a value, not a
binding, so ^x contributes nothing.
The rejection builder for action_property: §4 requires old./new..
The rejection builder for init: there is no earlier state to read.
The rejection builder for a params: generator, which receives the pre-state
as its own argument.
Rewrite an expression, resolving ^constants and bare variables.
Types
Functions
Every name bound anywhere in the AST, ignoring scope. See the module note on why this over-approximates.
The variable names bound by a pattern. A pinned name is a value, not a
binding, so ^x contributes nothing.
The rejection builder for action_property: §4 requires old./new..
The rejection builder for init: there is no earlier state to read.
The rejection builder for a params: generator, which receives the pre-state
as its own argument.
Rewrite an expression, resolving ^constants and bare variables.