Skip to content

Commit

Permalink
Collect unclosed delimiters in parent parser
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Mar 7, 2019
1 parent 51d0e86 commit ac6cc2d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 35 deletions.
17 changes: 13 additions & 4 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -1510,9 +1510,13 @@ impl<'a> Parser<'a> {
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
maybe_whole!(self, NtTraitItem, |x| x);
let attrs = self.parse_outer_attributes()?;
let mut unclosed_delims = vec![];
let (mut item, tokens) = self.collect_tokens(|this| {
this.parse_trait_item_(at_end, attrs)
let item = this.parse_trait_item_(at_end, attrs);
unclosed_delims.append(&mut this.unclosed_delims);
item
})?;
self.unclosed_delims.append(&mut unclosed_delims);
// See `parse_item` for why this clause is here.
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
item.tokens = Some(tokens);
Expand Down Expand Up @@ -6475,9 +6479,13 @@ impl<'a> Parser<'a> {
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
maybe_whole!(self, NtImplItem, |x| x);
let attrs = self.parse_outer_attributes()?;
let mut unclosed_delims = vec![];
let (mut item, tokens) = self.collect_tokens(|this| {
this.parse_impl_item_(at_end, attrs)
let item = this.parse_impl_item_(at_end, attrs);
unclosed_delims.append(&mut this.unclosed_delims);
item
})?;
self.unclosed_delims.append(&mut unclosed_delims);

// See `parse_item` for why this clause is here.
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
Expand Down Expand Up @@ -7797,12 +7805,13 @@ impl<'a> Parser<'a> {
macros_allowed: bool,
attributes_allowed: bool,
) -> PResult<'a, Option<P<Item>>> {
let mut unclosed_delims = vec![];
let (ret, tokens) = self.collect_tokens(|this| {
let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
let diag = this.diagnostic();
emit_unclosed_delims(&mut this.unclosed_delims, diag);
unclosed_delims.append(&mut this.unclosed_delims);
item
})?;
self.unclosed_delims.append(&mut unclosed_delims);

// Once we've parsed an item and recorded the tokens we got while
// parsing we may want to store `tokens` into the item we're about to
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/parser-recovery-2.stderr
@@ -1,3 +1,9 @@
error: unexpected token: `;`
--> $DIR/parser-recovery-2.rs:12:15
|
LL | let x = y.; //~ ERROR unexpected token
| ^

error: incorrect close delimiter: `)`
--> $DIR/parser-recovery-2.rs:8:5
|
Expand All @@ -7,12 +13,6 @@ LL | let x = foo(); //~ ERROR cannot find function `foo` in this scope
LL | ) //~ ERROR incorrect close delimiter: `)`
| ^ incorrect close delimiter

error: unexpected token: `;`
--> $DIR/parser-recovery-2.rs:12:15
|
LL | let x = y.; //~ ERROR unexpected token
| ^

error[E0425]: cannot find function `foo` in this scope
--> $DIR/parser-recovery-2.rs:7:17
|
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/resolve/token-error-correct-3.rs
Expand Up @@ -14,10 +14,10 @@ pub mod raw {
//~^ ERROR cannot find function `is_directory`
callback(path.as_ref();
//~^ ERROR expected one of
//~| ERROR this function takes 1 parameter but 2 parameters were supplied
fs::create_dir_all(path.as_ref()).map(|()| true)
//~^ ERROR mismatched types
} else {
//~^ ERROR incorrect close delimiter: `}`
//~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
Ok(false);
}

Expand Down
47 changes: 24 additions & 23 deletions src/test/ui/resolve/token-error-correct-3.stderr
@@ -1,38 +1,39 @@
error: incorrect close delimiter: `}`
--> $DIR/token-error-correct-3.rs:19:9
|
LL | if !is_directory(path.as_ref()) {
| - close delimiter possibly meant for this
LL | //~^ ERROR cannot find function `is_directory`
LL | callback(path.as_ref();
| - un-closed delimiter
...
LL | } else {
| ^ incorrect close delimiter

error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-3.rs:15:35
|
LL | callback(path.as_ref();
| ^ expected one of `)`, `,`, `.`, `?`, or an operator here
| - ^
| | |
| | help: `)` may belong here
| unclosed delimiter

error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
--> $DIR/token-error-correct-3.rs:19:9
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true)
| - expected one of `.`, `;`, `?`, `}`, or an operator here
LL | //~^ ERROR mismatched types
LL | } else {
| ^ unexpected token

error[E0425]: cannot find function `is_directory` in this scope
--> $DIR/token-error-correct-3.rs:13:13
|
LL | if !is_directory(path.as_ref()) {
| ^^^^^^^^^^^^ not found in this scope

error[E0057]: this function takes 1 parameter but 2 parameters were supplied
--> $DIR/token-error-correct-3.rs:15:13
error[E0308]: mismatched types
--> $DIR/token-error-correct-3.rs:17:13
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
| |
| expected (), found enum `std::result::Result`
|
LL | / callback(path.as_ref();
LL | | //~^ ERROR expected one of
LL | | //~| ERROR this function takes 1 parameter but 2 parameters were supplied
LL | | fs::create_dir_all(path.as_ref()).map(|()| true)
LL | | } else {
| |_________^ expected 1 parameter
= note: expected type `()`
found type `std::result::Result<bool, std::io::Error>`

error: aborting due to 4 previous errors

Some errors occurred: E0057, E0425.
For more information about an error, try `rustc --explain E0057`.
Some errors occurred: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.

0 comments on commit ac6cc2d

Please sign in to comment.