@@ -124,41 +124,59 @@ build_bitstr_each(Fun, [{'::',_,[H,V]}|T], Meta, S, Acc) ->
124124build_bitstr_each (Fun , [H |T ], Meta , S , Acc ) ->
125125 build_bitstr_each (Fun , T , Meta , S , Acc , H , default , default ).
126126
127+ build_bitstr_each (Fun , T , Meta , S , Acc , H , default , Types ) when is_binary (H ) ->
128+ Element =
129+ case types_allow_splice (Types , []) of
130+ true ->
131+ % % See explanation in elixir_utils:elixir_to_erl/1 to know
132+ % % why we can simply convert the binary to a list.
133+ { bin_element , ? line (Meta ), { string , 0 , binary_to_list (H ) }, default , default };
134+ false ->
135+ case types_require_conversion (Types ) of
136+ true ->
137+ { bin_element , ? line (Meta ), { string , 0 , elixir_utils :characters_to_list (H ) }, default , Types };
138+ false ->
139+ elixir_errors :compile_error (Meta , S # elixir_scope .file , " invalid types for literal string in <<>>. "
140+ " Accepted types are: little, big, utf8, utf16, utf32, bits, bytes, binary, bitstring" )
141+ end
142+ end ,
143+
144+ build_bitstr_each (Fun , T , Meta , S , [Element |Acc ]);
145+
146+ build_bitstr_each (_Fun , _T , Meta , S , _Acc , H , _Size , _Types ) when is_binary (H ) ->
147+ elixir_errors :compile_error (Meta , S # elixir_scope .file , " size is not supported for literal string in <<>>" );
148+
149+ build_bitstr_each (_Fun , _T , Meta , S , _Acc , H , _Size , _Types ) when is_list (H ); is_atom (H ) ->
150+ elixir_errors :compile_error (Meta , S # elixir_scope .file , " invalid literal ~ts in <<>>" ,
151+ ['Elixir.Macro' :to_string (H )]);
152+
127153build_bitstr_each (Fun , T , Meta , S , Acc , H , Size , Types ) ->
128154 { Expr , NS } = Fun (H , S ),
129155
130- AllowString = types_allow_string (Types ),
131- AllowSplice = types_allow_splice (Types ),
132- AllowAny = (AllowString orelse AllowSplice ) andalso (Size == default ),
133-
134- case AllowAny andalso Expr of
135- { bin , _ , [{ bin_element , 0 , { string , 0 , String }, default , default }] } when AllowString ->
136- build_bitstr_each (Fun , T , Meta , NS , [{ bin_element , ? line (Meta ), { string , 0 , String }, Size , Types }|Acc ]);
137- { bin , _ , Elements } when AllowSplice ->
138- build_bitstr_each (Fun , T , Meta , NS , lists :reverse (Elements ) ++ Acc );
139- { cons , _ , _ , _ } = Cons ->
140- build_bitstr_each (Fun , T , Meta , NS , rehash_cons (Cons , Size , Types , []) ++ Acc );
141- { nil , _ } ->
142- build_bitstr_each (Fun , T , Meta , NS , Acc );
156+ case Expr of
157+ { bin , _ , Elements } ->
158+ case (Size == default ) andalso types_allow_splice (Types , Elements ) of
159+ true -> build_bitstr_each (Fun , T , Meta , NS , lists :reverse (Elements ) ++ Acc );
160+ false -> build_bitstr_each (Fun , T , Meta , NS , [{ bin_element , ? line (Meta ), Expr , Size , Types }|Acc ])
161+ end ;
143162 _ ->
144163 build_bitstr_each (Fun , T , Meta , NS , [{ bin_element , ? line (Meta ), Expr , Size , Types }|Acc ])
145164 end .
146165
147- rehash_cons ({ nil , _ }, _Size , _Types , Acc ) -> Acc ;
148- rehash_cons ({ cons , Line , Left , Right }, Size , Types , Acc ) ->
149- rehash_cons (Right , Size , Types , [{ bin_element , Line , Left , Size , Types }|Acc ]).
150-
151- types_allow_string ([End |T ]) when End == little ; End == big -> types_allow_string (T );
152- types_allow_string ([UTF |T ]) when UTF == utf8 ; UTF == utf16 ; UTF == utf32 -> types_allow_string (T );
153- types_allow_string ([]) -> true ;
154- types_allow_string (_ ) -> false .
155-
156- types_allow_splice (default ) -> true ;
157- types_allow_splice ([bytes ]) -> true ;
158- types_allow_splice ([binary ]) -> true ;
159- types_allow_splice ([bits ]) -> true ;
160- types_allow_splice ([bitstring ]) -> true ;
161- types_allow_splice (_ ) -> false .
166+ types_require_conversion ([End |T ]) when End == little ; End == big -> types_require_conversion (T );
167+ types_require_conversion ([UTF |T ]) when UTF == utf8 ; UTF == utf16 ; UTF == utf32 -> types_require_conversion (T );
168+ types_require_conversion ([]) -> true ;
169+ types_require_conversion (_ ) -> false .
170+
171+ types_allow_splice ([bytes ], Elements ) -> lists :all (fun has_default_size /1 , Elements );
172+ types_allow_splice ([binary ], Elements ) -> lists :all (fun has_default_size /1 , Elements );
173+ types_allow_splice ([bits ], _ ) -> true ;
174+ types_allow_splice ([bitstring ], _ ) -> true ;
175+ types_allow_splice (default , _ ) -> true ;
176+ types_allow_splice (_ , _ ) -> false .
177+
178+ has_default_size ({ bin_element , _ , _ , default , _ }) -> true ;
179+ has_default_size ({ bin_element , _ , _ , _ , _ }) -> false .
162180
163181% % Extra bitstring specifiers
164182
0 commit comments