[erlang-questions] dialyzer: clause guard cannot succeed

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Wed Oct 26 21:19:50 CEST 2011


On Wed, Oct 26, 2011 at 16:35, Joel Reymont <joelr1@REDACTED> wrote:
> Any suggestions on what may be wrong here?

Yes.

>> gamelib.erl:525: Clause guard cannot succeed.

This error type is encountered when you have a guard which the system
determines can never succeed. The canonical example from the test
suite is the following:

f(A) when is_integer(A) andalso is_atom(A) -> never.

f can never succeed for any value A simply because an A is either an
integer() or an atom() but never both at the same time which the guard
states.

>>         %% buyin amount outside the range
>>         (R#pm_join.buy_in < (Game#game.buyin)#pm_buyin_type.minimum) orelse     <----------- line 525
>>         (R#pm_join.buy_in > (Game#game.buyin)#pm_buyin_type.maximum) ->

Simplifying: (BuyIn < Min) orelse (BuyIn > Max) is the guard
expression. Let BuyIn = 10:

(10 < Min) orelse (10 > Max). If we let Min = Max = 10 also we get:
false orelse false == false. This suggests to us that there exists
values for which the guard clause can never match. A vague guess is
that the Dialyzer derives some specific possible values for BuyIn, Max
and Min which is then discriminates on and come to a conclusion, if
not entirely like the above, then much in the same vein. Note that the
dialyzer is a subtyping system, so Buyin may be (10 | 1000 | 500 | 7)
which is a subtype of integer() which is a subtype again of number()
which is a subtype of term()/any(). Perhaps a well-placed
specification can persuade the dialyzer that you expect an integer
here.

The code is in dialyzer_dataflow for the interested. It looks like a
positive/negative information propagator, much in the style of a
pattern match compiler, but I might be wrong.


-- 
J.



More information about the erlang-questions mailing list