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