Way to selectively ignore elixir warnings (use case: tests in a library)

:waving_hand:

This is a bit of an odd scenario I realize and calling me over cautious is fair.

I want to know if there is, or is envisioned to be, a way to selectively ignore type warnings. My current use case is deep_merge

It has a couple of tests that specifically check that the library fails correctly when confronted with the wrong types:

The new elixir type system correctly identifies that these are the wrong types:

    warning: incompatible types given to DeepMerge.deep_merge/2:

        DeepMerge.deep_merge(%{a: 1}, 2)

    given types:

        %{a: integer()}, integer()

    but expected one of:

        (
          empty_list() or map() or non_empty_list(term(), term()),
          empty_list() or map() or non_empty_list(term(), term())
        )

    type warning found at:
    │
 91 │       assert_incompatible(fn -> deep_merge(%{a: 1}, 2) end)
    │                                 ~
    │
    └─ test/deep_merge_test.exs:91:33: DeepMergeTest."test .deep_merge/2 errors out with incompatible types"/1

My first reaction to that (PR) was to delete these tests.

However, then I actually ran into an incompatibility with the merging behavior inbetween elixir versions. So, I was worried “maybe this would/could break the tests I just removed”.

And so, I re-added the tests.

So, imo the best solution would be to be able to ignore type warnings selectively. But I also realize that my “I want to test that it does what I want when handed the wrong types across elixir versions” is a relative special case.

I suppose I could run those tests only on elixir versions pre 1.20, which is probably what I’m going to do/try to do. That said, another solution to it would still be good imo.

Happy for input and insight on this, thanks :slight_smile:

I’m still interested in knowing how others would resolve this, but for now I simply don’t compile those tests on elixir 1.20+:

Tests in my library also fail. Elixir has generated: true tag in AST metadata (Erlang has it too btw) to indicate that the code was generated and no warnings should be raised for it, but this new type system purposefully ignores it and my github issue raising this problem was closed as wont do.

By the way, I get way more funnier warnings

Jose Valim made it clear that we now have to write raise "Never" or other hacks to work around type system checks. So I would suggest something like this

send(self(), {:two, 2})
two = receive do {:two, x} -> x end
assert_incompatible(fn -> deep_merge(%{a: 1}, two) end)

The workaround for now is to write: Process.get(:unused, value). We will have a leaner way in the future.