diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ae46bfe3540..4f91f1fecba 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -449,6 +449,16 @@ impl<'a> Parser<'a> { if end.is_doc_comment() { err.span_label(end.span, "this doc comment doesn't document anything"); } + if end.meta_kind().is_some() { + if self.token.kind == TokenKind::Semi { + err.span_suggestion_verbose( + self.token.span, + "consider removing this semicolon", + String::new(), + Applicability::MaybeIncorrect, + ); + } + } if let [.., penultimate, _] = attrs { err.span_label(start.span.to(penultimate.span), "other attributes here"); } diff --git a/src/test/ui/parser/attr-with-a-semicolon.rs b/src/test/ui/parser/attr-with-a-semicolon.rs new file mode 100644 index 00000000000..56fe40b916b --- /dev/null +++ b/src/test/ui/parser/attr-with-a-semicolon.rs @@ -0,0 +1,4 @@ +#[derive(Debug, Clone)]; //~ERROR expected item after attributes +struct Foo; + +fn main() {} diff --git a/src/test/ui/parser/attr-with-a-semicolon.stderr b/src/test/ui/parser/attr-with-a-semicolon.stderr new file mode 100644 index 00000000000..49ed30150d0 --- /dev/null +++ b/src/test/ui/parser/attr-with-a-semicolon.stderr @@ -0,0 +1,14 @@ +error: expected item after attributes + --> $DIR/attr-with-a-semicolon.rs:1:1 + | +LL | #[derive(Debug, Clone)]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing this semicolon + | +LL - #[derive(Debug, Clone)]; +LL + #[derive(Debug, Clone)] + | + +error: aborting due to previous error +