diff --git a/lib/elixir/src/elixir_erl.erl b/lib/elixir/src/elixir_erl.erl index b8bfc852f59..395055c9c3f 100644 --- a/lib/elixir/src/elixir_erl.erl +++ b/lib/elixir/src/elixir_erl.erl @@ -96,6 +96,9 @@ elixir_to_erl(Tree, Ann) when is_binary(Tree) -> %% considers a string in a binary to be encoded in latin1, so the bytes %% are not changed in any fashion. {bin, Ann, [{bin_element, Ann, {string, Ann, binary_to_list(Tree)}, default, default}]}; +elixir_to_erl(Tree, Ann) when is_bitstring(Tree) -> + Segments = [elixir_to_erl_bitstring_segment(X, Ann) || X <- bitstring_to_list(Tree)], + {bin, Ann, Segments}; elixir_to_erl(Tree, Ann) when is_function(Tree) -> case (erlang:fun_info(Tree, type) == {type, external}) andalso (erlang:fun_info(Tree, env) == {env, []}) of @@ -115,6 +118,13 @@ elixir_to_erl(Tree, Ann) -> elixir_to_erl_cons([H | T], Ann) -> {cons, Ann, elixir_to_erl(H, Ann), elixir_to_erl_cons(T, Ann)}; elixir_to_erl_cons(T, Ann) -> elixir_to_erl(T, Ann). +elixir_to_erl_bitstring_segment(Int, Ann) when is_integer(Int) -> + {bin_element, Ann, {integer, Ann, Int}, default, [integer]}; +elixir_to_erl_bitstring_segment(Rest, Ann) when is_bitstring(Rest) -> + Size = bit_size(Rest), + <> = Rest, + {bin_element, Ann, {integer, Ann, Int}, {integer, Ann, Size}, [integer]}. + %% Returns a scope for translation. scope(_Meta, ExpandCaptures) -> diff --git a/lib/elixir/test/elixir/map_test.exs b/lib/elixir/test/elixir/map_test.exs index 61d4ce7cdc6..dd1dd6c5d83 100644 --- a/lib/elixir/test/elixir/map_test.exs +++ b/lib/elixir/test/elixir/map_test.exs @@ -395,6 +395,15 @@ defmodule MapTest do assert quoted == {:%, [], [User, {:%{}, [], [{:foo, 1}]}]} end + test "structs with bitstring defaults" do + defmodule WithBitstring do + defstruct bitstring: <<255, 127::7>> + end + + info = Macro.struct_info!(WithBitstring, __ENV__) + assert info == [%{default: <<255, 127::7>>, field: :bitstring}] + end + test "defstruct can only be used once in a module" do message = "defstruct has already been called for TestMod, " <>