The Dialyzer vs. Proplists Situation

Check out this module…

As you can see, all 3 functions look pretty similar. The difference lies in the Expansions list. While in good/0 tuples have lists as second elements, in bad/0 we have atoms and in wat/0 we have a mixture of both.

If we compile the module and try to use the functions, they actually work…

2> expand:good().

[expanded,expanded,too,c]

3> expand:bad().

[expanded,expanded,c]

4> expand:wat().

[expanded,expanded,too,c]

5>

But if we run dialyzer on it…

src/expand.erl

13: The call proplists:expand(Expansions::[{'a','expanded'} | {'b','expanded'},...], ListIn::['a' | 'b' | 'c',...]) breaks the contract (Expansions, ListIn) -> ListOut when Expansions :: [{Property::property(),Expansion::[term()]}], ListIn :: [term()], ListOut :: [term()]

Dialyzer here is correctly pointing out that the spec for proplists:expand/2 requires all Expansions to be lists. And in our line 13 (that is bad/0) we’re using atoms, which is wrong. But then… why is Dialyzer not complaining about line 18 (in wat/0) where we’re using atoms as well?