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