diff --git a/lib/elixir/src/elixir_fn.erl b/lib/elixir/src/elixir_fn.erl index a7ef530830f..38e8f00a2e9 100644 --- a/lib/elixir/src/elixir_fn.erl +++ b/lib/elixir/src/elixir_fn.erl @@ -128,11 +128,11 @@ validate(Meta, [{Pos, _} | _], Expected, E) -> validate(_Meta, [], _Pos, _E) -> []. -escape({'&', _, [Pos]}, _E, Dict) when is_integer(Pos), Pos > 0 -> +escape({'&', Meta, [Pos]}, _E, Dict) when is_integer(Pos), Pos > 0 -> % Using a nil context here to emit warnings when variable is unused. % This might pollute user space but is unlikely because variables % named :"&1" are not valid syntax. - Var = {list_to_atom([$& | integer_to_list(Pos)]), [], nil}, + Var = {list_to_atom([$& | integer_to_list(Pos)]), Meta, nil}, {Var, orddict:store(Pos, Var, Dict)}; escape({'&', Meta, [Pos]}, E, _Dict) when is_integer(Pos) -> file_error(Meta, E, ?MODULE, {invalid_arity_for_capture, Pos}); diff --git a/lib/elixir/test/elixir/kernel/expansion_test.exs b/lib/elixir/test/elixir/kernel/expansion_test.exs index 3da73890993..9f1725af0ce 100644 --- a/lib/elixir/test/elixir/kernel/expansion_test.exs +++ b/lib/elixir/test/elixir/kernel/expansion_test.exs @@ -1133,6 +1133,12 @@ defmodule Kernel.ExpansionTest do assert expand(quote(do: &unknown(&1, &2))) == {:&, [], [{:/, [], [{:unknown, [], nil}, 2]}]} end + test "keeps position meta on & variables" do + assert expand(Code.string_to_quoted!("& &1")) == + {:fn, [{:line, 1}], + [{:->, [{:line, 1}], [[{:"&1", [line: 1], nil}], {:"&1", [line: 1], nil}]}]} + end + test "expands remotes" do assert expand(quote(do: &List.flatten/2)) == quote(do: &:"Elixir.List".flatten/2)