Repository: elixir-lang/elixir

Issue #6378: Dialyzer warnings with 1.5 using with/else statements
Created: 2017-07-25T15:18:09Z
Environment

1.5 with otp-20
Linux

Current behavior
With 1.5 seems that with statements using an else block drive dialyzer crazy.
Don't know if is a dialyzer problem, but with elixir 1.4.5 it does not happens.
sample code here:
https://github.com/xadhoom/local_return/blob/master/lib/local_return.ex
Basically, when using inspect inside a fun within the with/else block , dialyzer complains about "The created fun has no local return".
I've another case when matching using :ets.lookup within with/else but I've not yet a simple reproducible example, will report later if I can draft an isolated case (basically messages like the pattern 'false' can never match the type [tuple(),...])

Duplicate issue #6380: `with` - warning: this clause cannot match because of different types/sizes
Created: 2017-07-26T07:29:25Z
Environment

Elixir 1.4.4 and Elixir 1.5.0
Erlang/OTP 20.0
Operating system: macOS 10.12.5 (16F73) / Darwin 16.6.0

Current behavior
Since upgrading to Elixir 1.5.0, I have been receiving warning messages for with statements where one of the matches has the right-hand side "wrapped" to help with matching without needing to make a separate function. Consider the following contrived example:
defmodule TestModule do
  def test_func do
    with \
      {:first, float1} when is_float(float1) <- {:first, rand_float_or_nil()},
      {:second, float2} when is_float(float2) <- {:second, rand_float_or_nil()}
    do
      {:ok, float1 + float2}
    else
      {:first, nil} -> {:error, "first number is nil"}
      {:second, nil} -> {:error, "second number is nil"}
    end
  end

  defp rand_float_or_nil do
    random_float = :rand.uniform()

    if random_float > 0.5, do: random_float, else: nil
  end
end
When compiling with Elixir 1.5.0, a module like the one above results in the following compiler warnings:
Compiling 1 file (.ex)
warning: this clause cannot match because of different types/sizes
  lib/test_app/test_module.ex:9

warning: this clause cannot match because of different types/sizes
  lib/test_app/test_module.ex:10

However, it's clear that all clauses do in fact match:
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.5.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> TestModule.test_func()
{:error, "first number is nil"}
iex(2)> TestModule.test_func()
{:ok, 1.6204920530174767}
iex(3)> TestModule.test_func()
{:error, "first number is nil"}
iex(4)> TestModule.test_func()
{:error, "second number is nil"}

Expected behavior
The warning messages do not appear when compiling with Elixir 1.4.4 and the function operates as expected.
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.4.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> TestModule.test_func()
{:error, "first number is nil"}
iex(2)> TestModule.test_func()
{:ok, 1.6464043208507562}
iex(3)> TestModule.test_func()
{:error, "first number is nil"}
iex(4)> TestModule.test_func()
{:error, "first number is nil"}
iex(5)> TestModule.test_func()
{:error, "second number is nil"}

Closing comment (2017-07-26T07:41:07Z): In a way, this is duplicate of #6378 and consequence of the chosen approach to making with tail recursive.