[erlang-questions] dialyzer -Wunderspecs and the binary() type

Kostis Sagonas kostis@REDACTED
Fri Sep 30 08:41:54 CEST 2011


On 09/29/11 21:27, James Aimonetti wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> We use -Wunderspecs a lot in our Dialyzing and the only minor complaint
> I have is when I get warnings that the success typing is more specfic
> with the binary() type.
>
> We see a lot of:
>
> foo.erl:123: Type specfication foo:a_fun(BinVal) ->  'ok' when
> is_subtype(BinVal, binary()) is a supertype of the success typing:
> foo:a_fun(<<_:8,_:_*8>>) ->  'ok'.
>
> In foo.erl, a_fun/1 is defined as:
>
> - -spec a_fun(BinVal) ->  'ok' when
>    BinVal :: binary().
> a_fun(BinVal) ->
>    %% do something with BinVal
>    ok.
>
> This is obviously a simplified, trivial example.

It's not just a simplified example.  It's an example that is incomplete 
because it does not show the problem.  Here is one that does:

   -module(foo).
   -export([a_fun/1]).

   -spec a_fun(binary()) -> 'ok'.
   a_fun(B) ->
     do(B), ok.

   do(<<_>>) -> ok;
   do(<<_,R/binary>>) -> do(R).

Note that the first clause of do/1 has a non-empty binary there (there 
is an underscore). From this clause dialyzer will infer that the do/1 
function only returns if its argument is a non-empty binary of at least 
one byte.

> Just curious if its
> possible to have Dialyzer *not* output the -Wunderspecs warnings for
> binaries?

Why on earth would we want to special case this?

> Or if there's a better way to specify binary inputs/outputs
> (since not all of our functions using binary() in the spec have this issue).

As I explained, the warning is related to the fact that these functions 
only accept non-empty binaries. (Whether this is intentional or not in 
your code I will let you decide.)  To suppress these warnings I 
recommend the following: define a non-empty binary type

   -type ne_binary() :: <<_:8,_:_*8>>.

and change the spec of your a_fun above to:

   -spec a_fun(ne_binary()) -> 'ok'.

(Aside: I do not see the need to use 'when' for type variables that only 
appear once in a spec. The non when form is shorter and nicer.)

Kostis



More information about the erlang-questions mailing list