[erlang-questions] Dialyzer underspecs and overspecs options

Dmitry Kakurin dima_kakurin@REDACTED
Fri Mar 24 19:42:28 CET 2017


Hi all,

I've started using Dialyzer and tried to enable as many warnings as possible.

Two of them that seem especially useful are underspecs and overspecs.

But after struggling with warnings produced by them for a while I've realized that what I really need is a subset of each.

In the example below (sorry, I'm using Elixir syntax but hope it's still obvious) the 2 warnings I want to enable are under_in and over_out. They are the ones that will break callers relying on the spec. While over_in and under_out warnings are more of a hints to the function author about current implementation and are much less serious.

The current Dialyzer options allow me to enable either both over_* warnings or both under_* warnings. But that's not useful.

Is there a way to configure Dialyzer the way I want?


Here is the demo code:


  # suboptimal implementation, fine for caller
  @spec over_in(x :: integer) :: nil
  def over_in(x) when is_number(x) do
    nil
  end

  # broken caller contract, could return unexpected value
  @spec over_out(x :: number) :: integer
  def over_out(x) when is_number(x) do
    x
  end

  # broken caller contract, rejects input allowed by the spec
  @spec under_in(x :: number) :: nil
  def under_in(x) when is_integer(x) do
    nil
  end

  # current implementation detail, does not concern caller
  @spec under_out(x :: integer) :: number
  def under_out(x) when is_integer(x) do
    x
  end


and here are the warnings:


demo.ex:4: Type specification
'Elixir.Virt':over_in(x::integer()) -> 'nil' is a subtype of the success typing:
'Elixir.Virt':over_in(number()) -> 'nil'

demo.ex:9: Type specification
'Elixir.Virt':over_out(x::number()) -> integer() is a subtype of the success typing:
'Elixir.Virt':over_out(number()) -> number()

demo.ex:14: Type specification
'Elixir.Virt':under_in(x::number()) -> 'nil' is a supertype of the success typing:
'Elixir.Virt':under_in(integer()) -> 'nil'

demo.ex:19: The specification for 'Elixir.Virt':under_out/1 states that the function might also return
float() but the inferred return is
integer()


Thanks, Dmitry.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170324/aee16ba6/attachment.htm>


More information about the erlang-questions mailing list