Skip to content

Commit 1eee532

Browse files
authored
Rollup merge of rust-lang#54409 - estebank:remove-in, r=pnkfelix
Detect `for _ in in bar {}` typo Fix rust-lang#36611, rust-lang#52964, without modifying the parsing of emplacement `in` to avoid further problems like rust-lang#50832.
2 parents 8455a7f + 06d577d commit 1eee532

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

src/libsyntax/parse/parser.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -2703,8 +2703,8 @@ impl<'a> Parser<'a> {
27032703
token::Literal(token::Float(n), _suf) => {
27042704
self.bump();
27052705
let fstr = n.as_str();
2706-
let mut err = self.diagnostic().struct_span_err(self.prev_span,
2707-
&format!("unexpected token: `{}`", n));
2706+
let mut err = self.diagnostic()
2707+
.struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n));
27082708
err.span_label(self.prev_span, "unexpected token");
27092709
if fstr.chars().all(|x| "0123456789.".contains(x)) {
27102710
let float = match fstr.parse::<f64>().ok() {
@@ -2864,8 +2864,8 @@ impl<'a> Parser<'a> {
28642864
let e = self.parse_prefix_expr(None);
28652865
let (span, e) = self.interpolated_or_expr_span(e)?;
28662866
let span_of_tilde = lo;
2867-
let mut err = self.diagnostic().struct_span_err(span_of_tilde,
2868-
"`~` cannot be used as a unary operator");
2867+
let mut err = self.diagnostic()
2868+
.struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator");
28692869
err.span_suggestion_short_with_applicability(
28702870
span_of_tilde,
28712871
"use `!` to perform bitwise negation",
@@ -3423,6 +3423,24 @@ impl<'a> Parser<'a> {
34233423
);
34243424
err.emit();
34253425
}
3426+
let in_span = self.prev_span;
3427+
if self.eat_keyword(keywords::In) {
3428+
// a common typo: `for _ in in bar {}`
3429+
let mut err = self.sess.span_diagnostic.struct_span_err(
3430+
self.prev_span,
3431+
"expected iterable, found keyword `in`",
3432+
);
3433+
err.span_suggestion_short_with_applicability(
3434+
in_span.until(self.prev_span),
3435+
"remove the duplicated `in`",
3436+
String::new(),
3437+
Applicability::MachineApplicable,
3438+
);
3439+
err.note("if you meant to use emplacement syntax, it is obsolete (for now, anyway)");
3440+
err.note("for more information on the status of emplacement syntax, see <\
3441+
https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>");
3442+
err.emit();
3443+
}
34263444
let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
34273445
let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
34283446
attrs.extend(iattrs);
@@ -4766,12 +4784,9 @@ impl<'a> Parser<'a> {
47664784
if !self.eat(&token::OpenDelim(token::Brace)) {
47674785
let sp = self.span;
47684786
let tok = self.this_token_to_string();
4769-
let mut do_not_suggest_help = false;
47704787
let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok));
4771-
if self.token.is_keyword(keywords::In) || self.token == token::Colon {
4772-
do_not_suggest_help = true;
4773-
e.span_label(sp, "expected `{`");
4774-
}
4788+
let do_not_suggest_help =
4789+
self.token.is_keyword(keywords::In) || self.token == token::Colon;
47754790

47764791
if self.token.is_ident_named("and") {
47774792
e.span_suggestion_short_with_applicability(
@@ -4802,6 +4817,7 @@ impl<'a> Parser<'a> {
48024817
|| do_not_suggest_help {
48034818
// if the next token is an open brace (e.g., `if a b {`), the place-
48044819
// inside-a-block suggestion would be more likely wrong than right
4820+
e.span_label(sp, "expected `{`");
48054821
return Err(e);
48064822
}
48074823
let mut stmt_span = stmt.span;

src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ error: expected `{`, found `and`
22
--> $DIR/issue-54109-and_instead_of_ampersands.rs:14:10
33
|
44
LL | if a and b {
5-
| -- ^^^ help: use `&&` instead of `and` for the boolean operator
6-
| |
5+
| -- ^^^
6+
| | |
7+
| | expected `{`
8+
| | help: use `&&` instead of `and` for the boolean operator
79
| this `if` statement has a condition, but no block
810

911
error: expected `{`, found `or`
1012
--> $DIR/issue-54109-and_instead_of_ampersands.rs:23:10
1113
|
1214
LL | if a or b {
13-
| -- ^^ help: use `||` instead of `or` for the boolean operator
14-
| |
15+
| -- ^^
16+
| | |
17+
| | expected `{`
18+
| | help: use `||` instead of `or` for the boolean operator
1519
| this `if` statement has a condition, but no block
1620

1721
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and`

src/test/ui/parser/if-in-in.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
for i in in 1..2 {
3+
println!("{}", i);
4+
}
5+
}

src/test/ui/parser/if-in-in.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: expected iterable, found keyword `in`
2+
--> $DIR/if-in-in.rs:2:14
3+
|
4+
LL | for i in in 1..2 {
5+
| ---^^
6+
| |
7+
| help: remove the duplicated `in`
8+
|
9+
= note: if you meant to use emplacement syntax, it is obsolete (for now, anyway)
10+
= note: for more information on the status of emplacement syntax, see <https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>
11+
12+
error: aborting due to previous error
13+

0 commit comments

Comments
 (0)