Suggest i += 1 when we see i++ or ++i#83536
Conversation
|
(rust-highfive has picked a reviewer for you, use r? to override) |
|
r? @estebank |
| help: try using `+= 1` instead | ||
| | | ||
| LL | i += 1; | ||
| | ^^^^ |
There was a problem hiding this comment.
One issue with using a structured suggestion is that we will suggest invalid code in the case of
fn main() {
let mut i = 0;
while i++ < 5 { /* ... */ }We suggest
fn main() {
let mut i = 0;
while i += 1 < 5 { /* ... */ }
}Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:3:11
|
3 | while i += 1 < 5 { /* ... */ }
| ^^^^^^^^^^ expected `bool`, found `()`
error[E0277]: cannot add-assign `bool` to `{integer}`
--> src/main.rs:3:13
|
3 | while i += 1 < 5 { /* ... */ }
| ^^ no implementation for `{integer} += bool`
|
= help: the trait `AddAssign<bool>` is not implemented for `{integer}`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
And adding parentheses doesn't fix it:
fn main() {
let mut i = 0;
while (i += 1) < 5 { /* ... */ }
}Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:3:22
|
3 | while (i += 1) < 5 { /* ... */ }
| ^ expected `()`, found integer
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
So maybe it would be better to just skip the structured suggestion?
There was a problem hiding this comment.
I'm thinking whether it would make sense to try to suggest while { i += 1; i } < 5?
There was a problem hiding this comment.
That's interesting! The advantage of that is that it will preserve the behavior of i++ in other languages. Would we always suggest { i += 1; i } or would we sometimes suggest just i += 1? I think it would probably be pretty hard to have conditional logic in this case, so I vote for unconditionally using { i += 1; i }, unless there's a simple way to encode the logic.
Also, what should we suggest in the ++i case? In that case, { i += 1; i } is not the correct behavior; rather, the equivalent in Rust is { let temp = i; i += 1; temp }. The problem with suggesting that is that the user may have code like:
++temp;and then we would suggest
{ let temp = temp; temp += 1; temp }which is incorrect.
There was a problem hiding this comment.
So, thinking about it more, maybe simply suggesting i += 1 in all cases is good enough? Or, alternatively, would it be better to just include a note and skip the structured suggestion?
There was a problem hiding this comment.
You wrote that backwards: preincrement ++i is { i += 1; i }, and postincrement i++ is { let temp = i; i += 1; temp }.
| ++i; //~ ERROR | ||
| } | ||
|
|
||
| fn main() {} |
There was a problem hiding this comment.
Probably should add tests for while i++ < 5 etc.
This comment has been minimized.
This comment has been minimized.
| && self.look_ahead(2, |t| !t.is_lit()) | ||
| { | ||
| err.note("Rust has no dedicated increment and decrement operators"); | ||
| err.help("try using `+= 1` instead"); |
There was a problem hiding this comment.
| err.help("try using `+= 1` instead"); | |
| let lo = self.token.span; // `+` | |
| self.bump(); // `+` | |
| let pre_sp = lo.to(self.token.span); | |
| err.multipart_suggestion( | |
| "try using `+= 1` instead" | |
| vec![ | |
| (pre_sp, String::new()), | |
| (self.token.span.shrink_to_hi(), " += 1".to_string()), | |
| ], | |
| Applicability::MachineApplicable, | |
| ); | |
| self.bump(); // ident |
There was a problem hiding this comment.
Won't this turn ++i into += 1i?
There was a problem hiding this comment.
Yes, good catch. You'll need to account for ++i and i++ specifically.
|
closing this due to inactivity |
Suggest `i += 1` when we see `i++` or `++i` Closes rust-lang#83502 (for `i++` and `++i`; `--i` should be covered by rust-lang#82987, and `i--` is tricky to handle). This is a continuation of rust-lang#83536. r? `@estebank`
Closes #83502 (for
i++and++i;--ishould be covered by #82987 andi--is tricky to handle).