about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyo Yoshida <low.ryoshida@gmail.com>2022-08-16 10:08:45 +0900
committerRyo Yoshida <low.ryoshida@gmail.com>2022-08-17 18:46:17 +0900
commita3409c3a83fb1d8139bac8b3e438f56f2ac633a3 (patch)
tree54781d22e9918a12b35b95bdbca7bd85793ccb44
parent010f68cacfdddcc50234b54965e1326d7ad925ab (diff)
downloadrust-a3409c3a83fb1d8139bac8b3e438f56f2ac633a3.tar.gz
rust-a3409c3a83fb1d8139bac8b3e438f56f2ac633a3.zip
fix: escape keywords used as names in earlier editions
-rw-r--r--crates/hir-expand/src/name.rs10
-rw-r--r--crates/ide-db/src/search.rs4
2 files changed, 11 insertions, 3 deletions
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 87c663eec8e..a1bb353374b 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -90,10 +90,16 @@ impl Name {
 
     /// Resolve a name from the text of token.
     fn resolve(raw_text: &str) -> Name {
-        // When `raw_text` starts with "r#" but the name does not coincide with any
-        // keyword, we never need the prefix so we strip it.
         match raw_text.strip_prefix("r#") {
+            // When `raw_text` starts with "r#" but the name does not coincide with any
+            // keyword, we never need the prefix so we strip it.
             Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)),
+            // Keywords (in the current edition) *can* be used as a name in earlier editions of
+            // Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their
+            // escaped form.
+            None if is_raw_identifier(raw_text) => {
+                Name::new_text(SmolStr::from_iter(["r#", raw_text]))
+            }
             _ => Name::new_text(raw_text.into()),
         }
     }
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index 9eaabeec7a4..2f4aa113170 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -402,7 +402,9 @@ impl<'a> FindUsages<'a> {
                             .or_else(|| ty.as_builtin().map(|builtin| builtin.name()))
                     })
                 };
-                self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.to_smol_str())
+                // We need to unescape the name in case it is written without "r#" in earlier
+                // editions of Rust where it isn't a keyword.
+                self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.unescaped().to_smol_str())
             }
         };
         let name = match &name {