]> git.proxmox.com Git - rustc.git/blame - vendor/syn/src/pat.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / syn / src / pat.rs
CommitLineData
e74abb32
XL
1use super::*;
2use crate::punctuated::Punctuated;
e74abb32 3use proc_macro2::TokenStream;
e74abb32
XL
4
5ast_enum_of_structs! {
6 /// A pattern in a local binding, function signature, match expression, or
7 /// various other places.
8 ///
f035d41b 9 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
1b1a35ee 19 pub enum Pat {
e74abb32
XL
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
82ast_struct! {
83 /// A box pattern: `box v`.
84 ///
f035d41b 85 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
86 pub struct PatBox {
87 pub attrs: Vec<Attribute>,
88 pub box_token: Token![box],
89 pub pat: Box<Pat>,
90 }
91}
92
93ast_struct! {
94 /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
95 ///
f035d41b
XL
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.*
e74abb32
XL
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
109ast_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 ///
f035d41b 115 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
116 pub struct PatLit {
117 pub attrs: Vec<Attribute>,
118 pub expr: Box<Expr>,
119 }
120}
121
122ast_struct! {
123 /// A macro in pattern position.
124 ///
f035d41b 125 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
126 pub struct PatMacro {
127 pub attrs: Vec<Attribute>,
128 pub mac: Macro,
129 }
130}
131
132ast_struct! {
133 /// A pattern that matches any one of a set of cases.
134 ///
f035d41b 135 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
136 pub struct PatOr {
137 pub attrs: Vec<Attribute>,
138 pub leading_vert: Option<Token![|]>,
139 pub cases: Punctuated<Pat, Token![|]>,
140 }
141}
142
143ast_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 ///
f035d41b 152 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
153 pub struct PatPath {
154 pub attrs: Vec<Attribute>,
155 pub qself: Option<QSelf>,
156 pub path: Path,
157 }
158}
159
160ast_struct! {
161 /// A range pattern: `1..=2`.
162 ///
f035d41b 163 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
172ast_struct! {
173 /// A reference pattern: `&mut var`.
174 ///
f035d41b 175 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
184ast_struct! {
185 /// The dots in a tuple or slice pattern: `[0, 1, ..]`
186 ///
f035d41b 187 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
188 pub struct PatRest {
189 pub attrs: Vec<Attribute>,
190 pub dot2_token: Token![..],
191 }
192}
193
194ast_struct! {
195 /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
196 ///
f035d41b 197 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
198 pub struct PatSlice {
199 pub attrs: Vec<Attribute>,
200 pub bracket_token: token::Bracket,
201 pub elems: Punctuated<Pat, Token![,]>,
202 }
203}
204
205ast_struct! {
206 /// A struct or struct variant pattern: `Variant { x, y, .. }`.
207 ///
f035d41b 208 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
218ast_struct! {
219 /// A tuple pattern: `(a, b)`.
220 ///
f035d41b 221 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
222 pub struct PatTuple {
223 pub attrs: Vec<Attribute>,
224 pub paren_token: token::Paren,
225 pub elems: Punctuated<Pat, Token![,]>,
226 }
227}
228
229ast_struct! {
230 /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
231 ///
f035d41b 232 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
233 pub struct PatTupleStruct {
234 pub attrs: Vec<Attribute>,
235 pub path: Path,
236 pub pat: PatTuple,
237 }
238}
239
240ast_struct! {
241 /// A type ascription pattern: `foo: f64`.
242 ///
f035d41b 243 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
252ast_struct! {
253 /// A pattern that matches any value: `_`.
254 ///
f035d41b 255 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
256 pub struct PatWild {
257 pub attrs: Vec<Attribute>,
258 pub underscore_token: Token![_],
259 }
260}
261
262ast_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 ///
f035d41b 268 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
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
e74abb32 277#[cfg(feature = "parsing")]
f035d41b 278pub mod parsing {
e74abb32
XL
279 use super::*;
280
281 use crate::ext::IdentExt;
f035d41b 282 use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
e74abb32
XL
283 use crate::path;
284
285 impl Parse for Pat {
286 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 287 let begin = input.fork();
e74abb32
XL
288 let lookahead = input.lookahead1();
289 if lookahead.peek(Ident)
290 && ({
291 input.peek2(Token![::])
292 || input.peek2(Token![!])
293 || input.peek2(token::Brace)
294 || input.peek2(token::Paren)
295 || input.peek2(Token![..])
296 && !{
297 let ahead = input.fork();
298 ahead.parse::<Ident>()?;
299 ahead.parse::<RangeLimits>()?;
300 ahead.is_empty() || ahead.peek(Token![,])
301 }
302 })
303 || input.peek(Token![self]) && input.peek2(Token![::])
304 || lookahead.peek(Token![::])
305 || lookahead.peek(Token![<])
306 || input.peek(Token![Self])
307 || input.peek(Token![super])
e74abb32
XL
308 || input.peek(Token![crate])
309 {
310 pat_path_or_macro_or_struct_or_range(input)
311 } else if lookahead.peek(Token![_]) {
312 input.call(pat_wild).map(Pat::Wild)
313 } else if input.peek(Token![box]) {
314 input.call(pat_box).map(Pat::Box)
315 } else if input.peek(Token![-]) || lookahead.peek(Lit) {
316 pat_lit_or_range(input)
317 } else if lookahead.peek(Token![ref])
318 || lookahead.peek(Token![mut])
319 || input.peek(Token![self])
320 || input.peek(Ident)
321 {
322 input.call(pat_ident).map(Pat::Ident)
323 } else if lookahead.peek(Token![&]) {
324 input.call(pat_reference).map(Pat::Reference)
325 } else if lookahead.peek(token::Paren) {
326 input.call(pat_tuple).map(Pat::Tuple)
327 } else if lookahead.peek(token::Bracket) {
328 input.call(pat_slice).map(Pat::Slice)
329 } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
f035d41b 330 pat_range_half_open(input, begin)
e74abb32
XL
331 } else {
332 Err(lookahead.error())
333 }
334 }
335 }
336
337 fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
f035d41b 338 let begin = input.fork();
e74abb32
XL
339 let (qself, path) = path::parsing::qpath(input, true)?;
340
341 if input.peek(Token![..]) {
f035d41b 342 return pat_range(input, begin, qself, path);
e74abb32
XL
343 }
344
345 if qself.is_some() {
346 return Ok(Pat::Path(PatPath {
347 attrs: Vec::new(),
348 qself,
349 path,
350 }));
351 }
352
353 if input.peek(Token![!]) && !input.peek(Token![!=]) {
354 let mut contains_arguments = false;
355 for segment in &path.segments {
356 match segment.arguments {
357 PathArguments::None => {}
358 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
359 contains_arguments = true;
360 }
361 }
362 }
363
364 if !contains_arguments {
365 let bang_token: Token![!] = input.parse()?;
366 let (delimiter, tokens) = mac::parse_delimiter(input)?;
367 return Ok(Pat::Macro(PatMacro {
368 attrs: Vec::new(),
369 mac: Macro {
370 path,
371 bang_token,
372 delimiter,
373 tokens,
374 },
375 }));
376 }
377 }
378
379 if input.peek(token::Brace) {
380 pat_struct(input, path).map(Pat::Struct)
381 } else if input.peek(token::Paren) {
382 pat_tuple_struct(input, path).map(Pat::TupleStruct)
383 } else if input.peek(Token![..]) {
f035d41b 384 pat_range(input, begin, qself, path)
e74abb32
XL
385 } else {
386 Ok(Pat::Path(PatPath {
387 attrs: Vec::new(),
388 qself,
389 path,
390 }))
391 }
392 }
393
394 fn pat_wild(input: ParseStream) -> Result<PatWild> {
395 Ok(PatWild {
396 attrs: Vec::new(),
397 underscore_token: input.parse()?,
398 })
399 }
400
401 fn pat_box(input: ParseStream) -> Result<PatBox> {
402 Ok(PatBox {
403 attrs: Vec::new(),
404 box_token: input.parse()?,
405 pat: input.parse()?,
406 })
407 }
408
409 fn pat_ident(input: ParseStream) -> Result<PatIdent> {
410 Ok(PatIdent {
411 attrs: Vec::new(),
412 by_ref: input.parse()?,
413 mutability: input.parse()?,
414 ident: input.call(Ident::parse_any)?,
415 subpat: {
416 if input.peek(Token![@]) {
417 let at_token: Token![@] = input.parse()?;
418 let subpat: Pat = input.parse()?;
419 Some((at_token, Box::new(subpat)))
420 } else {
421 None
422 }
423 },
424 })
425 }
426
427 fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
428 Ok(PatTupleStruct {
429 attrs: Vec::new(),
430 path,
431 pat: input.call(pat_tuple)?,
432 })
433 }
434
435 fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
436 let content;
437 let brace_token = braced!(content in input);
438
439 let mut fields = Punctuated::new();
440 while !content.is_empty() && !content.peek(Token![..]) {
441 let value = content.call(field_pat)?;
442 fields.push_value(value);
f035d41b 443 if content.is_empty() {
e74abb32
XL
444 break;
445 }
446 let punct: Token![,] = content.parse()?;
447 fields.push_punct(punct);
448 }
449
450 let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
451 Some(content.parse()?)
452 } else {
453 None
454 };
455
456 Ok(PatStruct {
457 attrs: Vec::new(),
458 path,
459 brace_token,
460 fields,
461 dot2_token,
462 })
463 }
464
465 impl Member {
466 fn is_unnamed(&self) -> bool {
467 match *self {
468 Member::Named(_) => false,
469 Member::Unnamed(_) => true,
470 }
471 }
472 }
473
474 fn field_pat(input: ParseStream) -> Result<FieldPat> {
60c5eb7d 475 let attrs = input.call(Attribute::parse_outer)?;
e74abb32
XL
476 let boxed: Option<Token![box]> = input.parse()?;
477 let by_ref: Option<Token![ref]> = input.parse()?;
478 let mutability: Option<Token![mut]> = input.parse()?;
479 let member: Member = input.parse()?;
480
481 if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
482 || member.is_unnamed()
483 {
484 return Ok(FieldPat {
60c5eb7d 485 attrs,
e74abb32
XL
486 member,
487 colon_token: input.parse()?,
f035d41b 488 pat: Box::new(multi_pat(input)?),
e74abb32
XL
489 });
490 }
491
492 let ident = match member {
493 Member::Named(ident) => ident,
494 Member::Unnamed(_) => unreachable!(),
495 };
496
497 let mut pat = Pat::Ident(PatIdent {
498 attrs: Vec::new(),
499 by_ref,
500 mutability,
501 ident: ident.clone(),
502 subpat: None,
503 });
504
505 if let Some(boxed) = boxed {
506 pat = Pat::Box(PatBox {
507 attrs: Vec::new(),
e74abb32 508 box_token: boxed,
60c5eb7d 509 pat: Box::new(pat),
e74abb32
XL
510 });
511 }
512
513 Ok(FieldPat {
60c5eb7d 514 attrs,
e74abb32 515 member: Member::Named(ident),
e74abb32 516 colon_token: None,
60c5eb7d 517 pat: Box::new(pat),
e74abb32
XL
518 })
519 }
520
f035d41b
XL
521 fn pat_range(
522 input: ParseStream,
523 begin: ParseBuffer,
524 qself: Option<QSelf>,
525 path: Path,
526 ) -> Result<Pat> {
527 let limits: RangeLimits = input.parse()?;
528 let hi = input.call(pat_lit_expr)?;
529 if let Some(hi) = hi {
530 Ok(Pat::Range(PatRange {
e74abb32 531 attrs: Vec::new(),
f035d41b
XL
532 lo: Box::new(Expr::Path(ExprPath {
533 attrs: Vec::new(),
534 qself,
535 path,
536 })),
537 limits,
538 hi,
539 }))
540 } else {
541 Ok(Pat::Verbatim(verbatim::between(begin, input)))
542 }
543 }
544
545 fn pat_range_half_open(input: ParseStream, begin: ParseBuffer) -> Result<Pat> {
546 let limits: RangeLimits = input.parse()?;
547 let hi = input.call(pat_lit_expr)?;
548 if hi.is_some() {
549 Ok(Pat::Verbatim(verbatim::between(begin, input)))
550 } else {
551 match limits {
552 RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
553 attrs: Vec::new(),
554 dot2_token,
555 })),
556 RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
557 }
558 }
e74abb32
XL
559 }
560
561 fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
562 let content;
563 let paren_token = parenthesized!(content in input);
564
565 let mut elems = Punctuated::new();
566 while !content.is_empty() {
f035d41b 567 let value = multi_pat(&content)?;
e74abb32
XL
568 elems.push_value(value);
569 if content.is_empty() {
570 break;
571 }
572 let punct = content.parse()?;
573 elems.push_punct(punct);
574 }
575
576 Ok(PatTuple {
577 attrs: Vec::new(),
578 paren_token,
579 elems,
580 })
581 }
582
583 fn pat_reference(input: ParseStream) -> Result<PatReference> {
584 Ok(PatReference {
585 attrs: Vec::new(),
586 and_token: input.parse()?,
587 mutability: input.parse()?,
588 pat: input.parse()?,
589 })
590 }
591
592 fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
f035d41b
XL
593 let begin = input.fork();
594 let lo = input.call(pat_lit_expr)?.unwrap();
e74abb32 595 if input.peek(Token![..]) {
f035d41b
XL
596 let limits: RangeLimits = input.parse()?;
597 let hi = input.call(pat_lit_expr)?;
598 if let Some(hi) = hi {
599 Ok(Pat::Range(PatRange {
600 attrs: Vec::new(),
601 lo,
602 limits,
603 hi,
604 }))
605 } else {
606 Ok(Pat::Verbatim(verbatim::between(begin, input)))
607 }
e74abb32
XL
608 } else {
609 Ok(Pat::Lit(PatLit {
610 attrs: Vec::new(),
611 expr: lo,
612 }))
613 }
614 }
615
f035d41b
XL
616 fn pat_lit_expr(input: ParseStream) -> Result<Option<Box<Expr>>> {
617 if input.is_empty()
618 || input.peek(Token![|])
619 || input.peek(Token![=>])
620 || input.peek(Token![:]) && !input.peek(Token![::])
621 || input.peek(Token![,])
622 || input.peek(Token![;])
623 {
624 return Ok(None);
625 }
626
e74abb32
XL
627 let neg: Option<Token![-]> = input.parse()?;
628
629 let lookahead = input.lookahead1();
630 let expr = if lookahead.peek(Lit) {
631 Expr::Lit(input.parse()?)
632 } else if lookahead.peek(Ident)
633 || lookahead.peek(Token![::])
634 || lookahead.peek(Token![<])
635 || lookahead.peek(Token![self])
636 || lookahead.peek(Token![Self])
637 || lookahead.peek(Token![super])
e74abb32
XL
638 || lookahead.peek(Token![crate])
639 {
640 Expr::Path(input.parse()?)
641 } else {
642 return Err(lookahead.error());
643 };
644
f035d41b 645 Ok(Some(Box::new(if let Some(neg) = neg {
e74abb32
XL
646 Expr::Unary(ExprUnary {
647 attrs: Vec::new(),
648 op: UnOp::Neg(neg),
649 expr: Box::new(expr),
650 })
651 } else {
652 expr
f035d41b 653 })))
e74abb32
XL
654 }
655
656 fn pat_slice(input: ParseStream) -> Result<PatSlice> {
657 let content;
658 let bracket_token = bracketed!(content in input);
659
660 let mut elems = Punctuated::new();
661 while !content.is_empty() {
f035d41b 662 let value = multi_pat(&content)?;
e74abb32
XL
663 elems.push_value(value);
664 if content.is_empty() {
665 break;
666 }
667 let punct = content.parse()?;
668 elems.push_punct(punct);
669 }
670
671 Ok(PatSlice {
672 attrs: Vec::new(),
673 bracket_token,
674 elems,
675 })
676 }
677
f035d41b
XL
678 pub fn multi_pat(input: ParseStream) -> Result<Pat> {
679 multi_pat_impl(input, None)
680 }
681
682 pub fn multi_pat_with_leading_vert(input: ParseStream) -> Result<Pat> {
683 let leading_vert: Option<Token![|]> = input.parse()?;
684 multi_pat_impl(input, leading_vert)
685 }
686
687 fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
688 let mut pat: Pat = input.parse()?;
689 if leading_vert.is_some()
690 || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
691 {
692 let mut cases = Punctuated::new();
693 cases.push_value(pat);
694 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
695 let punct = input.parse()?;
696 cases.push_punct(punct);
697 let pat: Pat = input.parse()?;
698 cases.push_value(pat);
699 }
700 pat = Pat::Or(PatOr {
701 attrs: Vec::new(),
702 leading_vert,
703 cases,
704 });
705 }
706 Ok(pat)
e74abb32
XL
707 }
708}
709
710#[cfg(feature = "printing")]
711mod printing {
712 use super::*;
713
714 use proc_macro2::TokenStream;
715 use quote::{ToTokens, TokenStreamExt};
716
717 use crate::attr::FilterAttrs;
718
719 impl ToTokens for PatWild {
720 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 721 tokens.append_all(self.attrs.outer());
e74abb32
XL
722 self.underscore_token.to_tokens(tokens);
723 }
724 }
725
726 impl ToTokens for PatIdent {
727 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 728 tokens.append_all(self.attrs.outer());
e74abb32
XL
729 self.by_ref.to_tokens(tokens);
730 self.mutability.to_tokens(tokens);
731 self.ident.to_tokens(tokens);
732 if let Some((at_token, subpat)) = &self.subpat {
733 at_token.to_tokens(tokens);
734 subpat.to_tokens(tokens);
735 }
736 }
737 }
738
739 impl ToTokens for PatStruct {
740 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 741 tokens.append_all(self.attrs.outer());
e74abb32
XL
742 self.path.to_tokens(tokens);
743 self.brace_token.surround(tokens, |tokens| {
744 self.fields.to_tokens(tokens);
745 // NOTE: We need a comma before the dot2 token if it is present.
746 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
747 <Token![,]>::default().to_tokens(tokens);
748 }
749 self.dot2_token.to_tokens(tokens);
750 });
751 }
752 }
753
754 impl ToTokens for PatTupleStruct {
755 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 756 tokens.append_all(self.attrs.outer());
e74abb32
XL
757 self.path.to_tokens(tokens);
758 self.pat.to_tokens(tokens);
759 }
760 }
761
762 impl ToTokens for PatType {
763 fn to_tokens(&self, tokens: &mut TokenStream) {
764 tokens.append_all(self.attrs.outer());
765 self.pat.to_tokens(tokens);
766 self.colon_token.to_tokens(tokens);
767 self.ty.to_tokens(tokens);
768 }
769 }
770
771 impl ToTokens for PatPath {
772 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 773 tokens.append_all(self.attrs.outer());
e74abb32
XL
774 private::print_path(tokens, &self.qself, &self.path);
775 }
776 }
777
778 impl ToTokens for PatTuple {
779 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 780 tokens.append_all(self.attrs.outer());
e74abb32
XL
781 self.paren_token.surround(tokens, |tokens| {
782 self.elems.to_tokens(tokens);
783 });
784 }
785 }
786
787 impl ToTokens for PatBox {
788 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 789 tokens.append_all(self.attrs.outer());
e74abb32
XL
790 self.box_token.to_tokens(tokens);
791 self.pat.to_tokens(tokens);
792 }
793 }
794
795 impl ToTokens for PatReference {
796 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 797 tokens.append_all(self.attrs.outer());
e74abb32
XL
798 self.and_token.to_tokens(tokens);
799 self.mutability.to_tokens(tokens);
800 self.pat.to_tokens(tokens);
801 }
802 }
803
804 impl ToTokens for PatRest {
805 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 806 tokens.append_all(self.attrs.outer());
e74abb32
XL
807 self.dot2_token.to_tokens(tokens);
808 }
809 }
810
811 impl ToTokens for PatLit {
812 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 813 tokens.append_all(self.attrs.outer());
e74abb32
XL
814 self.expr.to_tokens(tokens);
815 }
816 }
817
818 impl ToTokens for PatRange {
819 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 820 tokens.append_all(self.attrs.outer());
e74abb32
XL
821 self.lo.to_tokens(tokens);
822 match &self.limits {
823 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
824 RangeLimits::Closed(t) => t.to_tokens(tokens),
825 }
826 self.hi.to_tokens(tokens);
827 }
828 }
829
830 impl ToTokens for PatSlice {
831 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 832 tokens.append_all(self.attrs.outer());
e74abb32
XL
833 self.bracket_token.surround(tokens, |tokens| {
834 self.elems.to_tokens(tokens);
835 });
836 }
837 }
838
839 impl ToTokens for PatMacro {
840 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 841 tokens.append_all(self.attrs.outer());
e74abb32
XL
842 self.mac.to_tokens(tokens);
843 }
844 }
845
846 impl ToTokens for PatOr {
847 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 848 tokens.append_all(self.attrs.outer());
e74abb32
XL
849 self.leading_vert.to_tokens(tokens);
850 self.cases.to_tokens(tokens);
851 }
852 }
853
854 impl ToTokens for FieldPat {
855 fn to_tokens(&self, tokens: &mut TokenStream) {
60c5eb7d 856 tokens.append_all(self.attrs.outer());
e74abb32
XL
857 if let Some(colon_token) = &self.colon_token {
858 self.member.to_tokens(tokens);
859 colon_token.to_tokens(tokens);
860 }
861 self.pat.to_tokens(tokens);
862 }
863 }
864}