diff options
| author | xizheyin <xizheyin@smail.nju.edu.cn> | 2025-08-06 21:19:09 +0800 |
|---|---|---|
| committer | xizheyin <xizheyin@smail.nju.edu.cn> | 2025-08-06 21:19:09 +0800 |
| commit | 6e7b9d51495fd52a79dde8ef8950addb36610f85 (patch) | |
| tree | 4a458b33bacda5463aae93d310c8f570cd97e45d /compiler/rustc_span | |
| parent | dc0bae1db725fbba8524f195f74f680995fd549e (diff) | |
| download | rust-6e7b9d51495fd52a79dde8ef8950addb36610f85.tar.gz rust-6e7b9d51495fd52a79dde8ef8950addb36610f85.zip | |
Introduce ModernIdent type to unify macro 2.0 hygiene handling
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
Diffstat (limited to 'compiler/rustc_span')
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 52 |
2 files changed, 50 insertions, 5 deletions
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 3f72ccd9f89..d647ec28aae 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -66,7 +66,8 @@ pub use span_encoding::{DUMMY_SP, Span}; pub mod symbol; pub use symbol::{ - ByteSymbol, Ident, MacroRulesNormalizedIdent, STDLIB_STABLE_CRATES, Symbol, kw, sym, + ByteSymbol, Ident, MacroRulesNormalizedIdent, Macros20NormalizedIdent, STDLIB_STABLE_CRATES, + Symbol, kw, sym, }; mod analyze_source_file; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d54175548e3..d07d4e438fa 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -3,6 +3,7 @@ //! type, and vice versa. use std::hash::{Hash, Hasher}; +use std::ops::Deref; use std::{fmt, str}; use rustc_arena::DroplessArena; @@ -2562,16 +2563,17 @@ impl fmt::Display for IdentPrinter { } /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on -/// construction. -// FIXME(matthewj, petrochenkov) Use this more often, add a similar -// `ModernIdent` struct and use that as well. +/// construction for "local variable hygiene" comparisons. +/// +/// Use this type when you need to compare identifiers according to macro_rules hygiene. +/// This ensures compile-time safety and avoids manual normalization calls. #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct MacroRulesNormalizedIdent(Ident); impl MacroRulesNormalizedIdent { #[inline] pub fn new(ident: Ident) -> Self { - Self(ident.normalize_to_macro_rules()) + MacroRulesNormalizedIdent(ident.normalize_to_macro_rules()) } } @@ -2587,6 +2589,48 @@ impl fmt::Display for MacroRulesNormalizedIdent { } } +/// An newtype around `Ident` that calls [Ident::normalize_to_macros_2_0] on +/// construction for "item hygiene" comparisons. +/// +/// Identifiers with same string value become same if they came from the same macro 2.0 macro +/// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from +/// different macro 2.0 macros. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct Macros20NormalizedIdent(pub Ident); + +impl Macros20NormalizedIdent { + #[inline] + pub fn new(ident: Ident) -> Self { + Macros20NormalizedIdent(ident.normalize_to_macros_2_0()) + } + + // dummy_span does not need to be normalized, so we can use `Ident` directly + pub fn with_dummy_span(name: Symbol) -> Self { + Macros20NormalizedIdent(Ident::with_dummy_span(name)) + } +} + +impl fmt::Debug for Macros20NormalizedIdent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.0, f) + } +} + +impl fmt::Display for Macros20NormalizedIdent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +/// By impl Deref, we can access the wrapped Ident as if it were a normal Ident +/// such as `norm_ident.name` instead of `norm_ident.0.name`. +impl Deref for Macros20NormalizedIdent { + type Target = Ident; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + /// An interned UTF-8 string. /// /// Internally, a `Symbol` is implemented as an index, and all operations |
