Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,4 +545,18 @@ impl<'a> Parser<'a> {

Ok(())
}

/// Parse inner attributes and error if they are present
/// Returns whether any inner attributes were discarded
pub fn recover_inner_attributes(&mut self) -> PResult<'a, bool> {
let attributes = self.parse_inner_attributes()?;
for attr in &attributes {
self.error_on_forbidden_inner_attr(
attr.span,
InnerAttrPolicy::Forbidden(Some(InnerAttrForbiddenReason::InCodeBlock)),
true,
);
}
Ok(!attributes.is_empty())
}
}
4 changes: 4 additions & 0 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,9 @@ impl<'a> Parser<'a> {
}

fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
if self.recover_inner_attributes()? && self.check(exp![CloseBrace]) {
return Ok(None);
}
self.recover_vcs_conflict_marker();
let variant_attrs = self.parse_outer_attributes()?;
self.recover_vcs_conflict_marker();
Expand Down Expand Up @@ -2139,6 +2142,7 @@ impl<'a> Parser<'a> {
let mut fields = ThinVec::new();
let mut recovered = Recovered::No;
if self.eat(exp!(OpenBrace)) {
self.recover_inner_attributes()?;
while self.token != token::CloseBrace {
match self.parse_field_def(adt_ty, ident_span) {
Ok(field) => {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/parser/empty-adt-inner-attributes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
struct Test1 {
#![inline]
//~^ ERROR an inner attribute is not permitted in this context
}

enum Test2 {
#![inline]
//~^ ERROR an inner attribute is not permitted in this context
}

union Test3 {
//~^ ERROR unions cannot have zero fields
#![inline]
//~^ ERROR an inner attribute is not permitted in this context
}

fn main() { }
39 changes: 39 additions & 0 deletions tests/ui/parser/empty-adt-inner-attributes.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error: an inner attribute is not permitted in this context
--> $DIR/empty-adt-inner-attributes.rs:2:5
|
LL | #![inline]
| ^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
= note: outer attributes, like `#[test]`, annotate the item following them

error: an inner attribute is not permitted in this context
--> $DIR/empty-adt-inner-attributes.rs:7:5
|
LL | #![inline]
| ^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
= note: outer attributes, like `#[test]`, annotate the item following them

error: an inner attribute is not permitted in this context
--> $DIR/empty-adt-inner-attributes.rs:13:5
|
LL | #![inline]
| ^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
= note: outer attributes, like `#[test]`, annotate the item following them

error: unions cannot have zero fields
--> $DIR/empty-adt-inner-attributes.rs:11:1
|
LL | / union Test3 {
LL | |
LL | | #![inline]
LL | |
LL | | }
| |_^

error: aborting due to 4 previous errors

Loading