[erlang-questions] Strange Dialyzer behavior when matching record fields with opaque types

Nick Marino <>
Tue Jan 17 23:18:42 CET 2017


Hi all,

I recently encountered a rather strange, unexpected Dialyzer error. I'm
unsure if this might be considered a Dialyzer bug, or if I'm just missing
some key piece of knowledge that would help me understand what's going on
here.

I took the code that generated the warning and pruned it down down to this:

-module(opaque_weirdness).
-export([public_func/0]).

-record(a, {
    d = dict:new() :: dict:dict()
}).

-record(b, {
    q = queue:new() :: queue:queue()
}).

public_func() ->
    add_element(#b{}, my_key, my_value).

add_element(#a{d = Dict}, Key, Value) ->
    dict:store(Key, Value, Dict);
add_element(#b{q = Queue}, Key, Value) ->
    queue:in({Key, Value}, Queue).

Which yields the following warning when I run it through Dialyzer:

opaque_weirdness.erl:16: The attempt to match a term of type
#b{q::queue:queue(_)} against the pattern {'a', Dict} breaks the opaqueness
of queue:queue(_)

It seems like this warning is somehow being triggered by the presence of
the unused function clause in add_element. If I modify the code and add a
line to public_func so that we use both clauses, then Dialyzer passes with
no warnings.

If I modify the above code to use tagged tuples instead of records (i.e.
{dict, Dict} instead of #a{d = Dict}) then it gives a completely different
warning, which makes much more sense to me:

opaque_weirdness.erl:10: The pattern <{'queue', Queue}, Key, Value> can
never match the type <{'dict',dict:dict(_,_)},'my_key','my_value'>

So the use of records seems to be necessary to trigger the opaqueness
warning, though I can't fathom why this should matter.

In the original example code, can anyone explain why Dialyzer is giving a
warning about opaqueness instead of producing a "pattern X can never match
the type Y" warning? The opaqueness warning seems really bizarre to me;
obviously the term will never match the pattern, so how is opaqueness being
broken?

Thanks,
Nick Marino
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170117/ed6a8e2b/attachment.html>


More information about the erlang-questions mailing list