[erlang-questions] Dialyzer questions

Prashanth Mundkur pmundkur.erlang@REDACTED
Tue May 3 03:50:05 CEST 2011


We've recently been getting the upcoming release of Disco to go through the
Dialyzer wringer, and it has been a very useful exercise.  Thanks to Kostis'
helpful wielding of the cluebat at the SF Erlang Factory!

We are trying to understand the following output (I hope the inline code
pasting below comes out readable):

$ cat dial.erl
-module(dial).
-export([abort/2, extract/2,
         diskspace/1, monitor_diskspace/2, refresh_tags/1,
monitor_launch/0]).

% We have helper functions like this:
abort(Msg, Code) ->
    error_logger:warning_report(Msg),
    exit(Code).
% which give rise to the following dialyzer message:
%
%   Function abort/2 only terminates with explicit exception
% How do we interpret this message?


% Even with a plt that includes stdlib, there is no warning for the
% following code:
-spec extract(binary(), nonempty_string()) -> 'ok'.
extract(Pack, Dir) ->
    case zip:extract(Pack, [{cwd, Dir}]) of
        {ok, Files} ->
            Files;
        {error, Reason} ->
            exit({error, Reason})
    end.


% Here, the spawn_link of monitor_diskspace in monitor_launch() gives:
%   The created fun has no local return
% whereas the spawn_link of refresh_tags doesn't.  If the spawn_link
% of monitor_diskspace() function is commented out, there is no
% warning.  It's not clear how to interpret the warning or the
% inconsistency.
%
% Converting the nested list comprehension in monitor_diskspace into a
% list:map made the warning go away, at the expense of readability and
% perhaps even efficiency.

-type diskinfo() :: {non_neg_integer(), non_neg_integer()}.
-spec diskspace(nonempty_string()) -> {'ok', diskinfo()} | {'error',
term()}.
diskspace(Path) ->
    case Path of
        "a" -> {ok, {0,0}};
        _ -> {error, error}
    end.

-spec monitor_diskspace(nonempty_string(),
                        [{diskinfo(), nonempty_string()}]) ->
                               no_return().
monitor_diskspace(Root, Vols) ->
    Df = fun(VolName) ->
                 diskspace(filename:join([Root, VolName]))
         end,
    NewVols = [{Space, VolName}
               || {VolName, {ok, Space}}
                      <- [{VolName, Df(VolName)}
                          || {_OldSpace, VolName} <- Vols]],
    monitor_diskspace(Root, NewVols).

-spec refresh_tags(nonempty_string()) ->
    no_return().
refresh_tags(Root) ->
    {ok, _} = diskspace(Root),
    refresh_tags(Root).

monitor_launch() ->
    spawn_link(fun() -> refresh_tags("abc") end),
    spawn_link(fun() -> monitor_diskspace("root", [{{0,0}, "a"}]) end).

$ dialyzer --get_warnings -Wunmatched_returns -Werror_handling dial.erl
  Checking whether the PLT /home/mundkur/.dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
dial.erl:6: Function abort/2 only terminates with explicit exception
dial.erl:66: The created fun has no local return

$ dialyzer -v
Dialyzer version v2.4.0

$ erl
Erlang R14B01 (erts-5.8.2) [source] [64-bit] [smp:2:2] [rq:2]
[async-threads:0] [hipe] [kernel-poll:false]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110502/46d0fa80/attachment.htm>


More information about the erlang-questions mailing list