make Parser::parse_foreign_item()
return a foreign item or error
closes #54441
This commit is contained in:
parent
a57f1c9c95
commit
9da428dad8
5 changed files with 40 additions and 16 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
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…
Add table
Add a link
Reference in a new issue