Skip to content

Commit 1f9433f

Browse files
committed
not_a_map.key should raise BadMapError for consistency
1 parent f400ac9 commit 1f9433f

File tree

3 files changed

+17
-23
lines changed

3 files changed

+17
-23
lines changed

lib/elixir/lib/exception.ex

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ defmodule Exception do
178178
end
179179

180180
@doc false
181-
@spec _format_message_with_term(String.t(), any) :: String.t()
182-
def _format_message_with_term(message, term) do
181+
def __format_message_with_term__(message, term) do
183182
inspected =
184183
term
185184
|> inspect(pretty: true)
@@ -1447,7 +1446,7 @@ defmodule BadStructError do
14471446

14481447
@impl true
14491448
def message(exception) do
1450-
Exception._format_message_with_term(
1449+
Exception.__format_message_with_term__(
14511450
"expected a struct named #{inspect(exception.struct)}, got:",
14521451
exception.term
14531452
)
@@ -1470,7 +1469,7 @@ defmodule BadMapError do
14701469

14711470
@impl true
14721471
def message(exception) do
1473-
Exception._format_message_with_term(
1472+
Exception.__format_message_with_term__(
14741473
"expected a map, got:",
14751474
exception.term
14761475
)
@@ -1492,7 +1491,7 @@ defmodule BadBooleanError do
14921491

14931492
@impl true
14941493
def message(exception) do
1495-
Exception._format_message_with_term(
1494+
Exception.__format_message_with_term__(
14961495
"expected a boolean on left-side of \"#{exception.operator}\", got:",
14971496
exception.term
14981497
)
@@ -1517,7 +1516,7 @@ defmodule MatchError do
15171516

15181517
@impl true
15191518
def message(exception) do
1520-
Exception._format_message_with_term(
1519+
Exception.__format_message_with_term__(
15211520
"no match of right hand side value:",
15221521
exception.term
15231522
)
@@ -1546,7 +1545,7 @@ defmodule CaseClauseError do
15461545

15471546
@impl true
15481547
def message(exception) do
1549-
Exception._format_message_with_term(
1548+
Exception.__format_message_with_term__(
15501549
"no case clause matching:",
15511550
exception.term
15521551
)
@@ -1579,7 +1578,7 @@ defmodule WithClauseError do
15791578

15801579
@impl true
15811580
def message(exception) do
1582-
Exception._format_message_with_term(
1581+
Exception.__format_message_with_term__(
15831582
"no with clause matching:",
15841583
exception.term
15851584
)
@@ -1632,7 +1631,7 @@ defmodule TryClauseError do
16321631

16331632
@impl true
16341633
def message(exception) do
1635-
Exception._format_message_with_term(
1634+
Exception.__format_message_with_term__(
16361635
"no try clause matching:",
16371636
exception.term
16381637
)
@@ -2197,7 +2196,7 @@ defmodule KeyError do
21972196
"make sure to add parentheses after the function name)"
21982197

21992198
true ->
2200-
Exception._format_message_with_term(
2199+
Exception.__format_message_with_term__(
22012200
message <> " in:",
22022201
term
22032202
)

lib/elixir/src/elixir_erl_pass.erl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ translate({{'.', _, [Left, Right]}, Meta, []}, _Ann, S)
248248

249249
case proplists:get_value(no_parens, Meta, false) of
250250
true ->
251-
TError = {tuple, Ann, [{atom, Ann, badkey}, TRight, TVar]},
252251
{{'case', Generated, TLeft, [
253252
{clause, Generated,
254253
[{map, Ann, [{map_field_exact, Ann, TRight, TVar}]}],
@@ -261,7 +260,7 @@ translate({{'.', _, [Left, Right]}, Meta, []}, _Ann, S)
261260
{clause, Generated,
262261
[{tuple, Generated, [{atom, Generated, ok}, TInnerVar]}], [], [TInnerVar]},
263262
{clause, Generated,
264-
[{var, Generated, '_'}], [], [?remote(Ann, erlang, error, [TError])]}
263+
[{tuple, Generated, [{atom, Generated, error}, TInnerVar]}], [], [?remote(Ann, erlang, error, [TInnerVar])]}
265264
]}]}
266265
]}, SV};
267266
false ->
@@ -716,9 +715,9 @@ generate_struct_name_guard([Field | Rest], Acc, S) ->
716715
generate_struct_name_guard(Rest, [Field | Acc], S).
717716

718717
%% TODO: Make this a runtime error on Elixir v2.0
719-
no_parens_remote(nil, _Fun) -> error;
720-
no_parens_remote(false, _Fun) -> error;
721-
no_parens_remote(true, _Fun) -> error;
718+
no_parens_remote(nil, _Key) -> {error, {badmap, nil}};
719+
no_parens_remote(false, _Key) -> {error, {badmap, false}};
720+
no_parens_remote(true, _Key) -> {error, {badmap, false}};
722721
no_parens_remote(Atom, Fun) when is_atom(Atom) ->
723722
Message = fun() ->
724723
io_lib:format(
@@ -729,8 +728,10 @@ no_parens_remote(Atom, Fun) when is_atom(Atom) ->
729728
end,
730729
'Elixir.IO':warn_once(?MODULE, Message, 3),
731730
{ok, apply(Atom, Fun, [])};
732-
no_parens_remote(_Other, _Fun) ->
733-
error.
731+
no_parens_remote(#{} = Map, Key) ->
732+
{error, {badkey, Key, Map}};
733+
no_parens_remote(Other, _Key) ->
734+
{error, {badmap, Other}}.
734735

735736
parens_map_field(Key, Value) ->
736737
Message = fun() ->

lib/elixir/test/elixir/exception_test.exs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,12 +698,6 @@ defmodule ExceptionTest do
698698
"function :erlang.hash/2 is undefined or private, use erlang:phash2/2 instead"
699699
end
700700

701-
test "annotates undefined key error with nil hints" do
702-
assert blame_message(nil, & &1.foo) ==
703-
"key :foo not found in: nil\n\nIf you are using the dot syntax, " <>
704-
"such as map.field, make sure the left-hand side of the dot is a map"
705-
end
706-
707701
test "annotates undefined function clause error with nil hints" do
708702
assert blame_message(nil, & &1.foo()) ==
709703
"function nil.foo/0 is undefined. If you are using the dot syntax, " <>

0 commit comments

Comments
 (0)