1 use super::*;
2 use crate::punctuated::Punctuated;
3 use proc_macro2::TokenStream;
4 
5 ast_enum_of_structs! {
6     /// A pattern in a local binding, function signature, match expression, or
7     /// various other places.
8     ///
9     /// *This type is available only if Syn is built with the `"full"` feature.*
10     ///
11     /// # Syntax tree enum
12     ///
13     /// This type is a [syntax tree enum].
14     ///
15     /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
16     //
17     // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
18     // blocked on https://github.com/rust-lang/rust/issues/62833
19     pub enum Pat {
20         /// A box pattern: `box v`.
21         Box(PatBox),
22 
23         /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
24         Ident(PatIdent),
25 
26         /// A literal pattern: `0`.
27         ///
28         /// This holds an `Expr` rather than a `Lit` because negative numbers
29         /// are represented as an `Expr::Unary`.
30         Lit(PatLit),
31 
32         /// A macro in pattern position.
33         Macro(PatMacro),
34 
35         /// A pattern that matches any one of a set of cases.
36         Or(PatOr),
37 
38         /// A path pattern like `Color::Red`, optionally qualified with a
39         /// self-type.
40         ///
41         /// Unqualified path patterns can legally refer to variants, structs,
42         /// constants or associated constants. Qualified path patterns like
43         /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
44         /// associated constants.
45         Path(PatPath),
46 
47         /// A range pattern: `1..=2`.
48         Range(PatRange),
49 
50         /// A reference pattern: `&mut var`.
51         Reference(PatReference),
52 
53         /// The dots in a tuple or slice pattern: `[0, 1, ..]`
54         Rest(PatRest),
55 
56         /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
57         Slice(PatSlice),
58 
59         /// A struct or struct variant pattern: `Variant { x, y, .. }`.
60         Struct(PatStruct),
61 
62         /// A tuple pattern: `(a, b)`.
63         Tuple(PatTuple),
64 
65         /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
66         TupleStruct(PatTupleStruct),
67 
68         /// A type ascription pattern: `foo: f64`.
69         Type(PatType),
70 
71         /// Tokens in pattern position not interpreted by Syn.
72         Verbatim(TokenStream),
73 
74         /// A pattern that matches any value: `_`.
75         Wild(PatWild),
76 
77         #[doc(hidden)]
78         __Nonexhaustive,
79     }
80 }
81 
82 ast_struct! {
83     /// A box pattern: `box v`.
84     ///
85     /// *This type is available only if Syn is built with the `"full"` feature.*
86     pub struct PatBox {
87         pub attrs: Vec<Attribute>,
88         pub box_token: Token![box],
89         pub pat: Box<Pat>,
90     }
91 }
92 
93 ast_struct! {
94     /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
95     ///
96     /// It may also be a unit struct or struct variant (e.g. `None`), or a
97     /// constant; these cannot be distinguished syntactically.
98     ///
99     /// *This type is available only if Syn is built with the `"full"` feature.*
100     pub struct PatIdent {
101         pub attrs: Vec<Attribute>,
102         pub by_ref: Option<Token![ref]>,
103         pub mutability: Option<Token![mut]>,
104         pub ident: Ident,
105         pub subpat: Option<(Token![@], Box<Pat>)>,
106     }
107 }
108 
109 ast_struct! {
110     /// A literal pattern: `0`.
111     ///
112     /// This holds an `Expr` rather than a `Lit` because negative numbers
113     /// are represented as an `Expr::Unary`.
114     ///
115     /// *This type is available only if Syn is built with the `"full"` feature.*
116     pub struct PatLit {
117         pub attrs: Vec<Attribute>,
118         pub expr: Box<Expr>,
119     }
120 }
121 
122 ast_struct! {
123     /// A macro in pattern position.
124     ///
125     /// *This type is available only if Syn is built with the `"full"` feature.*
126     pub struct PatMacro {
127         pub attrs: Vec<Attribute>,
128         pub mac: Macro,
129     }
130 }
131 
132 ast_struct! {
133     /// A pattern that matches any one of a set of cases.
134     ///
135     /// *This type is available only if Syn is built with the `"full"` feature.*
136     pub struct PatOr {
137         pub attrs: Vec<Attribute>,
138         pub leading_vert: Option<Token![|]>,
139         pub cases: Punctuated<Pat, Token![|]>,
140     }
141 }
142 
143 ast_struct! {
144     /// A path pattern like `Color::Red`, optionally qualified with a
145     /// self-type.
146     ///
147     /// Unqualified path patterns can legally refer to variants, structs,
148     /// constants or associated constants. Qualified path patterns like
149     /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
150     /// associated constants.
151     ///
152     /// *This type is available only if Syn is built with the `"full"` feature.*
153     pub struct PatPath {
154         pub attrs: Vec<Attribute>,
155         pub qself: Option<QSelf>,
156         pub path: Path,
157     }
158 }
159 
160 ast_struct! {
161     /// A range pattern: `1..=2`.
162     ///
163     /// *This type is available only if Syn is built with the `"full"` feature.*
164     pub struct PatRange {
165         pub attrs: Vec<Attribute>,
166         pub lo: Box<Expr>,
167         pub limits: RangeLimits,
168         pub hi: Box<Expr>,
169     }
170 }
171 
172 ast_struct! {
173     /// A reference pattern: `&mut var`.
174     ///
175     /// *This type is available only if Syn is built with the `"full"` feature.*
176     pub struct PatReference {
177         pub attrs: Vec<Attribute>,
178         pub and_token: Token![&],
179         pub mutability: Option<Token![mut]>,
180         pub pat: Box<Pat>,
181     }
182 }
183 
184 ast_struct! {
185     /// The dots in a tuple or slice pattern: `[0, 1, ..]`
186     ///
187     /// *This type is available only if Syn is built with the `"full"` feature.*
188     pub struct PatRest {
189         pub attrs: Vec<Attribute>,
190         pub dot2_token: Token![..],
191     }
192 }
193 
194 ast_struct! {
195     /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
196     ///
197     /// *This type is available only if Syn is built with the `"full"` feature.*
198     pub struct PatSlice {
199         pub attrs: Vec<Attribute>,
200         pub bracket_token: token::Bracket,
201         pub elems: Punctuated<Pat, Token![,]>,
202     }
203 }
204 
205 ast_struct! {
206     /// A struct or struct variant pattern: `Variant { x, y, .. }`.
207     ///
208     /// *This type is available only if Syn is built with the `"full"` feature.*
209     pub struct PatStruct {
210         pub attrs: Vec<Attribute>,
211         pub path: Path,
212         pub brace_token: token::Brace,
213         pub fields: Punctuated<FieldPat, Token![,]>,
214         pub dot2_token: Option<Token![..]>,
215     }
216 }
217 
218 ast_struct! {
219     /// A tuple pattern: `(a, b)`.
220     ///
221     /// *This type is available only if Syn is built with the `"full"` feature.*
222     pub struct PatTuple {
223         pub attrs: Vec<Attribute>,
224         pub paren_token: token::Paren,
225         pub elems: Punctuated<Pat, Token![,]>,
226     }
227 }
228 
229 ast_struct! {
230     /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
231     ///
232     /// *This type is available only if Syn is built with the `"full"` feature.*
233     pub struct PatTupleStruct {
234         pub attrs: Vec<Attribute>,
235         pub path: Path,
236         pub pat: PatTuple,
237     }
238 }
239 
240 ast_struct! {
241     /// A type ascription pattern: `foo: f64`.
242     ///
243     /// *This type is available only if Syn is built with the `"full"` feature.*
244     pub struct PatType {
245         pub attrs: Vec<Attribute>,
246         pub pat: Box<Pat>,
247         pub colon_token: Token![:],
248         pub ty: Box<Type>,
249     }
250 }
251 
252 ast_struct! {
253     /// A pattern that matches any value: `_`.
254     ///
255     /// *This type is available only if Syn is built with the `"full"` feature.*
256     pub struct PatWild {
257         pub attrs: Vec<Attribute>,
258         pub underscore_token: Token![_],
259     }
260 }
261 
262 ast_struct! {
263     /// A single field in a struct pattern.
264     ///
265     /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
266     /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
267     ///
268     /// *This type is available only if Syn is built with the `"full"` feature.*
269     pub struct FieldPat {
270         pub attrs: Vec<Attribute>,
271         pub member: Member,
272         pub colon_token: Option<Token![:]>,
273         pub pat: Box<Pat>,
274     }
275 }
276 
277 #[cfg(feature = "parsing")]
278 pub mod parsing {
279     use super::*;
280     use crate::ext::IdentExt;
281     use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
282     use crate::path;
283 
284     impl Parse for Pat {
parse(input: ParseStream) -> Result<Self>285         fn parse(input: ParseStream) -> Result<Self> {
286             let begin = input.fork();
287             let lookahead = input.lookahead1();
288             if {
289                 let ahead = input.fork();
290                 ahead.parse::<Option<Ident>>()?.is_some()
291                     && (ahead.peek(Token![::])
292                         || ahead.peek(Token![!])
293                         || ahead.peek(token::Brace)
294                         || ahead.peek(token::Paren)
295                         || ahead.peek(Token![..])
296                             && ahead.parse::<RangeLimits>().is_ok()
297                             && !(ahead.is_empty() || ahead.peek(Token![,])))
298             } || {
299                 let ahead = input.fork();
300                 ahead.parse::<Option<Token![self]>>()?.is_some() && ahead.peek(Token![::])
301             } || lookahead.peek(Token![::])
302                 || lookahead.peek(Token![<])
303                 || input.peek(Token![Self])
304                 || input.peek(Token![super])
305                 || input.peek(Token![crate])
306             {
307                 pat_path_or_macro_or_struct_or_range(input)
308             } else if lookahead.peek(Token![_]) {
309                 input.call(pat_wild).map(Pat::Wild)
310             } else if input.peek(Token![box]) {
311                 input.call(pat_box).map(Pat::Box)
312             } else if input.peek(Token![-]) || lookahead.peek(Lit) {
313                 pat_lit_or_range(input)
314             } else if lookahead.peek(Token![ref])
315                 || lookahead.peek(Token![mut])
316                 || input.peek(Token![self])
317                 || input.peek(Ident)
318             {
319                 input.call(pat_ident).map(Pat::Ident)
320             } else if lookahead.peek(Token![&]) {
321                 input.call(pat_reference).map(Pat::Reference)
322             } else if lookahead.peek(token::Paren) {
323                 input.call(pat_tuple).map(Pat::Tuple)
324             } else if lookahead.peek(token::Bracket) {
325                 input.call(pat_slice).map(Pat::Slice)
326             } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
327                 pat_range_half_open(input, begin)
328             } else {
329                 Err(lookahead.error())
330             }
331         }
332     }
333 
pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat>334     fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
335         let begin = input.fork();
336         let (qself, path) = path::parsing::qpath(input, true)?;
337 
338         if input.peek(Token![..]) {
339             return pat_range(input, begin, qself, path);
340         }
341 
342         if qself.is_some() {
343             return Ok(Pat::Path(PatPath {
344                 attrs: Vec::new(),
345                 qself,
346                 path,
347             }));
348         }
349 
350         if input.peek(Token![!]) && !input.peek(Token![!=]) {
351             let mut contains_arguments = false;
352             for segment in &path.segments {
353                 match segment.arguments {
354                     PathArguments::None => {}
355                     PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
356                         contains_arguments = true;
357                     }
358                 }
359             }
360 
361             if !contains_arguments {
362                 let bang_token: Token![!] = input.parse()?;
363                 let (delimiter, tokens) = mac::parse_delimiter(input)?;
364                 return Ok(Pat::Macro(PatMacro {
365                     attrs: Vec::new(),
366                     mac: Macro {
367                         path,
368                         bang_token,
369                         delimiter,
370                         tokens,
371                     },
372                 }));
373             }
374         }
375 
376         if input.peek(token::Brace) {
377             pat_struct(input, path).map(Pat::Struct)
378         } else if input.peek(token::Paren) {
379             pat_tuple_struct(input, path).map(Pat::TupleStruct)
380         } else if input.peek(Token![..]) {
381             pat_range(input, begin, qself, path)
382         } else {
383             Ok(Pat::Path(PatPath {
384                 attrs: Vec::new(),
385                 qself,
386                 path,
387             }))
388         }
389     }
390 
pat_wild(input: ParseStream) -> Result<PatWild>391     fn pat_wild(input: ParseStream) -> Result<PatWild> {
392         Ok(PatWild {
393             attrs: Vec::new(),
394             underscore_token: input.parse()?,
395         })
396     }
397 
pat_box(input: ParseStream) -> Result<PatBox>398     fn pat_box(input: ParseStream) -> Result<PatBox> {
399         Ok(PatBox {
400             attrs: Vec::new(),
401             box_token: input.parse()?,
402             pat: input.parse()?,
403         })
404     }
405 
pat_ident(input: ParseStream) -> Result<PatIdent>406     fn pat_ident(input: ParseStream) -> Result<PatIdent> {
407         Ok(PatIdent {
408             attrs: Vec::new(),
409             by_ref: input.parse()?,
410             mutability: input.parse()?,
411             ident: input.call(Ident::parse_any)?,
412             subpat: {
413                 if input.peek(Token![@]) {
414                     let at_token: Token![@] = input.parse()?;
415                     let subpat: Pat = input.parse()?;
416                     Some((at_token, Box::new(subpat)))
417                 } else {
418                     None
419                 }
420             },
421         })
422     }
423 
pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct>424     fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
425         Ok(PatTupleStruct {
426             attrs: Vec::new(),
427             path,
428             pat: input.call(pat_tuple)?,
429         })
430     }
431 
pat_struct(input: ParseStream, path: Path) -> Result<PatStruct>432     fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
433         let content;
434         let brace_token = braced!(content in input);
435 
436         let mut fields = Punctuated::new();
437         while !content.is_empty() && !content.peek(Token![..]) {
438             let value = content.call(field_pat)?;
439             fields.push_value(value);
440             if content.is_empty() {
441                 break;
442             }
443             let punct: Token![,] = content.parse()?;
444             fields.push_punct(punct);
445         }
446 
447         let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
448             Some(content.parse()?)
449         } else {
450             None
451         };
452 
453         Ok(PatStruct {
454             attrs: Vec::new(),
455             path,
456             brace_token,
457             fields,
458             dot2_token,
459         })
460     }
461 
462     impl Member {
is_unnamed(&self) -> bool463         fn is_unnamed(&self) -> bool {
464             match *self {
465                 Member::Named(_) => false,
466                 Member::Unnamed(_) => true,
467             }
468         }
469     }
470 
field_pat(input: ParseStream) -> Result<FieldPat>471     fn field_pat(input: ParseStream) -> Result<FieldPat> {
472         let attrs = input.call(Attribute::parse_outer)?;
473         let boxed: Option<Token![box]> = input.parse()?;
474         let by_ref: Option<Token![ref]> = input.parse()?;
475         let mutability: Option<Token![mut]> = input.parse()?;
476         let member: Member = input.parse()?;
477 
478         if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
479             || member.is_unnamed()
480         {
481             return Ok(FieldPat {
482                 attrs,
483                 member,
484                 colon_token: input.parse()?,
485                 pat: Box::new(multi_pat(input)?),
486             });
487         }
488 
489         let ident = match member {
490             Member::Named(ident) => ident,
491             Member::Unnamed(_) => unreachable!(),
492         };
493 
494         let mut pat = Pat::Ident(PatIdent {
495             attrs: Vec::new(),
496             by_ref,
497             mutability,
498             ident: ident.clone(),
499             subpat: None,
500         });
501 
502         if let Some(boxed) = boxed {
503             pat = Pat::Box(PatBox {
504                 attrs: Vec::new(),
505                 box_token: boxed,
506                 pat: Box::new(pat),
507             });
508         }
509 
510         Ok(FieldPat {
511             attrs,
512             member: Member::Named(ident),
513             colon_token: None,
514             pat: Box::new(pat),
515         })
516     }
517 
pat_range( input: ParseStream, begin: ParseBuffer, qself: Option<QSelf>, path: Path, ) -> Result<Pat>518     fn pat_range(
519         input: ParseStream,
520         begin: ParseBuffer,
521         qself: Option<QSelf>,
522         path: Path,
523     ) -> Result<Pat> {
524         let limits: RangeLimits = input.parse()?;
525         let hi = input.call(pat_lit_expr)?;
526         if let Some(hi) = hi {
527             Ok(Pat::Range(PatRange {
528                 attrs: Vec::new(),
529                 lo: Box::new(Expr::Path(ExprPath {
530                     attrs: Vec::new(),
531                     qself,
532                     path,
533                 })),
534                 limits,
535                 hi,
536             }))
537         } else {
538             Ok(Pat::Verbatim(verbatim::between(begin, input)))
539         }
540     }
541 
pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat>542     fn pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat> {
543         let limits: RangeLimits = input.parse()?;
544         let hi = input.call(pat_lit_expr)?;
545         if hi.is_some() {
546             Ok(Pat::Verbatim(verbatim::between(begin, input)))
547         } else {
548             match limits {
549                 RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
550                     attrs: Vec::new(),
551                     dot2_token,
552                 })),
553                 RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
554             }
555         }
556     }
557 
pat_tuple(input: ParseStream) -> Result<PatTuple>558     fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
559         let content;
560         let paren_token = parenthesized!(content in input);
561 
562         let mut elems = Punctuated::new();
563         while !content.is_empty() {
564             let value = multi_pat(&content)?;
565             elems.push_value(value);
566             if content.is_empty() {
567                 break;
568             }
569             let punct = content.parse()?;
570             elems.push_punct(punct);
571         }
572 
573         Ok(PatTuple {
574             attrs: Vec::new(),
575             paren_token,
576             elems,
577         })
578     }
579 
pat_reference(input: ParseStream) -> Result<PatReference>580     fn pat_reference(input: ParseStream) -> Result<PatReference> {
581         Ok(PatReference {
582             attrs: Vec::new(),
583             and_token: input.parse()?,
584             mutability: input.parse()?,
585             pat: input.parse()?,
586         })
587     }
588 
pat_lit_or_range(input: ParseStream) -> Result<Pat>589     fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
590         let begin = input.fork();
591         let lo = input.call(pat_lit_expr)?.unwrap();
592         if input.peek(Token![..]) {
593             let limits: RangeLimits = input.parse()?;
594             let hi = input.call(pat_lit_expr)?;
595             if let Some(hi) = hi {
596                 Ok(Pat::Range(PatRange {
597                     attrs: Vec::new(),
598                     lo,
599                     limits,
600                     hi,
601                 }))
602             } else {
603                 Ok(Pat::Verbatim(verbatim::between(begin, input)))
604             }
605         } else {
606             Ok(Pat::Lit(PatLit {
607                 attrs: Vec::new(),
608                 expr: lo,
609             }))
610         }
611     }
612 
pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>>613     fn pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>> {
614         if input.is_empty()
615             || input.peek(Token![|])
616             || input.peek(Token![=>])
617             || input.peek(Token![:]) && !input.peek(Token![::])
618             || input.peek(Token![,])
619             || input.peek(Token![;])
620         {
621             return Ok(None);
622         }
623 
624         let neg: Option<Token![-]> = input.parse()?;
625 
626         let lookahead = input.lookahead1();
627         let expr = if lookahead.peek(Lit) {
628             Expr::Lit(input.parse()?)
629         } else if lookahead.peek(Ident)
630             || lookahead.peek(Token![::])
631             || lookahead.peek(Token![<])
632             || lookahead.peek(Token![self])
633             || lookahead.peek(Token![Self])
634             || lookahead.peek(Token![super])
635             || lookahead.peek(Token![crate])
636         {
637             Expr::Path(input.parse()?)
638         } else {
639             return Err(lookahead.error());
640         };
641 
642         Ok(Some(Box::new(if let Some(neg) = neg {
643             Expr::Unary(ExprUnary {
644                 attrs: Vec::new(),
645                 op: UnOp::Neg(neg),
646                 expr: Box::new(expr),
647             })
648         } else {
649             expr
650         })))
651     }
652 
pat_slice(input: ParseStream) -> Result<PatSlice>653     fn pat_slice(input: ParseStream) -> Result<PatSlice> {
654         let content;
655         let bracket_token = bracketed!(content in input);
656 
657         let mut elems = Punctuated::new();
658         while !content.is_empty() {
659             let value = multi_pat(&content)?;
660             elems.push_value(value);
661             if content.is_empty() {
662                 break;
663             }
664             let punct = content.parse()?;
665             elems.push_punct(punct);
666         }
667 
668         Ok(PatSlice {
669             attrs: Vec::new(),
670             bracket_token,
671             elems,
672         })
673     }
674 
multi_pat(input: ParseStream) -> Result<Pat>675     pub fn multi_pat(input: ParseStream) -> Result<Pat> {
676         multi_pat_impl(input, None)
677     }
678 
multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat>679     pub fn multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat> {
680         let leading_vert: Option<Token![|]> = input.parse()?;
681         multi_pat_impl(input, leading_vert)
682     }
683 
multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat>684     fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
685         let mut pat: Pat = input.parse()?;
686         if leading_vert.is_some()
687             || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
688         {
689             let mut cases = Punctuated::new();
690             cases.push_value(pat);
691             while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
692                 let punct = input.parse()?;
693                 cases.push_punct(punct);
694                 let pat: Pat = input.parse()?;
695                 cases.push_value(pat);
696             }
697             pat = Pat::Or(PatOr {
698                 attrs: Vec::new(),
699                 leading_vert,
700                 cases,
701             });
702         }
703         Ok(pat)
704     }
705 }
706 
707 #[cfg(feature = "printing")]
708 mod printing {
709     use super::*;
710     use crate::attr::FilterAttrs;
711     use proc_macro2::TokenStream;
712     use quote::{ToTokens, TokenStreamExt};
713 
714     impl ToTokens for PatWild {
to_tokens(&self, tokens: &mut TokenStream)715         fn to_tokens(&self, tokens: &mut TokenStream) {
716             tokens.append_all(self.attrs.outer());
717             self.underscore_token.to_tokens(tokens);
718         }
719     }
720 
721     impl ToTokens for PatIdent {
to_tokens(&self, tokens: &mut TokenStream)722         fn to_tokens(&self, tokens: &mut TokenStream) {
723             tokens.append_all(self.attrs.outer());
724             self.by_ref.to_tokens(tokens);
725             self.mutability.to_tokens(tokens);
726             self.ident.to_tokens(tokens);
727             if let Some((at_token, subpat)) = &self.subpat {
728                 at_token.to_tokens(tokens);
729                 subpat.to_tokens(tokens);
730             }
731         }
732     }
733 
734     impl ToTokens for PatStruct {
to_tokens(&self, tokens: &mut TokenStream)735         fn to_tokens(&self, tokens: &mut TokenStream) {
736             tokens.append_all(self.attrs.outer());
737             self.path.to_tokens(tokens);
738             self.brace_token.surround(tokens, |tokens| {
739                 self.fields.to_tokens(tokens);
740                 // NOTE: We need a comma before the dot2 token if it is present.
741                 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
742                     <Token![,]>::default().to_tokens(tokens);
743                 }
744                 self.dot2_token.to_tokens(tokens);
745             });
746         }
747     }
748 
749     impl ToTokens for PatTupleStruct {
to_tokens(&self, tokens: &mut TokenStream)750         fn to_tokens(&self, tokens: &mut TokenStream) {
751             tokens.append_all(self.attrs.outer());
752             self.path.to_tokens(tokens);
753             self.pat.to_tokens(tokens);
754         }
755     }
756 
757     impl ToTokens for PatType {
to_tokens(&self, tokens: &mut TokenStream)758         fn to_tokens(&self, tokens: &mut TokenStream) {
759             tokens.append_all(self.attrs.outer());
760             self.pat.to_tokens(tokens);
761             self.colon_token.to_tokens(tokens);
762             self.ty.to_tokens(tokens);
763         }
764     }
765 
766     impl ToTokens for PatPath {
to_tokens(&self, tokens: &mut TokenStream)767         fn to_tokens(&self, tokens: &mut TokenStream) {
768             tokens.append_all(self.attrs.outer());
769             private::print_path(tokens, &self.qself, &self.path);
770         }
771     }
772 
773     impl ToTokens for PatTuple {
to_tokens(&self, tokens: &mut TokenStream)774         fn to_tokens(&self, tokens: &mut TokenStream) {
775             tokens.append_all(self.attrs.outer());
776             self.paren_token.surround(tokens, |tokens| {
777                 self.elems.to_tokens(tokens);
778             });
779         }
780     }
781 
782     impl ToTokens for PatBox {
to_tokens(&self, tokens: &mut TokenStream)783         fn to_tokens(&self, tokens: &mut TokenStream) {
784             tokens.append_all(self.attrs.outer());
785             self.box_token.to_tokens(tokens);
786             self.pat.to_tokens(tokens);
787         }
788     }
789 
790     impl ToTokens for PatReference {
to_tokens(&self, tokens: &mut TokenStream)791         fn to_tokens(&self, tokens: &mut TokenStream) {
792             tokens.append_all(self.attrs.outer());
793             self.and_token.to_tokens(tokens);
794             self.mutability.to_tokens(tokens);
795             self.pat.to_tokens(tokens);
796         }
797     }
798 
799     impl ToTokens for PatRest {
to_tokens(&self, tokens: &mut TokenStream)800         fn to_tokens(&self, tokens: &mut TokenStream) {
801             tokens.append_all(self.attrs.outer());
802             self.dot2_token.to_tokens(tokens);
803         }
804     }
805 
806     impl ToTokens for PatLit {
to_tokens(&self, tokens: &mut TokenStream)807         fn to_tokens(&self, tokens: &mut TokenStream) {
808             tokens.append_all(self.attrs.outer());
809             self.expr.to_tokens(tokens);
810         }
811     }
812 
813     impl ToTokens for PatRange {
to_tokens(&self, tokens: &mut TokenStream)814         fn to_tokens(&self, tokens: &mut TokenStream) {
815             tokens.append_all(self.attrs.outer());
816             self.lo.to_tokens(tokens);
817             match &self.limits {
818                 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
819                 RangeLimits::Closed(t) => t.to_tokens(tokens),
820             }
821             self.hi.to_tokens(tokens);
822         }
823     }
824 
825     impl ToTokens for PatSlice {
to_tokens(&self, tokens: &mut TokenStream)826         fn to_tokens(&self, tokens: &mut TokenStream) {
827             tokens.append_all(self.attrs.outer());
828             self.bracket_token.surround(tokens, |tokens| {
829                 self.elems.to_tokens(tokens);
830             });
831         }
832     }
833 
834     impl ToTokens for PatMacro {
to_tokens(&self, tokens: &mut TokenStream)835         fn to_tokens(&self, tokens: &mut TokenStream) {
836             tokens.append_all(self.attrs.outer());
837             self.mac.to_tokens(tokens);
838         }
839     }
840 
841     impl ToTokens for PatOr {
to_tokens(&self, tokens: &mut TokenStream)842         fn to_tokens(&self, tokens: &mut TokenStream) {
843             tokens.append_all(self.attrs.outer());
844             self.leading_vert.to_tokens(tokens);
845             self.cases.to_tokens(tokens);
846         }
847     }
848 
849     impl ToTokens for FieldPat {
to_tokens(&self, tokens: &mut TokenStream)850         fn to_tokens(&self, tokens: &mut TokenStream) {
851             tokens.append_all(self.attrs.outer());
852             if let Some(colon_token) = &self.colon_token {
853                 self.member.to_tokens(tokens);
854                 colon_token.to_tokens(tokens);
855             }
856             self.pat.to_tokens(tokens);
857         }
858     }
859 }
860