[erlang-questions] Dialyzer underspecs and overspecs options

Dmitry Kakurin dima_kakurin@REDACTED
Tue Mar 28 19:29:59 CEST 2017

> What you want is provided as a default behaviour.

Hi Alex,

My observations don't match your statement above:

* Removing -Wunderspecs switch makes warning in both under_ methods disappear

* Removing -Woverspecs switch makes warning in both over_ methods disappear

* Removing both -W makes all 4 warnings disappear

And I'll reply to Jasper's email on usefulness of both underspecs and overspecs.

Thank you, Dmitry.
From: Alex S. <alex0player@REDACTED>
Sent: Monday, March 27, 2017 1:09 AM
To: Dmitry Kakurin
Cc: erlang-questions@REDACTED
Subject: Re: [erlang-questions] Dialyzer underspecs and overspecs options

What you want is provided as a default behaviour. Overspecs you shouldn’t really enable for production needs, it’s «debug the Dialyzer» feature.

24 марта 2017 г., в 21:42, Dmitry Kakurin <dima_kakurin@REDACTED<mailto:dima_kakurin@REDACTED>> написал(а):

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

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

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

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

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

Thanks, Dmitry.
erlang-questions mailing list

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170328/9022d0a1/attachment.htm>

More information about the erlang-questions mailing list