Skip to content

Commit 6715c52

Browse files
author
José Valim
committed
Improve error messages from typespecs, closes #1401
1 parent 1c7a37a commit 6715c52

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

lib/elixir/lib/kernel/typespec.ex

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,9 @@ defmodule Kernel.Typespec do
349349
do_deftype(kind, type, { :term, [line: caller.line], nil }, caller)
350350
end
351351

352-
def deftype(_kind, other, _caller) do
352+
def deftype(_kind, other, caller) do
353353
type_spec = Macro.to_string(other)
354-
raise ArgumentError, message: "invalid type specification #{type_spec}"
354+
compile_error caller, "invalid type specification #{type_spec}"
355355
end
356356

357357
defp do_deftype(kind, { name, _, args }, definition, caller) do
@@ -390,9 +390,9 @@ defmodule Kernel.Typespec do
390390
code
391391
end
392392

393-
def defspec(_type, other, _caller) do
393+
def defspec(_type, other, caller) do
394394
spec = Macro.to_string(other)
395-
raise ArgumentError, message: "invalid function type specification #{spec}"
395+
compile_error caller, "invalid function type specification #{spec}"
396396
end
397397

398398
defp guard_to_constraints({ :is_subtype, meta, [{ name, _, _ }, type] }, caller) do
@@ -591,9 +591,11 @@ defmodule Kernel.Typespec do
591591
end
592592

593593
# Handle remote calls
594-
defp typespec({{:., meta, [remote, name]}, _, args}, vars, caller) do
594+
defp typespec({{:., meta, [remote, name]}, _, args} = orig, vars, caller) do
595595
remote = Macro.expand remote, caller
596-
unless is_atom(remote), do: raise(ArgumentError, message: "invalid remote in typespec")
596+
unless is_atom(remote) do
597+
compile_error(caller, "invalid remote in typespec: #{Macro.to_string(orig)}")
598+
end
597599
remote_type({typespec(remote, vars, caller), meta, typespec(name, vars, caller), args}, vars, caller)
598600
end
599601

@@ -668,8 +670,8 @@ defmodule Kernel.Typespec do
668670
end
669671

670672
defp typespec([h|t] = l, vars, caller) do
671-
union = Enum.reduce(t, validate_kw(h, l), fn(x, acc) ->
672-
{ :|, [], [acc, validate_kw(x, l)] }
673+
union = Enum.reduce(t, validate_kw(h, l, caller), fn(x, acc) ->
674+
{ :|, [], [acc, validate_kw(x, l, caller)] }
673675
end)
674676
typespec({ :list, [], [union] }, vars, caller)
675677
end
@@ -681,6 +683,10 @@ defmodule Kernel.Typespec do
681683

682684
## Helpers
683685

686+
defp compile_error(caller, desc) do
687+
raise CompileError, file: caller.file, line: caller.line, description: desc
688+
end
689+
684690
defp remote_type({remote, meta, name, arguments}, vars, caller) do
685691
arguments = lc arg inlist arguments, do: typespec(arg, vars, caller)
686692
{ :remote_type, line(meta), [ remote, name, arguments ] }
@@ -689,9 +695,9 @@ defmodule Kernel.Typespec do
689695
defp collect_union({ :|, _, [a, b] }), do: [b|collect_union(a)]
690696
defp collect_union(v), do: [v]
691697

692-
defp validate_kw({ key, _ } = t, _) when is_atom(key), do: t
693-
defp validate_kw(_, original) do
694-
raise ArgumentError, message: "unexpected list #{inspect original} in typespec"
698+
defp validate_kw({ key, _ } = t, _, _caller) when is_atom(key), do: t
699+
defp validate_kw(_, original, caller) do
700+
compile_error(caller, "unexpected list #{Macro.to_string original} in typespec")
695701
end
696702

697703
defp fn_args(meta, args, return, vars, caller) do

0 commit comments

Comments
 (0)