Skip to content

Commit

Permalink
recover wrong-cased uses (Use, USE, etc)
Browse files Browse the repository at this point in the history
  • Loading branch information
WaffleLapkin committed Oct 1, 2022
1 parent de341fe commit 3694429
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 3 deletions.
25 changes: 22 additions & 3 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)?)))
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/parser/item-kw-case-mismatch.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// run-rustfix
#![allow(unused_imports)]

fn main() {}

use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
7 changes: 7 additions & 0 deletions src/test/ui/parser/item-kw-case-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// run-rustfix
#![allow(unused_imports)]

fn main() {}

Use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
14 changes: 14 additions & 0 deletions src/test/ui/parser/item-kw-case-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: keyword `use` is written in a wrong case
--> $DIR/item-kw-case-mismatch.rs:6:1
|
LL | Use std::ptr::read;
| ^^^ help: write it in the correct case (notice the capitalization): `use`

error: keyword `use` is written in a wrong case
--> $DIR/item-kw-case-mismatch.rs:7:1
|
LL | USE std::ptr::write;
| ^^^ help: write it in the correct case: `use`

error: aborting due to 2 previous errors

0 comments on commit 3694429

Please sign in to comment.