Skip to content

Commit 61e9faf

Browse files
author
José Valim
committed
Improve error message with invalid structures in maps
Closes #2958 Signed-off-by: José Valim <[email protected]>
1 parent aa48f6a commit 61e9faf

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

lib/elixir/src/elixir_map.erl

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
expand_map(Meta, [{'|', UpdateMeta, [Left, Right]}], E) ->
77
{[ELeft|ERight], EA} = elixir_exp:expand_args([Left|Right], E),
8+
validate_kv(Meta, ERight, Right, E),
89
{{'%{}', Meta, [{'|', UpdateMeta, [ELeft, ERight]}]}, EA};
910
expand_map(Meta, Args, E) ->
1011
{EArgs, EA} = elixir_exp:expand_args(Args, E),
12+
validate_kv(Meta, EArgs, Args, E),
1113
{{'%{}', Meta, EArgs}, EA}.
1214

1315
expand_struct(Meta, Left, Right, E) ->
@@ -35,6 +37,15 @@ expand_struct(Meta, Left, Right, E) ->
3537

3638
{{'%', EMeta, [ELeft, ERight]}, EE}.
3739

40+
validate_kv(Meta, KV, Original, E) ->
41+
lists:foldl(fun
42+
({_K, _V}, Acc) -> Acc + 1;
43+
(_, Acc) ->
44+
compile_error(Meta, ?m(E, file),
45+
"expected key-value pairs in a map, got: ~ts",
46+
['Elixir.Macro':to_string(lists:nth(Acc, Original))])
47+
end, 1, KV).
48+
3849
translate_map(Meta, Args, S) ->
3950
{Assocs, TUpdate, US} = extract_assoc_update(Args, S),
4051
translate_map(Meta, Assocs, TUpdate, US).
@@ -139,14 +150,10 @@ translate_map(Meta, Assocs, TUpdate, #elixir_scope{extra=Extra} = S) ->
139150

140151
Line = ?line(Meta),
141152

142-
{TArgs, SA} = lists:mapfoldl(fun
143-
({Key, Value}, Acc) ->
144-
{TKey, Acc1} = KeyFun(Key, Acc),
145-
{TValue, Acc2} = ValFun(Value, Acc1#elixir_scope{extra=Extra}),
146-
{{Op, ?line(Meta), TKey, TValue}, Acc2};
147-
(Other, _Acc) ->
148-
compile_error(Meta, S#elixir_scope.file, "expected key-value pairs in map, got: ~ts",
149-
['Elixir.Macro':to_string(Other)])
153+
{TArgs, SA} = lists:mapfoldl(fun({Key, Value}, Acc) ->
154+
{TKey, Acc1} = KeyFun(Key, Acc),
155+
{TValue, Acc2} = ValFun(Value, Acc1#elixir_scope{extra=Extra}),
156+
{{Op, ?line(Meta), TKey, TValue}, Acc2}
150157
end, S, Assocs),
151158

152159
build_map(Line, TUpdate, TArgs, SA).

lib/elixir/test/elixir/kernel/errors_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ defmodule Kernel.ErrorsTest do
231231
assert_compile_fail SyntaxError,
232232
"nofile:1: syntax error before: '{'",
233233
'%{:a, :b}{a: :b}'
234+
235+
assert_compile_fail CompileError,
236+
"nofile:1: expected key-value pairs in a map, got: put_in(foo.bar().baz(), nil)",
237+
'foo = 1; %{put_in(foo.bar.baz, nil), :bar}'
234238
end
235239

236240
test :struct_fields_on_defstruct do

0 commit comments

Comments
 (0)