Dialyzer's pattern can never match the type error with lists

I have a a fairly large project without typespecs and I’m now in the process of cleaning up Dialyzer warnings and hit a roadblock that can be demonstrated with the following barebones code.

defmodule DialyzerTest do
  def foo() do
    bar([:a, :b, :c])
  end

  defp bar([]), do: :empty
  defp bar(non_empty), do: :non_empty
end

Dialyxir gives the following warning:

The pattern can never match the type.

Pattern:
[]

Type:
[:a | :b | :c, ...]

Dialyzer knows that bar is never called with a non-empty list, so the first clause is redundant.

The problem is that I don’t want to just remove the first bar clause, because in the future I might want to add another function that calls bar, which might call it with an empty list, so I want to have a safeguard already.

I tried to replace the empty list pattern match with a guard, but Dialyzer obviously warns that it is never called.

The two solutions I’ve come up with are:

  • make the bar function public, but that function has no use outside of the module, so it doesn’t feel right
  • call Dialyzer with the -Wno_match option which just suppresses the warning, but I’m not sure I want to do this globally

Any other, perhaps more elegant, ways how to get rid of the warning?
Thanks in advance!

1 Like

You have 2 additional possibilities:

  1. Use dialyxirs ignore file, which is described in the Ignore Warnings section of the README.
  2. Use module attributes to control dialyzer directly, its described in the Requesting or suppressing warnings in source files section of the dialyzer manual. In your case it should be @dialyzer {:no_match, bar: 1}, IIRC.
3 Likes

This looks like what I was looking for, thanks a lot!

1 Like