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

Anthony Ramine n.oxyde@REDACTED
Mon Jun 17 20:05:39 CEST 2013


Hello José, hello Björn,

We already have two warnings:

- "this clause cannot match because a previous clause at line X always matches"
- "this clause cannot match because of different types/sizes"

The second is triggered for matches like "{_} = {X,Y}". Shouldn't we just use it in that case?

Note that diagnostics would help in the clause shadowing case:

foo.erl:3:8: Warning: this clause cannot match because a previous clause at line 2 always matches
	a -> bad
	^~~~~~~~
foo:erl:2:8: Note: This clause shadows clause at line 3
	Var -> good;
        ^~~~~~~~~~~

Or something like that.

Regards,

-- 
Anthony Ramine

Le 17 juin 2013 à 11:08, Björn Gustavsson a écrit :

> On Sun, Jun 16, 2013 at 5:38 PM, José Valim <jose.valim@REDACTED> 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 -> ...
>   end.
> 
> 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
> code):
> 
>   if
>    is_binary(V) -> bad;
>    true -> good
>   end
> 
> (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.
> 
> /Bjorn

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20130617/ce1ee036/attachment.htm>


More information about the erlang-bugs mailing list