Pinning does not seem to work in 'else' block of 'with' special form
jamesvl opened this issue · comments
Elixir and Erlang/OTP versions
Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:32:16] [ds:32:16:10] [async-threads:1] [jit:ns]
Elixir 1.17.0 (compiled with Erlang/OTP 27)
(neither the warning nor the buggy behavior occurs in Elixir 1.16)
Operating system
Linux / Fedora 40
Current behavior
According to the docs, the else
block of the with
special form is supposed to behave like a case
clause.
The following minimal example shows a warning in Elixir 1.17 and running the code in iex shows that the first clause in the else
block always matches any parse error in tuple form:
defmodule BugEx do
def spurious_warning(val) do
example_str = "abc"
with(
{int_val, ""} <- Integer.parse(val)
)
do
int_val + 0
else
{_x, ^example_str} ->
{:error, "#{example_str} is a bad integer and oh this clause always matches"}
{_x, str} ->
{:error, "#{str} is not valid"}
end
end
end
And in iex:
$iex -S mix
Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:32:16] [ds:32:16:10] [async-threads:1] [jit:ns]
Interactive Elixir (1.17.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> BugEx.spurious_warning("1abc")
{:error, "abc is a bad integer and oh this clause always matches"}
iex(2)> BugEx.spurious_warning("1abcd")
{:error, "abcd is a bad integer and oh this clause always matches"}
Expected behavior
Expected it to resped the pinned variable like a case
clause would and Elixir 1.16 does:
# same code as above, but running on 1.16.13
$iex -S mix
Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:32:16] [ds:32:16:10] [async-threads:1] [jit:ns]
Interactive Elixir (1.16.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> BugEx.spurious_warning("1abc")
{:error, "abc is a bad integer and oh this clause always matches"}
iex(2)> BugEx.spurious_warning("1abcd")
{:error, "abcd is not valid"}
iex(3)>