Detect Python-like slicing and suggest how to fix

Fix #108215
This commit is contained in:
Hirochika Matsumoto 2023-05-03 22:32:52 +09:00
parent b29a1e00f8
commit e65c060d78
4 changed files with 47 additions and 0 deletions

View File

@ -756,6 +756,11 @@ impl Token {
)
}
/// Returns `true` if the token is the integer literal.
pub fn is_integer_lit(&self) -> bool {
matches!(self.kind, Literal(Lit { kind: LitKind::Integer, .. }))
}
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
match self.ident() {

View File

@ -567,6 +567,22 @@ impl<'a> Parser<'a> {
snapshot.recover_diff_marker();
}
if self.token == token::Colon {
// if a previous and next token of the current one is
// integer literal (e.g. `1:42`), it's likely a range
// expression for Pythonistas and we can suggest so.
if self.prev_token.is_integer_lit()
&& self.look_ahead(1, |token| token.is_integer_lit())
{
// TODO(hkmatsumoto): Might be better to trigger
// this only when parsing an index expression.
err.span_suggestion_verbose(
self.token.span,
"you might have meant to make a slice with range index",
"..",
Applicability::MaybeIncorrect,
);
}
// if next token is following a colon, it's likely a path
// and we can suggest a path separator
self.bump();

View File

@ -0,0 +1,8 @@
// edition:2021
fn main() {
&[1, 2, 3][1:2];
//~^ ERROR: expected one of
//~| HELP: you might have meant to make a slice with range index
//~| HELP: maybe write a path separator here
}

View File

@ -0,0 +1,18 @@
error: expected one of `.`, `?`, `]`, or an operator, found `:`
--> $DIR/range-index-instead-of-colon.rs:4:17
|
LL | &[1, 2, 3][1:2];
| ^ expected one of `.`, `?`, `]`, or an operator
|
= note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: you might have meant to make a slice with range index
|
LL | &[1, 2, 3][1..2];
| ~~
help: maybe write a path separator here
|
LL | &[1, 2, 3][1::2];
| ~~
error: aborting due to previous error