summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@dashbit.co>2022-11-09 13:01:48 +0100
committerJosé Valim <jose.valim@dashbit.co>2022-11-09 13:02:04 +0100
commit123034569f3f80a8693efb33ba8d211048b37507 (patch)
tree5fbba0d0011d0c3b292ee538589f747a2a77b0c7
parentbdea27c1e38571a2cc89803b1deb3b7574c46afc (diff)
downloadelixir-123034569f3f80a8693efb33ba8d211048b37507.tar.gz
Generate unique vars in defguard
-rw-r--r--lib/elixir/lib/kernel/utils.ex2
-rw-r--r--lib/elixir/src/elixir_erl_var.erl15
-rw-r--r--lib/elixir/test/elixir/code_test.exs9
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()