Does dyalizer need @spec when a function has @impl?

You can provide a typespec for behaviour callback functions. If you do so, and some arg or the return type in your spec is not a subtype of the callback spec, dialyzer will emit a corresponding warning. The same will happen if the types inferred from the callback code do not match spec types.

So e.g. the following GenServer code:

@type state :: %{foo: integer}
@spec handle_call(:foo, GenServer.from(), state) :: {:reply, :ok, state}
def handle_call(:foo, _from, state) do
  {:reply, :ok, %{state | bar: 1}}
end

Will lead to a dialyzer warning:

Invalid type specification for function 'Elixir.TestServer':handle_call/3. 
The success typing is 
          ('foo', _, #{'bar' := _, _ => _}) ->
             {'reply', 'ok', #{'bar' := 1, _ => _}}

which means that either the spec or the impl is wrong.

So far, I didn’t got into a habit of writing specs for callbacks, but I’ve been toying with this idea for some time. I think it would help documenting expected callback args, and might help catching some errors.