syn/
token.rs

1//! Tokens representing Rust punctuation, keywords, and delimiters.
2//!
3//! The type names in this module can be difficult to keep straight, so we
4//! prefer to use the [`Token!`] macro instead. This is a type-macro that
5//! expands to the token type of the given token.
6//!
7//! [`Token!`]: crate::Token
8//!
9//! # Example
10//!
11//! The [`ItemStatic`] syntax tree node is defined like this.
12//!
13//! [`ItemStatic`]: crate::ItemStatic
14//!
15//! ```
16//! # use syn::{Attribute, Expr, Ident, Token, Type, Visibility};
17//! #
18//! pub struct ItemStatic {
19//!     pub attrs: Vec<Attribute>,
20//!     pub vis: Visibility,
21//!     pub static_token: Token![static],
22//!     pub mutability: Option<Token![mut]>,
23//!     pub ident: Ident,
24//!     pub colon_token: Token![:],
25//!     pub ty: Box<Type>,
26//!     pub eq_token: Token![=],
27//!     pub expr: Box<Expr>,
28//!     pub semi_token: Token![;],
29//! }
30//! ```
31//!
32//! # Parsing
33//!
34//! Keywords and punctuation can be parsed through the [`ParseStream::parse`]
35//! method. Delimiter tokens are parsed using the [`parenthesized!`],
36//! [`bracketed!`] and [`braced!`] macros.
37//!
38//! [`ParseStream::parse`]: crate::parse::ParseBuffer::parse()
39//! [`parenthesized!`]: crate::parenthesized!
40//! [`bracketed!`]: crate::bracketed!
41//! [`braced!`]: crate::braced!
42//!
43//! ```
44//! use syn::{Attribute, Result};
45//! use syn::parse::{Parse, ParseStream};
46//! #
47//! # enum ItemStatic {}
48//!
49//! // Parse the ItemStatic struct shown above.
50//! impl Parse for ItemStatic {
51//!     fn parse(input: ParseStream) -> Result<Self> {
52//!         # use syn::ItemStatic;
53//!         # fn parse(input: ParseStream) -> Result<ItemStatic> {
54//!         Ok(ItemStatic {
55//!             attrs: input.call(Attribute::parse_outer)?,
56//!             vis: input.parse()?,
57//!             static_token: input.parse()?,
58//!             mutability: input.parse()?,
59//!             ident: input.parse()?,
60//!             colon_token: input.parse()?,
61//!             ty: input.parse()?,
62//!             eq_token: input.parse()?,
63//!             expr: input.parse()?,
64//!             semi_token: input.parse()?,
65//!         })
66//!         # }
67//!         # unimplemented!()
68//!     }
69//! }
70//! ```
71//!
72//! # Other operations
73//!
74//! Every keyword and punctuation token supports the following operations.
75//!
76//! - [Peeking] — `input.peek(Token![...])`
77//!
78//! - [Parsing] — `input.parse::<Token![...]>()?`
79//!
80//! - [Printing] — `quote!( ... #the_token ... )`
81//!
82//! - Construction from a [`Span`] — `let the_token = Token![...](sp)`
83//!
84//! - Field access to its span — `let sp = the_token.span`
85//!
86//! [Peeking]: crate::parse::ParseBuffer::peek()
87//! [Parsing]: crate::parse::ParseBuffer::parse()
88//! [Printing]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html
89//! [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
90
91#[cfg(feature = "parsing")]
92pub(crate) use self::private::CustomToken;
93use self::private::WithSpan;
94#[cfg(feature = "parsing")]
95use crate::buffer::Cursor;
96#[cfg(feature = "parsing")]
97use crate::error::Result;
98#[cfg(feature = "parsing")]
99use crate::lifetime::Lifetime;
100#[cfg(feature = "parsing")]
101use crate::parse::{Parse, ParseStream};
102use crate::span::IntoSpans;
103#[cfg(feature = "extra-traits")]
104use core::cmp;
105#[cfg(feature = "extra-traits")]
106use core::fmt::{self, Debug};
107#[cfg(feature = "extra-traits")]
108use core::hash::{Hash, Hasher};
109use core::ops::{Deref, DerefMut};
110use proc_macro2::extra::DelimSpan;
111use proc_macro2::Span;
112#[cfg(feature = "printing")]
113use proc_macro2::TokenStream;
114#[cfg(any(feature = "parsing", feature = "printing"))]
115use proc_macro2::{Delimiter, Ident};
116#[cfg(feature = "parsing")]
117use proc_macro2::{Literal, Punct, TokenTree};
118#[cfg(feature = "printing")]
119use quote::{ToTokens, TokenStreamExt as _};
120
121/// Marker trait for types that represent single tokens.
122///
123/// This trait is sealed and cannot be implemented for types outside of Syn.
124#[cfg(feature = "parsing")]
125pub trait Token: private::Sealed {
126    // Not public API.
127    #[doc(hidden)]
128    fn peek(cursor: Cursor) -> bool;
129
130    // Not public API.
131    #[doc(hidden)]
132    fn display() -> &'static str;
133}
134
135pub(crate) mod private {
136    #[cfg(feature = "parsing")]
137    use crate::buffer::Cursor;
138    use proc_macro2::Span;
139
140    #[cfg(feature = "parsing")]
141    pub trait Sealed {}
142
143    /// Support writing `token.span` rather than `token.spans[0]` on tokens that
144    /// hold a single span.
145    #[repr(transparent)]
146    #[allow(unknown_lints, repr_transparent_non_zst_fields)] // False positive: https://github.com/rust-lang/rust/issues/115922
147    pub struct WithSpan {
148        pub span: Span,
149    }
150
151    // Not public API.
152    #[doc(hidden)]
153    #[cfg(feature = "parsing")]
154    pub trait CustomToken {
155        fn peek(cursor: Cursor) -> bool;
156        fn display() -> &'static str;
157    }
158}
159
160#[cfg(feature = "parsing")]
161impl private::Sealed for Ident {}
162
163macro_rules! impl_low_level_token {
164    ($display:literal $($path:ident)::+ $get:ident) => {
165        #[cfg(feature = "parsing")]
166        impl Token for $($path)::+ {
167            fn peek(cursor: Cursor) -> bool {
168                cursor.$get().is_some()
169            }
170
171            fn display() -> &'static str {
172                $display
173            }
174        }
175
176        #[cfg(feature = "parsing")]
177        impl private::Sealed for $($path)::+ {}
178    };
179}
180
181impl Token for Punct {
    fn peek(cursor: Cursor) -> bool { cursor.punct().is_some() }
    fn display() -> &'static str { "punctuation token" }
}
impl private::Sealed for Punct { }impl_low_level_token!("punctuation token" Punct punct);
182impl Token for Literal {
    fn peek(cursor: Cursor) -> bool { cursor.literal().is_some() }
    fn display() -> &'static str { "literal" }
}
impl private::Sealed for Literal { }impl_low_level_token!("literal" Literal literal);
183impl Token for TokenTree {
    fn peek(cursor: Cursor) -> bool { cursor.token_tree().is_some() }
    fn display() -> &'static str { "token" }
}
impl private::Sealed for TokenTree { }impl_low_level_token!("token" TokenTree token_tree);
184impl Token for proc_macro2::Group {
    fn peek(cursor: Cursor) -> bool { cursor.any_group().is_some() }
    fn display() -> &'static str { "group token" }
}
impl private::Sealed for proc_macro2::Group { }impl_low_level_token!("group token" proc_macro2::Group any_group);
185impl Token for Lifetime {
    fn peek(cursor: Cursor) -> bool { cursor.lifetime().is_some() }
    fn display() -> &'static str { "lifetime" }
}
impl private::Sealed for Lifetime { }impl_low_level_token!("lifetime" Lifetime lifetime);
186
187#[cfg(feature = "parsing")]
188impl<T: CustomToken> private::Sealed for T {}
189
190#[cfg(feature = "parsing")]
191impl<T: CustomToken> Token for T {
192    fn peek(cursor: Cursor) -> bool {
193        <Self as CustomToken>::peek(cursor)
194    }
195
196    fn display() -> &'static str {
197        <Self as CustomToken>::display()
198    }
199}
200
201macro_rules! define_keywords {
202    ($($token:literal pub struct $name:ident)*) => {
203        $(
204            #[doc = concat!('`', $token, '`')]
205            ///
206            /// Don't try to remember the name of this type &mdash; use the
207            /// [`Token!`] macro instead.
208            ///
209            /// [`Token!`]: crate::token
210            pub struct $name {
211                pub span: Span,
212            }
213
214            #[doc(hidden)]
215            #[allow(non_snake_case)]
216            pub fn $name<S: IntoSpans<Span>>(span: S) -> $name {
217                $name {
218                    span: span.into_spans(),
219                }
220            }
221
222            impl core::default::Default for $name {
223                fn default() -> Self {
224                    $name {
225                        span: Span::call_site(),
226                    }
227                }
228            }
229
230            #[cfg(feature = "clone-impls")]
231            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
232            impl Copy for $name {}
233
234            #[cfg(feature = "clone-impls")]
235            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
236            impl Clone for $name {
237                fn clone(&self) -> Self {
238                    *self
239                }
240            }
241
242            #[cfg(feature = "extra-traits")]
243            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
244            impl Debug for $name {
245                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246                    f.write_str(stringify!($name))
247                }
248            }
249
250            #[cfg(feature = "extra-traits")]
251            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
252            impl cmp::Eq for $name {}
253
254            #[cfg(feature = "extra-traits")]
255            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
256            impl PartialEq for $name {
257                fn eq(&self, _other: &$name) -> bool {
258                    true
259                }
260            }
261
262            #[cfg(feature = "extra-traits")]
263            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
264            impl Hash for $name {
265                fn hash<H: Hasher>(&self, _state: &mut H) {}
266            }
267
268            #[cfg(feature = "printing")]
269            #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
270            impl ToTokens for $name {
271                fn to_tokens(&self, tokens: &mut TokenStream) {
272                    printing::keyword($token, self.span, tokens);
273                }
274            }
275
276            #[cfg(feature = "parsing")]
277            #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
278            impl Parse for $name {
279                fn parse(input: ParseStream) -> Result<Self> {
280                    Ok($name {
281                        span: parsing::keyword(input, $token)?,
282                    })
283                }
284            }
285
286            #[cfg(feature = "parsing")]
287            impl Token for $name {
288                fn peek(cursor: Cursor) -> bool {
289                    parsing::peek_keyword(cursor, $token)
290                }
291
292                fn display() -> &'static str {
293                    concat!("`", $token, "`")
294                }
295            }
296
297            #[cfg(feature = "parsing")]
298            impl private::Sealed for $name {}
299        )*
300    };
301}
302
303macro_rules! impl_deref_if_len_is_1 {
304    ($name:ident/1) => {
305        impl Deref for $name {
306            type Target = WithSpan;
307
308            fn deref(&self) -> &Self::Target {
309                unsafe { &*(self as *const Self).cast::<WithSpan>() }
310            }
311        }
312
313        impl DerefMut for $name {
314            fn deref_mut(&mut self) -> &mut Self::Target {
315                unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
316            }
317        }
318    };
319
320    ($name:ident/$len:literal) => {};
321}
322
323macro_rules! define_punctuation_structs {
324    ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
325        $(
326            #[cfg_attr(not(doc), repr(transparent))]
327            #[allow(unknown_lints, repr_transparent_non_zst_fields)] // False positive: https://github.com/rust-lang/rust/issues/115922
328            #[doc = concat!('`', $token, '`')]
329            ///
330            /// Usage:
331            #[doc = concat!($usage, '.')]
332            ///
333            /// Don't try to remember the name of this type &mdash; use the
334            /// [`Token!`] macro instead.
335            ///
336            /// [`Token!`]: crate::token
337            pub struct $name {
338                pub spans: [Span; $len],
339            }
340
341            #[doc(hidden)]
342            #[allow(non_snake_case)]
343            pub fn $name<S: IntoSpans<[Span; $len]>>(spans: S) -> $name {
344                $name {
345                    spans: spans.into_spans(),
346                }
347            }
348
349            impl core::default::Default for $name {
350                fn default() -> Self {
351                    $name {
352                        spans: [Span::call_site(); $len],
353                    }
354                }
355            }
356
357            #[cfg(feature = "clone-impls")]
358            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
359            impl Copy for $name {}
360
361            #[cfg(feature = "clone-impls")]
362            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
363            impl Clone for $name {
364                fn clone(&self) -> Self {
365                    *self
366                }
367            }
368
369            #[cfg(feature = "extra-traits")]
370            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
371            impl Debug for $name {
372                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
373                    f.write_str(stringify!($name))
374                }
375            }
376
377            #[cfg(feature = "extra-traits")]
378            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
379            impl cmp::Eq for $name {}
380
381            #[cfg(feature = "extra-traits")]
382            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
383            impl PartialEq for $name {
384                fn eq(&self, _other: &$name) -> bool {
385                    true
386                }
387            }
388
389            #[cfg(feature = "extra-traits")]
390            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
391            impl Hash for $name {
392                fn hash<H: Hasher>(&self, _state: &mut H) {}
393            }
394
395            impl_deref_if_len_is_1!($name/$len);
396        )*
397    };
398}
399
400macro_rules! define_punctuation {
401    ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
402        $(
403            define_punctuation_structs! {
404                $token pub struct $name/$len #[doc = $usage]
405            }
406
407            #[cfg(feature = "printing")]
408            #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
409            impl ToTokens for $name {
410                fn to_tokens(&self, tokens: &mut TokenStream) {
411                    printing::punct($token, &self.spans, tokens);
412                }
413            }
414
415            #[cfg(feature = "parsing")]
416            #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
417            impl Parse for $name {
418                fn parse(input: ParseStream) -> Result<Self> {
419                    Ok($name {
420                        spans: parsing::punct(input, $token)?,
421                    })
422                }
423            }
424
425            #[cfg(feature = "parsing")]
426            impl Token for $name {
427                fn peek(cursor: Cursor) -> bool {
428                    parsing::peek_punct(cursor, $token)
429                }
430
431                fn display() -> &'static str {
432                    concat!("`", $token, "`")
433                }
434            }
435
436            #[cfg(feature = "parsing")]
437            impl private::Sealed for $name {}
438        )*
439    };
440}
441
442macro_rules! define_delimiters {
443    ($($delim:ident pub struct $name:ident #[$doc:meta])*) => {
444        $(
445            #[$doc]
446            pub struct $name {
447                pub span: DelimSpan,
448            }
449
450            #[doc(hidden)]
451            #[allow(non_snake_case)]
452            pub fn $name<S: IntoSpans<DelimSpan>>(span: S) -> $name {
453                $name {
454                    span: span.into_spans(),
455                }
456            }
457
458            impl core::default::Default for $name {
459                fn default() -> Self {
460                    $name(Span::call_site())
461                }
462            }
463
464            #[cfg(feature = "clone-impls")]
465            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
466            impl Copy for $name {}
467
468            #[cfg(feature = "clone-impls")]
469            #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
470            impl Clone for $name {
471                fn clone(&self) -> Self {
472                    *self
473                }
474            }
475
476            #[cfg(feature = "extra-traits")]
477            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
478            impl Debug for $name {
479                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
480                    f.write_str(stringify!($name))
481                }
482            }
483
484            #[cfg(feature = "extra-traits")]
485            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
486            impl cmp::Eq for $name {}
487
488            #[cfg(feature = "extra-traits")]
489            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
490            impl PartialEq for $name {
491                fn eq(&self, _other: &$name) -> bool {
492                    true
493                }
494            }
495
496            #[cfg(feature = "extra-traits")]
497            #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
498            impl Hash for $name {
499                fn hash<H: Hasher>(&self, _state: &mut H) {}
500            }
501
502            impl $name {
503                #[cfg(feature = "printing")]
504                #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
505                pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
506                where
507                    F: FnOnce(&mut TokenStream),
508                {
509                    let mut inner = TokenStream::new();
510                    f(&mut inner);
511                    printing::delim(Delimiter::$delim, self.span.join(), tokens, inner);
512                }
513            }
514
515            #[cfg(feature = "parsing")]
516            impl private::Sealed for $name {}
517        )*
518    };
519}
520
521#[allow(unknown_lints, repr_transparent_non_zst_fields)]
#[doc = "`_`"]
///
/// Usage:
#[doc =
" wildcard patterns, inferred types, unnamed items in constants, extern crates, use declarations, and destructuring assignment."]
///
/// Don't try to remember the name of this type &mdash; use the
/// [`Token!`] macro instead.
///
/// [`Token!`]: crate::token
pub struct Underscore {
    pub spans: [Span; 1],
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Underscore<S: IntoSpans<[Span; 1]>>(spans: S) -> Underscore {
    Underscore { spans: spans.into_spans() }
}
impl core::default::Default for Underscore {
    fn default() -> Self { Underscore { spans: [Span::call_site(); 1] } }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Underscore { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Underscore {
    fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Underscore {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Underscore")
    }
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Underscore { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Underscore {
    fn eq(&self, _other: &Underscore) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Underscore {
    fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl Deref for Underscore {
    type Target = WithSpan;
    fn deref(&self) -> &Self::Target {
        unsafe { &*(self as *const Self).cast::<WithSpan>() }
    }
}
impl DerefMut for Underscore {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
    }
}define_punctuation_structs! {
522    "_" pub struct Underscore/1 /// wildcard patterns, inferred types, unnamed items in constants, extern crates, use declarations, and destructuring assignment
523}
524
525#[cfg(feature = "printing")]
526#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
527impl ToTokens for Underscore {
528    fn to_tokens(&self, tokens: &mut TokenStream) {
529        tokens.append(Ident::new("_", self.span));
530    }
531}
532
533#[cfg(feature = "parsing")]
534#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
535impl Parse for Underscore {
536    fn parse(input: ParseStream) -> Result<Self> {
537        input.step(|cursor| {
538            if let Some((ident, rest)) = cursor.ident() {
539                if ident == "_" {
540                    return Ok((Underscore(ident.span()), rest));
541                }
542            }
543            if let Some((punct, rest)) = cursor.punct() {
544                if punct.as_char() == '_' {
545                    return Ok((Underscore(punct.span()), rest));
546                }
547            }
548            Err(cursor.error("expected `_`"))
549        })
550    }
551}
552
553#[cfg(feature = "parsing")]
554impl Token for Underscore {
555    fn peek(cursor: Cursor) -> bool {
556        if let Some((ident, _rest)) = cursor.ident() {
557            return ident == "_";
558        }
559        if let Some((punct, _rest)) = cursor.punct() {
560            return punct.as_char() == '_';
561        }
562        false
563    }
564
565    fn display() -> &'static str {
566        "`_`"
567    }
568}
569
570#[cfg(feature = "parsing")]
571impl private::Sealed for Underscore {}
572
573/// None-delimited group
574pub struct Group {
575    pub span: Span,
576}
577
578#[doc(hidden)]
579#[allow(non_snake_case)]
580pub fn Group<S: IntoSpans<Span>>(span: S) -> Group {
581    Group {
582        span: span.into_spans(),
583    }
584}
585
586impl core::default::Default for Group {
587    fn default() -> Self {
588        Group {
589            span: Span::call_site(),
590        }
591    }
592}
593
594#[cfg(feature = "clone-impls")]
595#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
596impl Copy for Group {}
597
598#[cfg(feature = "clone-impls")]
599#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
600impl Clone for Group {
601    fn clone(&self) -> Self {
602        *self
603    }
604}
605
606#[cfg(feature = "extra-traits")]
607#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
608impl Debug for Group {
609    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
610        f.write_str("Group")
611    }
612}
613
614#[cfg(feature = "extra-traits")]
615#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
616impl cmp::Eq for Group {}
617
618#[cfg(feature = "extra-traits")]
619#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
620impl PartialEq for Group {
621    fn eq(&self, _other: &Group) -> bool {
622        true
623    }
624}
625
626#[cfg(feature = "extra-traits")]
627#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
628impl Hash for Group {
629    fn hash<H: Hasher>(&self, _state: &mut H) {}
630}
631
632impl Group {
633    #[cfg(feature = "printing")]
634    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
635    pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
636    where
637        F: FnOnce(&mut TokenStream),
638    {
639        let mut inner = TokenStream::new();
640        f(&mut inner);
641        printing::delim(Delimiter::None, self.span, tokens, inner);
642    }
643}
644
645#[cfg(feature = "parsing")]
646impl private::Sealed for Group {}
647
648#[cfg(feature = "parsing")]
649impl Token for Paren {
650    fn peek(cursor: Cursor) -> bool {
651        cursor.group(Delimiter::Parenthesis).is_some()
652    }
653
654    fn display() -> &'static str {
655        "parentheses"
656    }
657}
658
659#[cfg(feature = "parsing")]
660impl Token for Brace {
661    fn peek(cursor: Cursor) -> bool {
662        cursor.group(Delimiter::Brace).is_some()
663    }
664
665    fn display() -> &'static str {
666        "curly braces"
667    }
668}
669
670#[cfg(feature = "parsing")]
671impl Token for Bracket {
672    fn peek(cursor: Cursor) -> bool {
673        cursor.group(Delimiter::Bracket).is_some()
674    }
675
676    fn display() -> &'static str {
677        "square brackets"
678    }
679}
680
681#[cfg(feature = "parsing")]
682impl Token for Group {
683    fn peek(cursor: Cursor) -> bool {
684        cursor.group(Delimiter::None).is_some()
685    }
686
687    fn display() -> &'static str {
688        "invisible group"
689    }
690}
691
692#[doc = "`yield`"]
///
/// Don't try to remember the name of this type &mdash; use the
/// [`Token!`] macro instead.
///
/// [`Token!`]: crate::token
pub struct Yield {
    pub span: Span,
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Yield<S: IntoSpans<Span>>(span: S) -> Yield {
    Yield { span: span.into_spans() }
}
impl core::default::Default for Yield {
    fn default() -> Self { Yield { span: Span::call_site() } }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Yield { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Yield {
    fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Yield {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Yield")
    }
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Yield { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Yield {
    fn eq(&self, _other: &Yield) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Yield {
    fn hash<H: Hasher>(&self, _state: &mut H) {}
}
#[doc(cfg(feature = "printing"))]
impl ToTokens for Yield {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        printing::keyword("yield", self.span, tokens);
    }
}
#[doc(cfg(feature = "parsing"))]
impl Parse for Yield {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Yield { span: parsing::keyword(input, "yield")? })
    }
}
impl Token for Yield {
    fn peek(cursor: Cursor) -> bool { parsing::peek_keyword(cursor, "yield") }
    fn display() -> &'static str { "`yield`" }
}
impl private::Sealed for Yield { }define_keywords! {
693    "abstract"    pub struct Abstract
694    "as"          pub struct As
695    "async"       pub struct Async
696    "auto"        pub struct Auto
697    "await"       pub struct Await
698    "become"      pub struct Become
699    "box"         pub struct Box
700    "break"       pub struct Break
701    "const"       pub struct Const
702    "continue"    pub struct Continue
703    "crate"       pub struct Crate
704    "default"     pub struct Default
705    "do"          pub struct Do
706    "dyn"         pub struct Dyn
707    "else"        pub struct Else
708    "enum"        pub struct Enum
709    "extern"      pub struct Extern
710    "final"       pub struct Final
711    "fn"          pub struct Fn
712    "for"         pub struct For
713    "if"          pub struct If
714    "impl"        pub struct Impl
715    "in"          pub struct In
716    "let"         pub struct Let
717    "loop"        pub struct Loop
718    "macro"       pub struct Macro
719    "match"       pub struct Match
720    "mod"         pub struct Mod
721    "move"        pub struct Move
722    "mut"         pub struct Mut
723    "override"    pub struct Override
724    "priv"        pub struct Priv
725    "pub"         pub struct Pub
726    "raw"         pub struct Raw
727    "ref"         pub struct Ref
728    "return"      pub struct Return
729    "Self"        pub struct SelfType
730    "self"        pub struct SelfValue
731    "static"      pub struct Static
732    "struct"      pub struct Struct
733    "super"       pub struct Super
734    "trait"       pub struct Trait
735    "try"         pub struct Try
736    "type"        pub struct Type
737    "typeof"      pub struct Typeof
738    "union"       pub struct Union
739    "unsafe"      pub struct Unsafe
740    "unsized"     pub struct Unsized
741    "use"         pub struct Use
742    "virtual"     pub struct Virtual
743    "where"       pub struct Where
744    "while"       pub struct While
745    "yield"       pub struct Yield
746}
747
748impl Deref for Tilde {
    type Target = WithSpan;
    fn deref(&self) -> &Self::Target {
        unsafe { &*(self as *const Self).cast::<WithSpan>() }
    }
}
impl DerefMut for Tilde {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
    }
}
#[doc(cfg(feature = "printing"))]
impl ToTokens for Tilde {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        printing::punct("~", &self.spans, tokens);
    }
}
#[doc(cfg(feature = "parsing"))]
impl Parse for Tilde {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Tilde { spans: parsing::punct(input, "~")? })
    }
}
impl Token for Tilde {
    fn peek(cursor: Cursor) -> bool { parsing::peek_punct(cursor, "~") }
    fn display() -> &'static str { "`~`" }
}
impl private::Sealed for Tilde { }define_punctuation! {
749    "&"           pub struct And/1        /// bitwise and logical AND, borrow, references, reference patterns
750    "&&"          pub struct AndAnd/2     /// lazy AND, borrow, references, reference patterns
751    "&="          pub struct AndEq/2      /// bitwise AND assignment
752    "@"           pub struct At/1         /// subpattern binding
753    "^"           pub struct Caret/1      /// bitwise and logical XOR
754    "^="          pub struct CaretEq/2    /// bitwise XOR assignment
755    ":"           pub struct Colon/1      /// various separators
756    ","           pub struct Comma/1      /// various separators
757    "$"           pub struct Dollar/1     /// macros
758    "."           pub struct Dot/1        /// field access, tuple index
759    ".."          pub struct DotDot/2     /// range, struct expressions, patterns, range patterns
760    "..."         pub struct DotDotDot/3  /// variadic functions, range patterns
761    "..="         pub struct DotDotEq/3   /// inclusive range, range patterns
762    "="           pub struct Eq/1         /// assignment, attributes, various type definitions
763    "=="          pub struct EqEq/2       /// equal
764    "=>"          pub struct FatArrow/2   /// match arms, macros
765    ">="          pub struct Ge/2         /// greater than or equal to, generics
766    ">"           pub struct Gt/1         /// greater than, generics, paths
767    "<-"          pub struct LArrow/2     /// unused
768    "<="          pub struct Le/2         /// less than or equal to
769    "<"           pub struct Lt/1         /// less than, generics, paths
770    "-"           pub struct Minus/1      /// subtraction, negation
771    "-="          pub struct MinusEq/2    /// subtraction assignment
772    "!="          pub struct Ne/2         /// not equal
773    "!"           pub struct Not/1        /// bitwise and logical NOT, macro calls, inner attributes, never type, negative impls
774    "|"           pub struct Or/1         /// bitwise and logical OR, closures, patterns in match, if let, and while let
775    "|="          pub struct OrEq/2       /// bitwise OR assignment
776    "||"          pub struct OrOr/2       /// lazy OR, closures
777    "::"          pub struct PathSep/2    /// path separator
778    "%"           pub struct Percent/1    /// remainder
779    "%="          pub struct PercentEq/2  /// remainder assignment
780    "+"           pub struct Plus/1       /// addition, trait bounds, macro Kleene matcher
781    "+="          pub struct PlusEq/2     /// addition assignment
782    "#"           pub struct Pound/1      /// attributes
783    "?"           pub struct Question/1   /// question mark operator, questionably sized, macro Kleene matcher
784    "->"          pub struct RArrow/2     /// function return type, closure return type, function pointer type
785    ";"           pub struct Semi/1       /// terminator for various items and statements, array types
786    "<<"          pub struct Shl/2        /// shift left, nested generics
787    "<<="         pub struct ShlEq/3      /// shift left assignment
788    ">>"          pub struct Shr/2        /// shift right, nested generics
789    ">>="         pub struct ShrEq/3      /// shift right assignment, nested generics
790    "/"           pub struct Slash/1      /// division
791    "/="          pub struct SlashEq/2    /// division assignment
792    "*"           pub struct Star/1       /// multiplication, dereference, raw pointers, macro Kleene matcher, use wildcards
793    "*="          pub struct StarEq/2     /// multiplication assignment
794    "~"           pub struct Tilde/1      /// unused since before Rust 1.0
795}
796
797#[doc = r" `(`&hellip;`)`"]
pub struct Paren {
    pub span: DelimSpan,
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Paren<S: IntoSpans<DelimSpan>>(span: S) -> Paren {
    Paren { span: span.into_spans() }
}
impl core::default::Default for Paren {
    fn default() -> Self { Paren(Span::call_site()) }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Paren { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Paren {
    fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Paren {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Paren")
    }
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Paren { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Paren {
    fn eq(&self, _other: &Paren) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Paren {
    fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl Paren {
    #[doc(cfg(feature = "printing"))]
    pub fn surround<F>(&self, tokens: &mut TokenStream, f: F) where
        F: FnOnce(&mut TokenStream) {
        let mut inner = TokenStream::new();
        f(&mut inner);
        printing::delim(Delimiter::Parenthesis, self.span.join(), tokens,
            inner);
    }
}
impl private::Sealed for Paren { }define_delimiters! {
798    Brace         pub struct Brace        /// `{`&hellip;`}`
799    Bracket       pub struct Bracket      /// `[`&hellip;`]`
800    Parenthesis   pub struct Paren        /// `(`&hellip;`)`
801}
802
803/// A type-macro that expands to the name of the Rust type representation of a
804/// given token.
805///
806/// As a type, `Token!` is commonly used in the type of struct fields, the type
807/// of a `let` statement, or in turbofish for a `parse` function.
808///
809/// ```
810/// use syn::{Ident, Token};
811/// use syn::parse::{Parse, ParseStream, Result};
812///
813/// // `struct Foo;`
814/// pub struct UnitStruct {
815///     struct_token: Token![struct],
816///     ident: Ident,
817///     semi_token: Token![;],
818/// }
819///
820/// impl Parse for UnitStruct {
821///     fn parse(input: ParseStream) -> Result<Self> {
822///         let struct_token: Token![struct] = input.parse()?;
823///         let ident: Ident = input.parse()?;
824///         let semi_token = input.parse::<Token![;]>()?;
825///         Ok(UnitStruct { struct_token, ident, semi_token })
826///     }
827/// }
828/// ```
829///
830/// As an expression, `Token!` is used for peeking tokens or instantiating
831/// tokens from a span.
832///
833/// ```
834/// # use syn::{Ident, Token};
835/// # use syn::parse::{Parse, ParseStream, Result};
836/// #
837/// # struct UnitStruct {
838/// #     struct_token: Token![struct],
839/// #     ident: Ident,
840/// #     semi_token: Token![;],
841/// # }
842/// #
843/// # impl Parse for UnitStruct {
844/// #     fn parse(input: ParseStream) -> Result<Self> {
845/// #         unimplemented!()
846/// #     }
847/// # }
848/// #
849/// fn make_unit_struct(name: Ident) -> UnitStruct {
850///     let span = name.span();
851///     UnitStruct {
852///         struct_token: Token![struct](span),
853///         ident: name,
854///         semi_token: Token![;](span),
855///     }
856/// }
857///
858/// # fn parse(input: ParseStream) -> Result<()> {
859/// if input.peek(Token![struct]) {
860///     let unit_struct: UnitStruct = input.parse()?;
861///     /* ... */
862/// }
863/// # Ok(())
864/// # }
865/// ```
866///
867/// See the [token module] documentation for details and examples.
868///
869/// [token module]: crate::token
870#[macro_export]
871macro_rules! Token {
872    [abstract]    => { $crate::token::Abstract };
873    [as]          => { $crate::token::As };
874    [async]       => { $crate::token::Async };
875    [auto]        => { $crate::token::Auto };
876    [await]       => { $crate::token::Await };
877    [become]      => { $crate::token::Become };
878    [box]         => { $crate::token::Box };
879    [break]       => { $crate::token::Break };
880    [const]       => { $crate::token::Const };
881    [continue]    => { $crate::token::Continue };
882    [crate]       => { $crate::token::Crate };
883    [default]     => { $crate::token::Default };
884    [do]          => { $crate::token::Do };
885    [dyn]         => { $crate::token::Dyn };
886    [else]        => { $crate::token::Else };
887    [enum]        => { $crate::token::Enum };
888    [extern]      => { $crate::token::Extern };
889    [final]       => { $crate::token::Final };
890    [fn]          => { $crate::token::Fn };
891    [for]         => { $crate::token::For };
892    [if]          => { $crate::token::If };
893    [impl]        => { $crate::token::Impl };
894    [in]          => { $crate::token::In };
895    [let]         => { $crate::token::Let };
896    [loop]        => { $crate::token::Loop };
897    [macro]       => { $crate::token::Macro };
898    [match]       => { $crate::token::Match };
899    [mod]         => { $crate::token::Mod };
900    [move]        => { $crate::token::Move };
901    [mut]         => { $crate::token::Mut };
902    [override]    => { $crate::token::Override };
903    [priv]        => { $crate::token::Priv };
904    [pub]         => { $crate::token::Pub };
905    [raw]         => { $crate::token::Raw };
906    [ref]         => { $crate::token::Ref };
907    [return]      => { $crate::token::Return };
908    [Self]        => { $crate::token::SelfType };
909    [self]        => { $crate::token::SelfValue };
910    [static]      => { $crate::token::Static };
911    [struct]      => { $crate::token::Struct };
912    [super]       => { $crate::token::Super };
913    [trait]       => { $crate::token::Trait };
914    [try]         => { $crate::token::Try };
915    [type]        => { $crate::token::Type };
916    [typeof]      => { $crate::token::Typeof };
917    [union]       => { $crate::token::Union };
918    [unsafe]      => { $crate::token::Unsafe };
919    [unsized]     => { $crate::token::Unsized };
920    [use]         => { $crate::token::Use };
921    [virtual]     => { $crate::token::Virtual };
922    [where]       => { $crate::token::Where };
923    [while]       => { $crate::token::While };
924    [yield]       => { $crate::token::Yield };
925    [&]           => { $crate::token::And };
926    [&&]          => { $crate::token::AndAnd };
927    [&=]          => { $crate::token::AndEq };
928    [@]           => { $crate::token::At };
929    [^]           => { $crate::token::Caret };
930    [^=]          => { $crate::token::CaretEq };
931    [:]           => { $crate::token::Colon };
932    [,]           => { $crate::token::Comma };
933    [$]           => { $crate::token::Dollar };
934    [.]           => { $crate::token::Dot };
935    [..]          => { $crate::token::DotDot };
936    [...]         => { $crate::token::DotDotDot };
937    [..=]         => { $crate::token::DotDotEq };
938    [=]           => { $crate::token::Eq };
939    [==]          => { $crate::token::EqEq };
940    [=>]          => { $crate::token::FatArrow };
941    [>=]          => { $crate::token::Ge };
942    [>]           => { $crate::token::Gt };
943    [<-]          => { $crate::token::LArrow };
944    [<=]          => { $crate::token::Le };
945    [<]           => { $crate::token::Lt };
946    [-]           => { $crate::token::Minus };
947    [-=]          => { $crate::token::MinusEq };
948    [!=]          => { $crate::token::Ne };
949    [!]           => { $crate::token::Not };
950    [|]           => { $crate::token::Or };
951    [|=]          => { $crate::token::OrEq };
952    [||]          => { $crate::token::OrOr };
953    [::]          => { $crate::token::PathSep };
954    [%]           => { $crate::token::Percent };
955    [%=]          => { $crate::token::PercentEq };
956    [+]           => { $crate::token::Plus };
957    [+=]          => { $crate::token::PlusEq };
958    [#]           => { $crate::token::Pound };
959    [?]           => { $crate::token::Question };
960    [->]          => { $crate::token::RArrow };
961    [;]           => { $crate::token::Semi };
962    [<<]          => { $crate::token::Shl };
963    [<<=]         => { $crate::token::ShlEq };
964    [>>]          => { $crate::token::Shr };
965    [>>=]         => { $crate::token::ShrEq };
966    [/]           => { $crate::token::Slash };
967    [/=]          => { $crate::token::SlashEq };
968    [*]           => { $crate::token::Star };
969    [*=]          => { $crate::token::StarEq };
970    [~]           => { $crate::token::Tilde };
971    [_]           => { $crate::token::Underscore };
972}
973
974// Not public API.
975#[doc(hidden)]
976#[cfg(feature = "parsing")]
977pub(crate) mod parsing {
978    use crate::buffer::Cursor;
979    use crate::error::{Error, Result};
980    use crate::parse::ParseStream;
981    use alloc::format;
982    use proc_macro2::{Spacing, Span};
983
984    pub(crate) fn keyword(input: ParseStream, token: &str) -> Result<Span> {
985        input.step(|cursor| {
986            if let Some((ident, rest)) = cursor.ident() {
987                if ident == token {
988                    return Ok((ident.span(), rest));
989                }
990            }
991            Err(cursor.error(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected `{0}`", token))
    })format!("expected `{}`", token)))
992        })
993    }
994
995    pub(crate) fn peek_keyword(cursor: Cursor, token: &str) -> bool {
996        if let Some((ident, _rest)) = cursor.ident() {
997            ident == token
998        } else {
999            false
1000        }
1001    }
1002
1003    #[doc(hidden)]
1004    pub fn punct<const N: usize>(input: ParseStream, token: &str) -> Result<[Span; N]> {
1005        let mut spans = [input.span(); N];
1006        punct_helper(input, token, &mut spans)?;
1007        Ok(spans)
1008    }
1009
1010    fn punct_helper(input: ParseStream, token: &str, spans: &mut [Span]) -> Result<()> {
1011        input.step(|cursor| {
1012            let mut cursor = *cursor;
1013            match (&token.len(), &spans.len()) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_eq!(token.len(), spans.len());
1014
1015            for (i, ch) in token.chars().enumerate() {
1016                match cursor.punct() {
1017                    Some((punct, rest)) => {
1018                        spans[i] = punct.span();
1019                        if punct.as_char() != ch {
1020                            break;
1021                        } else if i == token.len() - 1 {
1022                            return Ok(((), rest));
1023                        } else if punct.spacing() != Spacing::Joint {
1024                            break;
1025                        }
1026                        cursor = rest;
1027                    }
1028                    None => break,
1029                }
1030            }
1031
1032            Err(Error::new(spans[0], ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected `{0}`", token))
    })format!("expected `{}`", token)))
1033        })
1034    }
1035
1036    #[doc(hidden)]
1037    pub fn peek_punct(mut cursor: Cursor, token: &str) -> bool {
1038        for (i, ch) in token.chars().enumerate() {
1039            match cursor.punct() {
1040                Some((punct, rest)) => {
1041                    if punct.as_char() != ch {
1042                        break;
1043                    } else if i == token.len() - 1 {
1044                        return true;
1045                    } else if punct.spacing() != Spacing::Joint {
1046                        break;
1047                    }
1048                    cursor = rest;
1049                }
1050                None => break,
1051            }
1052        }
1053        false
1054    }
1055}
1056
1057// Not public API.
1058#[doc(hidden)]
1059#[cfg(feature = "printing")]
1060pub(crate) mod printing {
1061    use crate::ext::PunctExt as _;
1062    use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream};
1063    use quote::TokenStreamExt as _;
1064
1065    #[doc(hidden)]
1066    pub fn punct(s: &str, spans: &[Span], tokens: &mut TokenStream) {
1067        match (&s.len(), &spans.len()) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_eq!(s.len(), spans.len());
1068
1069        let mut chars = s.chars();
1070        let mut spans = spans.iter();
1071        let ch = chars.next_back().unwrap();
1072        let span = spans.next_back().unwrap();
1073        for (ch, span) in chars.zip(spans) {
1074            tokens.append(Punct::new_spanned(ch, Spacing::Joint, *span));
1075        }
1076
1077        tokens.append(Punct::new_spanned(ch, Spacing::Alone, *span));
1078    }
1079
1080    pub(crate) fn keyword(s: &str, span: Span, tokens: &mut TokenStream) {
1081        tokens.append(Ident::new(s, span));
1082    }
1083
1084    pub(crate) fn delim(
1085        delim: Delimiter,
1086        span: Span,
1087        tokens: &mut TokenStream,
1088        inner: TokenStream,
1089    ) {
1090        let mut g = Group::new(delim, inner);
1091        g.set_span(span);
1092        tokens.append(g);
1093    }
1094}