1use super::*;
2use crate::punctuated::Punctuated;
3#[cfg(feature = "extra-traits")]
4use crate::tt::TokenStreamHelper;
5use proc_macro2::TokenStream;
6#[cfg(feature = "extra-traits")]
7use std::hash::{Hash, Hasher};
8
9ast_enum_of_structs! {
10 pub enum Pat #manual_extra_traits {
24 Box(PatBox),
26
27 Ident(PatIdent),
29
30 Lit(PatLit),
35
36 Macro(PatMacro),
38
39 Or(PatOr),
41
42 Path(PatPath),
50
51 Range(PatRange),
53
54 Reference(PatReference),
56
57 Rest(PatRest),
59
60 Slice(PatSlice),
62
63 Struct(PatStruct),
65
66 Tuple(PatTuple),
68
69 TupleStruct(PatTupleStruct),
71
72 Type(PatType),
74
75 Verbatim(TokenStream),
77
78 Wild(PatWild),
80
81 #[doc(hidden)]
82 __Nonexhaustive,
83 }
84}
85
86ast_struct! {
87 pub struct PatBox {
91 pub attrs: Vec<Attribute>,
92 pub box_token: Token![box],
93 pub pat: Box<Pat>,
94 }
95}
96
97ast_struct! {
98 pub struct PatIdent {
102 pub attrs: Vec<Attribute>,
103 pub by_ref: Option<Token![ref]>,
104 pub mutability: Option<Token![mut]>,
105 pub ident: Ident,
106 pub subpat: Option<(Token![@], Box<Pat>)>,
107 }
108}
109
110ast_struct! {
111 pub struct PatLit {
118 pub attrs: Vec<Attribute>,
119 pub expr: Box<Expr>,
120 }
121}
122
123ast_struct! {
124 pub struct PatMacro {
128 pub attrs: Vec<Attribute>,
129 pub mac: Macro,
130 }
131}
132
133ast_struct! {
134 pub struct PatOr {
138 pub attrs: Vec<Attribute>,
139 pub leading_vert: Option<Token![|]>,
140 pub cases: Punctuated<Pat, Token![|]>,
141 }
142}
143
144ast_struct! {
145 pub struct PatPath {
155 pub attrs: Vec<Attribute>,
156 pub qself: Option<QSelf>,
157 pub path: Path,
158 }
159}
160
161ast_struct! {
162 pub struct PatRange {
166 pub attrs: Vec<Attribute>,
167 pub lo: Box<Expr>,
168 pub limits: RangeLimits,
169 pub hi: Box<Expr>,
170 }
171}
172
173ast_struct! {
174 pub struct PatReference {
178 pub attrs: Vec<Attribute>,
179 pub and_token: Token![&],
180 pub mutability: Option<Token![mut]>,
181 pub pat: Box<Pat>,
182 }
183}
184
185ast_struct! {
186 pub struct PatRest {
190 pub attrs: Vec<Attribute>,
191 pub dot2_token: Token![..],
192 }
193}
194
195ast_struct! {
196 pub struct PatSlice {
200 pub attrs: Vec<Attribute>,
201 pub bracket_token: token::Bracket,
202 pub elems: Punctuated<Pat, Token![,]>,
203 }
204}
205
206ast_struct! {
207 pub struct PatStruct {
211 pub attrs: Vec<Attribute>,
212 pub path: Path,
213 pub brace_token: token::Brace,
214 pub fields: Punctuated<FieldPat, Token![,]>,
215 pub dot2_token: Option<Token![..]>,
216 }
217}
218
219ast_struct! {
220 pub struct PatTuple {
224 pub attrs: Vec<Attribute>,
225 pub paren_token: token::Paren,
226 pub elems: Punctuated<Pat, Token![,]>,
227 }
228}
229
230ast_struct! {
231 pub struct PatTupleStruct {
235 pub attrs: Vec<Attribute>,
236 pub path: Path,
237 pub pat: PatTuple,
238 }
239}
240
241ast_struct! {
242 pub struct PatType {
246 pub attrs: Vec<Attribute>,
247 pub pat: Box<Pat>,
248 pub colon_token: Token![:],
249 pub ty: Box<Type>,
250 }
251}
252
253ast_struct! {
254 pub struct PatWild {
258 pub attrs: Vec<Attribute>,
259 pub underscore_token: Token![_],
260 }
261}
262
263ast_struct! {
264 pub struct FieldPat {
271 pub attrs: Vec<Attribute>,
272 pub member: Member,
273 pub colon_token: Option<Token![:]>,
274 pub pat: Box<Pat>,
275 }
276}
277
278#[cfg(feature = "extra-traits")]
279impl Eq for Pat {}
280
281#[cfg(feature = "extra-traits")]
282impl PartialEq for Pat {
283 fn eq(&self, other: &Self) -> bool {
284 match (self, other) {
285 (Pat::Box(this), Pat::Box(other)) => this == other,
286 (Pat::Ident(this), Pat::Ident(other)) => this == other,
287 (Pat::Lit(this), Pat::Lit(other)) => this == other,
288 (Pat::Macro(this), Pat::Macro(other)) => this == other,
289 (Pat::Or(this), Pat::Or(other)) => this == other,
290 (Pat::Path(this), Pat::Path(other)) => this == other,
291 (Pat::Range(this), Pat::Range(other)) => this == other,
292 (Pat::Reference(this), Pat::Reference(other)) => this == other,
293 (Pat::Rest(this), Pat::Rest(other)) => this == other,
294 (Pat::Slice(this), Pat::Slice(other)) => this == other,
295 (Pat::Struct(this), Pat::Struct(other)) => this == other,
296 (Pat::Tuple(this), Pat::Tuple(other)) => this == other,
297 (Pat::TupleStruct(this), Pat::TupleStruct(other)) => this == other,
298 (Pat::Type(this), Pat::Type(other)) => this == other,
299 (Pat::Verbatim(this), Pat::Verbatim(other)) => {
300 TokenStreamHelper(this) == TokenStreamHelper(other)
301 }
302 (Pat::Wild(this), Pat::Wild(other)) => this == other,
303 _ => false,
304 }
305 }
306}
307
308#[cfg(feature = "extra-traits")]
309impl Hash for Pat {
310 fn hash<H>(&self, hash: &mut H)
311 where
312 H: Hasher,
313 {
314 match self {
315 Pat::Box(pat) => {
316 hash.write_u8(0);
317 pat.hash(hash);
318 }
319 Pat::Ident(pat) => {
320 hash.write_u8(1);
321 pat.hash(hash);
322 }
323 Pat::Lit(pat) => {
324 hash.write_u8(2);
325 pat.hash(hash);
326 }
327 Pat::Macro(pat) => {
328 hash.write_u8(3);
329 pat.hash(hash);
330 }
331 Pat::Or(pat) => {
332 hash.write_u8(4);
333 pat.hash(hash);
334 }
335 Pat::Path(pat) => {
336 hash.write_u8(5);
337 pat.hash(hash);
338 }
339 Pat::Range(pat) => {
340 hash.write_u8(6);
341 pat.hash(hash);
342 }
343 Pat::Reference(pat) => {
344 hash.write_u8(7);
345 pat.hash(hash);
346 }
347 Pat::Rest(pat) => {
348 hash.write_u8(8);
349 pat.hash(hash);
350 }
351 Pat::Slice(pat) => {
352 hash.write_u8(9);
353 pat.hash(hash);
354 }
355 Pat::Struct(pat) => {
356 hash.write_u8(10);
357 pat.hash(hash);
358 }
359 Pat::Tuple(pat) => {
360 hash.write_u8(11);
361 pat.hash(hash);
362 }
363 Pat::TupleStruct(pat) => {
364 hash.write_u8(12);
365 pat.hash(hash);
366 }
367 Pat::Type(pat) => {
368 hash.write_u8(13);
369 pat.hash(hash);
370 }
371 Pat::Verbatim(pat) => {
372 hash.write_u8(14);
373 TokenStreamHelper(pat).hash(hash);
374 }
375 Pat::Wild(pat) => {
376 hash.write_u8(15);
377 pat.hash(hash);
378 }
379 Pat::__Nonexhaustive => unreachable!(),
380 }
381 }
382}
383
384#[cfg(feature = "parsing")]
385mod parsing {
386 use super::*;
387
388 use crate::ext::IdentExt;
389 use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
390 use crate::path;
391
392 impl Parse for Pat {
393 fn parse(input: ParseStream) -> Result<Self> {
394 let begin = input.fork();
395 let lookahead = input.lookahead1();
396 if lookahead.peek(Ident)
397 && ({
398 input.peek2(Token![::])
399 || input.peek2(Token![!])
400 || input.peek2(token::Brace)
401 || input.peek2(token::Paren)
402 || input.peek2(Token![..])
403 && !{
404 let ahead = input.fork();
405 ahead.parse::<Ident>()?;
406 ahead.parse::<RangeLimits>()?;
407 ahead.is_empty() || ahead.peek(Token![,])
408 }
409 })
410 || input.peek(Token![self]) && input.peek2(Token![::])
411 || lookahead.peek(Token![::])
412 || lookahead.peek(Token![<])
413 || input.peek(Token![Self])
414 || input.peek(Token![super])
415 || input.peek(Token![extern])
416 || input.peek(Token![crate])
417 {
418 pat_path_or_macro_or_struct_or_range(input)
419 } else if lookahead.peek(Token![_]) {
420 input.call(pat_wild).map(Pat::Wild)
421 } else if input.peek(Token![box]) {
422 input.call(pat_box).map(Pat::Box)
423 } else if input.peek(Token![-]) || lookahead.peek(Lit) {
424 pat_lit_or_range(input)
425 } else if lookahead.peek(Token![ref])
426 || lookahead.peek(Token![mut])
427 || input.peek(Token![self])
428 || input.peek(Ident)
429 {
430 input.call(pat_ident).map(Pat::Ident)
431 } else if lookahead.peek(Token![&]) {
432 input.call(pat_reference).map(Pat::Reference)
433 } else if lookahead.peek(token::Paren) {
434 input.call(pat_tuple).map(Pat::Tuple)
435 } else if lookahead.peek(token::Bracket) {
436 input.call(pat_slice).map(Pat::Slice)
437 } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
438 pat_range_half_open(input, begin)
439 } else {
440 Err(lookahead.error())
441 }
442 }
443 }
444
445 fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
446 let begin = input.fork();
447 let (qself, path) = path::parsing::qpath(input, true)?;
448
449 if input.peek(Token![..]) {
450 return pat_range(input, begin, qself, path);
451 }
452
453 if qself.is_some() {
454 return Ok(Pat::Path(PatPath {
455 attrs: Vec::new(),
456 qself,
457 path,
458 }));
459 }
460
461 if input.peek(Token![!]) && !input.peek(Token![!=]) {
462 let mut contains_arguments = false;
463 for segment in &path.segments {
464 match segment.arguments {
465 PathArguments::None => {}
466 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
467 contains_arguments = true;
468 }
469 }
470 }
471
472 if !contains_arguments {
473 let bang_token: Token![!] = input.parse()?;
474 let (delimiter, tokens) = mac::parse_delimiter(input)?;
475 return Ok(Pat::Macro(PatMacro {
476 attrs: Vec::new(),
477 mac: Macro {
478 path,
479 bang_token,
480 delimiter,
481 tokens,
482 },
483 }));
484 }
485 }
486
487 if input.peek(token::Brace) {
488 pat_struct(input, path).map(Pat::Struct)
489 } else if input.peek(token::Paren) {
490 pat_tuple_struct(input, path).map(Pat::TupleStruct)
491 } else if input.peek(Token![..]) {
492 pat_range(input, begin, qself, path)
493 } else {
494 Ok(Pat::Path(PatPath {
495 attrs: Vec::new(),
496 qself,
497 path,
498 }))
499 }
500 }
501
502 fn pat_wild(input: ParseStream) -> Result<PatWild> {
503 Ok(PatWild {
504 attrs: Vec::new(),
505 underscore_token: input.parse()?,
506 })
507 }
508
509 fn pat_box(input: ParseStream) -> Result<PatBox> {
510 Ok(PatBox {
511 attrs: Vec::new(),
512 box_token: input.parse()?,
513 pat: input.parse()?,
514 })
515 }
516
517 fn pat_ident(input: ParseStream) -> Result<PatIdent> {
518 Ok(PatIdent {
519 attrs: Vec::new(),
520 by_ref: input.parse()?,
521 mutability: input.parse()?,
522 ident: input.call(Ident::parse_any)?,
523 subpat: {
524 if input.peek(Token![@]) {
525 let at_token: Token![@] = input.parse()?;
526 let subpat: Pat = input.parse()?;
527 Some((at_token, Box::new(subpat)))
528 } else {
529 None
530 }
531 },
532 })
533 }
534
535 fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
536 Ok(PatTupleStruct {
537 attrs: Vec::new(),
538 path,
539 pat: input.call(pat_tuple)?,
540 })
541 }
542
543 fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
544 let content;
545 let brace_token = braced!(content in input);
546
547 let mut fields = Punctuated::new();
548 while !content.is_empty() && !content.peek(Token![..]) {
549 let value = content.call(field_pat)?;
550 fields.push_value(value);
551 if !content.peek(Token![,]) {
552 break;
553 }
554 let punct: Token![,] = content.parse()?;
555 fields.push_punct(punct);
556 }
557
558 let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
559 Some(content.parse()?)
560 } else {
561 None
562 };
563
564 Ok(PatStruct {
565 attrs: Vec::new(),
566 path,
567 brace_token,
568 fields,
569 dot2_token,
570 })
571 }
572
573 impl Member {
574 fn is_unnamed(&self) -> bool {
575 match *self {
576 Member::Named(_) => false,
577 Member::Unnamed(_) => true,
578 }
579 }
580 }
581
582 fn field_pat(input: ParseStream) -> Result<FieldPat> {
583 let attrs = input.call(Attribute::parse_outer)?;
584 let boxed: Option<Token![box]> = input.parse()?;
585 let by_ref: Option<Token![ref]> = input.parse()?;
586 let mutability: Option<Token![mut]> = input.parse()?;
587 let member: Member = input.parse()?;
588
589 if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
590 || member.is_unnamed()
591 {
592 return Ok(FieldPat {
593 attrs,
594 member,
595 colon_token: input.parse()?,
596 pat: input.parse()?,
597 });
598 }
599
600 let ident = match member {
601 Member::Named(ident) => ident,
602 Member::Unnamed(_) => unreachable!(),
603 };
604
605 let mut pat = Pat::Ident(PatIdent {
606 attrs: Vec::new(),
607 by_ref,
608 mutability,
609 ident: ident.clone(),
610 subpat: None,
611 });
612
613 if let Some(boxed) = boxed {
614 pat = Pat::Box(PatBox {
615 attrs: Vec::new(),
616 box_token: boxed,
617 pat: Box::new(pat),
618 });
619 }
620
621 Ok(FieldPat {
622 attrs,
623 member: Member::Named(ident),
624 colon_token: None,
625 pat: Box::new(pat),
626 })
627 }
628
629 fn pat_range(
630 input: ParseStream,
631 begin: ParseBuffer,
632 qself: Option<QSelf>,
633 path: Path,
634 ) -> Result<Pat> {
635 let limits: RangeLimits = input.parse()?;
636 let hi = input.call(pat_lit_expr)?;
637 if let Some(hi) = hi {
638 Ok(Pat::Range(PatRange {
639 attrs: Vec::new(),
640 lo: Box::new(Expr::Path(ExprPath {
641 attrs: Vec::new(),
642 qself,
643 path,
644 })),
645 limits,
646 hi,
647 }))
648 } else {
649 Ok(Pat::Verbatim(verbatim::between(begin, input)))
650 }
651 }
652
653 fn pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat> {
654 let limits: RangeLimits = input.parse()?;
655 let hi = input.call(pat_lit_expr)?;
656 if hi.is_some() {
657 Ok(Pat::Verbatim(verbatim::between(begin, input)))
658 } else {
659 match limits {
660 RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
661 attrs: Vec::new(),
662 dot2_token,
663 })),
664 RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
665 }
666 }
667 }
668
669 fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
670 let content;
671 let paren_token = parenthesized!(content in input);
672
673 let mut elems = Punctuated::new();
674 while !content.is_empty() {
675 let value: Pat = content.parse()?;
676 elems.push_value(value);
677 if content.is_empty() {
678 break;
679 }
680 let punct = content.parse()?;
681 elems.push_punct(punct);
682 }
683
684 Ok(PatTuple {
685 attrs: Vec::new(),
686 paren_token,
687 elems,
688 })
689 }
690
691 fn pat_reference(input: ParseStream) -> Result<PatReference> {
692 Ok(PatReference {
693 attrs: Vec::new(),
694 and_token: input.parse()?,
695 mutability: input.parse()?,
696 pat: input.parse()?,
697 })
698 }
699
700 fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
701 let begin = input.fork();
702 let lo = input.call(pat_lit_expr)?.unwrap();
703 if input.peek(Token![..]) {
704 let limits: RangeLimits = input.parse()?;
705 let hi = input.call(pat_lit_expr)?;
706 if let Some(hi) = hi {
707 Ok(Pat::Range(PatRange {
708 attrs: Vec::new(),
709 lo,
710 limits,
711 hi,
712 }))
713 } else {
714 Ok(Pat::Verbatim(verbatim::between(begin, input)))
715 }
716 } else {
717 Ok(Pat::Lit(PatLit {
718 attrs: Vec::new(),
719 expr: lo,
720 }))
721 }
722 }
723
724 fn pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>> {
725 if input.is_empty()
726 || input.peek(Token![|])
727 || input.peek(Token![=>])
728 || input.peek(Token![:]) && !input.peek(Token![::])
729 || input.peek(Token![,])
730 || input.peek(Token![;])
731 {
732 return Ok(None);
733 }
734
735 let neg: Option<Token![-]> = input.parse()?;
736
737 let lookahead = input.lookahead1();
738 let expr = if lookahead.peek(Lit) {
739 Expr::Lit(input.parse()?)
740 } else if lookahead.peek(Ident)
741 || lookahead.peek(Token![::])
742 || lookahead.peek(Token![<])
743 || lookahead.peek(Token![self])
744 || lookahead.peek(Token![Self])
745 || lookahead.peek(Token![super])
746 || lookahead.peek(Token![extern])
747 || lookahead.peek(Token![crate])
748 {
749 Expr::Path(input.parse()?)
750 } else {
751 return Err(lookahead.error());
752 };
753
754 Ok(Some(Box::new(if let Some(neg) = neg {
755 Expr::Unary(ExprUnary {
756 attrs: Vec::new(),
757 op: UnOp::Neg(neg),
758 expr: Box::new(expr),
759 })
760 } else {
761 expr
762 })))
763 }
764
765 fn pat_slice(input: ParseStream) -> Result<PatSlice> {
766 let content;
767 let bracket_token = bracketed!(content in input);
768
769 let mut elems = Punctuated::new();
770 while !content.is_empty() {
771 let value: Pat = content.parse()?;
772 elems.push_value(value);
773 if content.is_empty() {
774 break;
775 }
776 let punct = content.parse()?;
777 elems.push_punct(punct);
778 }
779
780 Ok(PatSlice {
781 attrs: Vec::new(),
782 bracket_token,
783 elems,
784 })
785 }
786}
787
788#[cfg(feature = "printing")]
789mod printing {
790 use super::*;
791
792 use proc_macro2::TokenStream;
793 use quote::{ToTokens, TokenStreamExt};
794
795 use crate::attr::FilterAttrs;
796
797 impl ToTokens for PatWild {
798 fn to_tokens(&self, tokens: &mut TokenStream) {
799 tokens.append_all(self.attrs.outer());
800 self.underscore_token.to_tokens(tokens);
801 }
802 }
803
804 impl ToTokens for PatIdent {
805 fn to_tokens(&self, tokens: &mut TokenStream) {
806 tokens.append_all(self.attrs.outer());
807 self.by_ref.to_tokens(tokens);
808 self.mutability.to_tokens(tokens);
809 self.ident.to_tokens(tokens);
810 if let Some((at_token, subpat)) = &self.subpat {
811 at_token.to_tokens(tokens);
812 subpat.to_tokens(tokens);
813 }
814 }
815 }
816
817 impl ToTokens for PatStruct {
818 fn to_tokens(&self, tokens: &mut TokenStream) {
819 tokens.append_all(self.attrs.outer());
820 self.path.to_tokens(tokens);
821 self.brace_token.surround(tokens, |tokens| {
822 self.fields.to_tokens(tokens);
823 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
825 <Token![,]>::default().to_tokens(tokens);
826 }
827 self.dot2_token.to_tokens(tokens);
828 });
829 }
830 }
831
832 impl ToTokens for PatTupleStruct {
833 fn to_tokens(&self, tokens: &mut TokenStream) {
834 tokens.append_all(self.attrs.outer());
835 self.path.to_tokens(tokens);
836 self.pat.to_tokens(tokens);
837 }
838 }
839
840 impl ToTokens for PatType {
841 fn to_tokens(&self, tokens: &mut TokenStream) {
842 tokens.append_all(self.attrs.outer());
843 self.pat.to_tokens(tokens);
844 self.colon_token.to_tokens(tokens);
845 self.ty.to_tokens(tokens);
846 }
847 }
848
849 impl ToTokens for PatPath {
850 fn to_tokens(&self, tokens: &mut TokenStream) {
851 tokens.append_all(self.attrs.outer());
852 private::print_path(tokens, &self.qself, &self.path);
853 }
854 }
855
856 impl ToTokens for PatTuple {
857 fn to_tokens(&self, tokens: &mut TokenStream) {
858 tokens.append_all(self.attrs.outer());
859 self.paren_token.surround(tokens, |tokens| {
860 self.elems.to_tokens(tokens);
861 });
862 }
863 }
864
865 impl ToTokens for PatBox {
866 fn to_tokens(&self, tokens: &mut TokenStream) {
867 tokens.append_all(self.attrs.outer());
868 self.box_token.to_tokens(tokens);
869 self.pat.to_tokens(tokens);
870 }
871 }
872
873 impl ToTokens for PatReference {
874 fn to_tokens(&self, tokens: &mut TokenStream) {
875 tokens.append_all(self.attrs.outer());
876 self.and_token.to_tokens(tokens);
877 self.mutability.to_tokens(tokens);
878 self.pat.to_tokens(tokens);
879 }
880 }
881
882 impl ToTokens for PatRest {
883 fn to_tokens(&self, tokens: &mut TokenStream) {
884 tokens.append_all(self.attrs.outer());
885 self.dot2_token.to_tokens(tokens);
886 }
887 }
888
889 impl ToTokens for PatLit {
890 fn to_tokens(&self, tokens: &mut TokenStream) {
891 tokens.append_all(self.attrs.outer());
892 self.expr.to_tokens(tokens);
893 }
894 }
895
896 impl ToTokens for PatRange {
897 fn to_tokens(&self, tokens: &mut TokenStream) {
898 tokens.append_all(self.attrs.outer());
899 self.lo.to_tokens(tokens);
900 match &self.limits {
901 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
902 RangeLimits::Closed(t) => t.to_tokens(tokens),
903 }
904 self.hi.to_tokens(tokens);
905 }
906 }
907
908 impl ToTokens for PatSlice {
909 fn to_tokens(&self, tokens: &mut TokenStream) {
910 tokens.append_all(self.attrs.outer());
911 self.bracket_token.surround(tokens, |tokens| {
912 self.elems.to_tokens(tokens);
913 });
914 }
915 }
916
917 impl ToTokens for PatMacro {
918 fn to_tokens(&self, tokens: &mut TokenStream) {
919 tokens.append_all(self.attrs.outer());
920 self.mac.to_tokens(tokens);
921 }
922 }
923
924 impl ToTokens for PatOr {
925 fn to_tokens(&self, tokens: &mut TokenStream) {
926 tokens.append_all(self.attrs.outer());
927 self.leading_vert.to_tokens(tokens);
928 self.cases.to_tokens(tokens);
929 }
930 }
931
932 impl ToTokens for FieldPat {
933 fn to_tokens(&self, tokens: &mut TokenStream) {
934 tokens.append_all(self.attrs.outer());
935 if let Some(colon_token) = &self.colon_token {
936 self.member.to_tokens(tokens);
937 colon_token.to_tokens(tokens);
938 }
939 self.pat.to_tokens(tokens);
940 }
941 }
942}