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

    code
  end

  def defspec(_type, other, _caller) do
    spec = Macro.to_string(other)
    raise ArgumentError, message: "invalid function type specification #{spec}"
  end

  defp guard_to_constraints({ :is_subtype, meta, [{ name, _, _ }, type] }, caller) do

  defp collect_union({ :|, _, [a, b] }), do: [b|collect_union(a)]
  defp collect_union(v), do: [v]

  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
