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
This commit is contained in:
commit
a95a6e287a
@ -1001,9 +1001,7 @@ pub fn parse_ast_fragment(&mut self, kind: AstFragmentKind, macro_legacy_warning
|
||||
AstFragmentKind::ForeignItems => {
|
||||
let mut items = SmallVec::new();
|
||||
while self.token != token::Eof {
|
||||
if let Some(item) = self.parse_foreign_item()? {
|
||||
items.push(item);
|
||||
}
|
||||
items.push(self.parse_foreign_item()?);
|
||||
}
|
||||
AstFragment::ForeignItems(items)
|
||||
}
|
||||
|
@ -6737,10 +6737,9 @@ fn parse_item_foreign_mod(&mut self,
|
||||
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 @@ fn parse_item_implementation(
|
||||
}
|
||||
|
||||
/// 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 @@ fn parse_item_implementation(
|
||||
).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 @@ fn parse_item_implementation(
|
||||
vis: visibility,
|
||||
node: ForeignItemKind::Macro(mac),
|
||||
}
|
||||
))
|
||||
)
|
||||
}
|
||||
None => {
|
||||
if !attrs.is_empty() {
|
||||
if !attrs.is_empty() {
|
||||
self.expected_item_err(&attrs);
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
self.unexpected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// 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 {
|
||||
pub pub fn foo();
|
||||
}
|
||||
|
13
src/test/ui/macros/issue-54441.rs
Normal file
13
src/test/ui/macros/issue-54441.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(macros_in_extern)]
|
||||
|
||||
macro_rules! m {
|
||||
() => {
|
||||
let //~ ERROR expected
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
m!();
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/macros/issue-54441.stderr
Normal file
14
src/test/ui/macros/issue-54441.stderr
Normal 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
|
||||
|
Loading…
Reference in New Issue
Block a user