From 0be2ca96fa7d723db870fb2f96df0f07d32c0774 Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Mon, 30 May 2022 15:56:43 +0800 Subject: Optimize the diagnostic generation for `extern unsafe` --- compiler/rustc_parse/src/parser/item.rs | 41 ++++++++++++--------------------- 1 file changed, 15 insertions(+), 26 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0f940cffcc4..5c9943b270f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -997,35 +997,24 @@ impl<'a> Parser<'a> { fn parse_item_foreign_mod( &mut self, attrs: &mut Vec, - unsafety: Unsafe, + mut unsafety: Unsafe, ) -> PResult<'a, ItemInfo> { - let sp_start = self.prev_token.span; let abi = self.parse_abi(); // ABI? - match self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No)) { - Ok(items) => { - let module = ast::ForeignMod { unsafety, abi, items }; - Ok((Ident::empty(), ItemKind::ForeignMod(module))) - } - Err(mut err) => { - let current_qual_sp = self.prev_token.span; - let current_qual_sp = current_qual_sp.to(sp_start); - if let Ok(current_qual) = self.span_to_snippet(current_qual_sp) { - // FIXME(davidtwco): avoid depending on the error message text - if err.message[0].0.expect_str() == "expected `{`, found keyword `unsafe`" { - let invalid_qual_sp = self.token.uninterpolated_span(); - let invalid_qual = self.span_to_snippet(invalid_qual_sp).unwrap(); - - err.span_suggestion( - current_qual_sp.to(invalid_qual_sp), - &format!("`{}` must come before `{}`", invalid_qual, current_qual), - format!("{} {}", invalid_qual, current_qual), - Applicability::MachineApplicable, - ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`"); - } - } - Err(err) - } + if unsafety == Unsafe::No + && self.token.is_keyword(kw::Unsafe) + && self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace)) + { + let mut err = self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err(); + err.emit(); + unsafety = Unsafe::Yes(self.token.span); + self.eat_keyword(kw::Unsafe); } + let module = ast::ForeignMod { + unsafety, + abi, + items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?, + }; + Ok((Ident::empty(), ItemKind::ForeignMod(module))) } /// Parses a foreign item (one in an `extern { ... }` block). -- cgit 1.4.1-3-g733a5