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
ANNOT: Reassign immutable [E0384] #984
Conversation
I think this annotation can only be implemented for a very limited set of cases at the moment. Otherwise, it will be a source of great deal of false positives. When I put this error to the list I thought of the implementation under the following circumstances:
That's not much, but at least that looks feasible. The next step would be struct fields reassigning, or some simple patterns support. But that's harder to do properly than it might seem at first glance. |
I also figured out a case I don't really know how I can detect and handle let x: int32
//...
x = 3; //First assignation -> should work (actually it doesn't)
//...
x = 5; //Second assignation -> shouldn't work (this part is OK) Or more tricky let x: int32
//...
if (stuff()) {
x = 5;
} else {
x = 3;
} What are your suggestions to handle that ? |
I would start with ignoring all cases when a left side resolves to a |
Ok, I'll do that. How could such an engine work ? What is the big picture ? |
I had a kind of prototype for this annotation. It visited Add those checks on absence of complex patterns and asterisks in the path, on presence of an assignment in |
Though I think binary expressions are more suitable elements to start such analysis than |
923fb9a
to
706f47d
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.
Looks as a reasonably safe start, we can extend this annotation to other cases in the future. 👍
return when (declaration) { | ||
is RsPatBinding -> declaration.isMut | ||
else -> false | ||
} |
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.
Can be simplified:
return (declaration as? RsPatBinding)?.isMut ?: false
@@ -285,6 +285,8 @@ class RsErrorAnnotator : Annotator, HighlightRangeExtension { | |||
private fun checkBinary(holder: AnnotationHolder, o: RsBinaryExpr) { | |||
if (o.isComparisonBinaryExpr() && (o.left.isComparisonBinaryExpr() || o.right.isComparisonBinaryExpr())) { | |||
holder.createErrorAnnotation(o, "Chained comparison operator require parentheses") | |||
} else if(o.isAssignBinaryExpr() && !o.left.isMutable()) { | |||
holder.createErrorAnnotation(o, "Reassigning an immutable variable [E0384]") |
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.
The exact rustc
message is "re-assignment of immutable variable foo
", so I'd suggest to use "Re-assignment of immutable variable foo
[E0384]". A simpler form would be without the variable name, though it sometimes useful to have it right in the error message.
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.
And the if ()
formatting.
let mut x = 5; | ||
x = 3; | ||
} | ||
""") |
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 usually add error numbers to the tests, like testE0384_ReassigningImmutableVariable()
and put them in the numerical order. Maybe we could stick to such rule to keep them manageable as their number grows?
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.
And I would also add a couple of tests to guarantee regression checks. For instance, a test for let
without assignment, a test for assignment through asterisk (we should ignore them).
706f47d
to
1957835
Compare
1957835
to
13cda81
Compare
The nice next step would be to add a quick fix to add a |
Detect reassignation of immutable bindings and mark the corresponding statements as an error. (E0384 of #886)
I'm trying to write a quick fix for this issue but I encounter some difficulties because the original bindings may come from either a
let
expression or a function argument. I need some tips to write that fix.