-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Pipe operator removes a function's import context if the import is outside a quote block #11651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi, I tried to look into this issue, here is a minimal example: iex> import Integer
Integer
iex> ast1 = quote do: is_odd(1)
{:is_odd, [context: Elixir, import: Integer], [1]}
iex> ast2 = quote do: 1 |> is_odd()
{:|>, [context: Elixir, import: Kernel], [1, {:is_odd, [], []}]}
iex> Code.eval_quoted(ast1)
{true, [{{:arg1, Elixir}, 1}]}
iex> Code.eval_quoted(ast2)
** (CompileError) nofile:1: undefined function is_odd/1 (there is no such import)
(elixir 1.13.4) expanding macro: Kernel.|>/2
nofile:1: (file) This seems rather tricky to solve, since the pipe operator is just a macro and from the AST point of view this is just equivalent to Actually, looking at the example, it would seem better to use |
More than I think that this problem is not specific to Per the documentation quote -- 'Hygiene in Imports' Elixir delays function resolution to the last possible moment. |
Correct. The pipe operator should be treated specially inside |
Actually, we should not treat any operator as special, because then it means people cannot implement pipe-like functionality using other operators. I started working on this issue in this commit: 169595f The idea is that we will keep imports as a list and we will annotate all arities and modules based on the function name. The open questions I have to address is:
|
Environment
Current behavior
The following code causes a compilation error related to
operation/3
being undefined.The code block below, however, has the import working as expected:
Expected behavior
I would expect the first snippet to be equivalent to the second one. Upon inspection of the AST, it seems that the pipe operator is removing the import context from the
{:operation, _, _}
node, which makes it try to resolve toT
s namespace. This also seems to be why it works if the macro also forces the import upon theT
module.The text was updated successfully, but these errors were encountered: