aboutsummaryrefslogtreecommitdiffstats
path: root/community/elixir/bit-comp-works.patch
blob: 6cda7edb0a33f7b4b4c9ecd9b26a291c6decd23c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
From 141c3276857ac09bb1f378ed6842495bb0b0e57d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com>
Date: Wed, 14 Mar 2018 21:45:13 +0100
Subject: [PATCH] Ensure bitstring comprehensions work on OTP 20.3 (#7453)

Closes #7452
---
 lib/elixir/lib/collectable.ex     |  3 +++
 lib/elixir/src/elixir_erl_for.erl | 24 +++++++++++++++++-------
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/lib/elixir/lib/collectable.ex b/lib/elixir/lib/collectable.ex
index f7a35cd65e..495eb848cb 100644
--- a/lib/elixir/lib/collectable.ex
+++ b/lib/elixir/lib/collectable.ex
@@ -101,6 +101,9 @@ defimpl Collectable, for: BitString do
       acc, {:cont, x} when is_bitstring(x) ->
         <<IO.iodata_to_binary(acc)::bitstring, x::bitstring>>

+      acc, :done when is_bitstring(acc) ->
+        acc
+
       acc, :done ->
         IO.iodata_to_binary(acc)

diff --git a/lib/elixir/src/elixir_erl_for.erl b/lib/elixir/src/elixir_erl_for.erl
index e24da55a8b..5c4ce62c6d 100644
--- a/lib/elixir/src/elixir_erl_for.erl
+++ b/lib/elixir/src/elixir_erl_for.erl
@@ -21,7 +21,7 @@ translate(Meta, Args, Return, S) ->

   case comprehension_expr(TInto, TExpr) of
     {inline, TIntoExpr} ->
-      {build_inline(Ann, TCases, TIntoExpr, TInto, TUniq, SF), SF};
+      build_inline(Ann, TCases, TIntoExpr, TInto, TUniq, SF);
     {into, TIntoExpr} ->
       build_into(Ann, TCases, TIntoExpr, TInto, TUniq, SF)
   end.
@@ -91,17 +91,17 @@ collect_filters([], Acc) ->

 build_inline(Ann, Clauses, Expr, Into, Uniq, S) ->
   case not Uniq and lists:all(fun(Clause) -> element(1, Clause) == bin end, Clauses) of
-    true  -> build_comprehension(Ann, Clauses, Expr, Into);
+    true  -> {build_comprehension(Ann, Clauses, Expr, Into), S};
     false -> build_inline_each(Ann, Clauses, Expr, Into, Uniq, S)
   end.

 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);
+  {build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, S), 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),
-  elixir_erl:remote(Ann, lists, reverse, [ReduceExpr]);
+  {elixir_erl:remote(Ann, lists, reverse, [ReduceExpr]), S};
 build_inline_each(Ann, Clauses, Expr, {bin, _, []}, Uniq, S) ->
   {InnerValue, SV} = build_var(Ann, S),

@@ -135,11 +135,21 @@ build_inline_each(Ann, Clauses, Expr, {bin, _, []}, Uniq, S) ->
   end,

   ReduceExpr = build_reduce(Ann, Clauses, InnerFun, Expr, {nil, Ann}, Uniq, SV),
-  elixir_erl:remote(Ann, erlang, iolist_to_binary, [ReduceExpr]).
+
+  {{'case', Ann, ReduceExpr, [
+    {clause, Ann,
+     [InnerValue],
+     [[elixir_erl:remote(Ann, erlang, is_bitstring, [InnerValue])]],
+     [InnerValue]},
+    {clause, Ann,
+     [InnerValue],
+     [],
+     [elixir_erl:remote(Ann, erlang, iolist_to_binary, [InnerValue])]}
+  ]}, SV}.

 build_into(Ann, Clauses, Expr, {map, _, []}, Uniq, S) ->
-  ReduceExpr = build_inline_each(Ann, Clauses, Expr, {nil, Ann}, Uniq, S),
-  {elixir_erl:remote(Ann, maps, from_list, [ReduceExpr]), S};
+  {ReduceExpr, SR} = build_inline_each(Ann, Clauses, Expr, {nil, Ann}, Uniq, S),
+  {elixir_erl:remote(Ann, maps, from_list, [ReduceExpr]), SR};
 build_into(Ann, Clauses, Expr, Into, Uniq, S) ->
   {Fun, SF}    = build_var(Ann, S),
   {Acc, SA}    = build_var(Ann, SF),