otp icon indicating copy to clipboard operation
otp copied to clipboard

Dialyzer error message misleading for some large patterns

Open TD5 opened this issue 1 year ago • 1 comments

Describe the bug

If I run Dialyzer on the following:

 1 | -module(example).
 2 | 
 3 | -export([f/0]).
 4 | 
 5 | -spec f() -> ok.
 6 | f() ->
 7 |  case #{{a,{a,{a,{a,{a,{a,{a,{a,{a}}}}}}}}} => ok} of
 8 |     #{{a,{a,{a,{a,{a,{a,{a,{a,{a}}}}}}}}} := _} -> ok; 
 9 |     #{{a,{a,{a,{a,{a,{a,{a,{a,{wrong}}}}}}}}} := _} -> ok % Make the pattern itself so complex Dialyzer *over* simplifies it in the error message
10 |   end.

Then Dialyzer correctly identifies a case that can never happen, but incorrectly renders it, simplifying the pattern too far:

example.erl:9:5: The pattern #{_:=_} can never match the type #{{'a',{'a',{'a',{'a',{'a',{'a',{'a',{'a',{'a'}}}}}}}}} => 'ok'}

In particular, the pattern #{_:=_} doesn't seem to make much sense, since it seems to suggest the map can have any entry for the pattern to apply (although this isn't actually valid syntax you could put in a source file). I suspect this is a case of Dialyzer's "it's always safe to generalise to a wider type" logic not actually applying in this position (even if it is just for error rendering, although I am not entirely sure it is limited to that situation).

Expected behavior I would expect the error message to contain the pattern verbatim, or to simplify it in a way which doesn't look like the map could have any entry at all for the warning to apply.

Affected versions OTP 25

Additional context I found this when investigating Dialyzer producing suspicious error messages around pattern matching on big maps, so in fixing this, you may stumble upon that issue too. In particular, I suspect there's a way to trigger this such that the analysis itself is wrong, but I've only been able to reproduce making the error message incorrect/misleading.

TD5 avatar Jun 19 '23 09:06 TD5