<div dir="ltr">On Sun, Jun 16, 2013 at 5:38 PM, José Valim <span dir="ltr"><<a href="mailto:jose.valim@plataformatec.com.br" target="_blank">jose.valim@plataformatec.com.br</a>></span> wrote:<br><div class="gmail_extra">
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<div><br></div><div>I have found a bug on the "cannot match clause" warning. Consider this minimal case:</div>
<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>-module(foo).</div>

</div><div><div>-export([bar/0]).</div></div><div><div><br></div></div><div><div>bar() -></div></div><div><div>  V = <<"hello">>,</div></div><div><div>  case is_binary(V) of</div></div><div><div>

    false -> good;</div>
</div><div><div>    true  -> bad</div></div><div><div>  end.</div></div></blockquote><div><br></div><div>When compiled, the code above spews the following warning:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">


<div><div>$ erlc foo.erl</div></div><div><div>foo.erl:7: Warning: this clause cannot match because <b>a previous</b> clause at line 8 always matches</div></div></blockquote><div><div><div><br></div><div>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:</div>


<div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div>foo.erl:7: Warning: this clause cannot match because <b>another</b> clause at line 8 always matches</div></div></div>


</blockquote><div><div><div><br></div><div><br></div></div></div></blockquote><div><br></div><div style>This is tricky and I will have to think about how to best</div><div style>fix the problem.</div><div style><br></div>
<div style>I want to keep the current wording of the warning when it</div><div style>is appropriate, for example for the following code:</div><div style><br></div><div style>  case E of</div><div style>    Var -> ...;</div>
<div style>    a -> ...</div><div style>  end.</div><div style><br></div><div style>In this case, the use of a variable forces the order in</div><div style>which the clauses are matched.</div><div style><br></div><div style>
In your example, a more appropriate message would be</div><div style>something like: "this clause cannot match, because the case</div><div style>expression evaluates to a literal, but it is the wrong literal".</div>
<div style>I am not sure yet how to best produce that message.</div><div style><br></div><div style>The reason that it is tricky is that the code is transformed</div><div style>in several internal steps. After one of those steps, the</div>
<div style>code would look something like this (if it were to be</div><div style>translated back to Erlang source code from Core Erlang</div><div style>code):</div><div style><br></div><div style>  if</div><div style>   is_binary(V) -> bad;</div>
<div style>   true -> good</div><div style>  end</div><div style><br></div><div style>(That transformation is done because the compiler will</div><div style>generally generate better code for guard expressons.)</div><div style>
<br></div><div style>When that code is further optimized, it will be seen that</div><div style>that the first clause will always match and a warning will</div><div style>be generated for the second clause in the 'if'.</div>
<div style><br></div><div style>It seems that I will have to add some sort of annotation</div><div style>to the transformed code so that the appropriate warning</div><div style>could be produced, or alternately evaluate the case</div>
<div style>expression before attempting to to move it into the guard.</div><div style><br></div><div style>/Bjorn</div><div style><br></div></div>-- <br>Björn Gustavsson, Erlang/OTP, Ericsson AB
</div></div>