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 lookahead.peek(Ident)
289                 && ({
290                     input.peek2(Token![::])
291                         || input.peek2(Token![!])
292                         || input.peek2(token::Brace)
293                         || input.peek2(token::Paren)
294                         || input.peek2(Token![..])
295                             && !{
296                                 let ahead = input.fork();
297                                 ahead.parse::<Ident>()?;
298                                 ahead.parse::<RangeLimits>()?;
299                                 ahead.is_empty() || ahead.peek(Token![,])
300                             }
301                 })
302                 || input.peek(Token![self]) && input.peek2(Token![::])
303                 || lookahead.peek(Token![::])
304                 || lookahead.peek(Token![<])
305                 || input.peek(Token![Self])
306                 || input.peek(Token![super])
307                 || input.peek(Token![crate])
308             {
309                 pat_path_or_macro_or_struct_or_range(input)
310             } else if lookahead.peek(Token![_]) {
311                 input.call(pat_wild).map(Pat::Wild)
312             } else if input.peek(Token![box]) {
313                 input.call(pat_box).map(Pat::Box)
314             } else if input.peek(Token![-]) || lookahead.peek(Lit) {
315                 pat_lit_or_range(input)
316             } else if lookahead.peek(Token![ref])
317                 || lookahead.peek(Token![mut])
318                 || input.peek(Token![self])
319                 || input.peek(Ident)
320             {
321                 input.call(pat_ident).map(Pat::Ident)
322             } else if lookahead.peek(Token![&]) {
323                 input.call(pat_reference).map(Pat::Reference)
324             } else if lookahead.peek(token::Paren) {
325                 input.call(pat_tuple).map(Pat::Tuple)
326             } else if lookahead.peek(token::Bracket) {
327                 input.call(pat_slice).map(Pat::Slice)
328             } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
329                 pat_range_half_open(input, begin)
330             } else {
331                 Err(lookahead.error())
332             }
333         }
334     }
335 
pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat>336     fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
337         let begin = input.fork();
338         let (qself, path) = path::parsing::qpath(input, true)?;
339 
340         if input.peek(Token![..]) {
341             return pat_range(input, begin, qself, path);
342         }
343 
344         if qself.is_some() {
345             return Ok(Pat::Path(PatPath {
346                 attrs: Vec::new(),
347                 qself,
348                 path,
349             }));
350         }
351 
352         if input.peek(Token![!]) && !input.peek(Token![!=]) {
353             let mut contains_arguments = false;
354             for segment in &path.segments {
355                 match segment.arguments {
356                     PathArguments::None => {}
357                     PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
358                         contains_arguments = true;
359                     }
360                 }
361             }
362 
363             if !contains_arguments {
364                 let bang_token: Token![!] = input.parse()?;
365                 let (delimiter, tokens) = mac::parse_delimiter(input)?;
366                 return Ok(Pat::Macro(PatMacro {
367                     attrs: Vec::new(),
368                     mac: Macro {
369                         path,
370                         bang_token,
371                         delimiter,
372                         tokens,
373                     },
374                 }));
375             }
376         }
377 
378         if input.peek(token::Brace) {
379             pat_struct(input, path).map(Pat::Struct)
380         } else if input.peek(token::Paren) {
381             pat_tuple_struct(input, path).map(Pat::TupleStruct)
382         } else if input.peek(Token![..]) {
383             pat_range(input, begin, qself, path)
384         } else {
385             Ok(Pat::Path(PatPath {
386                 attrs: Vec::new(),
387                 qself,
388                 path,
389             }))
390         }
391     }
392 
pat_wild(input: ParseStream) -> Result<PatWild>393     fn pat_wild(input: ParseStream) -> Result<PatWild> {
394         Ok(PatWild {
395             attrs: Vec::new(),
396             underscore_token: input.parse()?,
397         })
398     }
399 
pat_box(input: ParseStream) -> Result<PatBox>400     fn pat_box(input: ParseStream) -> Result<PatBox> {
401         Ok(PatBox {
402             attrs: Vec::new(),
403             box_token: input.parse()?,
404             pat: input.parse()?,
405         })
406     }
407 
pat_ident(input: ParseStream) -> Result<PatIdent>408     fn pat_ident(input: ParseStream) -> Result<PatIdent> {
409         Ok(PatIdent {
410             attrs: Vec::new(),
411             by_ref: input.parse()?,
412             mutability: input.parse()?,
413             ident: input.call(Ident::parse_any)?,
414             subpat: {
415                 if input.peek(Token![@]) {
416                     let at_token: Token![@] = input.parse()?;
417                     let subpat: Pat = input.parse()?;
418                     Some((at_token, Box::new(subpat)))
419                 } else {
420                     None
421                 }
422             },
423         })
424     }
425 
pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct>426     fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
427         Ok(PatTupleStruct {
428             attrs: Vec::new(),
429             path,
430             pat: input.call(pat_tuple)?,
431         })
432     }
433 
pat_struct(input: ParseStream, path: Path) -> Result<PatStruct>434     fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
435         let content;
436         let brace_token = braced!(content in input);
437 
438         let mut fields = Punctuated::new();
439         while !content.is_empty() && !content.peek(Token![..]) {
440             let value = content.call(field_pat)?;
441             fields.push_value(value);
442             if content.is_empty() {
443                 break;
444             }
445             let punct: Token![,] = content.parse()?;
446             fields.push_punct(punct);
447         }
448 
449         let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
450             Some(content.parse()?)
451         } else {
452             None
453         };
454 
455         Ok(PatStruct {
456             attrs: Vec::new(),
457             path,
458             brace_token,
459             fields,
460             dot2_token,
461         })
462     }
463 
464     impl Member {
is_unnamed(&self) -> bool465         fn is_unnamed(&self) -> bool {
466             match *self {
467                 Member::Named(_) => false,
468                 Member::Unnamed(_) => true,
469             }
470         }
471     }
472 
field_pat(input: ParseStream) -> Result<FieldPat>473     fn field_pat(input: ParseStream) -> Result<FieldPat> {
474         let attrs = input.call(Attribute::parse_outer)?;
475         let boxed: Option<Token![box]> = input.parse()?;
476         let by_ref: Option<Token![ref]> = input.parse()?;
477         let mutability: Option<Token![mut]> = input.parse()?;
478         let member: Member = input.parse()?;
479 
480         if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
481             || member.is_unnamed()
482         {
483             return Ok(FieldPat {
484                 attrs,
485                 member,
486                 colon_token: input.parse()?,
487                 pat: Box::new(multi_pat(input)?),
488             });
489         }
490 
491         let ident = match member {
492             Member::Named(ident) => ident,
493             Member::Unnamed(_) => unreachable!(),
494         };
495 
496         let mut pat = Pat::Ident(PatIdent {
497             attrs: Vec::new(),
498             by_ref,
499             mutability,
500             ident: ident.clone(),
501             subpat: None,
502         });
503 
504         if let Some(boxed) = boxed {
505             pat = Pat::Box(PatBox {
506                 attrs: Vec::new(),
507                 box_token: boxed,
508                 pat: Box::new(pat),
509             });
510         }
511 
512         Ok(FieldPat {
513             attrs,
514             member: Member::Named(ident),
515             colon_token: None,
516             pat: Box::new(pat),
517         })
518     }
519 
pat_range( input: ParseStream, begin: ParseBuffer, qself: Option<QSelf>, path: Path, ) -> Result<Pat>520     fn pat_range(
521         input: ParseStream,
522         begin: ParseBuffer,
523         qself: Option<QSelf>,
524         path: Path,
525     ) -> Result<Pat> {
526         let limits: RangeLimits = input.parse()?;
527         let hi = input.call(pat_lit_expr)?;
528         if let Some(hi) = hi {
529             Ok(Pat::Range(PatRange {
530                 attrs: Vec::new(),
531                 lo: Box::new(Expr::Path(ExprPath {
532                     attrs: Vec::new(),
533                     qself,
534                     path,
535                 })),
536                 limits,
537                 hi,
538             }))
539         } else {
540             Ok(Pat::Verbatim(verbatim::between(begin, input)))
541         }
542     }
543 
pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat>544     fn pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat> {
545         let limits: RangeLimits = input.parse()?;
546         let hi = input.call(pat_lit_expr)?;
547         if hi.is_some() {
548             Ok(Pat::Verbatim(verbatim::between(begin, input)))
549         } else {
550             match limits {
551                 RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
552                     attrs: Vec::new(),
553                     dot2_token,
554                 })),
555                 RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
556             }
557         }
558     }
559 
pat_tuple(input: ParseStream) -> Result<PatTuple>560     fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
561         let content;
562         let paren_token = parenthesized!(content in input);
563 
564         let mut elems = Punctuated::new();
565         while !content.is_empty() {
566             let value = multi_pat(&content)?;
567             elems.push_value(value);
568             if content.is_empty() {
569                 break;
570             }
571             let punct = content.parse()?;
572             elems.push_punct(punct);
573         }
574 
575         Ok(PatTuple {
576             attrs: Vec::new(),
577             paren_token,
578             elems,
579         })
580     }
581 
pat_reference(input: ParseStream) -> Result<PatReference>582     fn pat_reference(input: ParseStream) -> Result<PatReference> {
583         Ok(PatReference {
584             attrs: Vec::new(),
585             and_token: input.parse()?,
586             mutability: input.parse()?,
587             pat: input.parse()?,
588         })
589     }
590 
pat_lit_or_range(input: ParseStream) -> Result<Pat>591     fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
592         let begin = input.fork();
593         let lo = input.call(pat_lit_expr)?.unwrap();
594         if input.peek(Token![..]) {
595             let limits: RangeLimits = input.parse()?;
596             let hi = input.call(pat_lit_expr)?;
597             if let Some(hi) = hi {
598                 Ok(Pat::Range(PatRange {
599                     attrs: Vec::new(),
600                     lo,
601                     limits,
602                     hi,
603                 }))
604             } else {
605                 Ok(Pat::Verbatim(verbatim::between(begin, input)))
606             }
607         } else {
608             Ok(Pat::Lit(PatLit {
609                 attrs: Vec::new(),
610                 expr: lo,
611             }))
612         }
613     }
614 
pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>>615     fn pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>> {
616         if input.is_empty()
617             || input.peek(Token![|])
618             || input.peek(Token![=>])
619             || input.peek(Token![:]) && !input.peek(Token![::])
620             || input.peek(Token![,])
621             || input.peek(Token![;])
622         {
623             return Ok(None);
624         }
625 
626         let neg: Option<Token![-]> = input.parse()?;
627 
628         let lookahead = input.lookahead1();
629         let expr = if lookahead.peek(Lit) {
630             Expr::Lit(input.parse()?)
631         } else if lookahead.peek(Ident)
632             || lookahead.peek(Token![::])
633             || lookahead.peek(Token![<])
634             || lookahead.peek(Token![self])
635             || lookahead.peek(Token![Self])
636             || lookahead.peek(Token![super])
637             || lookahead.peek(Token![crate])
638         {
639             Expr::Path(input.parse()?)
640         } else {
641             return Err(lookahead.error());
642         };
643 
644         Ok(Some(Box::new(if let Some(neg) = neg {
645             Expr::Unary(ExprUnary {
646                 attrs: Vec::new(),
647                 op: UnOp::Neg(neg),
648                 expr: Box::new(expr),
649             })
650         } else {
651             expr
652         })))
653     }
654 
pat_slice(input: ParseStream) -> Result<PatSlice>655     fn pat_slice(input: ParseStream) -> Result<PatSlice> {
656         let content;
657         let bracket_token = bracketed!(content in input);
658 
659         let mut elems = Punctuated::new();
660         while !content.is_empty() {
661             let value = multi_pat(&content)?;
662             elems.push_value(value);
663             if content.is_empty() {
664                 break;
665             }
666             let punct = content.parse()?;
667             elems.push_punct(punct);
668         }
669 
670         Ok(PatSlice {
671             attrs: Vec::new(),
672             bracket_token,
673             elems,
674         })
675     }
676 
multi_pat(input: ParseStream) -> Result<Pat>677     pub fn multi_pat(input: ParseStream) -> Result<Pat> {
678         multi_pat_impl(input, None)
679     }
680 
multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat>681     pub fn multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat> {
682         let leading_vert: Option<Token![|]> = input.parse()?;
683         multi_pat_impl(input, leading_vert)
684     }
685 
multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat>686     fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
687         let mut pat: Pat = input.parse()?;
688         if leading_vert.is_some()
689             || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
690         {
691             let mut cases = Punctuated::new();
692             cases.push_value(pat);
693             while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
694                 let punct = input.parse()?;
695                 cases.push_punct(punct);
696                 let pat: Pat = input.parse()?;
697                 cases.push_value(pat);
698             }
699             pat = Pat::Or(PatOr {
700                 attrs: Vec::new(),
701                 leading_vert,
702                 cases,
703             });
704         }
705         Ok(pat)
706     }
707 }
708 
709 #[cfg(feature = "printing")]
710 mod printing {
711     use super::*;
712     use crate::attr::FilterAttrs;
713     use proc_macro2::TokenStream;
714     use quote::{ToTokens, TokenStreamExt};
715 
716     impl ToTokens for PatWild {
to_tokens(&self, tokens: &mut TokenStream)717         fn to_tokens(&self, tokens: &mut TokenStream) {
718             tokens.append_all(self.attrs.outer());
719             self.underscore_token.to_tokens(tokens);
720         }
721     }
722 
723     impl ToTokens for PatIdent {
to_tokens(&self, tokens: &mut TokenStream)724         fn to_tokens(&self, tokens: &mut TokenStream) {
725             tokens.append_all(self.attrs.outer());
726             self.by_ref.to_tokens(tokens);
727             self.mutability.to_tokens(tokens);
728             self.ident.to_tokens(tokens);
729             if let Some((at_token, subpat)) = &self.subpat {
730                 at_token.to_tokens(tokens);
731                 subpat.to_tokens(tokens);
732             }
733         }
734     }
735 
736     impl ToTokens for PatStruct {
to_tokens(&self, tokens: &mut TokenStream)737         fn to_tokens(&self, tokens: &mut TokenStream) {
738             tokens.append_all(self.attrs.outer());
739             self.path.to_tokens(tokens);
740             self.brace_token.surround(tokens, |tokens| {
741                 self.fields.to_tokens(tokens);
742                 // NOTE: We need a comma before the dot2 token if it is present.
743                 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
744                     <Token![,]>::default().to_tokens(tokens);
745                 }
746                 self.dot2_token.to_tokens(tokens);
747             });
748         }
749     }
750 
751     impl ToTokens for PatTupleStruct {
to_tokens(&self, tokens: &mut TokenStream)752         fn to_tokens(&self, tokens: &mut TokenStream) {
753             tokens.append_all(self.attrs.outer());
754             self.path.to_tokens(tokens);
755             self.pat.to_tokens(tokens);
756         }
757     }
758 
759     impl ToTokens for PatType {
to_tokens(&self, tokens: &mut TokenStream)760         fn to_tokens(&self, tokens: &mut TokenStream) {
761             tokens.append_all(self.attrs.outer());
762             self.pat.to_tokens(tokens);
763             self.colon_token.to_tokens(tokens);
764             self.ty.to_tokens(tokens);
765         }
766     }
767 
768     impl ToTokens for PatPath {
to_tokens(&self, tokens: &mut TokenStream)769         fn to_tokens(&self, tokens: &mut TokenStream) {
770             tokens.append_all(self.attrs.outer());
771             private::print_path(tokens, &self.qself, &self.path);
772         }
773     }
774 
775     impl ToTokens for PatTuple {
to_tokens(&self, tokens: &mut TokenStream)776         fn to_tokens(&self, tokens: &mut TokenStream) {
777             tokens.append_all(self.attrs.outer());
778             self.paren_token.surround(tokens, |tokens| {
779                 self.elems.to_tokens(tokens);
780             });
781         }
782     }
783 
784     impl ToTokens for PatBox {
to_tokens(&self, tokens: &mut TokenStream)785         fn to_tokens(&self, tokens: &mut TokenStream) {
786             tokens.append_all(self.attrs.outer());
787             self.box_token.to_tokens(tokens);
788             self.pat.to_tokens(tokens);
789         }
790     }
791 
792     impl ToTokens for PatReference {
to_tokens(&self, tokens: &mut TokenStream)793         fn to_tokens(&self, tokens: &mut TokenStream) {
794             tokens.append_all(self.attrs.outer());
795             self.and_token.to_tokens(tokens);
796             self.mutability.to_tokens(tokens);
797             self.pat.to_tokens(tokens);
798         }
799     }
800 
801     impl ToTokens for PatRest {
to_tokens(&self, tokens: &mut TokenStream)802         fn to_tokens(&self, tokens: &mut TokenStream) {
803             tokens.append_all(self.attrs.outer());
804             self.dot2_token.to_tokens(tokens);
805         }
806     }
807 
808     impl ToTokens for PatLit {
to_tokens(&self, tokens: &mut TokenStream)809         fn to_tokens(&self, tokens: &mut TokenStream) {
810             tokens.append_all(self.attrs.outer());
811             self.expr.to_tokens(tokens);
812         }
813     }
814 
815     impl ToTokens for PatRange {
to_tokens(&self, tokens: &mut TokenStream)816         fn to_tokens(&self, tokens: &mut TokenStream) {
817             tokens.append_all(self.attrs.outer());
818             self.lo.to_tokens(tokens);
819             match &self.limits {
820                 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
821                 RangeLimits::Closed(t) => t.to_tokens(tokens),
822             }
823             self.hi.to_tokens(tokens);
824         }
825     }
826 
827     impl ToTokens for PatSlice {
to_tokens(&self, tokens: &mut TokenStream)828         fn to_tokens(&self, tokens: &mut TokenStream) {
829             tokens.append_all(self.attrs.outer());
830             self.bracket_token.surround(tokens, |tokens| {
831                 self.elems.to_tokens(tokens);
832             });
833         }
834     }
835 
836     impl ToTokens for PatMacro {
to_tokens(&self, tokens: &mut TokenStream)837         fn to_tokens(&self, tokens: &mut TokenStream) {
838             tokens.append_all(self.attrs.outer());
839             self.mac.to_tokens(tokens);
840         }
841     }
842 
843     impl ToTokens for PatOr {
to_tokens(&self, tokens: &mut TokenStream)844         fn to_tokens(&self, tokens: &mut TokenStream) {
845             tokens.append_all(self.attrs.outer());
846             self.leading_vert.to_tokens(tokens);
847             self.cases.to_tokens(tokens);
848         }
849     }
850 
851     impl ToTokens for FieldPat {
to_tokens(&self, tokens: &mut TokenStream)852         fn to_tokens(&self, tokens: &mut TokenStream) {
853             tokens.append_all(self.attrs.outer());
854             if let Some(colon_token) = &self.colon_token {
855                 self.member.to_tokens(tokens);
856                 colon_token.to_tokens(tokens);
857             }
858             self.pat.to_tokens(tokens);
859         }
860     }
861 }
862