Hello everyone,

as usual thanks for all your outstanding work on Elixir & everything else.

Courtesy of a reddit discussion [1] I'd like to propose implementing some
more compiler warnings for matches that are impossible.

## Background

Elixir is very programmer friendly and issues compiler warnings in many
cases if something is impossible. So if we match just against `variable` in
a function head and further down match against a more specific value we get
a warning.

Similarly if we match against `__struct__` and the actual struct we get a
warning:

def struct_match(%{__struct__: Range}), do: "__struct__"
def struct_match(%Range{}), do: "struct"

This one warns as:

    warning: this clause cannot match because a previous clause at line 17
always matches
    │
 18 │   def struct_match(%Range{}), do: "struct"
    │   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/compiler_warnings_impossible_matches.ex:18

This is great! The idea here is to take it further.

## Proposal

The code examples used here can be found here:
https://github.com/PragTob/elixir_playground/blob/main/lib/compiler_warnings_impossible_matches.ex

I tried the examples on 1.18.0-dev (ed67d6b) with OTP 27.0 to make sure
none of them emit a warning right now.

In short, it's more warnings where for some of which I thought they'd
already warn you about impossible matches but found out they don't. I think
these warnings would be helpful to avoid bugs & help newcomers.

### Simple map match vs. Struct

def map_match(%{}), do: "map"
def map_match(%Range{}), do: "range"

Ideally this should warn as the match is impossible. Possibly also when
using the `is_map` guard.

### Map matching on struct specific keys

def key_match(%{first: _first}), do: "map"
def key_match(%Range{}), do: "range"

If we had a map where all keys overlap with a struct matched further down
in the function headers, ideally this should also warn. Of course, if we
add a second key to the match that the struct doesn't have it should not
warn.

Of this proposal, I think this is the one that I see causing bugs most
easily.

### atoms, nil and booleans

def atom_match(value) when is_atom(value), do: "atom"
def atom_match(nil), do: "nil"
def atom_match(value) when is_boolean(value), do: "bool"

I'm not sure how much guards should be taken into account with these kinds
of warnings, but these are also "unmatchable".

## Implementation
I'm aware there is a chance you're aware of this and it wasn't implemented
for compilation performance considerations. If so, sorry and happy to learn
how I could look something like this up.

If you agree that this could be worthwhile to implement, I'd be happy to
give the implementation a shot myself but I'd at least need basic guidance
as I don't know the internals all that well :)

Thanks y'all and have a splendid day!

[1] https://www.reddit.com/r/elixir/comments/1cibtia/comment/l2ckqjr/

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YTVO1Wrvx76fg%2BBEmqC3PgZsRG0rEpLwVt7fdOWFZ8n2w%40mail.gmail.com.

Reply via email to