I am using the elixir_talk library. After connecting I want to call a private function once connected to beanstalkd. I just added typespecs and ran Dialyzer (via dialyxir). I get the errors:
my_module.ex:3: The specification for 'Elixir.MyModule':f/0 states that the function might also return 'ok' | {'error',_} but the inferred return is none()
my_module.ex:4: Function f/0 has no local return
my_module.ex:14: Function g/1 will never be called
The minimal example I could find that produces this is
defmodule MyModule do
@spec f() :: :ok | {:error, term}
def f() do
case ElixirTalk.connect('127.0.0.1', 11300) do
{:ok, conn} ->
g(conn)
{:error, err} ->
{:error, err}
end
end
@spec g(pid) :: :ok
defp g(pid) do
:ok
end
end
If I replace the call to ElixirTalk.connect
with a call to spawn
instead, Dialyzer no longer reports any problems.
defmodule MyModule do
@spec f() :: :ok
def f() do
x = spawn fn -> :done end
g(x)
end
@spec g(pid) :: :ok
defp g(pid) do
:ok
end
end
Does anyone know why Dialyzer is getting confused here?
1条答案
按热度按时间bnlyeluc1#
看一下源代码,类型规范说第三个参数总是一个整数,即使默认值是atom infinity。因此,调用ElixirTalk. connect时使用infinite timeout是违反类型规范的。在Erlang中,你可以通过将类型指定为timeout()来解决这个问题,它允许整数和infinite;不知道这怎么翻译成长生不老药。-legoscia 5月16日15:56