diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-07-29 23:06:13 +0400 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-10-01 10:07:47 +0000 |
| commit | 3694429d09a2586cea5c769cddee10cd70f39d84 (patch) | |
| tree | fa09e66a0acbf8589a403f1c8e1106becf4c459f /compiler/rustc_parse/src | |
| parent | de341fe668fd821f701ca970c897d167104f0a17 (diff) | |
| download | rust-3694429d09a2586cea5c769cddee10cd70f39d84.tar.gz rust-3694429d09a2586cea5c769cddee10cd70f39d84.zip | |
recover wrong-cased `use`s (`Use`, `USE`, etc)
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 27 |
2 files changed, 49 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 25425fbb2c6..34c7d4ec481 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -143,8 +143,15 @@ impl<'a> Parser<'a> { let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; let mut def = self.parse_defaultness(); - let kind = - self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, fn_parse_mode)?; + let kind = self.parse_item_kind( + &mut attrs, + mac_allowed, + lo, + &vis, + &mut def, + fn_parse_mode, + false, + )?; if let Some((ident, kind)) = kind { self.error_on_unconsumed_default(def, &kind); let span = lo.to(self.prev_token.span); @@ -205,11 +212,12 @@ impl<'a> Parser<'a> { vis: &Visibility, def: &mut Defaultness, fn_parse_mode: FnParseMode, + kw_case_insensitive: bool, ) -> PResult<'a, Option<ItemInfo>> { let def_final = def == &Defaultness::Final; let mut def = || mem::replace(def, Defaultness::Final); - let info = if self.eat_keyword(kw::Use) { + let info = if self.eat_keyword_case(kw::Use, kw_case_insensitive) { self.parse_use_item()? } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM @@ -286,6 +294,17 @@ impl<'a> Parser<'a> { } else if self.isnt_macro_invocation() && vis.kind.is_pub() { self.recover_missing_kw_before_item()?; return Ok(None); + } else if self.isnt_macro_invocation() && !kw_case_insensitive { + // Recover wrong cased keywords + return self.parse_item_kind( + attrs, + macros_allowed, + lo, + vis, + &mut def(), + fn_parse_mode, + true, + ); } else if macros_allowed && self.check_path() { // MACRO INVOCATION ITEM (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?))) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2aebaf7c3af..b82ce90129f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -616,6 +616,33 @@ impl<'a> Parser<'a> { } } + /// Eats a keyword, optionally ignoring the case. + /// If the case differs (and is ignored) an error is issued. + /// This is useful for recovery. + fn eat_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool { + if self.eat_keyword(kw) { + return true; + } + + if case_insensitive + && let Some((ident, /* is_raw */ false)) = self.token.ident() + && ident.as_str().to_lowercase() == kw.as_str().to_lowercase() { + self + .struct_span_err(ident.span, format!("keyword `{kw}` is written in a wrong case")) + .span_suggestion( + ident.span, + "write it in the correct case", + kw, + Applicability::MachineApplicable + ).emit(); + + self.bump(); + return true; + } + + false + } + fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool { if self.token.is_keyword(kw) { self.bump(); |
