Provide better warning of unmatchable clauses in the presence of default arguments

20 views
Skip to first unread message

Mário Guimarães

unread,
Apr 12, 2019, 9:49:59 AM4/12/19
to elixir-lang-core
Hello

given the following module

defmodule X do
 
def foo(a, c), do: foo(a, :b, c)
 
def foo(a, b \\ "2", c \\ "3"), do: IO.inspect {a, b, c}
end

Elixir emits the following warning

Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
iex
(1)> defmodule X do
...(1)> def foo(a, c), do: foo(a, :b, c)
...(1)> def foo(a, b \\ "2", c \\ "3"), do: IO.inspect {a, b, c}
...(1)> end
warning
: this clause cannot match because a previous clause at line 2 always matches
  iex
:3

{:module, X,
 
<<70, 79, 82, 49, 0, 0, 5, 104, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 139,
   
0, 0, 0, 16, 8, 69, 108, 105, 120, 105, 114, 46, 88, 8, 95, 95, 105, 110,
   
102, 111, 95, 95, 7, 99, 111, 109, 112, ...>>, {:foo, 3}}


however it is possible to call both clauses:

iex(2)> X.foo(:a, :c)
{:a, :b, :c}
{:a, :b, :c}
iex
(3)> X.foo(:a, :z, :c)
{:a, :z, :c}
{:a, :z, :c}


It would be more clear if Elixir could report the actual clauses that cannot be called.

Thanks
Mário Guimarães 

Mário Guimarães

unread,
Apr 12, 2019, 10:03:26 AM4/12/19
to elixir-lang-core
This warning can be removed by expanding all possible "foo" clause combinations.

The nice thing would be the warning to make this clear, and preferably, by listing which clauses cannot be called and suggesting the developer to expand all possible clause combinations.

Cheers
Reply all
Reply to author
Forward
0 new messages