Skip to content

Commit 74d73ac

Browse files
author
José Valim
committed
Improve error message on invalid map definition, closes #4068
1 parent 4c67b83 commit 74d73ac

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

lib/elixir/lib/kernel/typespec.ex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,16 @@ defmodule Kernel.Typespec do
722722
{:type, line(meta), :map, :any}
723723
end
724724

725-
defp typespec({:%{}, meta, fields}, vars, caller) do
725+
defp typespec({:%{}, meta, fields} = map, vars, caller) do
726726
fields =
727-
:lists.map(fn {k, v} ->
728-
{:type, line(meta), :map_field_assoc, [typespec(k, vars, caller), typespec(v, vars, caller)]}
727+
:lists.map(fn
728+
{k, v} ->
729+
{:type, line(meta), :map_field_assoc, [typespec(k, vars, caller), typespec(v, vars, caller)]}
730+
{:|, _, [_, _]} ->
731+
compile_error(caller, "invalid map specification. When using the | operator in the map key, " <>
732+
"make sure to wrap the key type in parentheses: #{Macro.to_string(map)}")
733+
_ ->
734+
compile_error(caller, "invalid map specification: #{Macro.to_string(map)}")
729735
end, fields)
730736

731737
{:type, line(meta), :map, fields}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,6 @@ defmodule Kernel.ErrorsTest do
889889
'''
890890

891891
message = "nofile:2: spec for undefined function omg/0"
892-
893892
assert_compile_fail CompileError, message,
894893
'''
895894
defmodule Kernel.ErrorsTest.TypespecErrors2 do

lib/elixir/test/elixir/kernel/typespec_test.exs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,14 @@ defmodule Kernel.TypespecTest do
281281
end
282282
end
283283

284+
test "@type with an invalid map notation" do
285+
assert_raise CompileError, ~r"invalid map specification", fn ->
286+
test_module do
287+
@type content :: %{atom | String.t => term}
288+
end
289+
end
290+
end
291+
284292
test "@type with list shortcuts" do
285293
module = test_module do
286294
@type mytype :: []
@@ -662,7 +670,7 @@ defmodule Kernel.TypespecTest do
662670
end
663671
end
664672

665-
test "@spec gives a nice error message when return type is missing" do
673+
test "@spec shows readable error message when return type is missing" do
666674
assert_raise CompileError, ~r"type specification missing return type: myfun\(integer\)", fn ->
667675
test_module do
668676
@spec myfun(integer)

0 commit comments

Comments
 (0)