   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

  end

  # Handle remote calls
  defp typespec({{:., meta, [remote, name]}, _, args}, vars, caller) do
    remote = Macro.expand remote, caller
    unless is_atom(remote), do: raise(ArgumentError, message: "invalid remote in typespec")
    remote_type({typespec(remote, vars, caller), meta, typespec(name, vars, caller), args}, vars, caller)
  end


  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
