diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index b2445cf7b7f..5f6633313c9 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -1795,13 +1795,15 @@ defmodule Macro do defp do_expand_once({:__DIR__, _, atom}, env) when is_atom(atom), do: {:filename.dirname(env.file), true} - defp do_expand_once({:__ENV__, _, atom}, env) when is_atom(atom), - do: {{:%{}, [], Map.to_list(env)}, true} + defp do_expand_once({:__ENV__, _, atom}, env) when is_atom(atom) do + env = update_in(env.versioned_vars, &maybe_escape_map/1) + {maybe_escape_map(env), true} + end defp do_expand_once({{:., _, [{:__ENV__, _, atom}, field]}, _, []} = original, env) when is_atom(atom) and is_atom(field) do if Map.has_key?(env, field) do - {Map.get(env, field), true} + {maybe_escape_map(Map.get(env, field)), true} else {original, false} end @@ -1884,6 +1886,9 @@ defmodule Macro do # Anything else is just returned defp do_expand_once(other, _env), do: {other, false} + defp maybe_escape_map(map) when is_map(map), do: {:%{}, [], Map.to_list(map)} + defp maybe_escape_map(other), do: other + @doc """ Returns `true` if the given name and arity is a special form. """ diff --git a/lib/elixir/test/elixir/macro_test.exs b/lib/elixir/test/elixir/macro_test.exs index a6e38d25ebd..7820166b05c 100644 --- a/lib/elixir/test/elixir/macro_test.exs +++ b/lib/elixir/test/elixir/macro_test.exs @@ -173,9 +173,17 @@ defmodule MacroTest do test "env" do env = %{__ENV__ | line: 0} - assert Macro.expand_once(quote(do: __ENV__), env) == {:%{}, [], Map.to_list(env)} + + expanded = Macro.expand_once(quote(do: __ENV__), env) + assert Macro.validate(expanded) == :ok + assert Code.eval_quoted(expanded) == {env, []} + assert Macro.expand_once(quote(do: __ENV__.file), env) == env.file assert Macro.expand_once(quote(do: __ENV__.unknown), env) == quote(do: __ENV__.unknown) + + expanded = Macro.expand_once(quote(do: __ENV__.versioned_vars), env) + assert Macro.validate(expanded) == :ok + assert Code.eval_quoted(expanded) == {env.versioned_vars, []} end defmacro local_macro(), do: raise("ignored")