Skip to content

Commit 203aaf6

Browse files
Rollup merge of #111133 - hkmatsumoto:handle-python-slicing, r=TaKO8Ki
Detect Python-like slicing and suggest how to fix Fix #108215
2 parents 49b3924 + acec70d commit 203aaf6

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

compiler/rustc_ast/src/token.rs

+5
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,11 @@ impl Token {
756756
)
757757
}
758758

759+
/// Returns `true` if the token is the integer literal.
760+
pub fn is_integer_lit(&self) -> bool {
761+
matches!(self.kind, Literal(Lit { kind: LitKind::Integer, .. }))
762+
}
763+
759764
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
760765
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
761766
match self.ident() {

compiler/rustc_parse/src/parser/stmt.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -567,20 +567,37 @@ impl<'a> Parser<'a> {
567567
snapshot.recover_diff_marker();
568568
}
569569
if self.token == token::Colon {
570-
// if next token is following a colon, it's likely a path
571-
// and we can suggest a path separator
572-
self.bump();
573-
if self.token.span.lo() == self.prev_token.span.hi() {
570+
// if a previous and next token of the current one is
571+
// integer literal (e.g. `1:42`), it's likely a range
572+
// expression for Pythonistas and we can suggest so.
573+
if self.prev_token.is_integer_lit()
574+
&& self.may_recover()
575+
&& self.look_ahead(1, |token| token.is_integer_lit())
576+
{
577+
// FIXME(hkmatsumoto): Might be better to trigger
578+
// this only when parsing an index expression.
574579
err.span_suggestion_verbose(
575-
self.prev_token.span,
576-
"maybe write a path separator here",
577-
"::",
580+
self.token.span,
581+
"you might have meant a range expression",
582+
"..",
578583
Applicability::MaybeIncorrect,
579584
);
580-
}
581-
if self.sess.unstable_features.is_nightly_build() {
582-
// FIXME(Nilstrieb): Remove this again after a few months.
583-
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
585+
} else {
586+
// if next token is following a colon, it's likely a path
587+
// and we can suggest a path separator
588+
self.bump();
589+
if self.token.span.lo() == self.prev_token.span.hi() {
590+
err.span_suggestion_verbose(
591+
self.prev_token.span,
592+
"maybe write a path separator here",
593+
"::",
594+
Applicability::MaybeIncorrect,
595+
);
596+
}
597+
if self.sess.unstable_features.is_nightly_build() {
598+
// FIXME(Nilstrieb): Remove this again after a few months.
599+
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
600+
}
584601
}
585602
}
586603

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// edition:2021
2+
3+
fn main() {
4+
&[1, 2, 3][1:2];
5+
//~^ ERROR: expected one of
6+
//~| HELP: you might have meant a range expression
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: expected one of `.`, `?`, `]`, or an operator, found `:`
2+
--> $DIR/range-index-instead-of-colon.rs:4:17
3+
|
4+
LL | &[1, 2, 3][1:2];
5+
| ^ expected one of `.`, `?`, `]`, or an operator
6+
|
7+
help: you might have meant a range expression
8+
|
9+
LL | &[1, 2, 3][1..2];
10+
| ~~
11+
12+
error: aborting due to 1 previous error
13+

0 commit comments

Comments
 (0)