diff --git a/library/proc_macro/src/bridge/ident.rs b/library/proc_macro/src/bridge/ident.rs new file mode 100644 index 0000000000000..1cb81d15c6cc4 --- /dev/null +++ b/library/proc_macro/src/bridge/ident.rs @@ -0,0 +1,37 @@ +use std::{fmt, hash}; + +#[derive(Copy, Clone)] +pub struct Ident { + pub sym: Symbol, + pub is_raw: bool, + pub span: Span, +} + +impl PartialEq for Ident +where + Symbol: PartialEq, + T: AsRef + ?Sized, +{ + fn eq(&self, other: &T) -> bool { + self.to_string() == other.as_ref() + } +} + +impl hash::Hash for Ident { + fn hash(&self, state: &mut H) { + self.sym.hash(state); + self.is_raw.hash(state); + } +} + +/// Prints the identifier as a string that should be losslessly convertible back +/// into the same identifier. +#[stable(feature = "proc_macro_lib2", since = "1.29.0")] +impl fmt::Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_raw { + f.write_str("r#")?; + } + fmt::Display::fmt(&self.sym, f) + } +} diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index d60a76fff5dc5..1b89824b6bebc 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -151,6 +151,7 @@ mod closure; mod fxhash; #[forbid(unsafe_code)] mod handle; +mod ident; #[macro_use] #[forbid(unsafe_code)] mod rpc; @@ -162,6 +163,7 @@ pub mod server; mod symbol; use buffer::Buffer; +pub use ident::Ident; pub use rpc::PanicMessage; use rpc::{Decode, DecodeMut, Encode, Reader, Writer}; @@ -471,13 +473,6 @@ pub struct Punct { compound_traits!(struct Punct { ch, joint, span }); -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct Ident { - pub sym: Symbol, - pub is_raw: bool, - pub span: Span, -} - compound_traits!(struct Ident { sym, is_raw, span }); #[derive(Clone, Eq, PartialEq)] diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 57ca7db9fcdd7..1e7327b183723 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -11,12 +11,12 @@ use std::cell::RefCell; use std::num::NonZero; -use std::str; +use std::{cmp, str}; use super::*; /// Handle for a symbol string stored within the Interner. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone)] pub struct Symbol(NonZero); impl !Send for Symbol {} @@ -97,6 +97,38 @@ impl fmt::Display for Symbol { } } +impl PartialEq for Symbol { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl PartialEq for Symbol { + fn eq(&self, other: &str) -> bool { + self.with(|s| s == other) + } +} + +impl Eq for Symbol {} + +impl Hash for Symbol { + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + +impl PartialOrd for Symbol { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Symbol { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.with(|s| other.with(|o| s.cmp(o))) + } +} + impl Encode for Symbol { fn encode(self, w: &mut Writer, s: &mut S) { self.with(|sym| sym.encode(w, s)) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 162b4fdcc8ae2..389703649de8d 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1018,7 +1018,7 @@ impl PartialEq for char { } /// An identifier (`ident`). -#[derive(Clone)] +#[derive(Clone, Hash)] #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub struct Ident(bridge::Ident); @@ -1083,10 +1083,7 @@ impl Ident { #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.0.is_raw { - f.write_str("r#")?; - } - fmt::Display::fmt(&self.0.sym, f) + self.0.fmt(f) } } @@ -1100,6 +1097,13 @@ impl fmt::Debug for Ident { } } +#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> PartialEq for Ident { + fn eq(&self, other: &T) -> bool { + self.0 == other + } +} + /// A literal string (`"hello"`), byte string (`b"hello"`), C string (`c"hello"`), /// character (`'a'`), byte character (`b'a'`), an integer or floating point number /// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`). diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs index bb55539617fc5..34a9162055671 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs @@ -465,7 +465,7 @@ impl Expander { } else if let TT::Punct(p) = &input.tt && p.as_char() == '!' && let TT::Ident(name) = &tt - && name.to_string() == "inline" + && *name == "inline" { let g = expect_tt( input.iter.next(),