1
Fork 0

make Parser::parse_foreign_item() return a foreign item or error

closes #54441
This commit is contained in:
Austin Bonander 2018-10-03 14:24:31 -07:00
parent a57f1c9c95
commit 9da428dad8
5 changed files with 40 additions and 16 deletions

View file

@ -1008,9 +1008,7 @@ impl<'a> Parser<'a> {
AstFragmentKind::ForeignItems => { AstFragmentKind::ForeignItems => {
let mut items = SmallVec::new(); let mut items = SmallVec::new();
while self.token != token::Eof { while self.token != token::Eof {
if let Some(item) = self.parse_foreign_item()? { items.push(self.parse_foreign_item()?);
items.push(item);
}
} }
AstFragment::ForeignItems(items) AstFragment::ForeignItems(items)
} }

View file

@ -6718,10 +6718,9 @@ impl<'a> Parser<'a> {
attrs.extend(self.parse_inner_attributes()?); attrs.extend(self.parse_inner_attributes()?);
let mut foreign_items = vec![]; let mut foreign_items = vec![];
while let Some(item) = self.parse_foreign_item()? { while !self.eat(&token::CloseDelim(token::Brace)) {
foreign_items.push(item); foreign_items.push(self.parse_foreign_item()?);
} }
self.expect(&token::CloseDelim(token::Brace))?;
let prev_span = self.prev_span; let prev_span = self.prev_span;
let m = ast::ForeignMod { let m = ast::ForeignMod {
@ -7305,8 +7304,8 @@ impl<'a> Parser<'a> {
} }
/// Parse a foreign item. /// Parse a foreign item.
crate fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> { crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
maybe_whole!(self, NtForeignItem, |ni| Some(ni)); maybe_whole!(self, NtForeignItem, |ni| ni);
let attrs = self.parse_outer_attributes()?; let attrs = self.parse_outer_attributes()?;
let lo = self.span; let lo = self.span;
@ -7326,20 +7325,20 @@ impl<'a> Parser<'a> {
).emit(); ).emit();
} }
self.bump(); // `static` or `const` 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 // FOREIGN FUNCTION ITEM
if self.check_keyword(keywords::Fn) { 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 // FOREIGN TYPE ITEM
if self.check_keyword(keywords::Type) { 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)? { match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
Some(mac) => { Some(mac) => {
Ok(Some( Ok(
ForeignItem { ForeignItem {
ident: keywords::Invalid.ident(), ident: keywords::Invalid.ident(),
span: lo.to(self.prev_span), span: lo.to(self.prev_span),
@ -7348,14 +7347,14 @@ impl<'a> Parser<'a> {
vis: visibility, vis: visibility,
node: ForeignItemKind::Macro(mac), node: ForeignItemKind::Macro(mac),
} }
)) )
} }
None => { None => {
if !attrs.is_empty() { if !attrs.is_empty() {
self.expected_item_err(&attrs); self.expected_item_err(&attrs);
} }
Ok(None) self.unexpected()
} }
} }
} }

View file

@ -10,7 +10,7 @@
// compile-flags: -Z parse-only // compile-flags: -Z parse-only
// error-pattern:expected one of `(`, `fn`, `static`, `type`, or `}` here // error-pattern:expected one of `(`, `fn`, `static`, or `type`
extern { extern {
pub pub fn foo(); pub pub fn foo();
} }

View file

@ -0,0 +1,13 @@
#![feature(macros_in_extern)]
macro_rules! m {
() => {
let //~ ERROR expected
};
}
extern "C" {
m!();
}
fn main() {}

View file

@ -0,0 +1,14 @@
error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found `let`
--> $DIR/issue-54441.rs:5:9
|
LL | #![feature(macros_in_extern)]
| - expected one of `crate`, `fn`, `pub`, `static`, or `type` here
...
LL | let //~ ERROR expected
| ^^^ unexpected token
...
LL | m!();
| ----- in this macro invocation
error: aborting due to previous error