From 5daa0013177545446b26cdba0dbd167f0e040d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 22 Sep 2010 11:09:57 +0200 Subject: Don't generate multiple tail segments in binary matching In binary matching, there must only be one "tail segment" (i.e. a size-less segment of type binary) and it must be last. Thus, the compiler will reject the following function definition: foo(<>) -> ok. But code such as the following: [42 || <<_:8/integer, _/bits>> <= Bits] will internally (in the Core Erlang format) be translated to a binary matching pattern containing two tail segments. The compiler happens to generate correct code anyway (later passes will get rid of the redundant tail segment), but it is ugly and will confuse tools such as Dialyzer. Change the transformation of binary generators (in both list and binary comprehensions) not to generate add a tail segment if there already is one. --- lib/compiler/src/v3_core.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 3f33dbca52..2da24b2908 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -1118,6 +1118,16 @@ bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) -> append_tail_segment(Segs, St) -> app_tail_seg(Segs, St, []). +app_tail_seg([#c_bitstr{val=Var0,size=#c_literal{val=all}}=Seg0]=L, + St0, Acc) -> + case Var0 of + #c_var{name='_'} -> + {Var,St} = new_var(St0), + Seg = Seg0#c_bitstr{val=Var}, + {reverse(Acc, [Seg]),Var,St}; + #c_var{} -> + {reverse(Acc, L),Var0,St0} + end; app_tail_seg([H|T], St, Acc) -> app_tail_seg(T, St, [H|Acc]); app_tail_seg([], St0, Acc) -> -- cgit v1.2.3