hissssst / pathex

Fastest tool to access data in Elixir

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dialyzer complains about deletion functions

icehaunter opened this issue · comments

When using (some) functions which rely on the magic :delete_me atom, Dialyzer complains about a pattern that can never match the type (this error is for the most generic case where no types can be inferred at the place of use):

The pattern 
          'delete_me' can never match the type 
          'error' | {'ok', [any()] | tuple() | map()}

Affected functions (for me) are delete/2, delete!/2, and pop!/1. pop/1 Isn't affected, and I'm not sure why.

Reproduction:

Paste this module into any project which has pathex dependency installed, and run Dialyzer.

defmodule PathexTest do
  use Pathex

  def pop_key_from_my_map(%{} = my_map, key) do
    Pathex.delete(my_map, path(key)) # The pattern 'delete_me' can never match the type 'error' | {'ok',map()}
    Pathex.delete!(my_map, path(key)) # The pattern 'delete_me' can never match the type 'error' | {'ok',map()}
    Pathex.pop!(my_map, path(key)) # The pattern 'delete_me' can never match the type 'error' | {'ok',map()}
    Pathex.pop(my_map, path(key)) # No warning for some reason?
  end
end

For me this is reproducable on a mix new project with two dependencies, but also causes a warning in VSCode even without the dialyxir dependency:

[
  {:pathex, "~> 2.4.2"},
  {:dialyxir, "~> 1.0", only: [:dev], runtime: false}
]

My environment:

> elixir --version
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Elixir 1.14.1 (compiled with Erlang/OTP 25)

Yeah, this warning is true, because Pathex generates clauses which handle {:ok, result} | :error | :delete_me type, but paths created with path/2 macro return only {:ok, result} | :error type.

However, this warning can't be disabled in pathex, because path and delete are macro, thus they're expanded at compile-time and the dialyzer won't be capable to find that this warning is disabled

You can use this regex in .dialyzer_ignore.exs to disable the warning

  ~r/.*pattern_match The pattern can never match the type :error | {:ok, .*}/

Thanks for the explanation. Shame it can't be solved at the library level. mix dialyzer does respect the suggested disable file, while ElixirLS, unfortunately, does not.

As I understand your suggestion I can disable the check, but that will be disabled for the entire codebase. Is there a possibility of fixing this problem?

Best I could do is: @dialyzer {:no_match, modify_channel_configuration_aliases: 4} to ignore the function that calls this Library.

@grant-zukowski-xumo , the root of the problem is that dialyzer ignores generated: true metadata in AST and still generates warnings. And there is no way to not generate the unused clause, because pathex uses code-generation to achieve performance but language has no capability for Pathex to perform the check if this clause needed or not at compile-time

Yes, you can disable checks per-function, you should use this option