Skip to main content

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