   defp collect_union({ :|, _, [a, b] }), do: [b|collect_union(a)]
   defp collect_union(v), do: [v]
 
-  defp validate_kw({ key, _ } = t, _) when is_atom(key), do: t
-  defp validate_kw(_, original) do
-    raise ArgumentError, message: "unexpected list #{inspect original} in typespec"
+  defp validate_kw({ key, _ } = t, _, _caller) when is_atom(key), do: t
+  defp validate_kw(_, original, caller) do
+    compile_error(caller, "unexpected list #{Macro.to_string original} in typespec")
   end
 
   defp fn_args(meta, args, return, vars, caller) do


  ## Helpers

  defp remote_type({remote, meta, name, arguments}, vars, caller) do
    arguments = lc arg inlist arguments, do: typespec(arg, vars, caller)
    { :remote_type, line(meta), [ remote, name, arguments ] }

  end

  defp typespec([h|t] = l, vars, caller) do
    union = Enum.reduce(t, validate_kw(h, l, caller), fn(x, acc) ->
      { :|, [], [acc, validate_kw(x, l, caller)] }
    end)
    typespec({ :list, [], [union] }, vars, caller)
  end
