Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore usage of constructors that require having access to that constructor #2

Closed
zwilias opened this issue Jun 16, 2020 · 3 comments
Closed
Labels
hacktoberfest help wanted Extra attention is needed

Comments

@zwilias
Copy link

zwilias commented Jun 16, 2020

For example, given code like this:

module Main exposing (main)

type Foo = Foo | Bar

id : Foo -> Foo
id f =
  case f of
    Foo -> Foo
    Bar -> Bar

main =
  id Foo

There is no path from main that can ever lead to using Bar: the only function that can "create" a Bar is id, but in order to do so, you'd need access to a Bar to begin with. Note that in this instance, it is very clear, but there might be multiple levels of indirection! Essentially, usage of a constructor can be "ignored" in the entire callgraph stemming from matching on that same constructor.

I originally added such functionality to elm-xref after noticing that we had a few such instances in our codebase at work. For reference, implementation happened here: zwilias/elm-xref@7cc14f2 (which might provide some ideas on how to track this sort of thing)

@jfmengels
Copy link
Owner

I am sure that this will catch things in some of my projects!

Do you also catch things like the following?

case ( a, b ) of
  ( _ , Foo ) -> Foo
  ... -> ...

I am thinking that the rule should also try and ignore things like

if f == Foo then
  ...
else
  ...

if that is the only occurrence (along with other places where it is ignored).

@zwilias
Copy link
Author

zwilias commented Jun 16, 2020

It does catch the former:

addPatternConstructors : Scope -> Node Pattern -> List Function -> List Function
addPatternConstructors scope pat acc =
    List.foldl (addIgnoredConstructor scope) acc (Util.patternToFunctions pat)

It doesn't catch the latter, never actually thought about that! 😅

@jfmengels
Copy link
Owner

This issue is fixed on master.
Custom type constructors that require themselves to be built are reported, regardless how deep the pattern they're found in is. I've shown an example here: https://twitter.com/jfmengels/status/1337803716737560577

I have also partially applied the other suggestion. I made it so that "static" comparisons like a == Just Constructor don't count, but "dynamic" comparisons like a == someFunction Constructor would ignore a constructor in the expression, because that expression will always be the same value (True or False) for the entire life of the program. I've shown an example here: https://twitter.com/jfmengels/status/1337910280953716738

I haven't figured yet how to handle the case where we can ignore an if branch based on the condition. I've created #17 to talk about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants