]> git.proxmox.com Git - cargo.git/blob - vendor/syn/src/pat.rs
New upstream version 0.47.0
[cargo.git] / vendor / syn / src / pat.rs
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 {
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
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
393 fn pat_wild(input: ParseStream) -> Result<PatWild> {
394 Ok(PatWild {
395 attrs: Vec::new(),
396 underscore_token: input.parse()?,
397 })
398 }
399
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
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
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
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 {
465 fn is_unnamed(&self) -> bool {
466 match *self {
467 Member::Named(_) => false,
468 Member::Unnamed(_) => true,
469 }
470 }
471 }
472
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
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
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
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
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
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
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
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
677 pub fn multi_pat(input: ParseStream) -> Result<Pat> {
678 multi_pat_impl(input, None)
679 }
680
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
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 }