Skip to content

Commit

Permalink
Rollup merge of rust-lang#111133 - hkmatsumoto:handle-python-slicing,…
Browse files Browse the repository at this point in the history
… r=TaKO8Ki

Detect Python-like slicing and suggest how to fix

Fix rust-lang#108215
  • Loading branch information
matthiaskrgr authored Nov 27, 2023
2 parents 9f15a88 + acec70d commit 8d0f7a7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
39 changes: 28 additions & 11 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,20 +567,37 @@ impl<'a> Parser<'a> {
snapshot.recover_diff_marker();
}
if self.token == token::Colon {
// if next token is following a colon, it's likely a path
// and we can suggest a path separator
self.bump();
if self.token.span.lo() == self.prev_token.span.hi() {
// 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.may_recover()
&& self.look_ahead(1, |token| token.is_integer_lit())
{
// FIXME(hkmatsumoto): Might be better to trigger
// this only when parsing an index expression.
err.span_suggestion_verbose(
self.prev_token.span,
"maybe write a path separator here",
"::",
self.token.span,
"you might have meant a range expression",
"..",
Applicability::MaybeIncorrect,
);
}
if self.sess.unstable_features.is_nightly_build() {
// FIXME(Nilstrieb): Remove this again after a few months.
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
} else {
// if next token is following a colon, it's likely a path
// and we can suggest a path separator
self.bump();
if self.token.span.lo() == self.prev_token.span.hi() {
err.span_suggestion_verbose(
self.prev_token.span,
"maybe write a path separator here",
"::",
Applicability::MaybeIncorrect,
);
}
if self.sess.unstable_features.is_nightly_build() {
// FIXME(Nilstrieb): Remove this again after a few months.
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions tests/ui/suggestions/range-index-instead-of-colon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// edition:2021

fn main() {
&[1, 2, 3][1:2];
//~^ ERROR: expected one of
//~| HELP: you might have meant a range expression
}
13 changes: 13 additions & 0 deletions tests/ui/suggestions/range-index-instead-of-colon.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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
|
help: you might have meant a range expression
|
LL | &[1, 2, 3][1..2];
| ~~

error: aborting due to 1 previous error

0 comments on commit 8d0f7a7

Please sign in to comment.