Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
867da6f876 |
@@ -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.
|
||||
|
||||
@@ -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
-1
@@ -1,6 +1,6 @@
|
||||
{application, elixir,
|
||||
[{description, "elixir"},
|
||||
{vsn, "1.4.3"},
|
||||
{vsn, "1.4.4"},
|
||||
{modules, [
|
||||
elixir
|
||||
]},
|
||||
|
||||
Reference in New Issue
Block a user