Skip to content

Commit ca57cfe

Browse files
committed
Handle non-binary bitstring in struct default values (elixir-lang#14363)
1 parent c32f725 commit ca57cfe

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

lib/elixir/src/elixir_erl.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ elixir_to_erl(Tree, Ann) when is_binary(Tree) ->
9292
%% considers a string in a binary to be encoded in latin1, so the bytes
9393
%% are not changed in any fashion.
9494
{bin, Ann, [{bin_element, Ann, {string, Ann, binary_to_list(Tree)}, default, default}]};
95+
elixir_to_erl(Tree, Ann) when is_bitstring(Tree) ->
96+
Segments = [elixir_to_erl_bitstring_segment(X, Ann) || X <- bitstring_to_list(Tree)],
97+
{bin, Ann, Segments};
9598
elixir_to_erl(Tree, Ann) when is_function(Tree) ->
9699
case (erlang:fun_info(Tree, type) == {type, external}) andalso
97100
(erlang:fun_info(Tree, env) == {env, []}) of
@@ -111,6 +114,13 @@ elixir_to_erl(Tree, Ann) ->
111114
elixir_to_erl_cons([H | T], Ann) -> {cons, Ann, elixir_to_erl(H, Ann), elixir_to_erl_cons(T, Ann)};
112115
elixir_to_erl_cons(T, Ann) -> elixir_to_erl(T, Ann).
113116

117+
elixir_to_erl_bitstring_segment(Int, Ann) when is_integer(Int) ->
118+
{bin_element, Ann, {integer, Ann, Int}, default, [integer]};
119+
elixir_to_erl_bitstring_segment(Rest, Ann) when is_bitstring(Rest) ->
120+
Size = bit_size(Rest),
121+
<<Int:Size>> = Rest,
122+
{bin_element, Ann, {integer, Ann, Int}, {integer, Ann, Size}, [integer]}.
123+
114124
%% Returns a scope for translation.
115125

116126
scope(_Meta, ExpandCaptures) ->

lib/elixir/test/elixir/map_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,15 @@ defmodule MapTest do
395395
assert quoted == {:%, [], [User, {:%{}, [], [{:foo, 1}]}]}
396396
end
397397

398+
test "structs with bitstring defaults" do
399+
defmodule WithBitstring do
400+
defstruct bitstring: <<255, 127::7>>
401+
end
402+
403+
info = Macro.struct_info!(WithBitstring, __ENV__)
404+
assert info == [%{default: <<255, 127::7>>, field: :bitstring}]
405+
end
406+
398407
test "defstruct can only be used once in a module" do
399408
message =
400409
"defstruct has already been called for TestMod, " <>

0 commit comments

Comments
 (0)