diff options
| author | Michael Goulet <michael@errs.io> | 2022-05-30 15:57:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-30 15:57:27 -0700 |
| commit | 22da719762c1d101c20f59620f1445f5eaf75bba (patch) | |
| tree | f823806dacf96d81cbb1385152f08feed9c87f3d /compiler/rustc_parse/src/parser | |
| parent | 3c0b9d50ae43eb4c13390fcc363e7cc4d4d661d3 (diff) | |
| parent | 0be2ca96fa7d723db870fb2f96df0f07d32c0774 (diff) | |
| download | rust-22da719762c1d101c20f59620f1445f5eaf75bba.tar.gz rust-22da719762c1d101c20f59620f1445f5eaf75bba.zip | |
Rollup merge of #97172 - SparrowLii:unsafe_extern, r=compiler-errors
Optimize the diagnostic generation for `extern unsafe`
This PR does the following about diagnostic generation when parsing foreign mod:
1. Fixes the FIXME about avoiding depending on the error message text.
2. Continue parsing when `unsafe` is followed by `{` (just like `unsafe extern {...}`).
3. Add test case.
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e99347206fe..6720399aacb 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -996,35 +996,24 @@ impl<'a> Parser<'a> { fn parse_item_foreign_mod( &mut self, attrs: &mut Vec<Attribute>, - 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). |
