Permalink
Browse files

Release v1.4.4

  • Loading branch information...
josevalim committed May 15, 2017
1 parent b2b974d commit 867da6f876c48279823a41a33030c95ef37379b2
Showing with 49 additions and 14 deletions.
  1. +10 −0 CHANGELOG.md
  2. +1 −1 VERSION
  3. +16 −12 lib/elixir/src/elixir_map.erl
  4. +21 −0 lib/elixir/test/elixir/kernel/warning_test.exs
  5. +1 −1 src/elixir.app.src
@@ -109,6 +109,16 @@ You can now also install archives from Hex in this way. Since they are fetched a
It is also possible to install escripts and archives by providing a Git/GitHub repo. See `mix help escript.install` and `mix help archive.install` for more details.
## v1.4.4 (2017-05-15)
This version includes changes that make Elixir fully compatible with Erlang OTP 20-rc.1.
### 1. Bug fixes
#### Elixir
* [Map] Fix regression on struct update syntax
## v1.4.3 (2017-05-15)
This version includes changes that make Elixir fully compatible with Erlang OTP 20-rc.1.
@@ -1 +1 @@
1.4.3
1.4.4
@@ -13,18 +13,8 @@ expand_map(Meta, Args, E) ->
{{'%{}', Meta, EArgs}, EA}.

expand_struct(Meta, Left, {'%{}', MapMeta, MapArgs}, #{context := Context} = E) ->
CleanArgs =
case lists:keytake('__struct__', 1, MapArgs) of
{value, _, ValueArgs} ->
elixir_errors:warn(?line(Meta), ?m(E, file),
"key :__struct__ is ignored when building structs"),
ValueArgs;
false ->
MapArgs
end,

{[ELeft | EArgs], EE} = elixir_exp:expand_args([Left | CleanArgs], E),
ERight = {'%{}', MapMeta, EArgs},
CleanArgs = clean_struct_key_from_map_args(Meta, MapArgs, E),
{[ELeft, ERight], EE} = elixir_exp:expand_args([Left, {'%{}', MapMeta, CleanArgs}], E),

case validate_struct(ELeft, Context) of
true when is_atom(ELeft) ->
@@ -54,6 +44,20 @@ expand_struct(Meta, _Left, Right, E) ->
compile_error(Meta, ?m(E, file), "expected struct to be followed by a map, got: ~ts",
['Elixir.Macro':to_string(Right)]).

clean_struct_key_from_map_args(Meta, [{'|', PipeMeta, [Left, MapAssocs]}], E) ->
[{'|', PipeMeta, [Left, clean_struct_key_from_map_assocs(Meta, MapAssocs, E)]}];
clean_struct_key_from_map_args(Meta, MapAssocs, E) ->
clean_struct_key_from_map_assocs(Meta, MapAssocs, E).

clean_struct_key_from_map_assocs(Meta, Assocs, E) ->
case lists:keytake('__struct__', 1, Assocs) of
{value, _, CleanAssocs} ->
elixir_errors:warn(?line(Meta), ?m(E, file), "key :__struct__ is ignored when using structs"),
CleanAssocs;
false ->
Assocs
end.

validate_struct({'^', _, [{Var, _, Ctx}]}, match) when is_atom(Var), is_atom(Ctx) -> true;
validate_struct({Var, _Meta, Ctx}, match) when is_atom(Var), is_atom(Ctx) -> true;
validate_struct(Atom, _) when is_atom(Atom) -> true;
@@ -781,6 +781,27 @@ defmodule Kernel.WarningTest do
purge Sample
end

defmodule User do
defstruct [:name]
end

test ":__struct__ is ignored when using structs" do
assert capture_err(fn ->
Code.eval_string """
assert %Kernel.WarningTest.User{__struct__: Ignored, name: "joe"} ==
%Kernel.WarningTest.User{name: "joe"}
""", [], __ENV__
end) =~ "key :__struct__ is ignored when using structs"

assert capture_err(fn ->
Code.eval_string """
user = %Kernel.WarningTest.User{name: "meg"}
assert %Kernel.WarningTest.User{user | __struct__: Ignored, name: "joe"} ==
%Kernel.WarningTest.User{__struct__: Kernel.WarningTest.User, name: "joe"}
""", [], __ENV__
end) =~ "key :__struct__ is ignored when using structs"
end

defp purge(list) when is_list(list) do
Enum.each list, &purge/1
end
@@ -1,6 +1,6 @@
{application, elixir,
[{description, "elixir"},
{vsn, "1.4.3"},
{vsn, "1.4.4"},
{modules, [
elixir
]},

0 comments on commit 867da6f

Please sign in to comment.