Skip to content

Commit b765576

Browse files
committed
add trait impls to proc_macro::Ident
1 parent 5413f7d commit b765576

File tree

4 files changed

+116
-9
lines changed

4 files changed

+116
-9
lines changed

library/proc_macro/src/bridge/mod.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
#![deny(unsafe_code)]
1010

11-
use std::hash::Hash;
11+
use std::hash::{Hash, Hasher};
1212
use std::ops::{Bound, Range};
1313
use std::sync::Once;
1414
use std::{fmt, marker, mem, panic, thread};
@@ -449,13 +449,69 @@ pub struct Punct<Span> {
449449

450450
compound_traits!(struct Punct<Span> { ch, joint, span });
451451

452-
#[derive(Copy, Clone, Eq, PartialEq)]
452+
#[derive(Copy, Clone)]
453453
pub struct Ident<Span, Symbol> {
454454
pub sym: Symbol,
455455
pub is_raw: bool,
456456
pub span: Span,
457457
}
458458

459+
impl<Span, Symbol> PartialEq for Ident<Span, Symbol>
460+
where
461+
Symbol: PartialEq,
462+
{
463+
fn eq(&self, other: &Self) -> bool {
464+
self.sym == other.sym && self.is_raw == other.is_raw
465+
}
466+
}
467+
468+
impl<Span, Symbol> PartialEq<String> for Ident<Span, Symbol>
469+
where
470+
Symbol: PartialEq<str>,
471+
{
472+
fn eq(&self, other: &String) -> bool {
473+
if self.is_raw {
474+
other.strip_prefix("r#").is_some_and(|s| self.sym == *s)
475+
} else {
476+
self.sym == **other
477+
}
478+
}
479+
}
480+
481+
impl<Span, Symbol> PartialEq<str> for Ident<Span, Symbol>
482+
where
483+
Symbol: PartialEq<str>,
484+
{
485+
fn eq(&self, other: &str) -> bool {
486+
if self.is_raw {
487+
other.strip_prefix("r#").is_some_and(|s| self.sym == *s)
488+
} else {
489+
self.sym == *other
490+
}
491+
}
492+
}
493+
494+
impl<Span, Symbol> Eq for Ident<Span, Symbol> where Symbol: PartialEq {}
495+
496+
impl<Span, Symbol: Hash> Hash for Ident<Span, Symbol> {
497+
fn hash<H: Hasher>(&self, state: &mut H) {
498+
self.sym.hash(state);
499+
self.is_raw.hash(state);
500+
}
501+
}
502+
503+
/// Prints the identifier as a string that should be losslessly convertible back
504+
/// into the same identifier.
505+
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
506+
impl<Span, Symbol: fmt::Display> fmt::Display for Ident<Span, Symbol> {
507+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
508+
if self.is_raw {
509+
f.write_str("r#")?;
510+
}
511+
fmt::Display::fmt(&self.sym, f)
512+
}
513+
}
514+
459515
compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });
460516

461517
#[derive(Clone, Eq, PartialEq)]

library/proc_macro/src/bridge/symbol.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
1212
use std::cell::RefCell;
1313
use std::num::NonZero;
14+
use std::{cmp, str};
1415

1516
use super::*;
1617

1718
/// Handle for a symbol string stored within the Interner.
18-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
19+
#[derive(Copy, Clone)]
1920
pub struct Symbol(NonZero<u32>);
2021

2122
impl !Send for Symbol {}
@@ -96,6 +97,38 @@ impl fmt::Display for Symbol {
9697
}
9798
}
9899

100+
impl PartialEq<Self> for Symbol {
101+
fn eq(&self, other: &Self) -> bool {
102+
self.0 == other.0
103+
}
104+
}
105+
106+
impl PartialEq<str> for Symbol {
107+
fn eq(&self, other: &str) -> bool {
108+
self.with(|s| s == other)
109+
}
110+
}
111+
112+
impl Eq for Symbol {}
113+
114+
impl Hash for Symbol {
115+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
116+
self.0.hash(state);
117+
}
118+
}
119+
120+
impl PartialOrd for Symbol {
121+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
122+
Some(self.cmp(other))
123+
}
124+
}
125+
126+
impl Ord for Symbol {
127+
fn cmp(&self, other: &Self) -> cmp::Ordering {
128+
self.with(|s| other.with(|o| s.cmp(o)))
129+
}
130+
}
131+
99132
impl<S> Encode<S> for Symbol {
100133
fn encode(self, w: &mut Writer, s: &mut S) {
101134
self.with(|sym| sym.encode(w, s))

library/proc_macro/src/lib.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ impl PartialEq<Punct> for char {
10321032
}
10331033

10341034
/// An identifier (`ident`).
1035-
#[derive(Clone)]
1035+
#[derive(Clone, Hash)]
10361036
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
10371037
pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
10381038

@@ -1097,10 +1097,7 @@ impl Ident {
10971097
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
10981098
impl fmt::Display for Ident {
10991099
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1100-
if self.0.is_raw {
1101-
f.write_str("r#")?;
1102-
}
1103-
fmt::Display::fmt(&self.0.sym, f)
1100+
self.0.fmt(f)
11041101
}
11051102
}
11061103

@@ -1114,6 +1111,27 @@ impl fmt::Debug for Ident {
11141111
}
11151112
}
11161113

1114+
#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")]
1115+
impl PartialEq for Ident {
1116+
fn eq(&self, other: &Self) -> bool {
1117+
self.0 == other.0
1118+
}
1119+
}
1120+
1121+
#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")]
1122+
impl PartialEq<String> for Ident {
1123+
fn eq(&self, other: &String) -> bool {
1124+
self.0 == *other
1125+
}
1126+
}
1127+
1128+
#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")]
1129+
impl PartialEq<str> for Ident {
1130+
fn eq(&self, other: &str) -> bool {
1131+
self.0 == *other
1132+
}
1133+
}
1134+
11171135
/// A literal string (`"hello"`), byte string (`b"hello"`), C string (`c"hello"`),
11181136
/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
11191137
/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).

src/tools/clippy/tests/ui/auxiliary/proc_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ impl Expander {
465465
} else if let TT::Punct(p) = &input.tt
466466
&& p.as_char() == '!'
467467
&& let TT::Ident(name) = &tt
468-
&& name.to_string() == "inline"
468+
&& *name == "inline"
469469
{
470470
let g = expect_tt(
471471
input.iter.next(),

0 commit comments

Comments
 (0)