Skip to content

Commit c1a0b6d

Browse files
committed
Auto merge of #45503 - thombles:tk/i44339-v5, r=petrochenkov
Improve diagnostics when list of tokens has incorrect separators Make `parse_seq_to_before_tokens` more resilient to error conditions. Where possible it is better if it can consume up to the final bracket before returning. This change improves the diagnostics in a couple of situations: ``` struct S(pub () ()); // omitted separator use std::{foo. bar}; // used a similar but wrong separator ``` Fixes #44339 r? @petrochenkov
2 parents d9f1249 + ae6a9e6 commit c1a0b6d

File tree

7 files changed

+55
-4
lines changed

7 files changed

+55
-4
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,23 @@ impl<'a> Parser<'a> {
10331033
} else {
10341034
if let Err(e) = self.expect(t) {
10351035
fe(e);
1036-
break;
1036+
// Attempt to keep parsing if it was a similar separator
1037+
if let Some(ref tokens) = t.similar_tokens() {
1038+
if tokens.contains(&self.token) {
1039+
self.bump();
1040+
}
1041+
}
1042+
// Attempt to keep parsing if it was an omitted separator
1043+
match f(self) {
1044+
Ok(t) => {
1045+
v.push(t);
1046+
continue;
1047+
},
1048+
Err(mut e) => {
1049+
e.cancel();
1050+
break;
1051+
}
1052+
}
10371053
}
10381054
}
10391055
}

src/libsyntax/parse/token.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,16 @@ impl Token {
433433
})
434434
}
435435

436+
/// Returns tokens that are likely to be typed accidentally instead of the current token.
437+
/// Enables better error recovery when the wrong token is found.
438+
pub fn similar_tokens(&self) -> Option<Vec<Token>> {
439+
match *self {
440+
Comma => Some(vec![Dot, Lt]),
441+
Semi => Some(vec![Colon]),
442+
_ => None
443+
}
444+
}
445+
436446
/// Returns `true` if the token is either a special identifier or a keyword.
437447
pub fn is_reserved_ident(&self) -> bool {
438448
self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword()

src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ mod foo {
1313
struct S1(pub(in foo) (), pub(T), pub(crate) (), pub(((), T)));
1414
struct S2(pub((foo)) ());
1515
//~^ ERROR expected `,`, found `(`
16-
//~| ERROR expected one of `;` or `where`, found `(`
16+
//~| ERROR cannot find type `foo` in this scope
1717
}

src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ macro_rules! define_struct {
1414
struct S2(pub (in foo) ());
1515
struct S3(pub $t ());
1616
//~^ ERROR expected `,`, found `(`
17-
//~| ERROR expected one of `;` or `where`, found `(`
1817
}
1918
}
2019

src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ macro_rules! define_struct {
1414
struct S2(pub (in foo) ());
1515
struct S3(pub($t) ());
1616
//~^ ERROR expected `,`, found `(`
17-
//~| ERROR expected one of `;` or `where`, found `(`
1817
}
1918
}
2019

src/test/ui/similar-tokens.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
mod x {
12+
pub struct A;
13+
pub struct B;
14+
}
15+
16+
// `.` is similar to `,` so list parsing should continue to closing `}`
17+
use x::{A. B};
18+
19+
fn main() {}

src/test/ui/similar-tokens.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected one of `,` or `as`, found `.`
2+
--> $DIR/similar-tokens.rs:17:10
3+
|
4+
17 | use x::{A. B};
5+
| ^ expected one of `,` or `as` here
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)