Decrypting Dialyzer error message: "The pattern can never match the type."

The pattern can never match the type.

Pattern:
{:pass, :low_reputation}

Type:

  {:error,
   :incompatible_calendars
   | :invalid_date
   | :invalid_format
   | %Jason.DecodeError{
       :__exception__ => true,
       :data => binary(),
       :position => integer(),
       :token => _
     }}
  | {:ok, _}
  | {:pass, :unseasoned}

What is this attempting to communicate?

This means that Dialyzer has determined that a piece of code - usually either a case branch or a pattern-matching function head - can’t ever match the success type. This can happen if you’re trying to match a sum type (the | options above) but Dialyzer determines that some of the cases never happen.

I’ve encountered this before with GenServer callbacks that wrap other calls. Some code:

  def handle_call({:special, msg}, from, state) do
    case handle_call(msg, from, state) do
      {:reply, reply, new_state} ->
        Logger.info("special reply: #{inspect(reply)}")
        {:reply, reply, new_state}

      {:reply, reply, new_state, extra} ->
        Logger.info("special reply: #{inspect(reply)} extra: #{inspect(extra)}")
        {:reply, reply, new_state, extra}

      {:noreply, new_state} ->
         # etc
      {:noreply, new_state, extra} ->
      {:stop, reason, reply, new_state} ->
      {:stop, reason, new_state} ->
    end
  end

If no handle_call heads in this module return {:noreply, new_state} then Dialyzer will give an error of the sort you posted.

3 Likes

And the success types it’s trying to match against are:

{:error, :incompatible_calendars}
{:error, :invalid_date}
{:error, :invalid_format}
{:error, %Jason.DecodeError{_}}
{:ok, _}
{:pass, :unseasoned}

Or am I mistaken?

Correct.

1 Like