Skip to content

Commit 3694429

Browse files
committed
recover wrong-cased uses (Use, USE, etc)
1 parent de341fe commit 3694429

File tree

5 files changed

+77
-3
lines changed

5 files changed

+77
-3
lines changed

compiler/rustc_parse/src/parser/item.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,15 @@ impl<'a> Parser<'a> {
143143
let lo = self.token.span;
144144
let vis = self.parse_visibility(FollowedByType::No)?;
145145
let mut def = self.parse_defaultness();
146-
let kind =
147-
self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, fn_parse_mode)?;
146+
let kind = self.parse_item_kind(
147+
&mut attrs,
148+
mac_allowed,
149+
lo,
150+
&vis,
151+
&mut def,
152+
fn_parse_mode,
153+
false,
154+
)?;
148155
if let Some((ident, kind)) = kind {
149156
self.error_on_unconsumed_default(def, &kind);
150157
let span = lo.to(self.prev_token.span);
@@ -205,11 +212,12 @@ impl<'a> Parser<'a> {
205212
vis: &Visibility,
206213
def: &mut Defaultness,
207214
fn_parse_mode: FnParseMode,
215+
kw_case_insensitive: bool,
208216
) -> PResult<'a, Option<ItemInfo>> {
209217
let def_final = def == &Defaultness::Final;
210218
let mut def = || mem::replace(def, Defaultness::Final);
211219

212-
let info = if self.eat_keyword(kw::Use) {
220+
let info = if self.eat_keyword_case(kw::Use, kw_case_insensitive) {
213221
self.parse_use_item()?
214222
} else if self.check_fn_front_matter(def_final) {
215223
// FUNCTION ITEM
@@ -286,6 +294,17 @@ impl<'a> Parser<'a> {
286294
} else if self.isnt_macro_invocation() && vis.kind.is_pub() {
287295
self.recover_missing_kw_before_item()?;
288296
return Ok(None);
297+
} else if self.isnt_macro_invocation() && !kw_case_insensitive {
298+
// Recover wrong cased keywords
299+
return self.parse_item_kind(
300+
attrs,
301+
macros_allowed,
302+
lo,
303+
vis,
304+
&mut def(),
305+
fn_parse_mode,
306+
true,
307+
);
289308
} else if macros_allowed && self.check_path() {
290309
// MACRO INVOCATION ITEM
291310
(Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))

compiler/rustc_parse/src/parser/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,33 @@ impl<'a> Parser<'a> {
616616
}
617617
}
618618

619+
/// Eats a keyword, optionally ignoring the case.
620+
/// If the case differs (and is ignored) an error is issued.
621+
/// This is useful for recovery.
622+
fn eat_keyword_case(&mut self, kw: Symbol, case_insensitive: bool) -> bool {
623+
if self.eat_keyword(kw) {
624+
return true;
625+
}
626+
627+
if case_insensitive
628+
&& let Some((ident, /* is_raw */ false)) = self.token.ident()
629+
&& ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
630+
self
631+
.struct_span_err(ident.span, format!("keyword `{kw}` is written in a wrong case"))
632+
.span_suggestion(
633+
ident.span,
634+
"write it in the correct case",
635+
kw,
636+
Applicability::MachineApplicable
637+
).emit();
638+
639+
self.bump();
640+
return true;
641+
}
642+
643+
false
644+
}
645+
619646
fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
620647
if self.token.is_keyword(kw) {
621648
self.bump();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// run-rustfix
2+
#![allow(unused_imports)]
3+
4+
fn main() {}
5+
6+
use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
7+
use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// run-rustfix
2+
#![allow(unused_imports)]
3+
4+
fn main() {}
5+
6+
Use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
7+
USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: keyword `use` is written in a wrong case
2+
--> $DIR/item-kw-case-mismatch.rs:6:1
3+
|
4+
LL | Use std::ptr::read;
5+
| ^^^ help: write it in the correct case (notice the capitalization): `use`
6+
7+
error: keyword `use` is written in a wrong case
8+
--> $DIR/item-kw-case-mismatch.rs:7:1
9+
|
10+
LL | USE std::ptr::write;
11+
| ^^^ help: write it in the correct case: `use`
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)