I expect adding specs to never make things less safe, but that's exactly what happens in the following case.
In the following code, Dialyzer (wrongly) trusts me that the return type of bar is 1
. This leads it to saying that a pattern in foo() can never match–incorrect advice that, if heeded, would introduce a runtime error!
-module(sample).
-export([foo/0]).
foo() ->
case bar() of
1 -> ok;
2 -> something
end.
-spec bar() -> 1.
bar() ->
rand:uniform(2).
Deleting the spec for bar/0
fixes the problem–but why did Dialyzer trust me?
Dialyzer is violating its "no false positives" promise here: it warns when there is no bug. And (even worse) Dialyzer nudges to introduce a new bug.
Dialyzer calculates the success typing for each function before checking its spec, this action has several possible outcomes:
-Wunderspecs
or-Wspecdiffs
-Woverspecs
or-Wspecdiffs
.-1..1
andpos_integer()
): Same as 2.For 1, it continues with the success type, otherwise continues with the intersection between the success type and the spec type.
Your case is 3, which is usually not warned about because you, as the programmer, know better (as far as dialyzer is concerned, maybe
rand:uniform(2)
can only return1
). You can activate it within the
rebar.config
file