4
votes

A simple protocol yields two kinds of dialyzer warnings:

defmodule Dtest do
  defprotocol Valid do
    @doc "Returns true if data is in a valid state"
    def valid?(data)
  end

  defimpl Valid, for: Integer do
    def valid?(_), do: true
  end
end

The warning I can't figure out is this:

dtest.ex:2: The specification for
'Elixir.Dtest.Valid':'__protocol__'/1 states that the function might
also return 'true' but the inferred return is 
'Elixir.Dtest.Valid' | 'false' | [{'valid?',1},...]

I also couldn't figure out a @spec that'd work here to silence the warning.

The other kind of warning has been discussed elsewhere – many "unknown functions" listed:

Unknown functions:
  'Elixir.Dtest.Valid.Atom':'__impl__'/1
  'Elixir.Dtest.Valid.BitString':'__impl__'/1

(etc.)

Is there a @spec that can be used with defprotocol's? I haven't found any examples. Or, is there a way, in the source code to mark the defprotocol to be ignored by dialyzer?

EDIT: Here's the full fix for the first error:

defmodule Dtest do
  defprotocol Valid do
    @doc "Returns true if data is in a valid state"
    @dialyzer {:nowarn_function, __protocol__: 1}
    def valid?(data)
  end

  defimpl Valid, for: Integer do
    def valid?(_), do: true
  end
end
1
Can you take a look and see whether this recently created bug is related? bugs.erlang.org/browse/ERL-159aronisstav
@aronisstav that's a regression in erlang 19. I'm seeing this in 18, so probably not.Aaron Jensen

1 Answers

3
votes

I'm using

  @dialyzer {:nowarn_function, __protocol__: 1}

in the protocol definition for now.