about summary refs log tree commit diff
path: root/compiler/rustc_span/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-07 14:21:22 +0300
committerGitHub <noreply@github.com>2024-09-07 14:21:22 +0300
commitd6a42983e57766546db519dcd8859ba75d4eef62 (patch)
treeb0ce1117f9a8c84608a1f3c91a28ea6d0d372e75 /compiler/rustc_span/src
parent6dd07e4e26411d34f9102d685f2634d47a9429d2 (diff)
parent14e86eb7d93ebda57d2008ae37e88ac2a0604570 (diff)
downloadrust-d6a42983e57766546db519dcd8859ba75d4eef62.tar.gz
rust-d6a42983e57766546db519dcd8859ba75d4eef62.zip
Rollup merge of #129899 - veera-sivarajan:fix-97793-pr-final, r=chenyukang
Add Suggestions for Misspelled Keywords

Fixes #97793

This PR detects misspelled keywords using two heuristics:

1. Lowercasing the unexpected identifier.
2. Using edit distance to find a keyword similar to the unexpected identifier.

However, it does not detect each and every misspelled keyword to
minimize false positives and ambiguities. More details about the
implementation can be found in the comments.
Diffstat (limited to 'compiler/rustc_span/src')
-rw-r--r--compiler/rustc_span/src/symbol.rs42
1 files changed, 41 insertions, 1 deletions
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 418d1078900..7572d57309c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -20,7 +20,8 @@ mod tests;
 
 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
 symbols! {
-    // If you modify this list, adjust `is_special` and `is_used_keyword`/`is_unused_keyword`.
+    // If you modify this list, adjust `is_special`, `is_used_keyword`/`is_unused_keyword`
+    // and `AllKeywords`.
     // But this should rarely be necessary if the keywords are kept in alphabetic order.
     Keywords {
         // Special reserved identifiers used internally for elided lifetimes,
@@ -2579,3 +2580,42 @@ impl Ident {
         self.name.can_be_raw() && self.is_reserved()
     }
 }
+
+/// An iterator over all the keywords in Rust.
+#[derive(Copy, Clone)]
+pub struct AllKeywords {
+    curr_idx: u32,
+    end_idx: u32,
+}
+
+impl AllKeywords {
+    /// Initialize a new iterator over all the keywords.
+    ///
+    /// *Note:* Please update this if a new keyword is added beyond the current
+    /// range.
+    pub fn new() -> Self {
+        AllKeywords { curr_idx: kw::Empty.as_u32(), end_idx: kw::Yeet.as_u32() }
+    }
+
+    /// Collect all the keywords in a given edition into a vector.
+    pub fn collect_used(&self, edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
+        self.filter(|&keyword| {
+            keyword.is_used_keyword_always() || keyword.is_used_keyword_conditional(edition)
+        })
+        .collect()
+    }
+}
+
+impl Iterator for AllKeywords {
+    type Item = Symbol;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.curr_idx <= self.end_idx {
+            let keyword = Symbol::new(self.curr_idx);
+            self.curr_idx += 1;
+            Some(keyword)
+        } else {
+            None
+        }
+    }
+}