Skip to content

Commit fa091c6

Browse files
ericmjjosevalim
authored andcommitted
Only error for duplicate map keys in matches (#9748)
In matches we will error: %{a: :b, a: :c} = %{a: :b} In normal expressions we will only warn: %{a: :b, a: :c}
1 parent a561f81 commit fa091c6

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

lib/elixir/src/elixir_map.erl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@ validate_match_key(_, _, _) ->
8787
validate_not_repeated(Meta, Key, Used, E) ->
8888
case is_literal(Key) andalso Used of
8989
#{Key := true} ->
90-
form_error(Meta, ?key(E, file), ?MODULE, {repeated_key, Key});
90+
case E of
91+
#{context := match} ->
92+
form_error(Meta, ?key(E, file), ?MODULE, {repeated_key, Key});
93+
_ ->
94+
form_warn(Meta, ?key(E, file), ?MODULE, {repeated_key, Key}),
95+
Used
96+
end;
9197

9298
#{} ->
9399
Used#{Key => true};

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,23 +1226,13 @@ defmodule Kernel.ErrorsTest do
12261226
end
12271227

12281228
test "duplicate map keys" do
1229-
assert_eval_raise CompileError, "nofile:1: key :a will be overridden in map", """
1230-
%{a: :b, a: :c}
1231-
"""
1232-
12331229
assert_eval_raise CompileError, "nofile:1: key :a will be overridden in map", """
12341230
%{a: :b, a: :c} = %{a: :c}
12351231
"""
12361232

1237-
assert_eval_raise CompileError, "nofile:1: key :m will be overridden in map", """
1238-
%{m: :n, m: :o, m: :p}
1239-
"""
1240-
1241-
assert_eval_raise CompileError, "nofile:1: key 1 will be overridden in map", """
1242-
%{1 => 2, 1 => 3}
1233+
assert_eval_raise CompileError, "nofile:1: key :a will be overridden in map", """
1234+
%{a: :b, a: :c, a: :d} = %{a: :c}
12431235
"""
1244-
1245-
assert map_size(%{System.unique_integer() => 1, System.unique_integer() => 2}) == 2
12461236
end
12471237

12481238
defp bad_remote_call(x), do: x.foo

lib/elixir/test/elixir/kernel/warning_test.exs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,23 @@ defmodule Kernel.WarningTest do
578578
purge(Sample)
579579
end
580580

581+
test "duplicate map keys" do
582+
output =
583+
capture_err(fn ->
584+
defmodule DuplicateMapKeys do
585+
assert %{a: :b, a: :c} == %{a: :c}
586+
assert %{m: :n, m: :o, m: :p} == %{m: :p}
587+
assert %{1 => 2, 1 => 3} == %{1 => 3}
588+
end
589+
end)
590+
591+
assert output =~ "key :a will be overridden in map"
592+
assert output =~ "key :m will be overridden in map"
593+
assert output =~ "key 1 will be overridden in map"
594+
595+
assert map_size(%{System.unique_integer() => 1, System.unique_integer() => 2}) == 2
596+
end
597+
581598
test "unused guard" do
582599
assert capture_err(fn ->
583600
Code.eval_string("""

0 commit comments

Comments
 (0)