-
Notifications
You must be signed in to change notification settings - Fork 53
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
warn of unused variables #983
Conversation
d7a714a
to
ced3c87
Compare
08d1816
to
5baff4d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this whole thing can be simplified quite a bit.
- If the parser does not already give us a
SrcLoc
for each variable, it absolutely should. We should fix that rather than having a convoluted and error-pronetoErrPos
function. - All the stuff about downward vs upward scopes seems much too complicated, and possibly incorrect.
def
andbind
do not really scope "up" in any way that I can make sense of, they just scope over binds nested further to the right.Note also that it is not allowed to have aEDIT: this was wrong, sorry! See my later comment.def
anywhere except at the topmost level, for example it is not allowed to have(def a = ... end; def b = ... end); ...
so we don't have to worry about getting defined names from a "nested" bind like in that example.
Note that we already have a traversal fvT
defined in Swarm.Language.Syntax
which will fetch all the free variables in a term. However, we need something slightly more general here since we need all the free variable occurrences, with their SrcLoc
. Actually in the annotate-ast
branch I had to generalize fvT
to traverse over the Syntax
nodes instead of Term
, which would be perfect here. Let me see if I can extract something useful out of that as a separate PR.
If we had a way to traverse over free variables with their associated SrcLoc
, then in theory this should be as easy as just listing them and turning each one into an unused var warning.
EDIT: sorry, I was confused. It's not free variables we want (i.e. variable occurrences with no binder), but the opposite (variable bindings with no occurrences). It should still be possible to simplify this but I'll have to think about it a bit more.
In my first pass at implementing this, I got the sense that Def and Bind were somehow inherently different than Let and Lambda in the way they would need to be checked, though the "upward" scope idea is half-baked. In reading your comment, maybe "rightward" scope is what I was thinking. |
Of course the scoping rules are a bit different, but fundamentally they should not need to be handled in a different way. I am imagining something like this (pseudocode):
This is assuming that we enhance the parser to store e.g. the EDIT: then, after getting EDIT: I removed a case for |
@kostmo let me know whether/what kind of additional help you'd like with this. |
Chatting with @xsebek in IRC helped me realize I was wrong about nested
For more context about the difference between |
33d367d
to
a3056db
Compare
@byorgey this is now working for |
9d1271e
to
3f7c6fa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really nice! Just a few remaining issues + some new edge cases for the test suite.
a501e19
to
71a4296
Compare
All feedback addressed. Added 4 more tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
@Mergifyio refresh |
✅ Pull request refreshed |
f5e9334
to
53226a2
Compare
Closes #863.
Implements unused variable checking for
Let
,Lambda
, andBind
.Also: