Skip to content
/ rust Public
forked from rust-lang/rust

Commit b95fd85

Browse files
committed
Auto merge of rust-lang#114119 - nnethercote:opt-TokenKind-clone, r=petrochenkov
Optimize `TokenKind::clone`. `TokenKind` would impl `Copy` if it weren't for `TokenKind::Interpolated`. This commit makes `clone` reflect that. r? `@ghost`
2 parents e4c98ca + ac747a8 commit b95fd85

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

compiler/rustc_ast/src/token.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
226226
.contains(&name)
227227
}
228228

229-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
229+
// SAFETY: due to the `Clone` impl below, all fields of all variants other than
230+
// `Interpolated` must impl `Copy`.
231+
#[derive(PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
230232
pub enum TokenKind {
231233
/* Expression-operator symbols. */
232234
Eq,
@@ -299,6 +301,19 @@ pub enum TokenKind {
299301
Eof,
300302
}
301303

304+
impl Clone for TokenKind {
305+
fn clone(&self) -> Self {
306+
// `TokenKind` would impl `Copy` if it weren't for `Interpolated`. So
307+
// for all other variants, this implementation of `clone` is just like
308+
// a copy. This is faster than the `derive(Clone)` version which has a
309+
// separate path for every variant.
310+
match self {
311+
Interpolated(nt) => Interpolated(nt.clone()),
312+
_ => unsafe { std::ptr::read(self) },
313+
}
314+
}
315+
}
316+
302317
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
303318
pub struct Token {
304319
pub kind: TokenKind,

0 commit comments

Comments
 (0)