diff options
author | José Valim <jose.valim@dashbit.co> | 2022-11-09 13:01:48 +0100 |
---|---|---|
committer | José Valim <jose.valim@dashbit.co> | 2022-11-09 13:02:04 +0100 |
commit | 123034569f3f80a8693efb33ba8d211048b37507 (patch) | |
tree | 5fbba0d0011d0c3b292ee538589f747a2a77b0c7 | |
parent | bdea27c1e38571a2cc89803b1deb3b7574c46afc (diff) | |
download | elixir-123034569f3f80a8693efb33ba8d211048b37507.tar.gz |
Generate unique vars in defguard
-rw-r--r-- | lib/elixir/lib/kernel/utils.ex | 2 | ||||
-rw-r--r-- | lib/elixir/src/elixir_erl_var.erl | 15 | ||||
-rw-r--r-- | lib/elixir/test/elixir/code_test.exs | 9 |
3 files changed, 18 insertions, 8 deletions
diff --git a/lib/elixir/lib/kernel/utils.ex b/lib/elixir/lib/kernel/utils.ex index 2535a31aa..2deed63c2 100644 --- a/lib/elixir/lib/kernel/utils.ex +++ b/lib/elixir/lib/kernel/utils.ex @@ -375,7 +375,7 @@ defmodule Kernel.Utils do %{} -> generated = String.to_atom("arg" <> Integer.to_string(map_size(acc) + 1)) - new_var = Macro.var(generated, Elixir) + new_var = Macro.unique_var(generated, Elixir) {new_var, Map.put(acc, pair, {new_var, var})} end diff --git a/lib/elixir/src/elixir_erl_var.erl b/lib/elixir/src/elixir_erl_var.erl index 8f26003e0..90af6e3ca 100644 --- a/lib/elixir/src/elixir_erl_var.erl +++ b/lib/elixir/src/elixir_erl_var.erl @@ -109,13 +109,11 @@ dump_binding(Binding, ErlS, ExS, PruneBefore) -> #elixir_ex{vars={ExVars, _}, unused={Unused, _}} = ExS, maps:fold(fun - %% If the variable is part of the pruning (usually the input binding) - %% and is unused, we removed it from vars. - (Pair, Version, {B, V}) - when Version =< PruneBefore, not is_map_key({Pair, Version}, Unused) -> - {B, maps:remove(Pair, V)}; - - ({Var, Kind} = Pair, Version, {B, V}) when is_atom(Kind) -> + ({Var, Kind} = Pair, Version, {B, V}) + when is_atom(Kind), + %% If the variable is part of the pruning (usually the input binding) + %% and is unused, we removed it from vars. + Version > PruneBefore orelse is_map_key({Pair, Version}, Unused) -> Key = case Kind of nil -> Var; _ -> Pair @@ -125,6 +123,9 @@ dump_binding(Binding, ErlS, ExS, PruneBefore) -> Value = find_binding(ErlName, Binding), {[{Key, Value} | B], V}; + (Pair, _, {B, V}) when PruneBefore >= 0 -> + {B, maps:remove(Pair, V)}; + (_, _, Acc) -> Acc end, {[], ExVars}, ExVars). diff --git a/lib/elixir/test/elixir/code_test.exs b/lib/elixir/test/elixir/code_test.exs index 0f3bfdece..28542f527 100644 --- a/lib/elixir/test/elixir/code_test.exs +++ b/lib/elixir/test/elixir/code_test.exs @@ -234,6 +234,15 @@ defmodule CodeTest do assert trace_env.versioned_vars == %{{:result, Kernel} => 5, {:x, nil} => 1, {:y, nil} => 4} end + test "eval_quoted_with_env/3 with defguard" do + require Integer + env = Code.env_for_eval(__ENV__) + quoted = quote do: Integer.is_even(1) + {false, binding, env} = Code.eval_quoted_with_env(quoted, [], env, prune_binding: true) + assert binding == [] + assert Macro.Env.vars(env) == [] + end + test "compile_file/1" do assert Code.compile_file(fixture_path("code_sample.exs")) == [] refute fixture_path("code_sample.exs") in Code.required_files() |