-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Closed
Labels
Description
Elixir and Erlang/OTP versions
Erlang/OTP 26 [erts-14.2.5.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]
Elixir 1.17.3 (compiled with Erlang/OTP 26)
Operating system
any
Current behavior
I noticed some strange behavior related to quoted imports. Given this compilation tracer
defmodule MyTracer do
def trace(event, _env) do
dbg(event)
:ok
end
end
Code.put_compiler_option(:tracers, [MyTracer])
when I compile this code
defmodule MyModule do
def aaa, do: :ok
defmacro bbb, do: :ok
defmacro foo do
quote do
aaa()
&aaa/0
bbb()
&bbb/0
inspect(1)
&inspect/1
Node.list()
&Node.list/0
end
end
end
The emitted traces are
[iex:7: MyTracer.trace/2]
event #=> :defmodule
[iex:7: MyTracer.trace/2]
event #=> {:imported_macro, [line: 2, column: 3], Kernel, :defmacro, 2}
[iex:7: MyTracer.trace/2]
event #=> {:remote_function, [line: 2], :elixir_def, :store_definition, 3}
[iex:7: MyTracer.trace/2]
event #=> {:remote_function, [line: 1], :elixir_utils, :noop, 0}
[iex:7: MyTracer.trace/2]
event #=> {:imported_function, [line: 5, column: 7], Kernel, :inspect, 1}
[iex:7: MyTracer.trace/2]
event #=> {:imported_quoted, [line: 5, column: 15], Kernel, :/, [2]}
[iex:7: MyTracer.trace/2]
event #=> {:imported_quoted, [line: 5, column: 8], Kernel, :inspect, [1, 2]}
[iex:7: MyTracer.trace/2]
event #=> {:imported_quoted, [line: 4, column: 7], Kernel, :inspect, [1, 2]}
[iex:7: MyTracer.trace/2]
event #=> {:on_module,
<<70, 79, 82, 49, 0, 0, 6, 16, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 176,
0, 0, 0, 17, 15, 69, 108, 105, 120, 105, 114, 46, 78, 121, 77, 111, 100, 117,
108, 101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, :none}
[iex:7: MyTracer.trace/2]
event #=> :stop
- There are undocumented trace events
:imported_quoted
- Only
&inspect/1
results in a trace event. No similar events for remote and local captures - No events for calls
Next, when I eval the macro, it outputs this AST
apply(MyModule, :"MACRO-foo", [__ENV__])
{:__block__, [],
[
{:aaa, [], []},
{:&, [],
[
{:/, [context: MyModule, imports: [{2, Kernel}]],
[{:aaa, [], MyModule}, 0]}
]},
{:bbb, [], []},
{:&, [],
[
{:/, [context: MyModule, imports: [{2, Kernel}]],
[{:bbb, [], MyModule}, 0]}
]},
{:inspect, [context: MyModule, imports: [{1, Kernel}, {2, Kernel}]], [1]},
{:&, [imports: [{1, Kernel}], context: MyModule],
[
{:/, [context: MyModule, imports: [{2, Kernel}]],
[
{:inspect, [context: MyModule, imports: [{1, Kernel}, {2, Kernel}]],
MyModule},
1
]}
]},
{{:., [], [{:__aliases__, [alias: false], [:Node]}, :list]}, [], []},
{:&, [],
[
{:/, [context: MyModule, imports: [{2, Kernel}]],
[
{{:., [], [{:__aliases__, [alias: false], [:Node]}, :list]},
[no_parens: true], []},
1
]}
]}
]}
- Why is
Kernel
added twice in metaimports: [{1, Kernel}, {2, Kernel}]
?
Expected behavior
- Trace event should be documented. Code documentation does not mention any private events and suggests the list given there is exhaustive
I'm not sure if emitting {:imported_quoted, [line: 5, column: 15], Kernel, :/, [2]}
should happen
- Either all captures should emit events, none should emit events, or if import is special then it should be documented
- Call probably should emit events
Alternatively it's possible that events in quoted are not needed at all
- This looks strange but I don't understand the code in
:elixir_quote
so it may be correct