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
and pos_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 return 1
). You can activate it with
{dialyzer, [{warnings, [underspecs,overspecs]}]}.
in the rebar.config
file
Dialyzer's own analysis is (currently) based on over-approximations, of several kinds, so it cannot discern whether your stricter spec is due to you being definitely wrong or due to Dialyzer having over-approximated somewhere.
It therefore chooses to trust your spec, and goes for reporting a definitive error later based on that information.
In general, type-error-related info by other modern systems comes with "all parts reported and no blame explicitly assigned" for this reason. Here it is actually the case that the inference, the spec and the patterns being incompatible, but Dialyzer blames just the patterns. This is a quirk to have in mind when using it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With