Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#![deny(unsafe_code)]

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

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

#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone)]
pub struct Ident<Span, Symbol> {
pub sym: Symbol,
pub is_raw: bool,
pub span: Span,
}

impl<Span, Symbol> PartialEq for Ident<Span, Symbol>
where
Symbol: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.sym == other.sym && self.is_raw == other.is_raw
}
}

impl<Span, Symbol> PartialEq<String> for Ident<Span, Symbol>
where
Symbol: PartialEq<str>,
{
fn eq(&self, other: &String) -> bool {
if self.is_raw {
other.strip_prefix("r#").is_some_and(|s| self.sym == *s)
} else {
self.sym == **other
}
}
}

impl<Span, Symbol> PartialEq<str> for Ident<Span, Symbol>
where
Symbol: PartialEq<str>,
{
fn eq(&self, other: &str) -> bool {
if self.is_raw {
other.strip_prefix("r#").is_some_and(|s| self.sym == *s)
} else {
self.sym == *other
}
}
}

impl<Span, Symbol> Eq for Ident<Span, Symbol> where Symbol: PartialEq {}

impl<Span, Symbol: Hash> Hash for Ident<Span, Symbol> {
fn hash<H: Hasher>(&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<Span, Symbol: fmt::Display> fmt::Display for Ident<Span, Symbol> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_raw {
f.write_str("r#")?;
}
fmt::Display::fmt(&self.sym, f)
}
}

compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });

#[derive(Clone, Eq, PartialEq)]
Expand Down
35 changes: 34 additions & 1 deletion library/proc_macro/src/bridge/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@

use std::cell::RefCell;
use std::num::NonZero;
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<u32>);

impl !Send for Symbol {}
Expand Down Expand Up @@ -96,6 +97,38 @@ impl fmt::Display for Symbol {
}
}

impl PartialEq<Self> for Symbol {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}

impl PartialEq<str> for Symbol {
fn eq(&self, other: &str) -> bool {
self.with(|s| s == other)
}
}

impl Eq for Symbol {}

impl Hash for Symbol {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}

impl PartialOrd for Symbol {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
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<S> Encode<S> for Symbol {
fn encode(self, w: &mut Writer, s: &mut S) {
self.with(|sym| sym.encode(w, s))
Expand Down
21 changes: 16 additions & 5 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ impl PartialEq<Punct> for char {
}

/// An identifier (`ident`).
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq, Hash)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);

Expand Down Expand Up @@ -1097,10 +1097,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)
}
}

Expand All @@ -1114,6 +1111,20 @@ impl fmt::Debug for Ident {
}
}

#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")]
impl PartialEq<String> for Ident {
fn eq(&self, other: &String) -> bool {
self.0 == *other
}
}

#[stable(feature = "proc_macro_ident_impls", since = "CURRENT_RUSTC_VERSION")]
impl PartialEq<str> for Ident {
fn eq(&self, other: &str) -> 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`).
Expand Down
Loading