[erlang-bugs] Wrong "this clause cannot match because of a previous clause" warning

Björn Gustavsson <>
Mon Jun 17 11:08:56 CEST 2013

On Sun, Jun 16, 2013 at 5:38 PM, José Valim <
> wrote:

> Hello,
> I have found a bug on the "cannot match clause" warning. Consider this
> minimal case:
> -module(foo).
> -export([bar/0]).
> bar() ->
>   V = <<"hello">>,
>   case is_binary(V) of
>     false -> good;
>     true  -> bad
>   end.
> When compiled, the code above spews the following warning:
> $ erlc foo.erl
> foo.erl:7: Warning: this clause cannot match because *a previous* clause
> at line 8 always matches
> In fact, the clause that always match is the following one and not the
> previous one. One simple fix for this issue is to change the message to:
> foo.erl:7: Warning: this clause cannot match because *another* clause at
> line 8 always matches
This is tricky and I will have to think about how to best
fix the problem.

I want to keep the current wording of the warning when it
is appropriate, for example for the following code:

  case E of
    Var -> ...;
    a -> ...

In this case, the use of a variable forces the order in
which the clauses are matched.

In your example, a more appropriate message would be
something like: "this clause cannot match, because the case
expression evaluates to a literal, but it is the wrong literal".
I am not sure yet how to best produce that message.

The reason that it is tricky is that the code is transformed
in several internal steps. After one of those steps, the
code would look something like this (if it were to be
translated back to Erlang source code from Core Erlang

   is_binary(V) -> bad;
   true -> good

(That transformation is done because the compiler will
generally generate better code for guard expressons.)

When that code is further optimized, it will be seen that
that the first clause will always match and a warning will
be generated for the second clause in the 'if'.

It seems that I will have to add some sort of annotation
to the transformed code so that the appropriate warning
could be produced, or alternately evaluate the case
expression before attempting to to move it into the guard.


Björn Gustavsson, Erlang/OTP, Ericsson AB
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20130617/5d6aadb3/attachment.html>

More information about the erlang-bugs mailing list