1use super::*;
2use proc_macro2::{Span, TokenStream};
3use punctuated::Punctuated;
4#[cfg(feature = "extra-traits")]
5use std::hash::{Hash, Hasher};
6#[cfg(all(feature = "parsing", feature = "full"))]
7use std::mem;
8#[cfg(feature = "extra-traits")]
9use tt::TokenStreamHelper;
10
11ast_enum_of_structs! {
12 pub enum Expr {
99 pub Box(ExprBox #full {
103 pub attrs: Vec<Attribute>,
104 pub box_token: Token![box],
105 pub expr: Box<Expr>,
106 }),
107
108 pub InPlace(ExprInPlace #full {
112 pub attrs: Vec<Attribute>,
113 pub place: Box<Expr>,
114 pub arrow_token: Token![<-],
115 pub value: Box<Expr>,
116 }),
117
118 pub Array(ExprArray #full {
122 pub attrs: Vec<Attribute>,
123 pub bracket_token: token::Bracket,
124 pub elems: Punctuated<Expr, Token![,]>,
125 }),
126
127 pub Call(ExprCall {
132 pub attrs: Vec<Attribute>,
133 pub func: Box<Expr>,
134 pub paren_token: token::Paren,
135 pub args: Punctuated<Expr, Token![,]>,
136 }),
137
138 pub MethodCall(ExprMethodCall #full {
142 pub attrs: Vec<Attribute>,
143 pub receiver: Box<Expr>,
144 pub dot_token: Token![.],
145 pub method: Ident,
146 pub turbofish: Option<MethodTurbofish>,
147 pub paren_token: token::Paren,
148 pub args: Punctuated<Expr, Token![,]>,
149 }),
150
151 pub Tuple(ExprTuple #full {
155 pub attrs: Vec<Attribute>,
156 pub paren_token: token::Paren,
157 pub elems: Punctuated<Expr, Token![,]>,
158 }),
159
160 pub Binary(ExprBinary {
165 pub attrs: Vec<Attribute>,
166 pub left: Box<Expr>,
167 pub op: BinOp,
168 pub right: Box<Expr>,
169 }),
170
171 pub Unary(ExprUnary {
176 pub attrs: Vec<Attribute>,
177 pub op: UnOp,
178 pub expr: Box<Expr>,
179 }),
180
181 pub Lit(ExprLit {
186 pub attrs: Vec<Attribute>,
187 pub lit: Lit,
188 }),
189
190 pub Cast(ExprCast {
195 pub attrs: Vec<Attribute>,
196 pub expr: Box<Expr>,
197 pub as_token: Token![as],
198 pub ty: Box<Type>,
199 }),
200
201 pub Type(ExprType #full {
205 pub attrs: Vec<Attribute>,
206 pub expr: Box<Expr>,
207 pub colon_token: Token![:],
208 pub ty: Box<Type>,
209 }),
210
211 pub Let(ExprLet #full {
215 pub attrs: Vec<Attribute>,
216 pub let_token: Token![let],
217 pub pats: Punctuated<Pat, Token![|]>,
218 pub eq_token: Token![=],
219 pub expr: Box<Expr>,
220 }),
221
222 pub If(ExprIf #full {
230 pub attrs: Vec<Attribute>,
231 pub if_token: Token![if],
232 pub cond: Box<Expr>,
233 pub then_branch: Block,
234 pub else_branch: Option<(Token![else], Box<Expr>)>,
235 }),
236
237 pub While(ExprWhile #full {
241 pub attrs: Vec<Attribute>,
242 pub label: Option<Label>,
243 pub while_token: Token![while],
244 pub cond: Box<Expr>,
245 pub body: Block,
246 }),
247
248 pub ForLoop(ExprForLoop #full {
252 pub attrs: Vec<Attribute>,
253 pub label: Option<Label>,
254 pub for_token: Token![for],
255 pub pat: Box<Pat>,
256 pub in_token: Token![in],
257 pub expr: Box<Expr>,
258 pub body: Block,
259 }),
260
261 pub Loop(ExprLoop #full {
265 pub attrs: Vec<Attribute>,
266 pub label: Option<Label>,
267 pub loop_token: Token![loop],
268 pub body: Block,
269 }),
270
271 pub Match(ExprMatch #full {
275 pub attrs: Vec<Attribute>,
276 pub match_token: Token![match],
277 pub expr: Box<Expr>,
278 pub brace_token: token::Brace,
279 pub arms: Vec<Arm>,
280 }),
281
282 pub Closure(ExprClosure #full {
286 pub attrs: Vec<Attribute>,
287 pub asyncness: Option<Token![async]>,
288 pub movability: Option<Token![static]>,
289 pub capture: Option<Token![move]>,
290 pub or1_token: Token![|],
291 pub inputs: Punctuated<FnArg, Token![,]>,
292 pub or2_token: Token![|],
293 pub output: ReturnType,
294 pub body: Box<Expr>,
295 }),
296
297 pub Unsafe(ExprUnsafe #full {
301 pub attrs: Vec<Attribute>,
302 pub unsafe_token: Token![unsafe],
303 pub block: Block,
304 }),
305
306 pub Block(ExprBlock #full {
310 pub attrs: Vec<Attribute>,
311 pub label: Option<Label>,
312 pub block: Block,
313 }),
314
315 pub Assign(ExprAssign #full {
319 pub attrs: Vec<Attribute>,
320 pub left: Box<Expr>,
321 pub eq_token: Token![=],
322 pub right: Box<Expr>,
323 }),
324
325 pub AssignOp(ExprAssignOp #full {
329 pub attrs: Vec<Attribute>,
330 pub left: Box<Expr>,
331 pub op: BinOp,
332 pub right: Box<Expr>,
333 }),
334
335 pub Field(ExprField {
340 pub attrs: Vec<Attribute>,
341 pub base: Box<Expr>,
342 pub dot_token: Token![.],
343 pub member: Member,
344 }),
345
346 pub Index(ExprIndex {
351 pub attrs: Vec<Attribute>,
352 pub expr: Box<Expr>,
353 pub bracket_token: token::Bracket,
354 pub index: Box<Expr>,
355 }),
356
357 pub Range(ExprRange #full {
361 pub attrs: Vec<Attribute>,
362 pub from: Option<Box<Expr>>,
363 pub limits: RangeLimits,
364 pub to: Option<Box<Expr>>,
365 }),
366
367 pub Path(ExprPath {
375 pub attrs: Vec<Attribute>,
376 pub qself: Option<QSelf>,
377 pub path: Path,
378 }),
379
380 pub Reference(ExprReference #full {
384 pub attrs: Vec<Attribute>,
385 pub and_token: Token![&],
386 pub mutability: Option<Token![mut]>,
387 pub expr: Box<Expr>,
388 }),
389
390 pub Break(ExprBreak #full {
395 pub attrs: Vec<Attribute>,
396 pub break_token: Token![break],
397 pub label: Option<Lifetime>,
398 pub expr: Option<Box<Expr>>,
399 }),
400
401 pub Continue(ExprContinue #full {
405 pub attrs: Vec<Attribute>,
406 pub continue_token: Token![continue],
407 pub label: Option<Lifetime>,
408 }),
409
410 pub Return(ExprReturn #full {
414 pub attrs: Vec<Attribute>,
415 pub return_token: Token![return],
416 pub expr: Option<Box<Expr>>,
417 }),
418
419 pub Macro(ExprMacro #full {
423 pub attrs: Vec<Attribute>,
424 pub mac: Macro,
425 }),
426
427 pub Struct(ExprStruct #full {
434 pub attrs: Vec<Attribute>,
435 pub path: Path,
436 pub brace_token: token::Brace,
437 pub fields: Punctuated<FieldValue, Token![,]>,
438 pub dot2_token: Option<Token![..]>,
439 pub rest: Option<Box<Expr>>,
440 }),
441
442 pub Repeat(ExprRepeat #full {
446 pub attrs: Vec<Attribute>,
447 pub bracket_token: token::Bracket,
448 pub expr: Box<Expr>,
449 pub semi_token: Token![;],
450 pub len: Box<Expr>,
451 }),
452
453 pub Paren(ExprParen {
457 pub attrs: Vec<Attribute>,
458 pub paren_token: token::Paren,
459 pub expr: Box<Expr>,
460 }),
461
462 pub Group(ExprGroup #full {
470 pub attrs: Vec<Attribute>,
471 pub group_token: token::Group,
472 pub expr: Box<Expr>,
473 }),
474
475 pub Try(ExprTry #full {
479 pub attrs: Vec<Attribute>,
480 pub expr: Box<Expr>,
481 pub question_token: Token![?],
482 }),
483
484 pub Async(ExprAsync #full {
488 pub attrs: Vec<Attribute>,
489 pub async_token: Token![async],
490 pub capture: Option<Token![move]>,
491 pub block: Block,
492 }),
493
494 pub TryBlock(ExprTryBlock #full {
498 pub attrs: Vec<Attribute>,
499 pub try_token: Token![try],
500 pub block: Block,
501 }),
502
503 pub Yield(ExprYield #full {
507 pub attrs: Vec<Attribute>,
508 pub yield_token: Token![yield],
509 pub expr: Option<Box<Expr>>,
510 }),
511
512 pub Verbatim(ExprVerbatim #manual_extra_traits {
517 pub tts: TokenStream,
518 }),
519 }
520}
521
522#[cfg(feature = "extra-traits")]
523impl Eq for ExprVerbatim {}
524
525#[cfg(feature = "extra-traits")]
526impl PartialEq for ExprVerbatim {
527 fn eq(&self, other: &Self) -> bool {
528 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
529 }
530}
531
532#[cfg(feature = "extra-traits")]
533impl Hash for ExprVerbatim {
534 fn hash<H>(&self, state: &mut H)
535 where
536 H: Hasher,
537 {
538 TokenStreamHelper(&self.tts).hash(state);
539 }
540}
541
542impl Expr {
543 #[cfg(all(feature = "parsing", feature = "full"))]
544 fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
545 match *self {
546 Expr::Box(ExprBox { ref mut attrs, .. })
547 | Expr::InPlace(ExprInPlace { ref mut attrs, .. })
548 | Expr::Array(ExprArray { ref mut attrs, .. })
549 | Expr::Call(ExprCall { ref mut attrs, .. })
550 | Expr::MethodCall(ExprMethodCall { ref mut attrs, .. })
551 | Expr::Tuple(ExprTuple { ref mut attrs, .. })
552 | Expr::Binary(ExprBinary { ref mut attrs, .. })
553 | Expr::Unary(ExprUnary { ref mut attrs, .. })
554 | Expr::Lit(ExprLit { ref mut attrs, .. })
555 | Expr::Cast(ExprCast { ref mut attrs, .. })
556 | Expr::Type(ExprType { ref mut attrs, .. })
557 | Expr::Let(ExprLet { ref mut attrs, .. })
558 | Expr::If(ExprIf { ref mut attrs, .. })
559 | Expr::While(ExprWhile { ref mut attrs, .. })
560 | Expr::ForLoop(ExprForLoop { ref mut attrs, .. })
561 | Expr::Loop(ExprLoop { ref mut attrs, .. })
562 | Expr::Match(ExprMatch { ref mut attrs, .. })
563 | Expr::Closure(ExprClosure { ref mut attrs, .. })
564 | Expr::Unsafe(ExprUnsafe { ref mut attrs, .. })
565 | Expr::Block(ExprBlock { ref mut attrs, .. })
566 | Expr::Assign(ExprAssign { ref mut attrs, .. })
567 | Expr::AssignOp(ExprAssignOp { ref mut attrs, .. })
568 | Expr::Field(ExprField { ref mut attrs, .. })
569 | Expr::Index(ExprIndex { ref mut attrs, .. })
570 | Expr::Range(ExprRange { ref mut attrs, .. })
571 | Expr::Path(ExprPath { ref mut attrs, .. })
572 | Expr::Reference(ExprReference { ref mut attrs, .. })
573 | Expr::Break(ExprBreak { ref mut attrs, .. })
574 | Expr::Continue(ExprContinue { ref mut attrs, .. })
575 | Expr::Return(ExprReturn { ref mut attrs, .. })
576 | Expr::Macro(ExprMacro { ref mut attrs, .. })
577 | Expr::Struct(ExprStruct { ref mut attrs, .. })
578 | Expr::Repeat(ExprRepeat { ref mut attrs, .. })
579 | Expr::Paren(ExprParen { ref mut attrs, .. })
580 | Expr::Group(ExprGroup { ref mut attrs, .. })
581 | Expr::Try(ExprTry { ref mut attrs, .. })
582 | Expr::Async(ExprAsync { ref mut attrs, .. })
583 | Expr::TryBlock(ExprTryBlock { ref mut attrs, .. })
584 | Expr::Yield(ExprYield { ref mut attrs, .. }) => mem::replace(attrs, new),
585 Expr::Verbatim(_) => Vec::new(),
586 }
587 }
588}
589
590ast_enum! {
591 pub enum Member {
597 Named(Ident),
599 Unnamed(Index),
601 }
602}
603
604ast_struct! {
605 pub struct Index #manual_extra_traits {
610 pub index: u32,
611 pub span: Span,
612 }
613}
614
615impl From<usize> for Index {
616 fn from(index: usize) -> Index {
617 assert!(index < u32::max_value() as usize);
618 Index {
619 index: index as u32,
620 span: Span::call_site(),
621 }
622 }
623}
624
625#[cfg(feature = "extra-traits")]
626impl Eq for Index {}
627
628#[cfg(feature = "extra-traits")]
629impl PartialEq for Index {
630 fn eq(&self, other: &Self) -> bool {
631 self.index == other.index
632 }
633}
634
635#[cfg(feature = "extra-traits")]
636impl Hash for Index {
637 fn hash<H: Hasher>(&self, state: &mut H) {
638 self.index.hash(state);
639 }
640}
641
642#[cfg(feature = "full")]
643ast_struct! {
644 pub struct MethodTurbofish {
649 pub colon2_token: Token![::],
650 pub lt_token: Token![<],
651 pub args: Punctuated<GenericMethodArgument, Token![,]>,
652 pub gt_token: Token![>],
653 }
654}
655
656#[cfg(feature = "full")]
657ast_enum! {
658 pub enum GenericMethodArgument {
662 Type(Type),
664 Const(Expr),
669 }
670}
671
672#[cfg(feature = "full")]
673ast_struct! {
674 pub struct FieldValue {
678 pub attrs: Vec<Attribute>,
680
681 pub member: Member,
683
684 pub colon_token: Option<Token![:]>,
687
688 pub expr: Expr,
690 }
691}
692
693#[cfg(feature = "full")]
694ast_struct! {
695 pub struct Label {
699 pub name: Lifetime,
700 pub colon_token: Token![:],
701 }
702}
703
704#[cfg(feature = "full")]
705ast_struct! {
706 pub struct Block {
710 pub brace_token: token::Brace,
711 pub stmts: Vec<Stmt>,
713 }
714}
715
716#[cfg(feature = "full")]
717ast_enum! {
718 pub enum Stmt {
722 Local(Local),
724
725 Item(Item),
727
728 Expr(Expr),
730
731 Semi(Expr, Token![;]),
733 }
734}
735
736#[cfg(feature = "full")]
737ast_struct! {
738 pub struct Local {
742 pub attrs: Vec<Attribute>,
743 pub let_token: Token![let],
744 pub pats: Punctuated<Pat, Token![|]>,
745 pub ty: Option<(Token![:], Box<Type>)>,
746 pub init: Option<(Token![=], Box<Expr>)>,
747 pub semi_token: Token![;],
748 }
749}
750
751#[cfg(feature = "full")]
752ast_enum_of_structs! {
753 pub enum Pat {
764 pub Wild(PatWild {
768 pub underscore_token: Token![_],
769 }),
770
771 pub Ident(PatIdent {
775 pub by_ref: Option<Token![ref]>,
776 pub mutability: Option<Token![mut]>,
777 pub ident: Ident,
778 pub subpat: Option<(Token![@], Box<Pat>)>,
779 }),
780
781 pub Struct(PatStruct {
785 pub path: Path,
786 pub brace_token: token::Brace,
787 pub fields: Punctuated<FieldPat, Token![,]>,
788 pub dot2_token: Option<Token![..]>,
789 }),
790
791 pub TupleStruct(PatTupleStruct {
795 pub path: Path,
796 pub pat: PatTuple,
797 }),
798
799 pub Path(PatPath {
809 pub qself: Option<QSelf>,
810 pub path: Path,
811 }),
812
813 pub Tuple(PatTuple {
817 pub paren_token: token::Paren,
818 pub front: Punctuated<Pat, Token![,]>,
819 pub dot2_token: Option<Token![..]>,
820 pub comma_token: Option<Token![,]>,
821 pub back: Punctuated<Pat, Token![,]>,
822 }),
823
824 pub Box(PatBox {
828 pub box_token: Token![box],
829 pub pat: Box<Pat>,
830 }),
831
832 pub Ref(PatRef {
836 pub and_token: Token![&],
837 pub mutability: Option<Token![mut]>,
838 pub pat: Box<Pat>,
839 }),
840
841 pub Lit(PatLit {
848 pub expr: Box<Expr>,
849 }),
850
851 pub Range(PatRange {
855 pub lo: Box<Expr>,
856 pub limits: RangeLimits,
857 pub hi: Box<Expr>,
858 }),
859
860 pub Slice(PatSlice {
864 pub bracket_token: token::Bracket,
865 pub front: Punctuated<Pat, Token![,]>,
866 pub middle: Option<Box<Pat>>,
867 pub dot2_token: Option<Token![..]>,
868 pub comma_token: Option<Token![,]>,
869 pub back: Punctuated<Pat, Token![,]>,
870 }),
871
872 pub Macro(PatMacro {
876 pub mac: Macro,
877 }),
878
879 pub Verbatim(PatVerbatim #manual_extra_traits {
883 pub tts: TokenStream,
884 }),
885 }
886}
887
888#[cfg(all(feature = "full", feature = "extra-traits"))]
889impl Eq for PatVerbatim {}
890
891#[cfg(all(feature = "full", feature = "extra-traits"))]
892impl PartialEq for PatVerbatim {
893 fn eq(&self, other: &Self) -> bool {
894 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
895 }
896}
897
898#[cfg(all(feature = "full", feature = "extra-traits"))]
899impl Hash for PatVerbatim {
900 fn hash<H>(&self, state: &mut H)
901 where
902 H: Hasher,
903 {
904 TokenStreamHelper(&self.tts).hash(state);
905 }
906}
907
908#[cfg(feature = "full")]
909ast_struct! {
910 pub struct Arm {
930 pub attrs: Vec<Attribute>,
931 pub leading_vert: Option<Token![|]>,
932 pub pats: Punctuated<Pat, Token![|]>,
933 pub guard: Option<(Token![if], Box<Expr>)>,
934 pub fat_arrow_token: Token![=>],
935 pub body: Box<Expr>,
936 pub comma: Option<Token![,]>,
937 }
938}
939
940#[cfg(feature = "full")]
941ast_enum! {
942 #[cfg_attr(feature = "clone-impls", derive(Copy))]
946 pub enum RangeLimits {
947 HalfOpen(Token![..]),
949 Closed(Token![..=]),
951 }
952}
953
954#[cfg(feature = "full")]
955ast_struct! {
956 pub struct FieldPat {
963 pub attrs: Vec<Attribute>,
964 pub member: Member,
965 pub colon_token: Option<Token![:]>,
966 pub pat: Box<Pat>,
967 }
968}
969
970#[cfg(any(feature = "parsing", feature = "printing"))]
971#[cfg(feature = "full")]
972fn requires_terminator(expr: &Expr) -> bool {
973 match *expr {
975 Expr::Unsafe(..)
976 | Expr::Block(..)
977 | Expr::If(..)
978 | Expr::Match(..)
979 | Expr::While(..)
980 | Expr::Loop(..)
981 | Expr::ForLoop(..)
982 | Expr::Async(..)
983 | Expr::TryBlock(..) => false,
984 _ => true,
985 }
986}
987
988#[cfg(feature = "parsing")]
989pub mod parsing {
990 use super::*;
991
992 #[cfg(feature = "full")]
993 use ext::IdentExt;
994 use parse::{Parse, ParseStream, Result};
995 use path;
996
997 #[derive(Copy, Clone)]
1003 pub struct AllowStruct(bool);
1004
1005 #[derive(Copy, Clone, PartialEq, PartialOrd)]
1006 enum Precedence {
1007 Any,
1008 Assign,
1009 Placement,
1010 Range,
1011 Or,
1012 And,
1013 Compare,
1014 BitOr,
1015 BitXor,
1016 BitAnd,
1017 Shift,
1018 Arithmetic,
1019 Term,
1020 Cast,
1021 }
1022
1023 impl Precedence {
1024 fn of(op: &BinOp) -> Self {
1025 match *op {
1026 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1027 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1028 BinOp::And(_) => Precedence::And,
1029 BinOp::Or(_) => Precedence::Or,
1030 BinOp::BitXor(_) => Precedence::BitXor,
1031 BinOp::BitAnd(_) => Precedence::BitAnd,
1032 BinOp::BitOr(_) => Precedence::BitOr,
1033 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1034 BinOp::Eq(_)
1035 | BinOp::Lt(_)
1036 | BinOp::Le(_)
1037 | BinOp::Ne(_)
1038 | BinOp::Ge(_)
1039 | BinOp::Gt(_) => Precedence::Compare,
1040 BinOp::AddEq(_)
1041 | BinOp::SubEq(_)
1042 | BinOp::MulEq(_)
1043 | BinOp::DivEq(_)
1044 | BinOp::RemEq(_)
1045 | BinOp::BitXorEq(_)
1046 | BinOp::BitAndEq(_)
1047 | BinOp::BitOrEq(_)
1048 | BinOp::ShlEq(_)
1049 | BinOp::ShrEq(_) => Precedence::Assign,
1050 }
1051 }
1052 }
1053
1054 impl Parse for Expr {
1055 fn parse(input: ParseStream) -> Result<Self> {
1056 ambiguous_expr(input, AllowStruct(true))
1057 }
1058 }
1059
1060 #[cfg(feature = "full")]
1061 fn expr_no_struct(input: ParseStream) -> Result<Expr> {
1062 ambiguous_expr(input, AllowStruct(false))
1063 }
1064
1065 #[cfg(feature = "full")]
1066 fn parse_expr(
1067 input: ParseStream,
1068 mut lhs: Expr,
1069 allow_struct: AllowStruct,
1070 base: Precedence,
1071 ) -> Result<Expr> {
1072 loop {
1073 if input
1074 .fork()
1075 .parse::<BinOp>()
1076 .ok()
1077 .map_or(false, |op| Precedence::of(&op) >= base)
1078 {
1079 let op: BinOp = input.parse()?;
1080 let precedence = Precedence::of(&op);
1081 let mut rhs = unary_expr(input, allow_struct)?;
1082 loop {
1083 let next = peek_precedence(input);
1084 if next > precedence || next == precedence && precedence == Precedence::Assign {
1085 rhs = parse_expr(input, rhs, allow_struct, next)?;
1086 } else {
1087 break;
1088 }
1089 }
1090 lhs = if precedence == Precedence::Assign {
1091 Expr::AssignOp(ExprAssignOp {
1092 attrs: Vec::new(),
1093 left: Box::new(lhs),
1094 op: op,
1095 right: Box::new(rhs),
1096 })
1097 } else {
1098 Expr::Binary(ExprBinary {
1099 attrs: Vec::new(),
1100 left: Box::new(lhs),
1101 op: op,
1102 right: Box::new(rhs),
1103 })
1104 };
1105 } else if Precedence::Assign >= base
1106 && input.peek(Token![=])
1107 && !input.peek(Token![==])
1108 && !input.peek(Token![=>])
1109 {
1110 let eq_token: Token![=] = input.parse()?;
1111 let mut rhs = unary_expr(input, allow_struct)?;
1112 loop {
1113 let next = peek_precedence(input);
1114 if next >= Precedence::Assign {
1115 rhs = parse_expr(input, rhs, allow_struct, next)?;
1116 } else {
1117 break;
1118 }
1119 }
1120 lhs = Expr::Assign(ExprAssign {
1121 attrs: Vec::new(),
1122 left: Box::new(lhs),
1123 eq_token: eq_token,
1124 right: Box::new(rhs),
1125 });
1126 } else if Precedence::Placement >= base && input.peek(Token![<-]) {
1127 let arrow_token: Token![<-] = input.parse()?;
1128 let mut rhs = unary_expr(input, allow_struct)?;
1129 loop {
1130 let next = peek_precedence(input);
1131 if next > Precedence::Placement {
1132 rhs = parse_expr(input, rhs, allow_struct, next)?;
1133 } else {
1134 break;
1135 }
1136 }
1137 lhs = Expr::InPlace(ExprInPlace {
1138 attrs: Vec::new(),
1139 place: Box::new(lhs),
1140 arrow_token: arrow_token,
1141 value: Box::new(rhs),
1142 });
1143 } else if Precedence::Range >= base && input.peek(Token![..]) {
1144 let limits: RangeLimits = input.parse()?;
1145 let rhs = if input.is_empty()
1146 || input.peek(Token![,])
1147 || input.peek(Token![;])
1148 || !allow_struct.0 && input.peek(token::Brace)
1149 {
1150 None
1151 } else {
1152 let mut rhs = unary_expr(input, allow_struct)?;
1153 loop {
1154 let next = peek_precedence(input);
1155 if next > Precedence::Range {
1156 rhs = parse_expr(input, rhs, allow_struct, next)?;
1157 } else {
1158 break;
1159 }
1160 }
1161 Some(rhs)
1162 };
1163 lhs = Expr::Range(ExprRange {
1164 attrs: Vec::new(),
1165 from: Some(Box::new(lhs)),
1166 limits: limits,
1167 to: rhs.map(Box::new),
1168 });
1169 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1170 let as_token: Token![as] = input.parse()?;
1171 let ty = input.call(Type::without_plus)?;
1172 lhs = Expr::Cast(ExprCast {
1173 attrs: Vec::new(),
1174 expr: Box::new(lhs),
1175 as_token: as_token,
1176 ty: Box::new(ty),
1177 });
1178 } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1179 let colon_token: Token![:] = input.parse()?;
1180 let ty = input.call(Type::without_plus)?;
1181 lhs = Expr::Type(ExprType {
1182 attrs: Vec::new(),
1183 expr: Box::new(lhs),
1184 colon_token: colon_token,
1185 ty: Box::new(ty),
1186 });
1187 } else {
1188 break;
1189 }
1190 }
1191 Ok(lhs)
1192 }
1193
1194 #[cfg(not(feature = "full"))]
1195 fn parse_expr(
1196 input: ParseStream,
1197 mut lhs: Expr,
1198 allow_struct: AllowStruct,
1199 base: Precedence,
1200 ) -> Result<Expr> {
1201 loop {
1202 if input
1203 .fork()
1204 .parse::<BinOp>()
1205 .ok()
1206 .map_or(false, |op| Precedence::of(&op) >= base)
1207 {
1208 let op: BinOp = input.parse()?;
1209 let precedence = Precedence::of(&op);
1210 let mut rhs = unary_expr(input, allow_struct)?;
1211 loop {
1212 let next = peek_precedence(input);
1213 if next > precedence || next == precedence && precedence == Precedence::Assign {
1214 rhs = parse_expr(input, rhs, allow_struct, next)?;
1215 } else {
1216 break;
1217 }
1218 }
1219 lhs = Expr::Binary(ExprBinary {
1220 attrs: Vec::new(),
1221 left: Box::new(lhs),
1222 op: op,
1223 right: Box::new(rhs),
1224 });
1225 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1226 let as_token: Token![as] = input.parse()?;
1227 let ty = input.call(Type::without_plus)?;
1228 lhs = Expr::Cast(ExprCast {
1229 attrs: Vec::new(),
1230 expr: Box::new(lhs),
1231 as_token: as_token,
1232 ty: Box::new(ty),
1233 });
1234 } else {
1235 break;
1236 }
1237 }
1238 Ok(lhs)
1239 }
1240
1241 fn peek_precedence(input: ParseStream) -> Precedence {
1242 if let Ok(op) = input.fork().parse() {
1243 Precedence::of(&op)
1244 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1245 Precedence::Assign
1246 } else if input.peek(Token![<-]) {
1247 Precedence::Placement
1248 } else if input.peek(Token![..]) {
1249 Precedence::Range
1250 } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
1251 Precedence::Cast
1252 } else {
1253 Precedence::Any
1254 }
1255 }
1256
1257 fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1259 let lhs = unary_expr(input, allow_struct)?;
1260 parse_expr(input, lhs, allow_struct, Precedence::Any)
1261 }
1262
1263 #[cfg(feature = "full")]
1268 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1269 let ahead = input.fork();
1270 ahead.call(Attribute::parse_outer)?;
1271 if ahead.peek(Token![&])
1272 || ahead.peek(Token![box])
1273 || ahead.peek(Token![*])
1274 || ahead.peek(Token![!])
1275 || ahead.peek(Token![-])
1276 {
1277 let attrs = input.call(Attribute::parse_outer)?;
1278 if input.peek(Token![&]) {
1279 Ok(Expr::Reference(ExprReference {
1280 attrs: attrs,
1281 and_token: input.parse()?,
1282 mutability: input.parse()?,
1283 expr: Box::new(unary_expr(input, allow_struct)?),
1284 }))
1285 } else if input.peek(Token![box]) {
1286 Ok(Expr::Box(ExprBox {
1287 attrs: attrs,
1288 box_token: input.parse()?,
1289 expr: Box::new(unary_expr(input, allow_struct)?),
1290 }))
1291 } else {
1292 Ok(Expr::Unary(ExprUnary {
1293 attrs: attrs,
1294 op: input.parse()?,
1295 expr: Box::new(unary_expr(input, allow_struct)?),
1296 }))
1297 }
1298 } else {
1299 trailer_expr(input, allow_struct)
1300 }
1301 }
1302
1303 #[cfg(not(feature = "full"))]
1304 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1305 let ahead = input.fork();
1306 ahead.call(Attribute::parse_outer)?;
1307 if ahead.peek(Token![*]) || ahead.peek(Token![!]) || ahead.peek(Token![-]) {
1308 Ok(Expr::Unary(ExprUnary {
1309 attrs: input.call(Attribute::parse_outer)?,
1310 op: input.parse()?,
1311 expr: Box::new(unary_expr(input, allow_struct)?),
1312 }))
1313 } else {
1314 trailer_expr(input, allow_struct)
1315 }
1316 }
1317
1318 #[cfg(feature = "full")]
1325 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1326 if input.peek(token::Group) {
1327 return input.call(expr_group).map(Expr::Group);
1328 }
1329
1330 let outer_attrs = input.call(Attribute::parse_outer)?;
1331
1332 let atom = atom_expr(input, allow_struct)?;
1333 let mut e = trailer_helper(input, atom)?;
1334
1335 let inner_attrs = e.replace_attrs(Vec::new());
1336 let attrs = private::attrs(outer_attrs, inner_attrs);
1337 e.replace_attrs(attrs);
1338 Ok(e)
1339 }
1340
1341 #[cfg(feature = "full")]
1342 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1343 loop {
1344 if input.peek(token::Paren) {
1345 let content;
1346 e = Expr::Call(ExprCall {
1347 attrs: Vec::new(),
1348 func: Box::new(e),
1349 paren_token: parenthesized!(content in input),
1350 args: content.parse_terminated(Expr::parse)?,
1351 });
1352 } else if input.peek(Token![.]) && !input.peek(Token![..]) {
1353 let dot_token: Token![.] = input.parse()?;
1354 let member: Member = input.parse()?;
1355 let turbofish = if member.is_named() && input.peek(Token![::]) {
1356 Some(MethodTurbofish {
1357 colon2_token: input.parse()?,
1358 lt_token: input.parse()?,
1359 args: {
1360 let mut args = Punctuated::new();
1361 loop {
1362 if input.peek(Token![>]) {
1363 break;
1364 }
1365 let value = input.call(generic_method_argument)?;
1366 args.push_value(value);
1367 if input.peek(Token![>]) {
1368 break;
1369 }
1370 let punct = input.parse()?;
1371 args.push_punct(punct);
1372 }
1373 args
1374 },
1375 gt_token: input.parse()?,
1376 })
1377 } else {
1378 None
1379 };
1380
1381 if turbofish.is_some() || input.peek(token::Paren) {
1382 if let Member::Named(method) = member {
1383 let content;
1384 e = Expr::MethodCall(ExprMethodCall {
1385 attrs: Vec::new(),
1386 receiver: Box::new(e),
1387 dot_token: dot_token,
1388 method: method,
1389 turbofish: turbofish,
1390 paren_token: parenthesized!(content in input),
1391 args: content.parse_terminated(Expr::parse)?,
1392 });
1393 continue;
1394 }
1395 }
1396
1397 e = Expr::Field(ExprField {
1398 attrs: Vec::new(),
1399 base: Box::new(e),
1400 dot_token: dot_token,
1401 member: member,
1402 });
1403 } else if input.peek(token::Bracket) {
1404 let content;
1405 e = Expr::Index(ExprIndex {
1406 attrs: Vec::new(),
1407 expr: Box::new(e),
1408 bracket_token: bracketed!(content in input),
1409 index: content.parse()?,
1410 });
1411 } else if input.peek(Token![?]) {
1412 e = Expr::Try(ExprTry {
1413 attrs: Vec::new(),
1414 expr: Box::new(e),
1415 question_token: input.parse()?,
1416 });
1417 } else {
1418 break;
1419 }
1420 }
1421 Ok(e)
1422 }
1423
1424 #[cfg(not(feature = "full"))]
1425 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1426 let mut e = atom_expr(input, allow_struct)?;
1427
1428 loop {
1429 if input.peek(token::Paren) {
1430 let content;
1431 e = Expr::Call(ExprCall {
1432 attrs: Vec::new(),
1433 func: Box::new(e),
1434 paren_token: parenthesized!(content in input),
1435 args: content.parse_terminated(Expr::parse)?,
1436 });
1437 } else if input.peek(Token![.]) {
1438 e = Expr::Field(ExprField {
1439 attrs: Vec::new(),
1440 base: Box::new(e),
1441 dot_token: input.parse()?,
1442 member: input.parse()?,
1443 });
1444 } else if input.peek(token::Bracket) {
1445 let content;
1446 e = Expr::Index(ExprIndex {
1447 attrs: Vec::new(),
1448 expr: Box::new(e),
1449 bracket_token: bracketed!(content in input),
1450 index: content.parse()?,
1451 });
1452 } else {
1453 break;
1454 }
1455 }
1456
1457 Ok(e)
1458 }
1459
1460 #[cfg(feature = "full")]
1463 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1464 if input.peek(token::Group) {
1465 input.call(expr_group).map(Expr::Group)
1466 } else if input.peek(Lit) {
1467 input.parse().map(Expr::Lit)
1468 } else if input.peek(Token![async])
1469 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1470 {
1471 input.call(expr_async).map(Expr::Async)
1472 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1473 input.call(expr_try_block).map(Expr::TryBlock)
1474 } else if input.peek(Token![|])
1475 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1476 || input.peek(Token![static])
1477 || input.peek(Token![move])
1478 {
1479 expr_closure(input, allow_struct).map(Expr::Closure)
1480 } else if input.peek(Ident)
1481 || input.peek(Token![::])
1482 || input.peek(Token![<])
1483 || input.peek(Token![self])
1484 || input.peek(Token![Self])
1485 || input.peek(Token![super])
1486 || input.peek(Token![extern])
1487 || input.peek(Token![crate])
1488 {
1489 path_or_macro_or_struct(input, allow_struct)
1490 } else if input.peek(token::Paren) {
1491 paren_or_tuple(input)
1492 } else if input.peek(Token![break]) {
1493 expr_break(input, allow_struct).map(Expr::Break)
1494 } else if input.peek(Token![continue]) {
1495 input.call(expr_continue).map(Expr::Continue)
1496 } else if input.peek(Token![return]) {
1497 expr_ret(input, allow_struct).map(Expr::Return)
1498 } else if input.peek(token::Bracket) {
1499 array_or_repeat(input)
1500 } else if input.peek(Token![let]) {
1501 input.call(expr_let).map(Expr::Let)
1502 } else if input.peek(Token![if]) {
1503 input.parse().map(Expr::If)
1504 } else if input.peek(Token![while]) {
1505 input.parse().map(Expr::While)
1506 } else if input.peek(Token![for]) {
1507 input.parse().map(Expr::ForLoop)
1508 } else if input.peek(Token![loop]) {
1509 input.parse().map(Expr::Loop)
1510 } else if input.peek(Token![match]) {
1511 input.parse().map(Expr::Match)
1512 } else if input.peek(Token![yield]) {
1513 input.call(expr_yield).map(Expr::Yield)
1514 } else if input.peek(Token![unsafe]) {
1515 input.call(expr_unsafe).map(Expr::Unsafe)
1516 } else if input.peek(token::Brace) {
1517 input.call(expr_block).map(Expr::Block)
1518 } else if input.peek(Token![..]) {
1519 expr_range(input, allow_struct).map(Expr::Range)
1520 } else if input.peek(Lifetime) {
1521 let the_label: Label = input.parse()?;
1522 let mut expr = if input.peek(Token![while]) {
1523 Expr::While(input.parse()?)
1524 } else if input.peek(Token![for]) {
1525 Expr::ForLoop(input.parse()?)
1526 } else if input.peek(Token![loop]) {
1527 Expr::Loop(input.parse()?)
1528 } else if input.peek(token::Brace) {
1529 Expr::Block(input.call(expr_block)?)
1530 } else {
1531 return Err(input.error("expected loop or block expression"));
1532 };
1533 match expr {
1534 Expr::While(ExprWhile { ref mut label, .. })
1535 | Expr::ForLoop(ExprForLoop { ref mut label, .. })
1536 | Expr::Loop(ExprLoop { ref mut label, .. })
1537 | Expr::Block(ExprBlock { ref mut label, .. }) => *label = Some(the_label),
1538 _ => unreachable!(),
1539 }
1540 Ok(expr)
1541 } else {
1542 Err(input.error("expected expression"))
1543 }
1544 }
1545
1546 #[cfg(not(feature = "full"))]
1547 fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1548 if input.peek(Lit) {
1549 input.parse().map(Expr::Lit)
1550 } else if input.peek(token::Paren) {
1551 input.call(expr_paren).map(Expr::Paren)
1552 } else if input.peek(Ident)
1553 || input.peek(Token![::])
1554 || input.peek(Token![<])
1555 || input.peek(Token![self])
1556 || input.peek(Token![Self])
1557 || input.peek(Token![super])
1558 || input.peek(Token![extern])
1559 || input.peek(Token![crate])
1560 {
1561 input.parse().map(Expr::Path)
1562 } else {
1563 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1564 }
1565 }
1566
1567 #[cfg(feature = "full")]
1568 fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1569 let expr: ExprPath = input.parse()?;
1570 if expr.qself.is_some() {
1571 return Ok(Expr::Path(expr));
1572 }
1573
1574 if input.peek(Token![!]) && !input.peek(Token![!=]) {
1575 let mut contains_arguments = false;
1576 for segment in &expr.path.segments {
1577 match segment.arguments {
1578 PathArguments::None => {}
1579 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1580 contains_arguments = true;
1581 }
1582 }
1583 }
1584
1585 if !contains_arguments {
1586 let bang_token: Token![!] = input.parse()?;
1587 let (delimiter, tts) = mac::parse_delimiter(input)?;
1588 return Ok(Expr::Macro(ExprMacro {
1589 attrs: Vec::new(),
1590 mac: Macro {
1591 path: expr.path,
1592 bang_token: bang_token,
1593 delimiter: delimiter,
1594 tts: tts,
1595 },
1596 }));
1597 }
1598 }
1599
1600 if allow_struct.0 && input.peek(token::Brace) {
1601 let outer_attrs = Vec::new();
1602 expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1603 } else {
1604 Ok(Expr::Path(expr))
1605 }
1606 }
1607
1608 #[cfg(feature = "full")]
1609 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1610 let content;
1611 let paren_token = parenthesized!(content in input);
1612 let inner_attrs = content.call(Attribute::parse_inner)?;
1613 if content.is_empty() {
1614 return Ok(Expr::Tuple(ExprTuple {
1615 attrs: inner_attrs,
1616 paren_token: paren_token,
1617 elems: Punctuated::new(),
1618 }));
1619 }
1620
1621 let first: Expr = content.parse()?;
1622 if content.is_empty() {
1623 return Ok(Expr::Paren(ExprParen {
1624 attrs: inner_attrs,
1625 paren_token: paren_token,
1626 expr: Box::new(first),
1627 }));
1628 }
1629
1630 let mut elems = Punctuated::new();
1631 elems.push_value(first);
1632 while !content.is_empty() {
1633 let punct = content.parse()?;
1634 elems.push_punct(punct);
1635 if content.is_empty() {
1636 break;
1637 }
1638 let value = content.parse()?;
1639 elems.push_value(value);
1640 }
1641 Ok(Expr::Tuple(ExprTuple {
1642 attrs: inner_attrs,
1643 paren_token: paren_token,
1644 elems: elems,
1645 }))
1646 }
1647
1648 #[cfg(feature = "full")]
1649 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1650 let content;
1651 let bracket_token = bracketed!(content in input);
1652 let inner_attrs = content.call(Attribute::parse_inner)?;
1653 if content.is_empty() {
1654 return Ok(Expr::Array(ExprArray {
1655 attrs: inner_attrs,
1656 bracket_token: bracket_token,
1657 elems: Punctuated::new(),
1658 }));
1659 }
1660
1661 let first: Expr = content.parse()?;
1662 if content.is_empty() || content.peek(Token![,]) {
1663 let mut elems = Punctuated::new();
1664 elems.push_value(first);
1665 while !content.is_empty() {
1666 let punct = content.parse()?;
1667 elems.push_punct(punct);
1668 if content.is_empty() {
1669 break;
1670 }
1671 let value = content.parse()?;
1672 elems.push_value(value);
1673 }
1674 Ok(Expr::Array(ExprArray {
1675 attrs: inner_attrs,
1676 bracket_token: bracket_token,
1677 elems: elems,
1678 }))
1679 } else if content.peek(Token![;]) {
1680 let semi_token: Token![;] = content.parse()?;
1681 let len: Expr = content.parse()?;
1682 Ok(Expr::Repeat(ExprRepeat {
1683 attrs: inner_attrs,
1684 bracket_token: bracket_token,
1685 expr: Box::new(first),
1686 semi_token: semi_token,
1687 len: Box::new(len),
1688 }))
1689 } else {
1690 Err(content.error("expected `,` or `;`"))
1691 }
1692 }
1693
1694 #[cfg(feature = "full")]
1695 fn expr_early(input: ParseStream) -> Result<Expr> {
1696 let mut attrs = input.call(Attribute::parse_outer)?;
1697 let mut expr = if input.peek(Token![if]) {
1698 Expr::If(input.parse()?)
1699 } else if input.peek(Token![while]) {
1700 Expr::While(input.parse()?)
1701 } else if input.peek(Token![for]) {
1702 Expr::ForLoop(input.parse()?)
1703 } else if input.peek(Token![loop]) {
1704 Expr::Loop(input.parse()?)
1705 } else if input.peek(Token![match]) {
1706 Expr::Match(input.parse()?)
1707 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1708 Expr::TryBlock(input.call(expr_try_block)?)
1709 } else if input.peek(Token![unsafe]) {
1710 Expr::Unsafe(input.call(expr_unsafe)?)
1711 } else if input.peek(token::Brace) {
1712 Expr::Block(input.call(expr_block)?)
1713 } else {
1714 let allow_struct = AllowStruct(true);
1715 let mut expr = unary_expr(input, allow_struct)?;
1716
1717 attrs.extend(expr.replace_attrs(Vec::new()));
1718 expr.replace_attrs(attrs);
1719
1720 return parse_expr(input, expr, allow_struct, Precedence::Any);
1721 };
1722
1723 if input.peek(Token![.]) || input.peek(Token![?]) {
1724 expr = trailer_helper(input, expr)?;
1725
1726 attrs.extend(expr.replace_attrs(Vec::new()));
1727 expr.replace_attrs(attrs);
1728
1729 let allow_struct = AllowStruct(true);
1730 return parse_expr(input, expr, allow_struct, Precedence::Any);
1731 }
1732
1733 attrs.extend(expr.replace_attrs(Vec::new()));
1734 expr.replace_attrs(attrs);
1735 Ok(expr)
1736 }
1737
1738 impl Parse for ExprLit {
1739 fn parse(input: ParseStream) -> Result<Self> {
1740 Ok(ExprLit {
1741 attrs: Vec::new(),
1742 lit: input.parse()?,
1743 })
1744 }
1745 }
1746
1747 #[cfg(feature = "full")]
1748 fn expr_group(input: ParseStream) -> Result<ExprGroup> {
1749 let group = private::parse_group(input)?;
1750 Ok(ExprGroup {
1751 attrs: Vec::new(),
1752 group_token: group.token,
1753 expr: group.content.parse()?,
1754 })
1755 }
1756
1757 #[cfg(not(feature = "full"))]
1758 fn expr_paren(input: ParseStream) -> Result<ExprParen> {
1759 let content;
1760 Ok(ExprParen {
1761 attrs: Vec::new(),
1762 paren_token: parenthesized!(content in input),
1763 expr: content.parse()?,
1764 })
1765 }
1766
1767 #[cfg(feature = "full")]
1768 fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
1769 input.parse().map(GenericMethodArgument::Type)
1771 }
1772
1773 #[cfg(feature = "full")]
1774 fn expr_let(input: ParseStream) -> Result<ExprLet> {
1775 Ok(ExprLet {
1776 attrs: Vec::new(),
1777 let_token: input.parse()?,
1778 pats: {
1779 let mut pats = Punctuated::new();
1780 input.parse::<Option<Token![|]>>()?;
1781 let value: Pat = input.parse()?;
1782 pats.push_value(value);
1783 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
1784 let punct = input.parse()?;
1785 pats.push_punct(punct);
1786 let value: Pat = input.parse()?;
1787 pats.push_value(value);
1788 }
1789 pats
1790 },
1791 eq_token: input.parse()?,
1792 expr: Box::new(input.call(expr_no_struct)?),
1793 })
1794 }
1795
1796 #[cfg(feature = "full")]
1797 impl Parse for ExprIf {
1798 fn parse(input: ParseStream) -> Result<Self> {
1799 Ok(ExprIf {
1800 attrs: Vec::new(),
1801 if_token: input.parse()?,
1802 cond: Box::new(input.call(expr_no_struct)?),
1803 then_branch: input.parse()?,
1804 else_branch: {
1805 if input.peek(Token![else]) {
1806 Some(input.call(else_block)?)
1807 } else {
1808 None
1809 }
1810 },
1811 })
1812 }
1813 }
1814
1815 #[cfg(feature = "full")]
1816 fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
1817 let else_token: Token![else] = input.parse()?;
1818
1819 let lookahead = input.lookahead1();
1820 let else_branch = if input.peek(Token![if]) {
1821 input.parse().map(Expr::If)?
1822 } else if input.peek(token::Brace) {
1823 Expr::Block(ExprBlock {
1824 attrs: Vec::new(),
1825 label: None,
1826 block: input.parse()?,
1827 })
1828 } else {
1829 return Err(lookahead.error());
1830 };
1831
1832 Ok((else_token, Box::new(else_branch)))
1833 }
1834
1835 #[cfg(feature = "full")]
1836 impl Parse for ExprForLoop {
1837 fn parse(input: ParseStream) -> Result<Self> {
1838 let label: Option<Label> = input.parse()?;
1839 let for_token: Token![for] = input.parse()?;
1840 let pat: Pat = input.parse()?;
1841 let in_token: Token![in] = input.parse()?;
1842 let expr: Expr = input.call(expr_no_struct)?;
1843
1844 let content;
1845 let brace_token = braced!(content in input);
1846 let inner_attrs = content.call(Attribute::parse_inner)?;
1847 let stmts = content.call(Block::parse_within)?;
1848
1849 Ok(ExprForLoop {
1850 attrs: inner_attrs,
1851 label: label,
1852 for_token: for_token,
1853 pat: Box::new(pat),
1854 in_token: in_token,
1855 expr: Box::new(expr),
1856 body: Block {
1857 brace_token: brace_token,
1858 stmts: stmts,
1859 },
1860 })
1861 }
1862 }
1863
1864 #[cfg(feature = "full")]
1865 impl Parse for ExprLoop {
1866 fn parse(input: ParseStream) -> Result<Self> {
1867 let label: Option<Label> = input.parse()?;
1868 let loop_token: Token![loop] = input.parse()?;
1869
1870 let content;
1871 let brace_token = braced!(content in input);
1872 let inner_attrs = content.call(Attribute::parse_inner)?;
1873 let stmts = content.call(Block::parse_within)?;
1874
1875 Ok(ExprLoop {
1876 attrs: inner_attrs,
1877 label: label,
1878 loop_token: loop_token,
1879 body: Block {
1880 brace_token: brace_token,
1881 stmts: stmts,
1882 },
1883 })
1884 }
1885 }
1886
1887 #[cfg(feature = "full")]
1888 impl Parse for ExprMatch {
1889 fn parse(input: ParseStream) -> Result<Self> {
1890 let match_token: Token![match] = input.parse()?;
1891 let expr = expr_no_struct(input)?;
1892
1893 let content;
1894 let brace_token = braced!(content in input);
1895 let inner_attrs = content.call(Attribute::parse_inner)?;
1896
1897 let mut arms = Vec::new();
1898 while !content.is_empty() {
1899 arms.push(content.call(Arm::parse)?);
1900 }
1901
1902 Ok(ExprMatch {
1903 attrs: inner_attrs,
1904 match_token: match_token,
1905 expr: Box::new(expr),
1906 brace_token: brace_token,
1907 arms: arms,
1908 })
1909 }
1910 }
1911
1912 #[cfg(feature = "full")]
1913 fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
1914 Ok(ExprTryBlock {
1915 attrs: Vec::new(),
1916 try_token: input.parse()?,
1917 block: input.parse()?,
1918 })
1919 }
1920
1921 #[cfg(feature = "full")]
1922 fn expr_yield(input: ParseStream) -> Result<ExprYield> {
1923 Ok(ExprYield {
1924 attrs: Vec::new(),
1925 yield_token: input.parse()?,
1926 expr: {
1927 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
1928 Some(input.parse()?)
1929 } else {
1930 None
1931 }
1932 },
1933 })
1934 }
1935
1936 #[cfg(feature = "full")]
1937 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
1938 let asyncness: Option<Token![async]> = input.parse()?;
1939 let movability: Option<Token![static]> = if asyncness.is_none() {
1940 input.parse()?
1941 } else {
1942 None
1943 };
1944 let capture: Option<Token![move]> = input.parse()?;
1945 let or1_token: Token![|] = input.parse()?;
1946
1947 let mut inputs = Punctuated::new();
1948 loop {
1949 if input.peek(Token![|]) {
1950 break;
1951 }
1952 let value = fn_arg(input)?;
1953 inputs.push_value(value);
1954 if input.peek(Token![|]) {
1955 break;
1956 }
1957 let punct: Token![,] = input.parse()?;
1958 inputs.push_punct(punct);
1959 }
1960
1961 let or2_token: Token![|] = input.parse()?;
1962
1963 let (output, body) = if input.peek(Token![->]) {
1964 let arrow_token: Token![->] = input.parse()?;
1965 let ty: Type = input.parse()?;
1966 let body: Block = input.parse()?;
1967 let output = ReturnType::Type(arrow_token, Box::new(ty));
1968 let block = Expr::Block(ExprBlock {
1969 attrs: Vec::new(),
1970 label: None,
1971 block: body,
1972 });
1973 (output, block)
1974 } else {
1975 let body = ambiguous_expr(input, allow_struct)?;
1976 (ReturnType::Default, body)
1977 };
1978
1979 Ok(ExprClosure {
1980 attrs: Vec::new(),
1981 asyncness: asyncness,
1982 movability: movability,
1983 capture: capture,
1984 or1_token: or1_token,
1985 inputs: inputs,
1986 or2_token: or2_token,
1987 output: output,
1988 body: Box::new(body),
1989 })
1990 }
1991
1992 #[cfg(feature = "full")]
1993 fn expr_async(input: ParseStream) -> Result<ExprAsync> {
1994 Ok(ExprAsync {
1995 attrs: Vec::new(),
1996 async_token: input.parse()?,
1997 capture: input.parse()?,
1998 block: input.parse()?,
1999 })
2000 }
2001
2002 #[cfg(feature = "full")]
2003 fn fn_arg(input: ParseStream) -> Result<FnArg> {
2004 let pat: Pat = input.parse()?;
2005
2006 if input.peek(Token![:]) {
2007 Ok(FnArg::Captured(ArgCaptured {
2008 pat: pat,
2009 colon_token: input.parse()?,
2010 ty: input.parse()?,
2011 }))
2012 } else {
2013 Ok(FnArg::Inferred(pat))
2014 }
2015 }
2016
2017 #[cfg(feature = "full")]
2018 impl Parse for ExprWhile {
2019 fn parse(input: ParseStream) -> Result<Self> {
2020 let label: Option<Label> = input.parse()?;
2021 let while_token: Token![while] = input.parse()?;
2022 let cond = expr_no_struct(input)?;
2023
2024 let content;
2025 let brace_token = braced!(content in input);
2026 let inner_attrs = content.call(Attribute::parse_inner)?;
2027 let stmts = content.call(Block::parse_within)?;
2028
2029 Ok(ExprWhile {
2030 attrs: inner_attrs,
2031 label: label,
2032 while_token: while_token,
2033 cond: Box::new(cond),
2034 body: Block {
2035 brace_token: brace_token,
2036 stmts: stmts,
2037 },
2038 })
2039 }
2040 }
2041
2042 #[cfg(feature = "full")]
2043 impl Parse for Label {
2044 fn parse(input: ParseStream) -> Result<Self> {
2045 Ok(Label {
2046 name: input.parse()?,
2047 colon_token: input.parse()?,
2048 })
2049 }
2050 }
2051
2052 #[cfg(feature = "full")]
2053 impl Parse for Option<Label> {
2054 fn parse(input: ParseStream) -> Result<Self> {
2055 if input.peek(Lifetime) {
2056 input.parse().map(Some)
2057 } else {
2058 Ok(None)
2059 }
2060 }
2061 }
2062
2063 #[cfg(feature = "full")]
2064 fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
2065 Ok(ExprContinue {
2066 attrs: Vec::new(),
2067 continue_token: input.parse()?,
2068 label: input.parse()?,
2069 })
2070 }
2071
2072 #[cfg(feature = "full")]
2073 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2074 Ok(ExprBreak {
2075 attrs: Vec::new(),
2076 break_token: input.parse()?,
2077 label: input.parse()?,
2078 expr: {
2079 if input.is_empty()
2080 || input.peek(Token![,])
2081 || input.peek(Token![;])
2082 || !allow_struct.0 && input.peek(token::Brace)
2083 {
2084 None
2085 } else {
2086 let expr = ambiguous_expr(input, allow_struct)?;
2087 Some(Box::new(expr))
2088 }
2089 },
2090 })
2091 }
2092
2093 #[cfg(feature = "full")]
2094 fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2095 Ok(ExprReturn {
2096 attrs: Vec::new(),
2097 return_token: input.parse()?,
2098 expr: {
2099 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2100 None
2101 } else {
2102 let expr = ambiguous_expr(input, allow_struct)?;
2108 Some(Box::new(expr))
2109 }
2110 },
2111 })
2112 }
2113
2114 #[cfg(feature = "full")]
2115 impl Parse for FieldValue {
2116 fn parse(input: ParseStream) -> Result<Self> {
2117 let member: Member = input.parse()?;
2118 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2119 let colon_token: Token![:] = input.parse()?;
2120 let value: Expr = input.parse()?;
2121 (Some(colon_token), value)
2122 } else if let Member::Named(ref ident) = member {
2123 let value = Expr::Path(ExprPath {
2124 attrs: Vec::new(),
2125 qself: None,
2126 path: Path::from(ident.clone()),
2127 });
2128 (None, value)
2129 } else {
2130 unreachable!()
2131 };
2132
2133 Ok(FieldValue {
2134 attrs: Vec::new(),
2135 member: member,
2136 colon_token: colon_token,
2137 expr: value,
2138 })
2139 }
2140 }
2141
2142 #[cfg(feature = "full")]
2143 fn expr_struct_helper(
2144 input: ParseStream,
2145 outer_attrs: Vec<Attribute>,
2146 path: Path,
2147 ) -> Result<ExprStruct> {
2148 let content;
2149 let brace_token = braced!(content in input);
2150 let inner_attrs = content.call(Attribute::parse_inner)?;
2151
2152 let mut fields = Punctuated::new();
2153 loop {
2154 let attrs = content.call(Attribute::parse_outer)?;
2155 if content.fork().parse::<Member>().is_err() {
2156 if attrs.is_empty() {
2157 break;
2158 } else {
2159 return Err(content.error("expected struct field"));
2160 }
2161 }
2162
2163 fields.push(FieldValue {
2164 attrs: attrs,
2165 ..content.parse()?
2166 });
2167
2168 if !content.peek(Token![,]) {
2169 break;
2170 }
2171 let punct: Token![,] = content.parse()?;
2172 fields.push_punct(punct);
2173 }
2174
2175 let (dot2_token, rest) = if fields.empty_or_trailing() && content.peek(Token![..]) {
2176 let dot2_token: Token![..] = content.parse()?;
2177 let rest: Expr = content.parse()?;
2178 (Some(dot2_token), Some(Box::new(rest)))
2179 } else {
2180 (None, None)
2181 };
2182
2183 Ok(ExprStruct {
2184 attrs: private::attrs(outer_attrs, inner_attrs),
2185 brace_token: brace_token,
2186 path: path,
2187 fields: fields,
2188 dot2_token: dot2_token,
2189 rest: rest,
2190 })
2191 }
2192
2193 #[cfg(feature = "full")]
2194 fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
2195 let unsafe_token: Token![unsafe] = input.parse()?;
2196
2197 let content;
2198 let brace_token = braced!(content in input);
2199 let inner_attrs = content.call(Attribute::parse_inner)?;
2200 let stmts = content.call(Block::parse_within)?;
2201
2202 Ok(ExprUnsafe {
2203 attrs: inner_attrs,
2204 unsafe_token: unsafe_token,
2205 block: Block {
2206 brace_token: brace_token,
2207 stmts: stmts,
2208 },
2209 })
2210 }
2211
2212 #[cfg(feature = "full")]
2213 pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
2214 let label: Option<Label> = input.parse()?;
2215
2216 let content;
2217 let brace_token = braced!(content in input);
2218 let inner_attrs = content.call(Attribute::parse_inner)?;
2219 let stmts = content.call(Block::parse_within)?;
2220
2221 Ok(ExprBlock {
2222 attrs: inner_attrs,
2223 label: label,
2224 block: Block {
2225 brace_token: brace_token,
2226 stmts: stmts,
2227 },
2228 })
2229 }
2230
2231 #[cfg(feature = "full")]
2232 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2233 Ok(ExprRange {
2234 attrs: Vec::new(),
2235 from: None,
2236 limits: input.parse()?,
2237 to: {
2238 if input.is_empty()
2239 || input.peek(Token![,])
2240 || input.peek(Token![;])
2241 || !allow_struct.0 && input.peek(token::Brace)
2242 {
2243 None
2244 } else {
2245 let to = ambiguous_expr(input, allow_struct)?;
2246 Some(Box::new(to))
2247 }
2248 },
2249 })
2250 }
2251
2252 #[cfg(feature = "full")]
2253 impl Parse for RangeLimits {
2254 fn parse(input: ParseStream) -> Result<Self> {
2255 let lookahead = input.lookahead1();
2256 if lookahead.peek(Token![..=]) {
2257 input.parse().map(RangeLimits::Closed)
2258 } else if lookahead.peek(Token![...]) {
2259 let dot3: Token![...] = input.parse()?;
2260 Ok(RangeLimits::Closed(Token))
2261 } else if lookahead.peek(Token![..]) {
2262 input.parse().map(RangeLimits::HalfOpen)
2263 } else {
2264 Err(lookahead.error())
2265 }
2266 }
2267 }
2268
2269 impl Parse for ExprPath {
2270 fn parse(input: ParseStream) -> Result<Self> {
2271 #[cfg(not(feature = "full"))]
2272 let attrs = Vec::new();
2273 #[cfg(feature = "full")]
2274 let attrs = input.call(Attribute::parse_outer)?;
2275
2276 let (qself, path) = path::parsing::qpath(input, true)?;
2277
2278 Ok(ExprPath {
2279 attrs: attrs,
2280 qself: qself,
2281 path: path,
2282 })
2283 }
2284 }
2285
2286 #[cfg(feature = "full")]
2287 impl Parse for Block {
2288 fn parse(input: ParseStream) -> Result<Self> {
2289 let content;
2290 Ok(Block {
2291 brace_token: braced!(content in input),
2292 stmts: content.call(Block::parse_within)?,
2293 })
2294 }
2295 }
2296
2297 #[cfg(feature = "full")]
2298 impl Block {
2299 pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
2352 let mut stmts = Vec::new();
2353 loop {
2354 while input.peek(Token![;]) {
2355 input.parse::<Token![;]>()?;
2356 }
2357 if input.is_empty() {
2358 break;
2359 }
2360 let s = parse_stmt(input, true)?;
2361 let requires_semicolon = if let Stmt::Expr(ref s) = s {
2362 requires_terminator(s)
2363 } else {
2364 false
2365 };
2366 stmts.push(s);
2367 if input.is_empty() {
2368 break;
2369 } else if requires_semicolon {
2370 return Err(input.error("unexpected token"));
2371 }
2372 }
2373 Ok(stmts)
2374 }
2375 }
2376
2377 #[cfg(feature = "full")]
2378 impl Parse for Stmt {
2379 fn parse(input: ParseStream) -> Result<Self> {
2380 parse_stmt(input, false)
2381 }
2382 }
2383
2384 #[cfg(feature = "full")]
2385 fn parse_stmt(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2386 let ahead = input.fork();
2387 ahead.call(Attribute::parse_outer)?;
2388
2389 if {
2390 let ahead = ahead.fork();
2391 ahead.call(Path::parse_mod_style).is_ok()
2394 && ahead.parse::<Token![!]>().is_ok()
2395 && (ahead.peek(token::Brace) || ahead.peek(Ident))
2396 } {
2397 stmt_mac(input)
2398 } else if ahead.peek(Token![let]) {
2399 stmt_local(input).map(Stmt::Local)
2400 } else if ahead.peek(Token![pub])
2401 || ahead.peek(Token![crate]) && !ahead.peek2(Token![::])
2402 || ahead.peek(Token![extern]) && !ahead.peek2(Token![::])
2403 || ahead.peek(Token![use])
2404 || ahead.peek(Token![static]) && (ahead.peek2(Token![mut]) || ahead.peek2(Ident))
2405 || ahead.peek(Token![const])
2406 || ahead.peek(Token![unsafe]) && !ahead.peek2(token::Brace)
2407 || ahead.peek(Token![async]) && (ahead.peek2(Token![extern]) || ahead.peek2(Token![fn]))
2408 || ahead.peek(Token![fn])
2409 || ahead.peek(Token![mod])
2410 || ahead.peek(Token![type])
2411 || ahead.peek(Token![existential]) && ahead.peek2(Token![type])
2412 || ahead.peek(Token![struct])
2413 || ahead.peek(Token![enum])
2414 || ahead.peek(Token![union]) && ahead.peek2(Ident)
2415 || ahead.peek(Token![auto]) && ahead.peek2(Token![trait])
2416 || ahead.peek(Token![trait])
2417 || ahead.peek(Token![default])
2418 && (ahead.peek2(Token![unsafe]) || ahead.peek2(Token![impl]))
2419 || ahead.peek(Token![impl])
2420 || ahead.peek(Token![macro])
2421 {
2422 input.parse().map(Stmt::Item)
2423 } else {
2424 stmt_expr(input, allow_nosemi)
2425 }
2426 }
2427
2428 #[cfg(feature = "full")]
2429 fn stmt_mac(input: ParseStream) -> Result<Stmt> {
2430 let attrs = input.call(Attribute::parse_outer)?;
2431 let path = input.call(Path::parse_mod_style)?;
2432 let bang_token: Token![!] = input.parse()?;
2433 let ident: Option<Ident> = input.parse()?;
2434 let (delimiter, tts) = mac::parse_delimiter(input)?;
2435 let semi_token: Option<Token![;]> = input.parse()?;
2436
2437 Ok(Stmt::Item(Item::Macro(ItemMacro {
2438 attrs: attrs,
2439 ident: ident,
2440 mac: Macro {
2441 path: path,
2442 bang_token: bang_token,
2443 delimiter: delimiter,
2444 tts: tts,
2445 },
2446 semi_token: semi_token,
2447 })))
2448 }
2449
2450 #[cfg(feature = "full")]
2451 fn stmt_local(input: ParseStream) -> Result<Local> {
2452 Ok(Local {
2453 attrs: input.call(Attribute::parse_outer)?,
2454 let_token: input.parse()?,
2455 pats: {
2456 let mut pats = Punctuated::new();
2457 let value: Pat = input.parse()?;
2458 pats.push_value(value);
2459 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
2460 let punct = input.parse()?;
2461 pats.push_punct(punct);
2462 let value: Pat = input.parse()?;
2463 pats.push_value(value);
2464 }
2465 pats
2466 },
2467 ty: {
2468 if input.peek(Token![:]) {
2469 let colon_token: Token![:] = input.parse()?;
2470 let ty: Type = input.parse()?;
2471 Some((colon_token, Box::new(ty)))
2472 } else {
2473 None
2474 }
2475 },
2476 init: {
2477 if input.peek(Token![=]) {
2478 let eq_token: Token![=] = input.parse()?;
2479 let init: Expr = input.parse()?;
2480 Some((eq_token, Box::new(init)))
2481 } else {
2482 None
2483 }
2484 },
2485 semi_token: input.parse()?,
2486 })
2487 }
2488
2489 #[cfg(feature = "full")]
2490 fn stmt_expr(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2491 let mut attrs = input.call(Attribute::parse_outer)?;
2492 let mut e = expr_early(input)?;
2493
2494 attrs.extend(e.replace_attrs(Vec::new()));
2495 e.replace_attrs(attrs);
2496
2497 if input.peek(Token![;]) {
2498 return Ok(Stmt::Semi(e, input.parse()?));
2499 }
2500
2501 if allow_nosemi || !requires_terminator(&e) {
2502 Ok(Stmt::Expr(e))
2503 } else {
2504 Err(input.error("expected semicolon"))
2505 }
2506 }
2507
2508 #[cfg(feature = "full")]
2509 impl Parse for Pat {
2510 fn parse(input: ParseStream) -> Result<Self> {
2511 let lookahead = input.lookahead1();
2512 if lookahead.peek(Token![_]) {
2513 input.call(pat_wild).map(Pat::Wild)
2514 } else if lookahead.peek(Token![box]) {
2515 input.call(pat_box).map(Pat::Box)
2516 } else if lookahead.peek(Token![-]) || lookahead.peek(Lit) {
2517 pat_lit_or_range(input)
2518 } else if input.peek(Ident)
2519 && ({
2520 input.peek2(Token![::])
2521 || input.peek2(Token![!])
2522 || input.peek2(token::Brace)
2523 || input.peek2(token::Paren)
2524 || input.peek2(Token![..])
2525 && !{
2526 let ahead = input.fork();
2527 ahead.parse::<Ident>()?;
2528 ahead.parse::<RangeLimits>()?;
2529 ahead.is_empty() || ahead.peek(Token![,])
2530 }
2531 })
2532 || input.peek(Token![self]) && input.peek2(Token![::])
2533 || input.peek(Token![::])
2534 || input.peek(Token![<])
2535 || input.peek(Token![Self])
2536 || input.peek(Token![super])
2537 || input.peek(Token![extern])
2538 || input.peek(Token![crate])
2539 {
2540 pat_path_or_macro_or_struct_or_range(input)
2541 } else if input.peek(Token![ref])
2542 || input.peek(Token![mut])
2543 || input.peek(Token![self])
2544 || input.peek(Ident)
2545 {
2546 input.call(pat_ident).map(Pat::Ident)
2547 } else if lookahead.peek(token::Paren) {
2548 input.call(pat_tuple).map(Pat::Tuple)
2549 } else if lookahead.peek(Token![&]) {
2550 input.call(pat_ref).map(Pat::Ref)
2551 } else if lookahead.peek(token::Bracket) {
2552 input.call(pat_slice).map(Pat::Slice)
2553 } else {
2554 Err(lookahead.error())
2555 }
2556 }
2557 }
2558
2559 #[cfg(feature = "full")]
2560 fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
2561 let (qself, path) = path::parsing::qpath(input, true)?;
2562
2563 if input.peek(Token![..]) {
2564 return pat_range(input, qself, path).map(Pat::Range);
2565 }
2566
2567 if qself.is_some() {
2568 return Ok(Pat::Path(PatPath {
2569 qself: qself,
2570 path: path,
2571 }));
2572 }
2573
2574 if input.peek(Token![!]) && !input.peek(Token![!=]) {
2575 let mut contains_arguments = false;
2576 for segment in &path.segments {
2577 match segment.arguments {
2578 PathArguments::None => {}
2579 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
2580 contains_arguments = true;
2581 }
2582 }
2583 }
2584
2585 if !contains_arguments {
2586 let bang_token: Token![!] = input.parse()?;
2587 let (delimiter, tts) = mac::parse_delimiter(input)?;
2588 return Ok(Pat::Macro(PatMacro {
2589 mac: Macro {
2590 path: path,
2591 bang_token: bang_token,
2592 delimiter: delimiter,
2593 tts: tts,
2594 },
2595 }));
2596 }
2597 }
2598
2599 if input.peek(token::Brace) {
2600 pat_struct(input, path).map(Pat::Struct)
2601 } else if input.peek(token::Paren) {
2602 pat_tuple_struct(input, path).map(Pat::TupleStruct)
2603 } else if input.peek(Token![..]) {
2604 pat_range(input, qself, path).map(Pat::Range)
2605 } else {
2606 Ok(Pat::Path(PatPath {
2607 qself: qself,
2608 path: path,
2609 }))
2610 }
2611 }
2612
2613 #[cfg(feature = "full")]
2614 fn pat_wild(input: ParseStream) -> Result<PatWild> {
2615 Ok(PatWild {
2616 underscore_token: input.parse()?,
2617 })
2618 }
2619
2620 #[cfg(feature = "full")]
2621 fn pat_box(input: ParseStream) -> Result<PatBox> {
2622 Ok(PatBox {
2623 box_token: input.parse()?,
2624 pat: input.parse()?,
2625 })
2626 }
2627
2628 #[cfg(feature = "full")]
2629 fn pat_ident(input: ParseStream) -> Result<PatIdent> {
2630 Ok(PatIdent {
2631 by_ref: input.parse()?,
2632 mutability: input.parse()?,
2633 ident: input.call(Ident::parse_any)?,
2634 subpat: {
2635 if input.peek(Token![@]) {
2636 let at_token: Token![@] = input.parse()?;
2637 let subpat: Pat = input.parse()?;
2638 Some((at_token, Box::new(subpat)))
2639 } else {
2640 None
2641 }
2642 },
2643 })
2644 }
2645
2646 #[cfg(feature = "full")]
2647 fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
2648 Ok(PatTupleStruct {
2649 path: path,
2650 pat: input.call(pat_tuple)?,
2651 })
2652 }
2653
2654 #[cfg(feature = "full")]
2655 fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
2656 let content;
2657 let brace_token = braced!(content in input);
2658
2659 let mut fields = Punctuated::new();
2660 while !content.is_empty() && !content.peek(Token![..]) {
2661 let value = content.call(field_pat)?;
2662 fields.push_value(value);
2663 if !content.peek(Token![,]) {
2664 break;
2665 }
2666 let punct: Token![,] = content.parse()?;
2667 fields.push_punct(punct);
2668 }
2669
2670 let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
2671 Some(content.parse()?)
2672 } else {
2673 None
2674 };
2675
2676 Ok(PatStruct {
2677 path: path,
2678 brace_token: brace_token,
2679 fields: fields,
2680 dot2_token: dot2_token,
2681 })
2682 }
2683
2684 #[cfg(feature = "full")]
2685 fn field_pat(input: ParseStream) -> Result<FieldPat> {
2686 let boxed: Option<Token![box]> = input.parse()?;
2687 let by_ref: Option<Token![ref]> = input.parse()?;
2688 let mutability: Option<Token![mut]> = input.parse()?;
2689 let member: Member = input.parse()?;
2690
2691 if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
2692 || member.is_unnamed()
2693 {
2694 return Ok(FieldPat {
2695 attrs: Vec::new(),
2696 member: member,
2697 colon_token: input.parse()?,
2698 pat: input.parse()?,
2699 });
2700 }
2701
2702 let ident = match member {
2703 Member::Named(ident) => ident,
2704 Member::Unnamed(_) => unreachable!(),
2705 };
2706
2707 let mut pat = Pat::Ident(PatIdent {
2708 by_ref: by_ref,
2709 mutability: mutability,
2710 ident: ident.clone(),
2711 subpat: None,
2712 });
2713
2714 if let Some(boxed) = boxed {
2715 pat = Pat::Box(PatBox {
2716 pat: Box::new(pat),
2717 box_token: boxed,
2718 });
2719 }
2720
2721 Ok(FieldPat {
2722 member: Member::Named(ident),
2723 pat: Box::new(pat),
2724 attrs: Vec::new(),
2725 colon_token: None,
2726 })
2727 }
2728
2729 impl Parse for Member {
2730 fn parse(input: ParseStream) -> Result<Self> {
2731 if input.peek(Ident) {
2732 input.parse().map(Member::Named)
2733 } else if input.peek(LitInt) {
2734 input.parse().map(Member::Unnamed)
2735 } else {
2736 Err(input.error("expected identifier or integer"))
2737 }
2738 }
2739 }
2740
2741 #[cfg(feature = "full")]
2742 impl Parse for Arm {
2743 fn parse(input: ParseStream) -> Result<Arm> {
2744 let requires_comma;
2745 Ok(Arm {
2746 attrs: input.call(Attribute::parse_outer)?,
2747 leading_vert: input.parse()?,
2748 pats: {
2749 let mut pats = Punctuated::new();
2750 let value: Pat = input.parse()?;
2751 pats.push_value(value);
2752 loop {
2753 if !input.peek(Token![|]) {
2754 break;
2755 }
2756 let punct = input.parse()?;
2757 pats.push_punct(punct);
2758 let value: Pat = input.parse()?;
2759 pats.push_value(value);
2760 }
2761 pats
2762 },
2763 guard: {
2764 if input.peek(Token![if]) {
2765 let if_token: Token![if] = input.parse()?;
2766 let guard: Expr = input.parse()?;
2767 Some((if_token, Box::new(guard)))
2768 } else {
2769 None
2770 }
2771 },
2772 fat_arrow_token: input.parse()?,
2773 body: {
2774 let body = input.call(expr_early)?;
2775 requires_comma = requires_terminator(&body);
2776 Box::new(body)
2777 },
2778 comma: {
2779 if requires_comma && !input.is_empty() {
2780 Some(input.parse()?)
2781 } else {
2782 input.parse()?
2783 }
2784 },
2785 })
2786 }
2787 }
2788
2789 impl Parse for Index {
2790 fn parse(input: ParseStream) -> Result<Self> {
2791 let lit: LitInt = input.parse()?;
2792 if let IntSuffix::None = lit.suffix() {
2793 Ok(Index {
2794 index: lit.value() as u32,
2795 span: lit.span(),
2796 })
2797 } else {
2798 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2799 }
2800 }
2801 }
2802
2803 #[cfg(feature = "full")]
2804 fn pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatRange> {
2805 Ok(PatRange {
2806 lo: Box::new(Expr::Path(ExprPath {
2807 attrs: Vec::new(),
2808 qself: qself,
2809 path: path,
2810 })),
2811 limits: input.parse()?,
2812 hi: input.call(pat_lit_expr)?,
2813 })
2814 }
2815
2816 #[cfg(feature = "full")]
2817 fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
2818 let content;
2819 let paren_token = parenthesized!(content in input);
2820
2821 let mut front = Punctuated::new();
2822 let mut dot2_token = None::<Token![..]>;
2823 let mut comma_token = None::<Token![,]>;
2824 loop {
2825 if content.is_empty() {
2826 break;
2827 }
2828 if content.peek(Token![..]) {
2829 dot2_token = Some(content.parse()?);
2830 comma_token = content.parse()?;
2831 break;
2832 }
2833 let value: Pat = content.parse()?;
2834 front.push_value(value);
2835 if content.is_empty() {
2836 break;
2837 }
2838 let punct = content.parse()?;
2839 front.push_punct(punct);
2840 }
2841
2842 let mut back = Punctuated::new();
2843 while !content.is_empty() {
2844 let value: Pat = content.parse()?;
2845 back.push_value(value);
2846 if content.is_empty() {
2847 break;
2848 }
2849 let punct = content.parse()?;
2850 back.push_punct(punct);
2851 }
2852
2853 Ok(PatTuple {
2854 paren_token: paren_token,
2855 front: front,
2856 dot2_token: dot2_token,
2857 comma_token: comma_token,
2858 back: back,
2859 })
2860 }
2861
2862 #[cfg(feature = "full")]
2863 fn pat_ref(input: ParseStream) -> Result<PatRef> {
2864 Ok(PatRef {
2865 and_token: input.parse()?,
2866 mutability: input.parse()?,
2867 pat: input.parse()?,
2868 })
2869 }
2870
2871 #[cfg(feature = "full")]
2872 fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
2873 let lo = input.call(pat_lit_expr)?;
2874 if input.peek(Token![..]) {
2875 Ok(Pat::Range(PatRange {
2876 lo: lo,
2877 limits: input.parse()?,
2878 hi: input.call(pat_lit_expr)?,
2879 }))
2880 } else {
2881 Ok(Pat::Lit(PatLit { expr: lo }))
2882 }
2883 }
2884
2885 #[cfg(feature = "full")]
2886 fn pat_lit_expr(input: ParseStream) -> Result<Box<Expr>> {
2887 let neg: Option<Token![-]> = input.parse()?;
2888
2889 let lookahead = input.lookahead1();
2890 let expr = if lookahead.peek(Lit) {
2891 Expr::Lit(input.parse()?)
2892 } else if lookahead.peek(Ident)
2893 || lookahead.peek(Token![::])
2894 || lookahead.peek(Token![<])
2895 || lookahead.peek(Token![self])
2896 || lookahead.peek(Token![Self])
2897 || lookahead.peek(Token![super])
2898 || lookahead.peek(Token![extern])
2899 || lookahead.peek(Token![crate])
2900 {
2901 Expr::Path(input.parse()?)
2902 } else {
2903 return Err(lookahead.error());
2904 };
2905
2906 Ok(Box::new(if let Some(neg) = neg {
2907 Expr::Unary(ExprUnary {
2908 attrs: Vec::new(),
2909 op: UnOp::Neg(neg),
2910 expr: Box::new(expr),
2911 })
2912 } else {
2913 expr
2914 }))
2915 }
2916
2917 #[cfg(feature = "full")]
2918 fn pat_slice(input: ParseStream) -> Result<PatSlice> {
2919 let content;
2920 let bracket_token = bracketed!(content in input);
2921
2922 let mut front = Punctuated::new();
2923 let mut middle = None;
2924 loop {
2925 if content.is_empty() || content.peek(Token![..]) {
2926 break;
2927 }
2928 let value: Pat = content.parse()?;
2929 if content.peek(Token![..]) {
2930 middle = Some(Box::new(value));
2931 break;
2932 }
2933 front.push_value(value);
2934 if content.is_empty() {
2935 break;
2936 }
2937 let punct = content.parse()?;
2938 front.push_punct(punct);
2939 }
2940
2941 let dot2_token: Option<Token![..]> = content.parse()?;
2942 let mut comma_token = None::<Token![,]>;
2943 let mut back = Punctuated::new();
2944 if dot2_token.is_some() {
2945 comma_token = content.parse()?;
2946 if comma_token.is_some() {
2947 loop {
2948 if content.is_empty() {
2949 break;
2950 }
2951 let value: Pat = content.parse()?;
2952 back.push_value(value);
2953 if content.is_empty() {
2954 break;
2955 }
2956 let punct = content.parse()?;
2957 back.push_punct(punct);
2958 }
2959 }
2960 }
2961
2962 Ok(PatSlice {
2963 bracket_token: bracket_token,
2964 front: front,
2965 middle: middle,
2966 dot2_token: dot2_token,
2967 comma_token: comma_token,
2968 back: back,
2969 })
2970 }
2971
2972 #[cfg(feature = "full")]
2973 impl Member {
2974 fn is_named(&self) -> bool {
2975 match *self {
2976 Member::Named(_) => true,
2977 Member::Unnamed(_) => false,
2978 }
2979 }
2980
2981 fn is_unnamed(&self) -> bool {
2982 match *self {
2983 Member::Named(_) => false,
2984 Member::Unnamed(_) => true,
2985 }
2986 }
2987 }
2988}
2989
2990#[cfg(feature = "printing")]
2991mod printing {
2992 use super::*;
2993
2994 use proc_macro2::{Literal, TokenStream};
2995 use quote::{ToTokens, TokenStreamExt};
2996
2997 #[cfg(feature = "full")]
2998 use attr::FilterAttrs;
2999 #[cfg(feature = "full")]
3000 use print::TokensOrDefault;
3001
3002 #[cfg(feature = "full")]
3005 fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
3006 if let Expr::Struct(_) = *e {
3007 token::Paren::default().surround(tokens, |tokens| {
3008 e.to_tokens(tokens);
3009 });
3010 } else {
3011 e.to_tokens(tokens);
3012 }
3013 }
3014
3015 #[cfg(feature = "full")]
3016 fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3017 tokens.append_all(attrs.outer());
3018 }
3019
3020 #[cfg(feature = "full")]
3021 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3022 tokens.append_all(attrs.inner());
3023 }
3024
3025 #[cfg(not(feature = "full"))]
3026 fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3027
3028 #[cfg(not(feature = "full"))]
3029 fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3030
3031 #[cfg(feature = "full")]
3032 impl ToTokens for ExprBox {
3033 fn to_tokens(&self, tokens: &mut TokenStream) {
3034 outer_attrs_to_tokens(&self.attrs, tokens);
3035 self.box_token.to_tokens(tokens);
3036 self.expr.to_tokens(tokens);
3037 }
3038 }
3039
3040 #[cfg(feature = "full")]
3041 impl ToTokens for ExprInPlace {
3042 fn to_tokens(&self, tokens: &mut TokenStream) {
3043 outer_attrs_to_tokens(&self.attrs, tokens);
3044 self.place.to_tokens(tokens);
3045 self.arrow_token.to_tokens(tokens);
3046 self.value.to_tokens(tokens);
3047 }
3048 }
3049
3050 #[cfg(feature = "full")]
3051 impl ToTokens for ExprArray {
3052 fn to_tokens(&self, tokens: &mut TokenStream) {
3053 outer_attrs_to_tokens(&self.attrs, tokens);
3054 self.bracket_token.surround(tokens, |tokens| {
3055 inner_attrs_to_tokens(&self.attrs, tokens);
3056 self.elems.to_tokens(tokens);
3057 })
3058 }
3059 }
3060
3061 impl ToTokens for ExprCall {
3062 fn to_tokens(&self, tokens: &mut TokenStream) {
3063 outer_attrs_to_tokens(&self.attrs, tokens);
3064 self.func.to_tokens(tokens);
3065 self.paren_token.surround(tokens, |tokens| {
3066 self.args.to_tokens(tokens);
3067 })
3068 }
3069 }
3070
3071 #[cfg(feature = "full")]
3072 impl ToTokens for ExprMethodCall {
3073 fn to_tokens(&self, tokens: &mut TokenStream) {
3074 outer_attrs_to_tokens(&self.attrs, tokens);
3075 self.receiver.to_tokens(tokens);
3076 self.dot_token.to_tokens(tokens);
3077 self.method.to_tokens(tokens);
3078 self.turbofish.to_tokens(tokens);
3079 self.paren_token.surround(tokens, |tokens| {
3080 self.args.to_tokens(tokens);
3081 });
3082 }
3083 }
3084
3085 #[cfg(feature = "full")]
3086 impl ToTokens for MethodTurbofish {
3087 fn to_tokens(&self, tokens: &mut TokenStream) {
3088 self.colon2_token.to_tokens(tokens);
3089 self.lt_token.to_tokens(tokens);
3090 self.args.to_tokens(tokens);
3091 self.gt_token.to_tokens(tokens);
3092 }
3093 }
3094
3095 #[cfg(feature = "full")]
3096 impl ToTokens for GenericMethodArgument {
3097 fn to_tokens(&self, tokens: &mut TokenStream) {
3098 match *self {
3099 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
3100 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
3101 }
3102 }
3103 }
3104
3105 #[cfg(feature = "full")]
3106 impl ToTokens for ExprTuple {
3107 fn to_tokens(&self, tokens: &mut TokenStream) {
3108 outer_attrs_to_tokens(&self.attrs, tokens);
3109 self.paren_token.surround(tokens, |tokens| {
3110 inner_attrs_to_tokens(&self.attrs, tokens);
3111 self.elems.to_tokens(tokens);
3112 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3115 <Token![,]>::default().to_tokens(tokens);
3116 }
3117 })
3118 }
3119 }
3120
3121 impl ToTokens for ExprBinary {
3122 fn to_tokens(&self, tokens: &mut TokenStream) {
3123 outer_attrs_to_tokens(&self.attrs, tokens);
3124 self.left.to_tokens(tokens);
3125 self.op.to_tokens(tokens);
3126 self.right.to_tokens(tokens);
3127 }
3128 }
3129
3130 impl ToTokens for ExprUnary {
3131 fn to_tokens(&self, tokens: &mut TokenStream) {
3132 outer_attrs_to_tokens(&self.attrs, tokens);
3133 self.op.to_tokens(tokens);
3134 self.expr.to_tokens(tokens);
3135 }
3136 }
3137
3138 impl ToTokens for ExprLit {
3139 fn to_tokens(&self, tokens: &mut TokenStream) {
3140 outer_attrs_to_tokens(&self.attrs, tokens);
3141 self.lit.to_tokens(tokens);
3142 }
3143 }
3144
3145 impl ToTokens for ExprCast {
3146 fn to_tokens(&self, tokens: &mut TokenStream) {
3147 outer_attrs_to_tokens(&self.attrs, tokens);
3148 self.expr.to_tokens(tokens);
3149 self.as_token.to_tokens(tokens);
3150 self.ty.to_tokens(tokens);
3151 }
3152 }
3153
3154 #[cfg(feature = "full")]
3155 impl ToTokens for ExprType {
3156 fn to_tokens(&self, tokens: &mut TokenStream) {
3157 outer_attrs_to_tokens(&self.attrs, tokens);
3158 self.expr.to_tokens(tokens);
3159 self.colon_token.to_tokens(tokens);
3160 self.ty.to_tokens(tokens);
3161 }
3162 }
3163
3164 #[cfg(feature = "full")]
3165 fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
3166 if let Some((ref else_token, ref else_)) = *else_ {
3167 else_token.to_tokens(tokens);
3168
3169 match **else_ {
3172 Expr::If(_) | Expr::Block(_) => {
3173 else_.to_tokens(tokens);
3174 }
3175 _ => {
3176 token::Brace::default().surround(tokens, |tokens| {
3177 else_.to_tokens(tokens);
3178 });
3179 }
3180 }
3181 }
3182 }
3183
3184 #[cfg(feature = "full")]
3185 impl ToTokens for ExprLet {
3186 fn to_tokens(&self, tokens: &mut TokenStream) {
3187 outer_attrs_to_tokens(&self.attrs, tokens);
3188 self.let_token.to_tokens(tokens);
3189 self.pats.to_tokens(tokens);
3190 self.eq_token.to_tokens(tokens);
3191 wrap_bare_struct(tokens, &self.expr);
3192 }
3193 }
3194
3195 #[cfg(feature = "full")]
3196 impl ToTokens for ExprIf {
3197 fn to_tokens(&self, tokens: &mut TokenStream) {
3198 outer_attrs_to_tokens(&self.attrs, tokens);
3199 self.if_token.to_tokens(tokens);
3200 wrap_bare_struct(tokens, &self.cond);
3201 self.then_branch.to_tokens(tokens);
3202 maybe_wrap_else(tokens, &self.else_branch);
3203 }
3204 }
3205
3206 #[cfg(feature = "full")]
3207 impl ToTokens for ExprWhile {
3208 fn to_tokens(&self, tokens: &mut TokenStream) {
3209 outer_attrs_to_tokens(&self.attrs, tokens);
3210 self.label.to_tokens(tokens);
3211 self.while_token.to_tokens(tokens);
3212 wrap_bare_struct(tokens, &self.cond);
3213 self.body.brace_token.surround(tokens, |tokens| {
3214 inner_attrs_to_tokens(&self.attrs, tokens);
3215 tokens.append_all(&self.body.stmts);
3216 });
3217 }
3218 }
3219
3220 #[cfg(feature = "full")]
3221 impl ToTokens for ExprForLoop {
3222 fn to_tokens(&self, tokens: &mut TokenStream) {
3223 outer_attrs_to_tokens(&self.attrs, tokens);
3224 self.label.to_tokens(tokens);
3225 self.for_token.to_tokens(tokens);
3226 self.pat.to_tokens(tokens);
3227 self.in_token.to_tokens(tokens);
3228 wrap_bare_struct(tokens, &self.expr);
3229 self.body.brace_token.surround(tokens, |tokens| {
3230 inner_attrs_to_tokens(&self.attrs, tokens);
3231 tokens.append_all(&self.body.stmts);
3232 });
3233 }
3234 }
3235
3236 #[cfg(feature = "full")]
3237 impl ToTokens for ExprLoop {
3238 fn to_tokens(&self, tokens: &mut TokenStream) {
3239 outer_attrs_to_tokens(&self.attrs, tokens);
3240 self.label.to_tokens(tokens);
3241 self.loop_token.to_tokens(tokens);
3242 self.body.brace_token.surround(tokens, |tokens| {
3243 inner_attrs_to_tokens(&self.attrs, tokens);
3244 tokens.append_all(&self.body.stmts);
3245 });
3246 }
3247 }
3248
3249 #[cfg(feature = "full")]
3250 impl ToTokens for ExprMatch {
3251 fn to_tokens(&self, tokens: &mut TokenStream) {
3252 outer_attrs_to_tokens(&self.attrs, tokens);
3253 self.match_token.to_tokens(tokens);
3254 wrap_bare_struct(tokens, &self.expr);
3255 self.brace_token.surround(tokens, |tokens| {
3256 inner_attrs_to_tokens(&self.attrs, tokens);
3257 for (i, arm) in self.arms.iter().enumerate() {
3258 arm.to_tokens(tokens);
3259 let is_last = i == self.arms.len() - 1;
3262 if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3263 <Token![,]>::default().to_tokens(tokens);
3264 }
3265 }
3266 });
3267 }
3268 }
3269
3270 #[cfg(feature = "full")]
3271 impl ToTokens for ExprAsync {
3272 fn to_tokens(&self, tokens: &mut TokenStream) {
3273 outer_attrs_to_tokens(&self.attrs, tokens);
3274 self.async_token.to_tokens(tokens);
3275 self.capture.to_tokens(tokens);
3276 self.block.to_tokens(tokens);
3277 }
3278 }
3279
3280 #[cfg(feature = "full")]
3281 impl ToTokens for ExprTryBlock {
3282 fn to_tokens(&self, tokens: &mut TokenStream) {
3283 outer_attrs_to_tokens(&self.attrs, tokens);
3284 self.try_token.to_tokens(tokens);
3285 self.block.to_tokens(tokens);
3286 }
3287 }
3288
3289 #[cfg(feature = "full")]
3290 impl ToTokens for ExprYield {
3291 fn to_tokens(&self, tokens: &mut TokenStream) {
3292 outer_attrs_to_tokens(&self.attrs, tokens);
3293 self.yield_token.to_tokens(tokens);
3294 self.expr.to_tokens(tokens);
3295 }
3296 }
3297
3298 #[cfg(feature = "full")]
3299 impl ToTokens for ExprClosure {
3300 fn to_tokens(&self, tokens: &mut TokenStream) {
3301 outer_attrs_to_tokens(&self.attrs, tokens);
3302 self.asyncness.to_tokens(tokens);
3303 self.movability.to_tokens(tokens);
3304 self.capture.to_tokens(tokens);
3305 self.or1_token.to_tokens(tokens);
3306 for input in self.inputs.pairs() {
3307 match **input.value() {
3308 FnArg::Captured(ArgCaptured {
3309 ref pat,
3310 ty: Type::Infer(_),
3311 ..
3312 }) => {
3313 pat.to_tokens(tokens);
3314 }
3315 _ => input.value().to_tokens(tokens),
3316 }
3317 input.punct().to_tokens(tokens);
3318 }
3319 self.or2_token.to_tokens(tokens);
3320 self.output.to_tokens(tokens);
3321 self.body.to_tokens(tokens);
3322 }
3323 }
3324
3325 #[cfg(feature = "full")]
3326 impl ToTokens for ExprUnsafe {
3327 fn to_tokens(&self, tokens: &mut TokenStream) {
3328 outer_attrs_to_tokens(&self.attrs, tokens);
3329 self.unsafe_token.to_tokens(tokens);
3330 self.block.brace_token.surround(tokens, |tokens| {
3331 inner_attrs_to_tokens(&self.attrs, tokens);
3332 tokens.append_all(&self.block.stmts);
3333 });
3334 }
3335 }
3336
3337 #[cfg(feature = "full")]
3338 impl ToTokens for ExprBlock {
3339 fn to_tokens(&self, tokens: &mut TokenStream) {
3340 outer_attrs_to_tokens(&self.attrs, tokens);
3341 self.label.to_tokens(tokens);
3342 self.block.brace_token.surround(tokens, |tokens| {
3343 inner_attrs_to_tokens(&self.attrs, tokens);
3344 tokens.append_all(&self.block.stmts);
3345 });
3346 }
3347 }
3348
3349 #[cfg(feature = "full")]
3350 impl ToTokens for ExprAssign {
3351 fn to_tokens(&self, tokens: &mut TokenStream) {
3352 outer_attrs_to_tokens(&self.attrs, tokens);
3353 self.left.to_tokens(tokens);
3354 self.eq_token.to_tokens(tokens);
3355 self.right.to_tokens(tokens);
3356 }
3357 }
3358
3359 #[cfg(feature = "full")]
3360 impl ToTokens for ExprAssignOp {
3361 fn to_tokens(&self, tokens: &mut TokenStream) {
3362 outer_attrs_to_tokens(&self.attrs, tokens);
3363 self.left.to_tokens(tokens);
3364 self.op.to_tokens(tokens);
3365 self.right.to_tokens(tokens);
3366 }
3367 }
3368
3369 impl ToTokens for ExprField {
3370 fn to_tokens(&self, tokens: &mut TokenStream) {
3371 outer_attrs_to_tokens(&self.attrs, tokens);
3372 self.base.to_tokens(tokens);
3373 self.dot_token.to_tokens(tokens);
3374 self.member.to_tokens(tokens);
3375 }
3376 }
3377
3378 impl ToTokens for Member {
3379 fn to_tokens(&self, tokens: &mut TokenStream) {
3380 match *self {
3381 Member::Named(ref ident) => ident.to_tokens(tokens),
3382 Member::Unnamed(ref index) => index.to_tokens(tokens),
3383 }
3384 }
3385 }
3386
3387 impl ToTokens for Index {
3388 fn to_tokens(&self, tokens: &mut TokenStream) {
3389 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3390 lit.set_span(self.span);
3391 tokens.append(lit);
3392 }
3393 }
3394
3395 impl ToTokens for ExprIndex {
3396 fn to_tokens(&self, tokens: &mut TokenStream) {
3397 outer_attrs_to_tokens(&self.attrs, tokens);
3398 self.expr.to_tokens(tokens);
3399 self.bracket_token.surround(tokens, |tokens| {
3400 self.index.to_tokens(tokens);
3401 });
3402 }
3403 }
3404
3405 #[cfg(feature = "full")]
3406 impl ToTokens for ExprRange {
3407 fn to_tokens(&self, tokens: &mut TokenStream) {
3408 outer_attrs_to_tokens(&self.attrs, tokens);
3409 self.from.to_tokens(tokens);
3410 match self.limits {
3411 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3412 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
3413 }
3414 self.to.to_tokens(tokens);
3415 }
3416 }
3417
3418 impl ToTokens for ExprPath {
3419 fn to_tokens(&self, tokens: &mut TokenStream) {
3420 outer_attrs_to_tokens(&self.attrs, tokens);
3421 private::print_path(tokens, &self.qself, &self.path);
3422 }
3423 }
3424
3425 #[cfg(feature = "full")]
3426 impl ToTokens for ExprReference {
3427 fn to_tokens(&self, tokens: &mut TokenStream) {
3428 outer_attrs_to_tokens(&self.attrs, tokens);
3429 self.and_token.to_tokens(tokens);
3430 self.mutability.to_tokens(tokens);
3431 self.expr.to_tokens(tokens);
3432 }
3433 }
3434
3435 #[cfg(feature = "full")]
3436 impl ToTokens for ExprBreak {
3437 fn to_tokens(&self, tokens: &mut TokenStream) {
3438 outer_attrs_to_tokens(&self.attrs, tokens);
3439 self.break_token.to_tokens(tokens);
3440 self.label.to_tokens(tokens);
3441 self.expr.to_tokens(tokens);
3442 }
3443 }
3444
3445 #[cfg(feature = "full")]
3446 impl ToTokens for ExprContinue {
3447 fn to_tokens(&self, tokens: &mut TokenStream) {
3448 outer_attrs_to_tokens(&self.attrs, tokens);
3449 self.continue_token.to_tokens(tokens);
3450 self.label.to_tokens(tokens);
3451 }
3452 }
3453
3454 #[cfg(feature = "full")]
3455 impl ToTokens for ExprReturn {
3456 fn to_tokens(&self, tokens: &mut TokenStream) {
3457 outer_attrs_to_tokens(&self.attrs, tokens);
3458 self.return_token.to_tokens(tokens);
3459 self.expr.to_tokens(tokens);
3460 }
3461 }
3462
3463 #[cfg(feature = "full")]
3464 impl ToTokens for ExprMacro {
3465 fn to_tokens(&self, tokens: &mut TokenStream) {
3466 outer_attrs_to_tokens(&self.attrs, tokens);
3467 self.mac.to_tokens(tokens);
3468 }
3469 }
3470
3471 #[cfg(feature = "full")]
3472 impl ToTokens for ExprStruct {
3473 fn to_tokens(&self, tokens: &mut TokenStream) {
3474 outer_attrs_to_tokens(&self.attrs, tokens);
3475 self.path.to_tokens(tokens);
3476 self.brace_token.surround(tokens, |tokens| {
3477 inner_attrs_to_tokens(&self.attrs, tokens);
3478 self.fields.to_tokens(tokens);
3479 if self.rest.is_some() {
3480 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3481 self.rest.to_tokens(tokens);
3482 }
3483 })
3484 }
3485 }
3486
3487 #[cfg(feature = "full")]
3488 impl ToTokens for ExprRepeat {
3489 fn to_tokens(&self, tokens: &mut TokenStream) {
3490 outer_attrs_to_tokens(&self.attrs, tokens);
3491 self.bracket_token.surround(tokens, |tokens| {
3492 inner_attrs_to_tokens(&self.attrs, tokens);
3493 self.expr.to_tokens(tokens);
3494 self.semi_token.to_tokens(tokens);
3495 self.len.to_tokens(tokens);
3496 })
3497 }
3498 }
3499
3500 #[cfg(feature = "full")]
3501 impl ToTokens for ExprGroup {
3502 fn to_tokens(&self, tokens: &mut TokenStream) {
3503 outer_attrs_to_tokens(&self.attrs, tokens);
3504 self.group_token.surround(tokens, |tokens| {
3505 self.expr.to_tokens(tokens);
3506 });
3507 }
3508 }
3509
3510 impl ToTokens for ExprParen {
3511 fn to_tokens(&self, tokens: &mut TokenStream) {
3512 outer_attrs_to_tokens(&self.attrs, tokens);
3513 self.paren_token.surround(tokens, |tokens| {
3514 inner_attrs_to_tokens(&self.attrs, tokens);
3515 self.expr.to_tokens(tokens);
3516 });
3517 }
3518 }
3519
3520 #[cfg(feature = "full")]
3521 impl ToTokens for ExprTry {
3522 fn to_tokens(&self, tokens: &mut TokenStream) {
3523 outer_attrs_to_tokens(&self.attrs, tokens);
3524 self.expr.to_tokens(tokens);
3525 self.question_token.to_tokens(tokens);
3526 }
3527 }
3528
3529 impl ToTokens for ExprVerbatim {
3530 fn to_tokens(&self, tokens: &mut TokenStream) {
3531 self.tts.to_tokens(tokens);
3532 }
3533 }
3534
3535 #[cfg(feature = "full")]
3536 impl ToTokens for Label {
3537 fn to_tokens(&self, tokens: &mut TokenStream) {
3538 self.name.to_tokens(tokens);
3539 self.colon_token.to_tokens(tokens);
3540 }
3541 }
3542
3543 #[cfg(feature = "full")]
3544 impl ToTokens for FieldValue {
3545 fn to_tokens(&self, tokens: &mut TokenStream) {
3546 outer_attrs_to_tokens(&self.attrs, tokens);
3547 self.member.to_tokens(tokens);
3548 if let Some(ref colon_token) = self.colon_token {
3549 colon_token.to_tokens(tokens);
3550 self.expr.to_tokens(tokens);
3551 }
3552 }
3553 }
3554
3555 #[cfg(feature = "full")]
3556 impl ToTokens for Arm {
3557 fn to_tokens(&self, tokens: &mut TokenStream) {
3558 tokens.append_all(&self.attrs);
3559 self.leading_vert.to_tokens(tokens);
3560 self.pats.to_tokens(tokens);
3561 if let Some((ref if_token, ref guard)) = self.guard {
3562 if_token.to_tokens(tokens);
3563 guard.to_tokens(tokens);
3564 }
3565 self.fat_arrow_token.to_tokens(tokens);
3566 self.body.to_tokens(tokens);
3567 self.comma.to_tokens(tokens);
3568 }
3569 }
3570
3571 #[cfg(feature = "full")]
3572 impl ToTokens for PatWild {
3573 fn to_tokens(&self, tokens: &mut TokenStream) {
3574 self.underscore_token.to_tokens(tokens);
3575 }
3576 }
3577
3578 #[cfg(feature = "full")]
3579 impl ToTokens for PatIdent {
3580 fn to_tokens(&self, tokens: &mut TokenStream) {
3581 self.by_ref.to_tokens(tokens);
3582 self.mutability.to_tokens(tokens);
3583 self.ident.to_tokens(tokens);
3584 if let Some((ref at_token, ref subpat)) = self.subpat {
3585 at_token.to_tokens(tokens);
3586 subpat.to_tokens(tokens);
3587 }
3588 }
3589 }
3590
3591 #[cfg(feature = "full")]
3592 impl ToTokens for PatStruct {
3593 fn to_tokens(&self, tokens: &mut TokenStream) {
3594 self.path.to_tokens(tokens);
3595 self.brace_token.surround(tokens, |tokens| {
3596 self.fields.to_tokens(tokens);
3597 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
3599 <Token![,]>::default().to_tokens(tokens);
3600 }
3601 self.dot2_token.to_tokens(tokens);
3602 });
3603 }
3604 }
3605
3606 #[cfg(feature = "full")]
3607 impl ToTokens for PatTupleStruct {
3608 fn to_tokens(&self, tokens: &mut TokenStream) {
3609 self.path.to_tokens(tokens);
3610 self.pat.to_tokens(tokens);
3611 }
3612 }
3613
3614 #[cfg(feature = "full")]
3615 impl ToTokens for PatPath {
3616 fn to_tokens(&self, tokens: &mut TokenStream) {
3617 private::print_path(tokens, &self.qself, &self.path);
3618 }
3619 }
3620
3621 #[cfg(feature = "full")]
3622 impl ToTokens for PatTuple {
3623 fn to_tokens(&self, tokens: &mut TokenStream) {
3624 self.paren_token.surround(tokens, |tokens| {
3625 self.front.to_tokens(tokens);
3626 if let Some(ref dot2_token) = self.dot2_token {
3627 if !self.front.empty_or_trailing() {
3628 <Token![,]>::default().to_tokens(tokens);
3630 }
3631 dot2_token.to_tokens(tokens);
3632 self.comma_token.to_tokens(tokens);
3633 if self.comma_token.is_none() && !self.back.is_empty() {
3634 <Token![,]>::default().to_tokens(tokens);
3636 }
3637 }
3638 self.back.to_tokens(tokens);
3639 });
3640 }
3641 }
3642
3643 #[cfg(feature = "full")]
3644 impl ToTokens for PatBox {
3645 fn to_tokens(&self, tokens: &mut TokenStream) {
3646 self.box_token.to_tokens(tokens);
3647 self.pat.to_tokens(tokens);
3648 }
3649 }
3650
3651 #[cfg(feature = "full")]
3652 impl ToTokens for PatRef {
3653 fn to_tokens(&self, tokens: &mut TokenStream) {
3654 self.and_token.to_tokens(tokens);
3655 self.mutability.to_tokens(tokens);
3656 self.pat.to_tokens(tokens);
3657 }
3658 }
3659
3660 #[cfg(feature = "full")]
3661 impl ToTokens for PatLit {
3662 fn to_tokens(&self, tokens: &mut TokenStream) {
3663 self.expr.to_tokens(tokens);
3664 }
3665 }
3666
3667 #[cfg(feature = "full")]
3668 impl ToTokens for PatRange {
3669 fn to_tokens(&self, tokens: &mut TokenStream) {
3670 self.lo.to_tokens(tokens);
3671 match self.limits {
3672 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3673 RangeLimits::Closed(ref t) => Token.to_tokens(tokens),
3674 }
3675 self.hi.to_tokens(tokens);
3676 }
3677 }
3678
3679 #[cfg(feature = "full")]
3680 impl ToTokens for PatSlice {
3681 fn to_tokens(&self, tokens: &mut TokenStream) {
3682 self.bracket_token.surround(tokens, |tokens| {
3683 self.front.to_tokens(tokens);
3684
3685 if !self.front.empty_or_trailing()
3688 && (self.middle.is_some() || self.dot2_token.is_some())
3689 {
3690 <Token![,]>::default().to_tokens(tokens);
3691 }
3692
3693 if self.middle.is_some() {
3695 self.middle.to_tokens(tokens);
3696 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3697 } else if self.dot2_token.is_some() {
3698 self.dot2_token.to_tokens(tokens);
3699 }
3700
3701 if !self.back.is_empty() {
3703 TokensOrDefault(&self.comma_token).to_tokens(tokens);
3704 self.back.to_tokens(tokens);
3705 } else {
3706 self.comma_token.to_tokens(tokens);
3707 }
3708 })
3709 }
3710 }
3711
3712 #[cfg(feature = "full")]
3713 impl ToTokens for PatMacro {
3714 fn to_tokens(&self, tokens: &mut TokenStream) {
3715 self.mac.to_tokens(tokens);
3716 }
3717 }
3718
3719 #[cfg(feature = "full")]
3720 impl ToTokens for PatVerbatim {
3721 fn to_tokens(&self, tokens: &mut TokenStream) {
3722 self.tts.to_tokens(tokens);
3723 }
3724 }
3725
3726 #[cfg(feature = "full")]
3727 impl ToTokens for FieldPat {
3728 fn to_tokens(&self, tokens: &mut TokenStream) {
3729 if let Some(ref colon_token) = self.colon_token {
3730 self.member.to_tokens(tokens);
3731 colon_token.to_tokens(tokens);
3732 }
3733 self.pat.to_tokens(tokens);
3734 }
3735 }
3736
3737 #[cfg(feature = "full")]
3738 impl ToTokens for Block {
3739 fn to_tokens(&self, tokens: &mut TokenStream) {
3740 self.brace_token.surround(tokens, |tokens| {
3741 tokens.append_all(&self.stmts);
3742 });
3743 }
3744 }
3745
3746 #[cfg(feature = "full")]
3747 impl ToTokens for Stmt {
3748 fn to_tokens(&self, tokens: &mut TokenStream) {
3749 match *self {
3750 Stmt::Local(ref local) => local.to_tokens(tokens),
3751 Stmt::Item(ref item) => item.to_tokens(tokens),
3752 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
3753 Stmt::Semi(ref expr, ref semi) => {
3754 expr.to_tokens(tokens);
3755 semi.to_tokens(tokens);
3756 }
3757 }
3758 }
3759 }
3760
3761 #[cfg(feature = "full")]
3762 impl ToTokens for Local {
3763 fn to_tokens(&self, tokens: &mut TokenStream) {
3764 outer_attrs_to_tokens(&self.attrs, tokens);
3765 self.let_token.to_tokens(tokens);
3766 self.pats.to_tokens(tokens);
3767 if let Some((ref colon_token, ref ty)) = self.ty {
3768 colon_token.to_tokens(tokens);
3769 ty.to_tokens(tokens);
3770 }
3771 if let Some((ref eq_token, ref init)) = self.init {
3772 eq_token.to_tokens(tokens);
3773 init.to_tokens(tokens);
3774 }
3775 self.semi_token.to_tokens(tokens);
3776 }
3777 }
3778}