Hi Tobias!

This feature would indeed by very useful however:

1. Implementing overlapping warnings can be quite complex. Those examples
are trivial but a correct, complete, and precise implementation needs to
take into account patterns, nesting, guards, equality, comparisons,.
structs, and more
2. Today's warnings are emitted by the Erlang compiler for the most obvious
cases

If we want to fully tackle the problem, one approach is a type system that
understands the semantics of patterns and guards. That's what we have been
working on. But I also want to be clear that this is months of work, if you
want them to be correct and complete.

That said, I think the first warning would be valuable to propose to
Erlang, since both languages share the issue that an empty map matches all
maps. Erlang does not guarantee to find overlaps but this may be cheap
enough to perform. The Erlang/OTP team would know best, so I suggest
proposing those there, if nobody has done that yet.




On Thu, May 30, 2024 at 3:25 PM Tobias Pfeiffer <prag...@gmail.com> wrote:

> 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
> <https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YTVO1Wrvx76fg%2BBEmqC3PgZsRG0rEpLwVt7fdOWFZ8n2w%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAGnRm4Lq6%2BaHqZwY%2BhvcqtuhSinfUKBWL%3D9U0shByqu0rGTgVw%40mail.gmail.com.

Reply via email to