Here is some code with an error which I think Dialyzer should be able to spot:
-module(myapp_thing).
-spec exists(pos_integer()) -> yes | no.
exists(Id) ->
myapp_mnesia:thing_exists(Id).
-module(myapp_mnesia).
thing_exists(Id) ->
Exists = fun() ->
case mnesia:read({thing, Id}) of
[] -> false;
_ -> true
end
end,
mnesia:activity(transaction, Exists).
myapp_thing:exists/1
is specified as returning yes | no
, but the return type will actually be true | false
(i.e., boolean()
), which is what is returned from myapp_mnesia:thing_exists/1
.
However, running Dialyzer on myapp passes it without warnings.
If I change myapp_mnesia:thing_exists/1
to just return true
I get an appropriate warning; similarly if I add the right spec:
-spec session_exists(pos_integer()) -> boolean().
But it looks like Dialyzer can't look inside the mnesia transaction function Exists, or for some other reason can't infer a return type for thing_exists.
So, are mnesia transaction functions a barrier for Dialyzer, or is there a more general barrier to Dialyzer's return type inference?