diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c44ccfadda52d..ee24286241468 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1010,9 +1010,18 @@ impl<'a> Parser<'a> { ) -> PResult<'a, ItemInfo> { let impl_span = self.token.span; let mut err = self.expected_ident_found(); - let mut impl_info = self.parse_item_impl(attrs, defaultness)?; + + // Only try to recover if this is implementing a trait for a type + let mut impl_info = match self.parse_item_impl(attrs, defaultness) { + Ok(impl_info) => impl_info, + Err(mut recovery_error) => { + // Recovery failed, raise the "expected identifier" error + recovery_error.cancel(); + return Err(err); + } + }; + match impl_info.1 { - // only try to recover if this is implementing a trait for a type ItemKind::Impl(box ImplKind { of_trait: Some(ref trai), ref mut constness, .. }) => { @@ -1030,6 +1039,7 @@ impl<'a> Parser<'a> { ItemKind::Impl { .. } => return Err(err), _ => unreachable!(), } + Ok(impl_info) } diff --git a/src/test/ui/parser/issue-81806.rs b/src/test/ui/parser/issue-81806.rs new file mode 100644 index 0000000000000..ca86788dff79c --- /dev/null +++ b/src/test/ui/parser/issue-81806.rs @@ -0,0 +1,5 @@ +trait T { const +impl //~ ERROR: expected identifier, found keyword `impl` +} + +fn main() {} diff --git a/src/test/ui/parser/issue-81806.stderr b/src/test/ui/parser/issue-81806.stderr new file mode 100644 index 0000000000000..b8ada11d922b2 --- /dev/null +++ b/src/test/ui/parser/issue-81806.stderr @@ -0,0 +1,17 @@ +error: expected identifier, found keyword `impl` + --> $DIR/issue-81806.rs:2:1 + | +LL | trait T { const + | - while parsing this item list starting here +LL | impl + | ^^^^ expected identifier, found keyword +LL | } + | - the item list ends here + | +help: you can escape reserved keywords to use them as identifiers + | +LL | r#impl + | ^^^^^^ + +error: aborting due to previous error +