Skip to content

Commit f8d775c

Browse files
author
José Valim
committed
Warn when overriding __struct__ key
1 parent da10a7d commit f8d775c

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

lib/elixir/src/elixir_map.erl

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,19 @@ expand_map(Meta, Args, E) ->
1212
validate_kv(Meta, EArgs, Args, E),
1313
{{'%{}', Meta, EArgs}, EA}.
1414

15-
expand_struct(Meta, Left, Right, #{context := Context} = E) ->
16-
{[ELeft, ERight], EE} = elixir_exp:expand_args([Left, Right], E),
15+
expand_struct(Meta, Left, {'%{}', MapMeta, MapArgs}, #{context := Context} = E) ->
16+
CleanArgs =
17+
case lists:keytake('__struct__', 1, MapArgs) of
18+
{value, _, ValueArgs} ->
19+
elixir_errors:warn(?line(Meta), ?m(E, file),
20+
"key :__struct__ is ignored when building structs"),
21+
ValueArgs;
22+
false ->
23+
MapArgs
24+
end,
25+
26+
{[ELeft | EArgs], EE} = elixir_exp:expand_args([Left | CleanArgs], E),
27+
ERight = {'%{}', MapMeta, EArgs},
1728

1829
case validate_struct(ELeft, Context) of
1930
true when is_atom(ELeft) ->
@@ -38,14 +49,10 @@ expand_struct(Meta, Left, Right, #{context := Context} = E) ->
3849
false -> Meta
3950
end,
4051

41-
case ERight of
42-
{'%{}', _, _} -> ok;
43-
_ -> compile_error(Meta, ?m(E, file),
44-
"expected struct to be followed by a map, got: ~ts",
45-
['Elixir.Macro':to_string(ERight)])
46-
end,
47-
48-
{{'%', EMeta, [ELeft, ERight]}, EE}.
52+
{{'%', EMeta, [ELeft, ERight]}, EE};
53+
expand_struct(Meta, _Left, Right, E) ->
54+
compile_error(Meta, ?m(E, file), "expected struct to be followed by a map, got: ~ts",
55+
['Elixir.Macro':to_string(Right)]).
4956

5057
validate_struct({'^', _, [{Var, _, Ctx}]}, match) when is_atom(Var), is_atom(Ctx) -> true;
5158
validate_struct({Var, _Meta, Ctx}, match) when is_atom(Var), is_atom(Ctx) -> true;
@@ -66,11 +73,10 @@ translate_map(Meta, Args, S) ->
6673
translate_map(Meta, Assocs, TUpdate, US).
6774

6875
translate_struct(_Meta, Name, {'%{}', MapMeta, Assocs}, S) when is_tuple(Name) ->
69-
translate_map(MapMeta, [{'__struct__', Name} | delete_struct_key(Assocs)], nil, S);
76+
translate_map(MapMeta, [{'__struct__', Name} | Assocs], nil, S);
7077

7178
translate_struct(Meta, Name, {'%{}', MapMeta, Args}, S) ->
72-
{TAssocs, TUpdate, US} = extract_assoc_update(Args, S),
73-
Assocs = delete_struct_key(TAssocs),
79+
{Assocs, TUpdate, US} = extract_assoc_update(Args, S),
7480
Operation = operation(TUpdate, S),
7581

7682
Struct = case Operation of
@@ -191,9 +197,6 @@ extract_assoc_update([{'|', _Meta, [Update, Args]}], S) ->
191197
{Args, TArg, SA};
192198
extract_assoc_update(Args, SA) -> {Args, nil, SA}.
193199

194-
delete_struct_key(Assocs) ->
195-
lists:keydelete('__struct__', 1, Assocs).
196-
197200
extract_key_val_op(_TUpdate, #elixir_scope{context=match}) ->
198201
{map_field_exact,
199202
fun(X, Acc) -> elixir_translator:translate(X, Acc#elixir_scope{extra=map_key}) end,

0 commit comments

Comments
 (0)