[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