summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksei Matiushkin <aleksei.matiushkin@kantox.com>2022-01-01 09:00:18 +0100
committerGitHub <noreply@github.com>2022-01-01 09:00:18 +0100
commit3c6b8a96e57e3c04ef3d531fc932f0bf88a3d009 (patch)
tree3011602d9f1b458294620a1d4e19971849fded52
parent6d803edf73cb5cfb0fef333949055c96c6769093 (diff)
downloadelixir-3c6b8a96e57e3c04ef3d531fc932f0bf88a3d009.tar.gz
Fix the nested `uniq:` acc name clash by preserving a scope (#11532)
-rw-r--r--lib/elixir/src/elixir_erl_for.erl20
-rw-r--r--lib/elixir/test/elixir/kernel/comprehension_test.exs13
2 files changed, 23 insertions, 10 deletions
diff --git a/lib/elixir/src/elixir_erl_for.erl b/lib/elixir/src/elixir_erl_for.erl
index 72225ed2f..9252f4300 100644
--- a/lib/elixir/src/elixir_erl_for.erl
+++ b/lib/elixir/src/elixir_erl_for.erl
@@ -21,7 +21,7 @@ translate_reduce(Meta, Cases, Expr, Reduce, S) ->
({'case', CaseAnn, _, CaseBlock}, InnerAcc) -> {'case', CaseAnn, InnerAcc, CaseBlock}
end,
- {build_reduce(Ann, TCases, InnerFun, TExpr, TReduce, false, SE), SE}.
+ build_reduce(Ann, TCases, InnerFun, TExpr, TReduce, false, SE).
translate_into(Meta, Cases, Expr, Opts, Return, S) ->
Ann = ?ann(Meta),
@@ -115,11 +115,11 @@ build_inline(Ann, Clauses, Expr, Into, Uniq, S) ->
build_inline_each(Ann, Clauses, Expr, false, Uniq, S) ->
InnerFun = fun(InnerExpr, _InnerAcc) -> InnerExpr end,
- {build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, S), S};
+ build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, S);
build_inline_each(Ann, Clauses, Expr, {nil, _} = Into, Uniq, S) ->
InnerFun = fun(InnerExpr, InnerAcc) -> {cons, Ann, InnerExpr, InnerAcc} end,
- ReduceExpr = build_reduce(Ann, Clauses, InnerFun, Expr, Into, Uniq, S),
- {?remote(Ann, lists, reverse, [ReduceExpr]), S};
+ {ReduceExpr, SR} = build_reduce(Ann, Clauses, InnerFun, Expr, Into, Uniq, S),
+ {?remote(Ann, lists, reverse, [ReduceExpr]), SR};
build_inline_each(Ann, Clauses, Expr, {bin, _, []}, Uniq, S) ->
{InnerValue, SV} = build_var(Ann, S),
Generated = erl_anno:set_generated(true, Ann),
@@ -138,8 +138,8 @@ build_inline_each(Ann, Clauses, Expr, {bin, _, []}, Uniq, S) ->
]}
end,
- ReduceExpr = build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, SV),
- {?remote(Ann, erlang, list_to_bitstring, [ReduceExpr]), SV}.
+ {ReduceExpr, SR} = build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, SV),
+ {?remote(Ann, erlang, list_to_bitstring, [ReduceExpr]), SR}.
build_into(Ann, Clauses, Expr, {map, _, []}, Uniq, S) ->
{ReduceExpr, SR} = build_inline_each(Ann, Clauses, Expr, {nil, Ann}, Uniq, S),
@@ -161,7 +161,7 @@ build_into(Ann, Clauses, Expr, Into, Uniq, S) ->
?remote(Ann, 'Elixir.Collectable', into, [Into])
},
- IntoReduceExpr = build_reduce(Ann, Clauses, InnerFun, Expr, Acc, Uniq, SD),
+ {IntoReduceExpr, SN} = build_reduce(Ann, Clauses, InnerFun, Expr, Acc, Uniq, SD),
TryExpr =
{'try', Ann,
@@ -173,7 +173,7 @@ build_into(Ann, Clauses, Expr, Into, Uniq, S) ->
[stacktrace_clause(Ann, Fun, Acc, Kind, Reason, Stack)],
[]},
- {{block, Ann, [MatchExpr, TryExpr]}, SD}.
+ {{block, Ann, [MatchExpr, TryExpr]}, SN}.
stacktrace_clause(Ann, Fun, Acc, Kind, Reason, Stack) ->
{clause, Ann,
@@ -186,7 +186,7 @@ stacktrace_clause(Ann, Fun, Acc, Kind, Reason, Stack) ->
build_reduce(Ann, Clauses, InnerFun, Expr, Into, false, S) ->
{Acc, SA} = build_var(Ann, S),
- build_reduce_each(Clauses, InnerFun(Expr, Acc), Into, Acc, SA);
+ {build_reduce_each(Clauses, InnerFun(Expr, Acc), Into, Acc, SA), SA};
build_reduce(Ann, Clauses, InnerFun, Expr, Into, true, S) ->
%% Those variables are used only inside the anonymous function
%% so we don't need to worry about returning the scope.
@@ -209,7 +209,7 @@ build_reduce(Ann, Clauses, InnerFun, Expr, Into, true, S) ->
]},
EnumReduceCall = build_reduce_each(Clauses, InnerExpr, NewInto, Acc, SU),
- ?remote(Ann, erlang, element, [{integer, Ann, 1}, EnumReduceCall]).
+ {?remote(Ann, erlang, element, [{integer, Ann, 1}, EnumReduceCall]), SU}.
build_reduce_each([{enum, Meta, Left, Right, Filters} | T], Expr, Arg, Acc, S) ->
Ann = ?ann(Meta),
diff --git a/lib/elixir/test/elixir/kernel/comprehension_test.exs b/lib/elixir/test/elixir/kernel/comprehension_test.exs
index 92bbb57ca..7c1ebf761 100644
--- a/lib/elixir/test/elixir/kernel/comprehension_test.exs
+++ b/lib/elixir/test/elixir/kernel/comprehension_test.exs
@@ -98,6 +98,19 @@ defmodule Kernel.ComprehensionTest do
assert Process.get(:into_halt)
end
+ test "nested for comprehensions with unique values" do
+ assert for(x <- [1, 1, 2], uniq: true, do: for(y <- [3, 3], uniq: true, do: x * y)) == [
+ [3],
+ [6]
+ ]
+
+ assert for(<<x <- "abcabc">>,
+ uniq: true,
+ into: "",
+ do: for(<<y <- "zz">>, uniq: true, into: "", do: to_bin(x) <> to_bin(y))
+ ) == "azbzcz"
+ end
+
test "for comprehensions with nilly filters" do
assert for(x <- 1..3, nilly(), do: x * 2) == []
end