From 3364bf4e803f2f132ae822db327c30d3ec9006f5 Mon Sep 17 00:00:00 2001 From: sabiwara Date: Fri, 6 Sep 2024 11:04:53 +0900 Subject: [PATCH] Fix: Macro.expand/2 should not expand __ENV__ on :match context --- lib/elixir/lib/macro.ex | 4 ++-- lib/elixir/test/elixir/macro_test.exs | 10 +++++++++ lib/ex_unit/test/ex_unit/assertions_test.exs | 22 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index 6f9ff8dc7b5..4e106b74752 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -1832,13 +1832,13 @@ 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 + defp do_expand_once({:__ENV__, _, atom}, env) when is_atom(atom) and env.context != :match 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 + when is_atom(atom) and is_atom(field) and env.context != :match do if Map.has_key?(env, field) do {maybe_escape_map(Map.get(env, field)), true} else diff --git a/lib/elixir/test/elixir/macro_test.exs b/lib/elixir/test/elixir/macro_test.exs index 15004ed8db9..9302e5df709 100644 --- a/lib/elixir/test/elixir/macro_test.exs +++ b/lib/elixir/test/elixir/macro_test.exs @@ -196,6 +196,16 @@ defmodule MacroTest do assert Code.eval_quoted(expanded) == {env.versioned_vars, []} end + test "env in :match context does not expand" do + env = %{__ENV__ | line: 0, lexical_tracker: self(), context: :match} + + expanded = Macro.expand_once(quote(do: __ENV__), env) + assert expanded == quote(do: __ENV__) + + expanded = Macro.expand_once(quote(do: __ENV__.file), env) + assert expanded == quote(do: __ENV__.file) + end + defmacro local_macro(), do: raise("ignored") test "vars" do diff --git a/lib/ex_unit/test/ex_unit/assertions_test.exs b/lib/ex_unit/test/ex_unit/assertions_test.exs index cebf202288f..dcbf338afc8 100644 --- a/lib/ex_unit/test/ex_unit/assertions_test.exs +++ b/lib/ex_unit/test/ex_unit/assertions_test.exs @@ -256,6 +256,28 @@ defmodule ExUnit.AssertionsTest do end end + test "assert match with __ENV__ in the pattern" do + message = + ExUnit.CaptureIO.capture_io(:stderr, fn -> + assert_raise CompileError, fn -> + Code.eval_string(""" + defmodule EnvMatch do + import ExUnit.Assertions + + def run do + assert __ENV__ = %{} + end + end + """) + end + end) + + assert message =~ "invalid pattern in match, __ENV__ is not allowed in matches" + after + :code.purge(EnvMatch) + :code.delete(EnvMatch) + end + test "assert match?" do true = assert match?({2, 1}, Value.tuple())