%% Dialyzer couldn't infer that monitor_diskspace would go in an infinite loop %% instead of crashing due to the existence of list comprehensions that have a %% normal success typing. These were added to the monitor_diskspace's SCC and %% dialyzer_typesig didn't try to assign unit() to monitor_diskspace, as it %% required all the members of the SCC to return none(). %% %% Testcase was submitted in erlang-questions mailing list by Prashanth Mundkur %% (http://erlang.org/pipermail/erlang-questions/2011-May/058063.html) -module(no_return_bug). -export([diskspace/1, monitor_diskspace/2, refresh_tags/1, monitor_launch/0]). -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).