Skip to content

Commit 7cb1809

Browse files
committed
Better error reporting for invalid type specifications
Closes #818
1 parent 8994feb commit 7cb1809

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

lib/elixir/lib/kernel/typespec.ex

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,17 @@ defmodule Kernel.Typespec do
350350
do_deftype(kind, type, definition, caller)
351351
end
352352

353-
def deftype(kind, type, caller) do
353+
def deftype(kind, {name, _meta, args} = type, caller) when
354+
is_atom(name) and
355+
not is_list(args) do
354356
do_deftype(kind, type, { :term, [line: caller.line], nil }, caller)
355357
end
356358

359+
def deftype(_kind, other, _caller) do
360+
type_spec = Macro.to_binary(other)
361+
raise ArgumentError, message: "invalid type specification #{type_spec}"
362+
end
363+
357364
defp do_deftype(kind, { name, _, args }, definition, caller) do
358365
args =
359366
if is_atom(args) do
@@ -390,6 +397,11 @@ defmodule Kernel.Typespec do
390397
code
391398
end
392399

400+
def defspec(_type, other, _caller) do
401+
spec = Macro.to_binary(other)
402+
raise ArgumentError, message: "invalid function type specification #{spec}"
403+
end
404+
393405
defp guard_to_constraints({ :is_subtype, meta, [{ name, _, _ }, type] }, caller) do
394406
line = line(meta)
395407
contraints = [{ :atom, line, :is_subtype }, [{:var, line, name}, typespec(type, [], caller)]]

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,32 @@ defmodule Typespec.TypeTest do
1717
end
1818
end
1919

20+
test "invalid type specification" do
21+
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
22+
test_module do
23+
@type mytype = 1
24+
end
25+
end
26+
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
27+
test_module do
28+
@typep mytype = 1
29+
end
30+
end
31+
assert_raise ArgumentError, "invalid type specification mytype = 1", fn ->
32+
test_module do
33+
@opaque mytype = 1
34+
end
35+
end
36+
end
37+
38+
test "invalid function specification" do
39+
assert_raise ArgumentError, "invalid function type specification myfun = 1", fn ->
40+
test_module do
41+
@spec myfun = 1
42+
end
43+
end
44+
end
45+
2046
test "@type with no body (defaults to 'term')" do
2147
spec = test_module do
2248
@type mytype

0 commit comments

Comments
 (0)