diff options
| author | Pietro Albini <pietro@pietroalbini.org> | 2018-10-05 22:33:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-05 22:33:17 +0200 |
| commit | a95a6e287a9ea2665e6e1a230cf6acaeb1bbe9d1 (patch) | |
| tree | 6fc17abed4c52dd300c415ea77154bb16d079755 /src/libsyntax/parse | |
| parent | 08af25fb27a521ee924787c10c96e8d9e2b04db9 (diff) | |
| parent | 9da428dad8eefa8a821214bc0fe0d4159ba4efed (diff) | |
| download | rust-a95a6e287a9ea2665e6e1a230cf6acaeb1bbe9d1.tar.gz rust-a95a6e287a9ea2665e6e1a230cf6acaeb1bbe9d1.zip | |
Rollup merge of #54833 - abonander:issue-54441, r=petrochenkov
make `Parser::parse_foreign_item()` return a foreign item or error Fixes `Parser::parse_foreign_item()` to follow the convention of `parse_trait_item()` and `parse_impl_item()` in that it *must* parse an item or return an error, and then the caller is responsible for detecting the closing delimiter. This prevents it from looping endlessly on an unexpected token in `ext/expand.rs` where it was also leaking memory by continually pushing to `Parser::expected_tokens` via `Parser::check_keyword()`. closes #54441 r? @petrochenkov cc @dtolnay
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1825ee6eab8..d653ed819fd 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6737,10 +6737,9 @@ impl<'a> Parser<'a> { attrs.extend(self.parse_inner_attributes()?); let mut foreign_items = vec![]; - while let Some(item) = self.parse_foreign_item()? { - foreign_items.push(item); + while !self.eat(&token::CloseDelim(token::Brace)) { + foreign_items.push(self.parse_foreign_item()?); } - self.expect(&token::CloseDelim(token::Brace))?; let prev_span = self.prev_span; let m = ast::ForeignMod { @@ -7324,8 +7323,8 @@ impl<'a> Parser<'a> { } /// Parse a foreign item. - crate fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> { - maybe_whole!(self, NtForeignItem, |ni| Some(ni)); + crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> { + maybe_whole!(self, NtForeignItem, |ni| ni); let attrs = self.parse_outer_attributes()?; let lo = self.span; @@ -7345,20 +7344,20 @@ impl<'a> Parser<'a> { ).emit(); } self.bump(); // `static` or `const` - return Ok(Some(self.parse_item_foreign_static(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?); } // FOREIGN FUNCTION ITEM if self.check_keyword(keywords::Fn) { - return Ok(Some(self.parse_item_foreign_fn(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_fn(visibility, lo, attrs)?); } // FOREIGN TYPE ITEM if self.check_keyword(keywords::Type) { - return Ok(Some(self.parse_item_foreign_type(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?); } match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? { Some(mac) => { - Ok(Some( + Ok( ForeignItem { ident: keywords::Invalid.ident(), span: lo.to(self.prev_span), @@ -7367,14 +7366,14 @@ impl<'a> Parser<'a> { vis: visibility, node: ForeignItemKind::Macro(mac), } - )) + ) } None => { - if !attrs.is_empty() { + if !attrs.is_empty() { self.expected_item_err(&attrs); } - Ok(None) + self.unexpected() } } } |
