Skip to content

Add a hint when a local variable may be shadowing a function #692

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

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

timbertson
Copy link
Contributor

Adds a hint when a non-callable local variable is used as a function, suggesting that it may be shadowing another function.

I got very confused the first time I encountered the case in the attached test, where a struct accessor (or other "method") gets shadowed by a local variable with the same name. The type error points you in the wrong direction if you don't realise that this shadowing is happening.

I'm assuming that a Var whose name is nonQualified means "local variable" (or at least global variable in the same file), so is the message accurate here?

Improvements

I couldn't figure out how to do any of these, but I think they would make this even better:

  • Include the location (filename + range) for where the name (port in this test) is defined
  • Print out all the bindings with the same name which the local var is shadowing (i.e. similar to the "ambiguous overload" function listing)
  • (Maybe) only have this hint when you're using dot syntax, i.e. foo.bar and not bar(foo) since that's the case where this error is the most surprising.

@TimWhiting
Copy link
Collaborator

Yeah, it would be best not to assume unqualified names are locals.

We should use the NameInfo portion of the matches (map snd matches), that will let us know whether it is a value or function we are referring to and since values could be lambdas we probably also want to look at the type scheme in the infoType field to determine whether the val is a function. If any of the matches contains a value instead of a function we can report it, but I wouldn't necessarily indicate that it is a local variable, because it could be a top-level variable as well. We should probably add more info to the NameInfo to indicate whether a value is top-level or not.

@timbertson
Copy link
Contributor Author

since values could be lambdas we probably also want to look at the type scheme in the infoType field to determine whether the val is a function

The code branch I'm modifying is reporting that the subject isn't callable, so does that mean we can skip this check?

If it's not easy to detect local from toplevel that seems fine (I can just make the hint less specific), but is there a way to insert the location of the variable's definition? That seems like the most useful information.

@TimWhiting
Copy link
Collaborator

= InfoVal{ infoVis :: !Visibility, infoCName :: !Name, infoType :: !Scheme, infoRange :: !Range, infoIsVar :: !Bool, infoAllowImplictMaskX :: !Bool, infoDoc :: !String }

There should be source range information from the NameInfo

@timbertson
Copy link
Contributor Author

Silly me, I thought Range was just the lineno/column and I had to figure out the path myself. I've pushed a commit which includes the definition location, but I did have to pass "." as the cwd argument, I feel like that's cheating and I should be getting it from somewhere else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants