[erlang-questions] dialyzer is driving me nuts

Joel Reymont <>
Tue Oct 18 20:45:03 CEST 2011

On Oct 18, 2011, at 7:35 PM, Jesper Louis Andersen wrote:

> Clearly, this specification says nothing about the return value {skip,
> Game, Ctx}. Remember that a success type here states: "If this
> function, barrier_start/3, returns, then its return value is of the
> return type in the contract and the inputs were of the form specified.

Expanding the type spec to

-spec barrier_start(#game{}, game_ctx(), barrier_event()) -> {continue, #game{}, game_ctx()};
                   (#game{}, game_ctx(), {'EXIT', pid(), _}) -> {stop, #game{}, game_ctx()};
                   (#game{}, game_ctx(), _) -> {skip, #game{}, game_ctx()}.

results in an error

barrier_start.erl:50: Overloaded contract has overlapping domains; such contracts are currently unsupported and are simply ignored

> My guess is that gamelib:join/3 outright requires the types in #game{}
> to be correct, whereas the barrier_start/3 function only needs it to
> be of the right record type and doesn't care for the internals.

I had this in my record definition

          xref = gb_trees:empty() :: tuple(),

but there's a gb_tree() built-in type that I didn't know about (thanks Kostis!).

Typing xref properly made the opaque errors go away for gamelib:join and gamelib:leave.
          xref = gb_trees:empty() :: gb_tree(), 

What are the different built-in types, though? 

Why are they not in the type spec section of the reference manual?

I tried to dialyze a simple module, e.g.



-record(z, {
    xref = gb_trees:empty()

-spec foo(#z{}) -> tuple().

foo(Z = #z{}) -> Z#z.xref.

Dialyzer did not warn me on the mismatch between tuple() and gb_tree(), though. 

After removing the foo spec, Typer told me that the return type is any().

- for hire: mac osx device driver ninja, kernel extensions and usb drivers
http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont

More information about the erlang-questions mailing list