diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-expand/src/name.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-expand/src/name.rs | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 85b0a7735..4ce21a579 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -7,12 +7,16 @@ use syntax::{ast, SmolStr, SyntaxKind}; /// `Name` is a wrapper around string, which is used in hir for both references /// and declarations. In theory, names should also carry hygiene info, but we are /// not there yet! +/// +/// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it +/// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the +/// name without "r#". #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Name(Repr); -/// `EscapedName` will add a prefix "r#" to the wrapped `Name` when it is a raw identifier +/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct EscapedName<'a>(&'a Name); +pub struct UnescapedName<'a>(&'a Name); #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] enum Repr { @@ -34,37 +38,26 @@ fn is_raw_identifier(name: &str) -> bool { is_keyword && !matches!(name, "self" | "crate" | "super" | "Self") } -impl<'a> fmt::Display for EscapedName<'a> { +impl<'a> fmt::Display for UnescapedName<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 .0 { Repr::Text(text) => { - if is_raw_identifier(text) { - write!(f, "r#{}", &text) - } else { - fmt::Display::fmt(&text, f) - } + let text = text.strip_prefix("r#").unwrap_or(text); + fmt::Display::fmt(&text, f) } Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), } } } -impl<'a> EscapedName<'a> { - pub fn is_escaped(&self) -> bool { - match &self.0 .0 { - Repr::Text(it) => is_raw_identifier(&it), - Repr::TupleField(_) => false, - } - } - - /// Returns the textual representation of this name as a [`SmolStr`]. - /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in - /// the general case. +impl<'a> UnescapedName<'a> { + /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over + /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case. pub fn to_smol_str(&self) -> SmolStr { match &self.0 .0 { Repr::Text(it) => { - if is_raw_identifier(&it) { - SmolStr::from_iter(["r#", &it]) + if let Some(stripped) = it.strip_prefix("r#") { + SmolStr::new(stripped) } else { it.clone() } @@ -98,8 +91,16 @@ impl Name { /// Resolve a name from the text of token. fn resolve(raw_text: &str) -> Name { match raw_text.strip_prefix("r#") { - Some(text) => Name::new_text(SmolStr::new(text)), - None => Name::new_text(raw_text.into()), + // 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()), } } @@ -142,8 +143,15 @@ impl Name { } } - pub fn escaped(&self) -> EscapedName<'_> { - EscapedName(self) + pub fn unescaped(&self) -> UnescapedName<'_> { + UnescapedName(self) + } + + pub fn is_escaped(&self) -> bool { + match &self.0 { + Repr::Text(it) => it.starts_with("r#"), + Repr::TupleField(_) => false, + } } } @@ -258,6 +266,7 @@ pub mod known { Try, Ok, Future, + IntoFuture, Result, Option, Output, @@ -327,6 +336,7 @@ pub mod known { test, test_case, recursion_limit, + feature, // Safe intrinsics abort, add_with_overflow, @@ -381,6 +391,7 @@ pub mod known { bitor, bitxor_assign, bitxor, + branch, deref_mut, deref, div_assign, @@ -390,12 +401,14 @@ pub mod known { future_trait, index, index_mut, + into_future, mul_assign, mul, neg, not, owned_box, partial_ord, + poll, r#fn, rem_assign, rem, |