I have two function clauses
@spec some_function(integer(), :unavailable) ::
{:ok, User.t()} | {:error, Ecto.Changeset.t()}
def some_function(id, :unavailable) do
@spec some_function(integer(), :waiting | :working) ::
{:ok, User.t()} | {:error, Ecto.Changeset.t()}
def some_function(id, state) do
call this function
SomeModule.some_function(3, :waiting)
This will raise warning from dialyzer.
Is there better way to implement this function? or I can ignore warning?
al2o3cr
November 11, 2022, 8:44pm
2
What warning?
Depending on the specific message, this thread may be relevant:
I’m confused… when grooming the docs for https://elixir-lang.org/getting-started/typespecs-and-behaviours.html I got the feedback that multiple function clauses require multiple @specs. But now that I’m digging into dialyzer, I’m getting errors in places where I’ve done that. E.g.
Overloaded contract for MyApp.some_function/1 has
overlapping domains; such contracts are currently unsupported and
are simply ignored.
Consider this module:
defmodule MyApp.Helpers do
alias Absinthe.Blueprin…
the warning probably is about defining twice the spec. Use 1 spec for both functions
@spec some_function(integer(), :unavailable | :waiting | :warning) ::
{:ok, User.t()} | {:error, Ecto.Changeset.t()}
1 Like
The call 'Elixir.MyApp.SomeModule':some_function
(_id@1 :: any(),
'waiting') breaks the contract
(integer(),'atom') ->
{'ok',
'Elixir.MyApp.SomeModule.User':t()} |
{'error', 'Elixir.Ecto.Changeset':t()};
(integer(), binary(), 'unavailable') ->
{'ok',
'Elixir.MyApp.SomeModule.User':t()} |
{'error', 'Elixir.Ecto.Changeset':t()} in the 2nd argument
I think function call pattern matched on first function function only that has :unavaiable
al2o3cr
November 11, 2022, 9:55pm
5
That message implies that some_function
s spec has been parsed as if it was written:
@spec some_function(integer(), :atom) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
@spec some_function(integer(), binary(), :unavailable) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
which explains why Dialyzer is complaining - some_function(3, :waiting)
doesn’t match either of those.
A followup question - why does the compiler think the spec is like that? - is harder to answer.
A good first step would be removing the _build
directory in the project to regenerate all the compiled BEAM files; this may not fix the problem but it definitely won’t make things any worse.
If you’re using a language server, check its documentation to see if it has any other artifact hoards that might need clearing.