1use super::*;
2use crate::punctuated::Punctuated;
3#[cfg(feature = "full")]
4use crate::reserved::Reserved;
5use proc_macro2::{Span, TokenStream};
6#[cfg(feature = "printing")]
7use quote::IdentFragment;
8#[cfg(feature = "printing")]
9use std::fmt::{self, Display};
10use std::hash::{Hash, Hasher};
11#[cfg(feature = "parsing")]
12use std::mem;
13
14ast_enum_of_structs! {
15 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
90 #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)]
91 pub enum Expr {
92 Array(ExprArray),
94
95 Assign(ExprAssign),
97
98 AssignOp(ExprAssignOp),
100
101 Async(ExprAsync),
103
104 Await(ExprAwait),
106
107 Binary(ExprBinary),
109
110 Block(ExprBlock),
112
113 Box(ExprBox),
115
116 Break(ExprBreak),
119
120 Call(ExprCall),
122
123 Cast(ExprCast),
125
126 Closure(ExprClosure),
128
129 Continue(ExprContinue),
131
132 Field(ExprField),
135
136 ForLoop(ExprForLoop),
138
139 Group(ExprGroup),
145
146 If(ExprIf),
152
153 Index(ExprIndex),
155
156 Let(ExprLet),
158
159 Lit(ExprLit),
161
162 Loop(ExprLoop),
164
165 Macro(ExprMacro),
167
168 Match(ExprMatch),
170
171 MethodCall(ExprMethodCall),
173
174 Paren(ExprParen),
176
177 Path(ExprPath),
182
183 Range(ExprRange),
185
186 Reference(ExprReference),
188
189 Repeat(ExprRepeat),
191
192 Return(ExprReturn),
194
195 Struct(ExprStruct),
200
201 Try(ExprTry),
203
204 TryBlock(ExprTryBlock),
206
207 Tuple(ExprTuple),
209
210 Type(ExprType),
212
213 Unary(ExprUnary),
215
216 Unsafe(ExprUnsafe),
218
219 Verbatim(TokenStream),
221
222 While(ExprWhile),
224
225 Yield(ExprYield),
227
228 #[cfg(syn_no_non_exhaustive)]
247 #[doc(hidden)]
248 __NonExhaustive,
249 }
250}
251
252ast_struct! {
253 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
257 pub struct ExprArray #full {
258 pub attrs: Vec<Attribute>,
259 pub bracket_token: token::Bracket,
260 pub elems: Punctuated<Expr, Token![,]>,
261 }
262}
263
264ast_struct! {
265 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
269 pub struct ExprAssign #full {
270 pub attrs: Vec<Attribute>,
271 pub left: Box<Expr>,
272 pub eq_token: Token![=],
273 pub right: Box<Expr>,
274 }
275}
276
277ast_struct! {
278 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
282 pub struct ExprAssignOp #full {
283 pub attrs: Vec<Attribute>,
284 pub left: Box<Expr>,
285 pub op: BinOp,
286 pub right: Box<Expr>,
287 }
288}
289
290ast_struct! {
291 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
295 pub struct ExprAsync #full {
296 pub attrs: Vec<Attribute>,
297 pub async_token: Token![async],
298 pub capture: Option<Token![move]>,
299 pub block: Block,
300 }
301}
302
303ast_struct! {
304 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
308 pub struct ExprAwait #full {
309 pub attrs: Vec<Attribute>,
310 pub base: Box<Expr>,
311 pub dot_token: Token![.],
312 pub await_token: token::Await,
313 }
314}
315
316ast_struct! {
317 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
322 pub struct ExprBinary {
323 pub attrs: Vec<Attribute>,
324 pub left: Box<Expr>,
325 pub op: BinOp,
326 pub right: Box<Expr>,
327 }
328}
329
330ast_struct! {
331 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
335 pub struct ExprBlock #full {
336 pub attrs: Vec<Attribute>,
337 pub label: Option<Label>,
338 pub block: Block,
339 }
340}
341
342ast_struct! {
343 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
347 pub struct ExprBox #full {
348 pub attrs: Vec<Attribute>,
349 pub box_token: Token![box],
350 pub expr: Box<Expr>,
351 }
352}
353
354ast_struct! {
355 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
360 pub struct ExprBreak #full {
361 pub attrs: Vec<Attribute>,
362 pub break_token: Token![break],
363 pub label: Option<Lifetime>,
364 pub expr: Option<Box<Expr>>,
365 }
366}
367
368ast_struct! {
369 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
374 pub struct ExprCall {
375 pub attrs: Vec<Attribute>,
376 pub func: Box<Expr>,
377 pub paren_token: token::Paren,
378 pub args: Punctuated<Expr, Token![,]>,
379 }
380}
381
382ast_struct! {
383 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
388 pub struct ExprCast {
389 pub attrs: Vec<Attribute>,
390 pub expr: Box<Expr>,
391 pub as_token: Token![as],
392 pub ty: Box<Type>,
393 }
394}
395
396ast_struct! {
397 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
401 pub struct ExprClosure #full {
402 pub attrs: Vec<Attribute>,
403 pub movability: Option<Token![static]>,
404 pub asyncness: Option<Token![async]>,
405 pub capture: Option<Token![move]>,
406 pub or1_token: Token![|],
407 pub inputs: Punctuated<Pat, Token![,]>,
408 pub or2_token: Token![|],
409 pub output: ReturnType,
410 pub body: Box<Expr>,
411 }
412}
413
414ast_struct! {
415 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
419 pub struct ExprContinue #full {
420 pub attrs: Vec<Attribute>,
421 pub continue_token: Token![continue],
422 pub label: Option<Lifetime>,
423 }
424}
425
426ast_struct! {
427 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
432 pub struct ExprField {
433 pub attrs: Vec<Attribute>,
434 pub base: Box<Expr>,
435 pub dot_token: Token![.],
436 pub member: Member,
437 }
438}
439
440ast_struct! {
441 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
445 pub struct ExprForLoop #full {
446 pub attrs: Vec<Attribute>,
447 pub label: Option<Label>,
448 pub for_token: Token![for],
449 pub pat: Pat,
450 pub in_token: Token![in],
451 pub expr: Box<Expr>,
452 pub body: Block,
453 }
454}
455
456ast_struct! {
457 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
465 pub struct ExprGroup #full {
466 pub attrs: Vec<Attribute>,
467 pub group_token: token::Group,
468 pub expr: Box<Expr>,
469 }
470}
471
472ast_struct! {
473 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
481 pub struct ExprIf #full {
482 pub attrs: Vec<Attribute>,
483 pub if_token: Token![if],
484 pub cond: Box<Expr>,
485 pub then_branch: Block,
486 pub else_branch: Option<(Token![else], Box<Expr>)>,
487 }
488}
489
490ast_struct! {
491 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
496 pub struct ExprIndex {
497 pub attrs: Vec<Attribute>,
498 pub expr: Box<Expr>,
499 pub bracket_token: token::Bracket,
500 pub index: Box<Expr>,
501 }
502}
503
504ast_struct! {
505 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
509 pub struct ExprLet #full {
510 pub attrs: Vec<Attribute>,
511 pub let_token: Token![let],
512 pub pat: Pat,
513 pub eq_token: Token![=],
514 pub expr: Box<Expr>,
515 }
516}
517
518ast_struct! {
519 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
524 pub struct ExprLit {
525 pub attrs: Vec<Attribute>,
526 pub lit: Lit,
527 }
528}
529
530ast_struct! {
531 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
535 pub struct ExprLoop #full {
536 pub attrs: Vec<Attribute>,
537 pub label: Option<Label>,
538 pub loop_token: Token![loop],
539 pub body: Block,
540 }
541}
542
543ast_struct! {
544 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
548 pub struct ExprMacro #full {
549 pub attrs: Vec<Attribute>,
550 pub mac: Macro,
551 }
552}
553
554ast_struct! {
555 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
559 pub struct ExprMatch #full {
560 pub attrs: Vec<Attribute>,
561 pub match_token: Token![match],
562 pub expr: Box<Expr>,
563 pub brace_token: token::Brace,
564 pub arms: Vec<Arm>,
565 }
566}
567
568ast_struct! {
569 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
573 pub struct ExprMethodCall #full {
574 pub attrs: Vec<Attribute>,
575 pub receiver: Box<Expr>,
576 pub dot_token: Token![.],
577 pub method: Ident,
578 pub turbofish: Option<MethodTurbofish>,
579 pub paren_token: token::Paren,
580 pub args: Punctuated<Expr, Token![,]>,
581 }
582}
583
584ast_struct! {
585 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
589 pub struct ExprParen {
590 pub attrs: Vec<Attribute>,
591 pub paren_token: token::Paren,
592 pub expr: Box<Expr>,
593 }
594}
595
596ast_struct! {
597 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
605 pub struct ExprPath {
606 pub attrs: Vec<Attribute>,
607 pub qself: Option<QSelf>,
608 pub path: Path,
609 }
610}
611
612ast_struct! {
613 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
617 pub struct ExprRange #full {
618 pub attrs: Vec<Attribute>,
619 pub from: Option<Box<Expr>>,
620 pub limits: RangeLimits,
621 pub to: Option<Box<Expr>>,
622 }
623}
624
625ast_struct! {
626 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
630 pub struct ExprReference #full {
631 pub attrs: Vec<Attribute>,
632 pub and_token: Token![&],
633 pub raw: Reserved,
634 pub mutability: Option<Token![mut]>,
635 pub expr: Box<Expr>,
636 }
637}
638
639ast_struct! {
640 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
644 pub struct ExprRepeat #full {
645 pub attrs: Vec<Attribute>,
646 pub bracket_token: token::Bracket,
647 pub expr: Box<Expr>,
648 pub semi_token: Token![;],
649 pub len: Box<Expr>,
650 }
651}
652
653ast_struct! {
654 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
658 pub struct ExprReturn #full {
659 pub attrs: Vec<Attribute>,
660 pub return_token: Token![return],
661 pub expr: Option<Box<Expr>>,
662 }
663}
664
665ast_struct! {
666 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
673 pub struct ExprStruct #full {
674 pub attrs: Vec<Attribute>,
675 pub path: Path,
676 pub brace_token: token::Brace,
677 pub fields: Punctuated<FieldValue, Token![,]>,
678 pub dot2_token: Option<Token![..]>,
679 pub rest: Option<Box<Expr>>,
680 }
681}
682
683ast_struct! {
684 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
688 pub struct ExprTry #full {
689 pub attrs: Vec<Attribute>,
690 pub expr: Box<Expr>,
691 pub question_token: Token![?],
692 }
693}
694
695ast_struct! {
696 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
700 pub struct ExprTryBlock #full {
701 pub attrs: Vec<Attribute>,
702 pub try_token: Token![try],
703 pub block: Block,
704 }
705}
706
707ast_struct! {
708 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
712 pub struct ExprTuple #full {
713 pub attrs: Vec<Attribute>,
714 pub paren_token: token::Paren,
715 pub elems: Punctuated<Expr, Token![,]>,
716 }
717}
718
719ast_struct! {
720 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
724 pub struct ExprType #full {
725 pub attrs: Vec<Attribute>,
726 pub expr: Box<Expr>,
727 pub colon_token: Token![:],
728 pub ty: Box<Type>,
729 }
730}
731
732ast_struct! {
733 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
738 pub struct ExprUnary {
739 pub attrs: Vec<Attribute>,
740 pub op: UnOp,
741 pub expr: Box<Expr>,
742 }
743}
744
745ast_struct! {
746 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
750 pub struct ExprUnsafe #full {
751 pub attrs: Vec<Attribute>,
752 pub unsafe_token: Token![unsafe],
753 pub block: Block,
754 }
755}
756
757ast_struct! {
758 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
762 pub struct ExprWhile #full {
763 pub attrs: Vec<Attribute>,
764 pub label: Option<Label>,
765 pub while_token: Token![while],
766 pub cond: Box<Expr>,
767 pub body: Block,
768 }
769}
770
771ast_struct! {
772 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
776 pub struct ExprYield #full {
777 pub attrs: Vec<Attribute>,
778 pub yield_token: Token![yield],
779 pub expr: Option<Box<Expr>>,
780 }
781}
782
783impl Expr {
784 #[cfg(all(feature = "parsing", not(syn_no_const_vec_new)))]
785 const DUMMY: Self = Expr::Path(ExprPath {
786 attrs: Vec::new(),
787 qself: None,
788 path: Path {
789 leading_colon: None,
790 segments: Punctuated::new(),
791 },
792 });
793
794 #[cfg(all(feature = "parsing", feature = "full"))]
795 pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
796 match self {
797 Expr::Box(ExprBox { attrs, .. })
798 | Expr::Array(ExprArray { attrs, .. })
799 | Expr::Call(ExprCall { attrs, .. })
800 | Expr::MethodCall(ExprMethodCall { attrs, .. })
801 | Expr::Tuple(ExprTuple { attrs, .. })
802 | Expr::Binary(ExprBinary { attrs, .. })
803 | Expr::Unary(ExprUnary { attrs, .. })
804 | Expr::Lit(ExprLit { attrs, .. })
805 | Expr::Cast(ExprCast { attrs, .. })
806 | Expr::Type(ExprType { attrs, .. })
807 | Expr::Let(ExprLet { attrs, .. })
808 | Expr::If(ExprIf { attrs, .. })
809 | Expr::While(ExprWhile { attrs, .. })
810 | Expr::ForLoop(ExprForLoop { attrs, .. })
811 | Expr::Loop(ExprLoop { attrs, .. })
812 | Expr::Match(ExprMatch { attrs, .. })
813 | Expr::Closure(ExprClosure { attrs, .. })
814 | Expr::Unsafe(ExprUnsafe { attrs, .. })
815 | Expr::Block(ExprBlock { attrs, .. })
816 | Expr::Assign(ExprAssign { attrs, .. })
817 | Expr::AssignOp(ExprAssignOp { attrs, .. })
818 | Expr::Field(ExprField { attrs, .. })
819 | Expr::Index(ExprIndex { attrs, .. })
820 | Expr::Range(ExprRange { attrs, .. })
821 | Expr::Path(ExprPath { attrs, .. })
822 | Expr::Reference(ExprReference { attrs, .. })
823 | Expr::Break(ExprBreak { attrs, .. })
824 | Expr::Continue(ExprContinue { attrs, .. })
825 | Expr::Return(ExprReturn { attrs, .. })
826 | Expr::Macro(ExprMacro { attrs, .. })
827 | Expr::Struct(ExprStruct { attrs, .. })
828 | Expr::Repeat(ExprRepeat { attrs, .. })
829 | Expr::Paren(ExprParen { attrs, .. })
830 | Expr::Group(ExprGroup { attrs, .. })
831 | Expr::Try(ExprTry { attrs, .. })
832 | Expr::Async(ExprAsync { attrs, .. })
833 | Expr::Await(ExprAwait { attrs, .. })
834 | Expr::TryBlock(ExprTryBlock { attrs, .. })
835 | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
836 Expr::Verbatim(_) => Vec::new(),
837
838 #[cfg(syn_no_non_exhaustive)]
839 _ => unreachable!(),
840 }
841 }
842}
843
844ast_enum! {
845 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
851 pub enum Member {
852 Named(Ident),
854 Unnamed(Index),
856 }
857}
858
859impl From<Ident> for Member {
860 fn from(ident: Ident) -> Member {
861 Member::Named(ident)
862 }
863}
864
865impl From<Index> for Member {
866 fn from(index: Index) -> Member {
867 Member::Unnamed(index)
868 }
869}
870
871impl From<usize> for Member {
872 fn from(index: usize) -> Member {
873 Member::Unnamed(Index::from(index))
874 }
875}
876
877impl Eq for Member {}
878
879impl PartialEq for Member {
880 fn eq(&self, other: &Self) -> bool {
881 match (self, other) {
882 (Member::Named(this), Member::Named(other)) => this == other,
883 (Member::Unnamed(this), Member::Unnamed(other)) => this == other,
884 _ => false,
885 }
886 }
887}
888
889impl Hash for Member {
890 fn hash<H: Hasher>(&self, state: &mut H) {
891 match self {
892 Member::Named(m) => m.hash(state),
893 Member::Unnamed(m) => m.hash(state),
894 }
895 }
896}
897
898#[cfg(feature = "printing")]
899impl IdentFragment for Member {
900 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
901 match self {
902 Member::Named(m) => Display::fmt(m, formatter),
903 Member::Unnamed(m) => Display::fmt(&m.index, formatter),
904 }
905 }
906
907 fn span(&self) -> Option<Span> {
908 match self {
909 Member::Named(m) => Some(m.span()),
910 Member::Unnamed(m) => Some(m.span),
911 }
912 }
913}
914
915ast_struct! {
916 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
921 pub struct Index {
922 pub index: u32,
923 pub span: Span,
924 }
925}
926
927impl From<usize> for Index {
928 fn from(index: usize) -> Index {
929 assert!(index < u32::max_value() as usize);
930 Index {
931 index: index as u32,
932 span: Span::call_site(),
933 }
934 }
935}
936
937impl Eq for Index {}
938
939impl PartialEq for Index {
940 fn eq(&self, other: &Self) -> bool {
941 self.index == other.index
942 }
943}
944
945impl Hash for Index {
946 fn hash<H: Hasher>(&self, state: &mut H) {
947 self.index.hash(state);
948 }
949}
950
951#[cfg(feature = "printing")]
952impl IdentFragment for Index {
953 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
954 Display::fmt(&self.index, formatter)
955 }
956
957 fn span(&self) -> Option<Span> {
958 Some(self.span)
959 }
960}
961
962#[cfg(feature = "full")]
963ast_struct! {
964 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
969 pub struct MethodTurbofish {
970 pub colon2_token: Token![::],
971 pub lt_token: Token![<],
972 pub args: Punctuated<GenericMethodArgument, Token![,]>,
973 pub gt_token: Token![>],
974 }
975}
976
977#[cfg(feature = "full")]
978ast_enum! {
979 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
983 pub enum GenericMethodArgument {
984 Type(Type),
986 Const(Expr),
991 }
992}
993
994#[cfg(feature = "full")]
995ast_struct! {
996 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1000 pub struct FieldValue {
1001 pub attrs: Vec<Attribute>,
1003
1004 pub member: Member,
1006
1007 pub colon_token: Option<Token![:]>,
1010
1011 pub expr: Expr,
1013 }
1014}
1015
1016#[cfg(feature = "full")]
1017ast_struct! {
1018 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1022 pub struct Label {
1023 pub name: Lifetime,
1024 pub colon_token: Token![:],
1025 }
1026}
1027
1028#[cfg(feature = "full")]
1029ast_struct! {
1030 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1050 pub struct Arm {
1051 pub attrs: Vec<Attribute>,
1052 pub pat: Pat,
1053 pub guard: Option<(Token![if], Box<Expr>)>,
1054 pub fat_arrow_token: Token![=>],
1055 pub body: Box<Expr>,
1056 pub comma: Option<Token![,]>,
1057 }
1058}
1059
1060#[cfg(feature = "full")]
1061ast_enum! {
1062 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1066 pub enum RangeLimits {
1067 HalfOpen(Token![..]),
1069 Closed(Token![..=]),
1071 }
1072}
1073
1074#[cfg(any(feature = "parsing", feature = "printing"))]
1075#[cfg(feature = "full")]
1076pub(crate) fn requires_terminator(expr: &Expr) -> bool {
1077 match *expr {
1079 Expr::Unsafe(..)
1080 | Expr::Block(..)
1081 | Expr::If(..)
1082 | Expr::Match(..)
1083 | Expr::While(..)
1084 | Expr::Loop(..)
1085 | Expr::ForLoop(..)
1086 | Expr::Async(..)
1087 | Expr::TryBlock(..) => false,
1088 _ => true,
1089 }
1090}
1091
1092#[cfg(feature = "parsing")]
1093pub(crate) mod parsing {
1094 use super::*;
1095 #[cfg(feature = "full")]
1096 use crate::parse::ParseBuffer;
1097 use crate::parse::{Parse, ParseStream, Result};
1098 use crate::path;
1099 #[cfg(feature = "full")]
1100 use proc_macro2::TokenTree;
1101 use std::cmp::Ordering;
1102
1103 crate::custom_keyword!(raw);
1104
1105 pub struct AllowStruct(bool);
1111
1112 enum Precedence {
1113 Any,
1114 Assign,
1115 Range,
1116 Or,
1117 And,
1118 Compare,
1119 BitOr,
1120 BitXor,
1121 BitAnd,
1122 Shift,
1123 Arithmetic,
1124 Term,
1125 Cast,
1126 }
1127
1128 impl Precedence {
1129 fn of(op: &BinOp) -> Self {
1130 match *op {
1131 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1132 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1133 BinOp::And(_) => Precedence::And,
1134 BinOp::Or(_) => Precedence::Or,
1135 BinOp::BitXor(_) => Precedence::BitXor,
1136 BinOp::BitAnd(_) => Precedence::BitAnd,
1137 BinOp::BitOr(_) => Precedence::BitOr,
1138 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1139 BinOp::Eq(_)
1140 | BinOp::Lt(_)
1141 | BinOp::Le(_)
1142 | BinOp::Ne(_)
1143 | BinOp::Ge(_)
1144 | BinOp::Gt(_) => Precedence::Compare,
1145 BinOp::AddEq(_)
1146 | BinOp::SubEq(_)
1147 | BinOp::MulEq(_)
1148 | BinOp::DivEq(_)
1149 | BinOp::RemEq(_)
1150 | BinOp::BitXorEq(_)
1151 | BinOp::BitAndEq(_)
1152 | BinOp::BitOrEq(_)
1153 | BinOp::ShlEq(_)
1154 | BinOp::ShrEq(_) => Precedence::Assign,
1155 }
1156 }
1157 }
1158
1159 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1160 impl Parse for Expr {
1161 fn parse(input: ParseStream) -> Result<Self> {
1162 ambiguous_expr(input, AllowStruct(true))
1163 }
1164 }
1165
1166 impl Expr {
1167 #[cfg(feature = "full")]
1248 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "full", feature = "parsing"))))]
1249 pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
1250 ambiguous_expr(input, AllowStruct(false))
1251 }
1252 }
1253
1254 impl Copy for AllowStruct {}
1255
1256 impl Clone for AllowStruct {
1257 fn clone(&self) -> Self {
1258 *self
1259 }
1260 }
1261
1262 impl Copy for Precedence {}
1263
1264 impl Clone for Precedence {
1265 fn clone(&self) -> Self {
1266 *self
1267 }
1268 }
1269
1270 impl PartialEq for Precedence {
1271 fn eq(&self, other: &Self) -> bool {
1272 *self as u8 == *other as u8
1273 }
1274 }
1275
1276 impl PartialOrd for Precedence {
1277 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1278 let this = *self as u8;
1279 let other = *other as u8;
1280 Some(this.cmp(&other))
1281 }
1282 }
1283
1284 #[cfg(feature = "full")]
1285 fn parse_expr(
1286 input: ParseStream,
1287 mut lhs: Expr,
1288 allow_struct: AllowStruct,
1289 base: Precedence,
1290 ) -> Result<Expr> {
1291 loop {
1292 if input
1293 .fork()
1294 .parse::<BinOp>()
1295 .ok()
1296 .map_or(false, |op| Precedence::of(&op) >= base)
1297 {
1298 let op: BinOp = input.parse()?;
1299 let precedence = Precedence::of(&op);
1300 let mut rhs = unary_expr(input, allow_struct)?;
1301 loop {
1302 let next = peek_precedence(input);
1303 if next > precedence || next == precedence && precedence == Precedence::Assign {
1304 rhs = parse_expr(input, rhs, allow_struct, next)?;
1305 } else {
1306 break;
1307 }
1308 }
1309 lhs = if precedence == Precedence::Assign {
1310 Expr::AssignOp(ExprAssignOp {
1311 attrs: Vec::new(),
1312 left: Box::new(lhs),
1313 op,
1314 right: Box::new(rhs),
1315 })
1316 } else {
1317 Expr::Binary(ExprBinary {
1318 attrs: Vec::new(),
1319 left: Box::new(lhs),
1320 op,
1321 right: Box::new(rhs),
1322 })
1323 };
1324 } else if Precedence::Assign >= base
1325 && input.peek(Token![=])
1326 && !input.peek(Token![==])
1327 && !input.peek(Token![=>])
1328 {
1329 let eq_token: Token![=] = input.parse()?;
1330 let mut rhs = unary_expr(input, allow_struct)?;
1331 loop {
1332 let next = peek_precedence(input);
1333 if next >= Precedence::Assign {
1334 rhs = parse_expr(input, rhs, allow_struct, next)?;
1335 } else {
1336 break;
1337 }
1338 }
1339 lhs = Expr::Assign(ExprAssign {
1340 attrs: Vec::new(),
1341 left: Box::new(lhs),
1342 eq_token,
1343 right: Box::new(rhs),
1344 });
1345 } else if Precedence::Range >= base && input.peek(Token![..]) {
1346 let limits: RangeLimits = input.parse()?;
1347 let rhs = if input.is_empty()
1348 || input.peek(Token![,])
1349 || input.peek(Token![;])
1350 || input.peek(Token![.]) && !input.peek(Token![..])
1351 || !allow_struct.0 && input.peek(token::Brace)
1352 {
1353 None
1354 } else {
1355 let mut rhs = unary_expr(input, allow_struct)?;
1356 loop {
1357 let next = peek_precedence(input);
1358 if next > Precedence::Range {
1359 rhs = parse_expr(input, rhs, allow_struct, next)?;
1360 } else {
1361 break;
1362 }
1363 }
1364 Some(rhs)
1365 };
1366 lhs = Expr::Range(ExprRange {
1367 attrs: Vec::new(),
1368 from: Some(Box::new(lhs)),
1369 limits,
1370 to: rhs.map(Box::new),
1371 });
1372 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1373 let as_token: Token![as] = input.parse()?;
1374 let ty = input.call(Type::without_plus)?;
1375 check_cast(input)?;
1376 lhs = Expr::Cast(ExprCast {
1377 attrs: Vec::new(),
1378 expr: Box::new(lhs),
1379 as_token,
1380 ty: Box::new(ty),
1381 });
1382 } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1383 let colon_token: Token![:] = input.parse()?;
1384 let ty = input.call(Type::without_plus)?;
1385 check_cast(input)?;
1386 lhs = Expr::Type(ExprType {
1387 attrs: Vec::new(),
1388 expr: Box::new(lhs),
1389 colon_token,
1390 ty: Box::new(ty),
1391 });
1392 } else {
1393 break;
1394 }
1395 }
1396 Ok(lhs)
1397 }
1398
1399 #[cfg(not(feature = "full"))]
1400 fn parse_expr(
1401 input: ParseStream,
1402 mut lhs: Expr,
1403 allow_struct: AllowStruct,
1404 base: Precedence,
1405 ) -> Result<Expr> {
1406 loop {
1407 if input
1408 .fork()
1409 .parse::<BinOp>()
1410 .ok()
1411 .map_or(false, |op| Precedence::of(&op) >= base)
1412 {
1413 let op: BinOp = input.parse()?;
1414 let precedence = Precedence::of(&op);
1415 let mut rhs = unary_expr(input, allow_struct)?;
1416 loop {
1417 let next = peek_precedence(input);
1418 if next > precedence || next == precedence && precedence == Precedence::Assign {
1419 rhs = parse_expr(input, rhs, allow_struct, next)?;
1420 } else {
1421 break;
1422 }
1423 }
1424 lhs = Expr::Binary(ExprBinary {
1425 attrs: Vec::new(),
1426 left: Box::new(lhs),
1427 op,
1428 right: Box::new(rhs),
1429 });
1430 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1431 let as_token: Token![as] = input.parse()?;
1432 let ty = input.call(Type::without_plus)?;
1433 check_cast(input)?;
1434 lhs = Expr::Cast(ExprCast {
1435 attrs: Vec::new(),
1436 expr: Box::new(lhs),
1437 as_token,
1438 ty: Box::new(ty),
1439 });
1440 } else {
1441 break;
1442 }
1443 }
1444 Ok(lhs)
1445 }
1446
1447 fn peek_precedence(input: ParseStream) -> Precedence {
1448 if let Ok(op) = input.fork().parse() {
1449 Precedence::of(&op)
1450 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1451 Precedence::Assign
1452 } else if input.peek(Token![..]) {
1453 Precedence::Range
1454 } else if input.peek(Token![as])
1455 || cfg!(feature = "full") && input.peek(Token![:]) && !input.peek(Token![::])
1456 {
1457 Precedence::Cast
1458 } else {
1459 Precedence::Any
1460 }
1461 }
1462
1463 fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1465 let lhs = unary_expr(input, allow_struct)?;
1466 parse_expr(input, lhs, allow_struct, Precedence::Any)
1467 }
1468
1469 #[cfg(feature = "full")]
1470 fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
1471 let mut attrs = Vec::new();
1472 loop {
1473 if input.peek(token::Group) {
1474 let ahead = input.fork();
1475 let group = crate::group::parse_group(&ahead)?;
1476 if !group.content.peek(Token![#]) || group.content.peek2(Token![!]) {
1477 break;
1478 }
1479 let attr = group.content.call(attr::parsing::single_parse_outer)?;
1480 if !group.content.is_empty() {
1481 break;
1482 }
1483 attrs.push(attr);
1484 } else if input.peek(Token![#]) {
1485 attrs.push(input.call(attr::parsing::single_parse_outer)?);
1486 } else {
1487 break;
1488 }
1489 }
1490 Ok(attrs)
1491 }
1492
1493 #[cfg(feature = "full")]
1498 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1499 let begin = input.fork();
1500 let attrs = input.call(expr_attrs)?;
1501 if input.peek(Token![&]) {
1502 let and_token: Token![&] = input.parse()?;
1503 let raw: Option<raw> =
1504 if input.peek(raw) && (input.peek2(Token![mut]) || input.peek2(Token![const])) {
1505 Some(input.parse()?)
1506 } else {
1507 None
1508 };
1509 let mutability: Option<Token![mut]> = input.parse()?;
1510 if raw.is_some() && mutability.is_none() {
1511 input.parse::<Token![const]>()?;
1512 }
1513 let expr = Box::new(unary_expr(input, allow_struct)?);
1514 if raw.is_some() {
1515 Ok(Expr::Verbatim(verbatim::between(begin, input)))
1516 } else {
1517 Ok(Expr::Reference(ExprReference {
1518 attrs,
1519 and_token,
1520 raw: Reserved::default(),
1521 mutability,
1522 expr,
1523 }))
1524 }
1525 } else if input.peek(Token![box]) {
1526 expr_box(input, attrs, allow_struct).map(Expr::Box)
1527 } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1528 expr_unary(input, attrs, allow_struct).map(Expr::Unary)
1529 } else {
1530 trailer_expr(begin, attrs, input, allow_struct)
1531 }
1532 }
1533
1534 #[cfg(not(feature = "full"))]
1535 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1536 if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1537 Ok(Expr::Unary(ExprUnary {
1538 attrs: Vec::new(),
1539 op: input.parse()?,
1540 expr: Box::new(unary_expr(input, allow_struct)?),
1541 }))
1542 } else {
1543 trailer_expr(input, allow_struct)
1544 }
1545 }
1546
1547 #[cfg(feature = "full")]
1554 fn trailer_expr(
1555 begin: ParseBuffer,
1556 mut attrs: Vec<Attribute>,
1557 input: ParseStream,
1558 allow_struct: AllowStruct,
1559 ) -> Result<Expr> {
1560 let atom = atom_expr(input, allow_struct)?;
1561 let mut e = trailer_helper(input, atom)?;
1562
1563 if let Expr::Verbatim(tokens) = &mut e {
1564 *tokens = verbatim::between(begin, input);
1565 } else {
1566 let inner_attrs = e.replace_attrs(Vec::new());
1567 attrs.extend(inner_attrs);
1568 e.replace_attrs(attrs);
1569 }
1570
1571 Ok(e)
1572 }
1573
1574 #[cfg(feature = "full")]
1575 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1576 loop {
1577 if input.peek(token::Paren) {
1578 let content;
1579 e = Expr::Call(ExprCall {
1580 attrs: Vec::new(),
1581 func: Box::new(e),
1582 paren_token: parenthesized!(content in input),
1583 args: content.parse_terminated(Expr::parse)?,
1584 });
1585 } else if input.peek(Token![.])
1586 && !input.peek(Token![..])
1587 && match e {
1588 Expr::Range(_) => false,
1589 _ => true,
1590 }
1591 {
1592 let mut dot_token: Token![.] = input.parse()?;
1593
1594 let await_token: Option<token::Await> = input.parse()?;
1595 if let Some(await_token) = await_token {
1596 e = Expr::Await(ExprAwait {
1597 attrs: Vec::new(),
1598 base: Box::new(e),
1599 dot_token,
1600 await_token,
1601 });
1602 continue;
1603 }
1604
1605 let float_token: Option<LitFloat> = input.parse()?;
1606 if let Some(float_token) = float_token {
1607 if multi_index(&mut e, &mut dot_token, float_token)? {
1608 continue;
1609 }
1610 }
1611
1612 let member: Member = input.parse()?;
1613 let turbofish = if member.is_named() && input.peek(Token![::]) {
1614 Some(input.parse::<MethodTurbofish>()?)
1615 } else {
1616 None
1617 };
1618
1619 if turbofish.is_some() || input.peek(token::Paren) {
1620 if let Member::Named(method) = member {
1621 let content;
1622 e = Expr::MethodCall(ExprMethodCall {
1623 attrs: Vec::new(),
1624 receiver: Box::new(e),
1625 dot_token,
1626 method,
1627 turbofish,
1628 paren_token: parenthesized!(content in input),
1629 args: content.parse_terminated(Expr::parse)?,
1630 });
1631 continue;
1632 }
1633 }
1634
1635 e = Expr::Field(ExprField {
1636 attrs: Vec::new(),
1637 base: Box::new(e),
1638 dot_token,
1639 member,
1640 });
1641 } else if input.peek(token::Bracket) {
1642 let content;
1643 e = Expr::Index(ExprIndex {
1644 attrs: Vec::new(),
1645 expr: Box::new(e),
1646 bracket_token: bracketed!(content in input),
1647 index: content.parse()?,
1648 });
1649 } else if input.peek(Token![?]) {
1650 e = Expr::Try(ExprTry {
1651 attrs: Vec::new(),
1652 expr: Box::new(e),
1653 question_token: input.parse()?,
1654 });
1655 } else {
1656 break;
1657 }
1658 }
1659 Ok(e)
1660 }
1661
1662 #[cfg(not(feature = "full"))]
1663 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1664 let mut e = atom_expr(input, allow_struct)?;
1665
1666 loop {
1667 if input.peek(token::Paren) {
1668 let content;
1669 e = Expr::Call(ExprCall {
1670 attrs: Vec::new(),
1671 func: Box::new(e),
1672 paren_token: parenthesized!(content in input),
1673 args: content.parse_terminated(Expr::parse)?,
1674 });
1675 } else if input.peek(Token![.]) && !input.peek(Token![..]) && !input.peek2(token::Await)
1676 {
1677 let mut dot_token: Token![.] = input.parse()?;
1678 let float_token: Option<LitFloat> = input.parse()?;
1679 if let Some(float_token) = float_token {
1680 if multi_index(&mut e, &mut dot_token, float_token)? {
1681 continue;
1682 }
1683 }
1684 e = Expr::Field(ExprField {
1685 attrs: Vec::new(),
1686 base: Box::new(e),
1687 dot_token,
1688 member: input.parse()?,
1689 });
1690 } else if input.peek(token::Bracket) {
1691 let content;
1692 e = Expr::Index(ExprIndex {
1693 attrs: Vec::new(),
1694 expr: Box::new(e),
1695 bracket_token: bracketed!(content in input),
1696 index: content.parse()?,
1697 });
1698 } else {
1699 break;
1700 }
1701 }
1702
1703 Ok(e)
1704 }
1705
1706 #[cfg(feature = "full")]
1709 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1710 if input.peek(token::Group)
1711 && !input.peek2(Token![::])
1712 && !input.peek2(Token![!])
1713 && !input.peek2(token::Brace)
1714 {
1715 input.call(expr_group).map(Expr::Group)
1716 } else if input.peek(Lit) {
1717 input.parse().map(Expr::Lit)
1718 } else if input.peek(Token![async])
1719 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1720 {
1721 input.parse().map(Expr::Async)
1722 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1723 input.parse().map(Expr::TryBlock)
1724 } else if input.peek(Token![|])
1725 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1726 || input.peek(Token![static])
1727 || input.peek(Token![move])
1728 {
1729 expr_closure(input, allow_struct).map(Expr::Closure)
1730 } else if input.peek(Token![for])
1731 && input.peek2(Token![<])
1732 && (input.peek3(Lifetime) || input.peek3(Token![>]))
1733 {
1734 let begin = input.fork();
1735 input.parse::<BoundLifetimes>()?;
1736 expr_closure(input, allow_struct)?;
1737 let verbatim = verbatim::between(begin, input);
1738 Ok(Expr::Verbatim(verbatim))
1739 } else if input.peek(Ident)
1740 || input.peek(Token![::])
1741 || input.peek(Token![<])
1742 || input.peek(Token![self])
1743 || input.peek(Token![Self])
1744 || input.peek(Token![super])
1745 || input.peek(Token![crate])
1746 {
1747 path_or_macro_or_struct(input, allow_struct)
1748 } else if input.peek(token::Paren) {
1749 paren_or_tuple(input)
1750 } else if input.peek(Token![break]) {
1751 expr_break(input, allow_struct).map(Expr::Break)
1752 } else if input.peek(Token![continue]) {
1753 input.parse().map(Expr::Continue)
1754 } else if input.peek(Token![return]) {
1755 expr_ret(input, allow_struct).map(Expr::Return)
1756 } else if input.peek(token::Bracket) {
1757 array_or_repeat(input)
1758 } else if input.peek(Token![let]) {
1759 input.parse().map(Expr::Let)
1760 } else if input.peek(Token![if]) {
1761 input.parse().map(Expr::If)
1762 } else if input.peek(Token![while]) {
1763 input.parse().map(Expr::While)
1764 } else if input.peek(Token![for]) {
1765 input.parse().map(Expr::ForLoop)
1766 } else if input.peek(Token![loop]) {
1767 input.parse().map(Expr::Loop)
1768 } else if input.peek(Token![match]) {
1769 input.parse().map(Expr::Match)
1770 } else if input.peek(Token![yield]) {
1771 input.parse().map(Expr::Yield)
1772 } else if input.peek(Token![unsafe]) {
1773 input.parse().map(Expr::Unsafe)
1774 } else if input.peek(Token![const]) {
1775 input.call(expr_const).map(Expr::Verbatim)
1776 } else if input.peek(token::Brace) {
1777 input.parse().map(Expr::Block)
1778 } else if input.peek(Token![..]) {
1779 expr_range(input, allow_struct).map(Expr::Range)
1780 } else if input.peek(Token![_]) {
1781 Ok(Expr::Verbatim(TokenStream::from(
1782 input.parse::<TokenTree>()?,
1783 )))
1784 } else if input.peek(Lifetime) {
1785 let the_label: Label = input.parse()?;
1786 let mut expr = if input.peek(Token![while]) {
1787 Expr::While(input.parse()?)
1788 } else if input.peek(Token![for]) {
1789 Expr::ForLoop(input.parse()?)
1790 } else if input.peek(Token![loop]) {
1791 Expr::Loop(input.parse()?)
1792 } else if input.peek(token::Brace) {
1793 Expr::Block(input.parse()?)
1794 } else {
1795 return Err(input.error("expected loop or block expression"));
1796 };
1797 match &mut expr {
1798 Expr::While(ExprWhile { label, .. })
1799 | Expr::ForLoop(ExprForLoop { label, .. })
1800 | Expr::Loop(ExprLoop { label, .. })
1801 | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
1802 _ => unreachable!(),
1803 }
1804 Ok(expr)
1805 } else {
1806 Err(input.error("expected expression"))
1807 }
1808 }
1809
1810 #[cfg(not(feature = "full"))]
1811 fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1812 if input.peek(Lit) {
1813 input.parse().map(Expr::Lit)
1814 } else if input.peek(token::Paren) {
1815 input.call(expr_paren).map(Expr::Paren)
1816 } else if input.peek(Ident)
1817 || input.peek(Token![::])
1818 || input.peek(Token![<])
1819 || input.peek(Token![self])
1820 || input.peek(Token![Self])
1821 || input.peek(Token![super])
1822 || input.peek(Token![crate])
1823 {
1824 input.parse().map(Expr::Path)
1825 } else {
1826 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1827 }
1828 }
1829
1830 #[cfg(feature = "full")]
1831 fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1832 let begin = input.fork();
1833 let expr: ExprPath = input.parse()?;
1834
1835 if expr.qself.is_none() && input.peek(Token![!]) && !input.peek(Token![!=]) {
1836 let mut contains_arguments = false;
1837 for segment in &expr.path.segments {
1838 match segment.arguments {
1839 PathArguments::None => {}
1840 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1841 contains_arguments = true;
1842 }
1843 }
1844 }
1845
1846 if !contains_arguments {
1847 let bang_token: Token![!] = input.parse()?;
1848 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1849 return Ok(Expr::Macro(ExprMacro {
1850 attrs: Vec::new(),
1851 mac: Macro {
1852 path: expr.path,
1853 bang_token,
1854 delimiter,
1855 tokens,
1856 },
1857 }));
1858 }
1859 }
1860
1861 if allow_struct.0 && input.peek(token::Brace) {
1862 let expr_struct = expr_struct_helper(input, expr.path)?;
1863 if expr.qself.is_some() {
1864 Ok(Expr::Verbatim(verbatim::between(begin, input)))
1865 } else {
1866 Ok(Expr::Struct(expr_struct))
1867 }
1868 } else {
1869 Ok(Expr::Path(expr))
1870 }
1871 }
1872
1873 #[cfg(feature = "full")]
1874 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1875 impl Parse for ExprMacro {
1876 fn parse(input: ParseStream) -> Result<Self> {
1877 Ok(ExprMacro {
1878 attrs: Vec::new(),
1879 mac: input.parse()?,
1880 })
1881 }
1882 }
1883
1884 #[cfg(feature = "full")]
1885 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1886 let content;
1887 let paren_token = parenthesized!(content in input);
1888 if content.is_empty() {
1889 return Ok(Expr::Tuple(ExprTuple {
1890 attrs: Vec::new(),
1891 paren_token,
1892 elems: Punctuated::new(),
1893 }));
1894 }
1895
1896 let first: Expr = content.parse()?;
1897 if content.is_empty() {
1898 return Ok(Expr::Paren(ExprParen {
1899 attrs: Vec::new(),
1900 paren_token,
1901 expr: Box::new(first),
1902 }));
1903 }
1904
1905 let mut elems = Punctuated::new();
1906 elems.push_value(first);
1907 while !content.is_empty() {
1908 let punct = content.parse()?;
1909 elems.push_punct(punct);
1910 if content.is_empty() {
1911 break;
1912 }
1913 let value = content.parse()?;
1914 elems.push_value(value);
1915 }
1916 Ok(Expr::Tuple(ExprTuple {
1917 attrs: Vec::new(),
1918 paren_token,
1919 elems,
1920 }))
1921 }
1922
1923 #[cfg(feature = "full")]
1924 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1925 let content;
1926 let bracket_token = bracketed!(content in input);
1927 if content.is_empty() {
1928 return Ok(Expr::Array(ExprArray {
1929 attrs: Vec::new(),
1930 bracket_token,
1931 elems: Punctuated::new(),
1932 }));
1933 }
1934
1935 let first: Expr = content.parse()?;
1936 if content.is_empty() || content.peek(Token![,]) {
1937 let mut elems = Punctuated::new();
1938 elems.push_value(first);
1939 while !content.is_empty() {
1940 let punct = content.parse()?;
1941 elems.push_punct(punct);
1942 if content.is_empty() {
1943 break;
1944 }
1945 let value = content.parse()?;
1946 elems.push_value(value);
1947 }
1948 Ok(Expr::Array(ExprArray {
1949 attrs: Vec::new(),
1950 bracket_token,
1951 elems,
1952 }))
1953 } else if content.peek(Token![;]) {
1954 let semi_token: Token![;] = content.parse()?;
1955 let len: Expr = content.parse()?;
1956 Ok(Expr::Repeat(ExprRepeat {
1957 attrs: Vec::new(),
1958 bracket_token,
1959 expr: Box::new(first),
1960 semi_token,
1961 len: Box::new(len),
1962 }))
1963 } else {
1964 Err(content.error("expected `,` or `;`"))
1965 }
1966 }
1967
1968 #[cfg(feature = "full")]
1969 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1970 impl Parse for ExprArray {
1971 fn parse(input: ParseStream) -> Result<Self> {
1972 let content;
1973 let bracket_token = bracketed!(content in input);
1974 let mut elems = Punctuated::new();
1975
1976 while !content.is_empty() {
1977 let first: Expr = content.parse()?;
1978 elems.push_value(first);
1979 if content.is_empty() {
1980 break;
1981 }
1982 let punct = content.parse()?;
1983 elems.push_punct(punct);
1984 }
1985
1986 Ok(ExprArray {
1987 attrs: Vec::new(),
1988 bracket_token,
1989 elems,
1990 })
1991 }
1992 }
1993
1994 #[cfg(feature = "full")]
1995 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1996 impl Parse for ExprRepeat {
1997 fn parse(input: ParseStream) -> Result<Self> {
1998 let content;
1999 Ok(ExprRepeat {
2000 bracket_token: bracketed!(content in input),
2001 attrs: Vec::new(),
2002 expr: content.parse()?,
2003 semi_token: content.parse()?,
2004 len: content.parse()?,
2005 })
2006 }
2007 }
2008
2009 #[cfg(feature = "full")]
2010 pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
2011 let mut attrs = input.call(expr_attrs)?;
2012 let mut expr = if input.peek(Token![if]) {
2013 Expr::If(input.parse()?)
2014 } else if input.peek(Token![while]) {
2015 Expr::While(input.parse()?)
2016 } else if input.peek(Token![for])
2017 && !(input.peek2(Token![<]) && (input.peek3(Lifetime) || input.peek3(Token![>])))
2018 {
2019 Expr::ForLoop(input.parse()?)
2020 } else if input.peek(Token![loop]) {
2021 Expr::Loop(input.parse()?)
2022 } else if input.peek(Token![match]) {
2023 Expr::Match(input.parse()?)
2024 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
2025 Expr::TryBlock(input.parse()?)
2026 } else if input.peek(Token![unsafe]) {
2027 Expr::Unsafe(input.parse()?)
2028 } else if input.peek(Token![const]) {
2029 Expr::Verbatim(input.call(expr_const)?)
2030 } else if input.peek(token::Brace) {
2031 Expr::Block(input.parse()?)
2032 } else {
2033 let allow_struct = AllowStruct(true);
2034 let mut expr = unary_expr(input, allow_struct)?;
2035
2036 attrs.extend(expr.replace_attrs(Vec::new()));
2037 expr.replace_attrs(attrs);
2038
2039 return parse_expr(input, expr, allow_struct, Precedence::Any);
2040 };
2041
2042 if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
2043 expr = trailer_helper(input, expr)?;
2044
2045 attrs.extend(expr.replace_attrs(Vec::new()));
2046 expr.replace_attrs(attrs);
2047
2048 let allow_struct = AllowStruct(true);
2049 return parse_expr(input, expr, allow_struct, Precedence::Any);
2050 }
2051
2052 attrs.extend(expr.replace_attrs(Vec::new()));
2053 expr.replace_attrs(attrs);
2054 Ok(expr)
2055 }
2056
2057 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2058 impl Parse for ExprLit {
2059 fn parse(input: ParseStream) -> Result<Self> {
2060 Ok(ExprLit {
2061 attrs: Vec::new(),
2062 lit: input.parse()?,
2063 })
2064 }
2065 }
2066
2067 #[cfg(feature = "full")]
2068 fn expr_group(input: ParseStream) -> Result<ExprGroup> {
2069 let group = crate::group::parse_group(input)?;
2070 Ok(ExprGroup {
2071 attrs: Vec::new(),
2072 group_token: group.token,
2073 expr: group.content.parse()?,
2074 })
2075 }
2076
2077 #[cfg(feature = "full")]
2078 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2079 impl Parse for ExprParen {
2080 fn parse(input: ParseStream) -> Result<Self> {
2081 expr_paren(input)
2082 }
2083 }
2084
2085 fn expr_paren(input: ParseStream) -> Result<ExprParen> {
2086 let content;
2087 Ok(ExprParen {
2088 attrs: Vec::new(),
2089 paren_token: parenthesized!(content in input),
2090 expr: content.parse()?,
2091 })
2092 }
2093
2094 #[cfg(feature = "full")]
2095 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2096 impl Parse for GenericMethodArgument {
2097 fn parse(input: ParseStream) -> Result<Self> {
2098 if input.peek(Lit) {
2099 let lit = input.parse()?;
2100 return Ok(GenericMethodArgument::Const(Expr::Lit(lit)));
2101 }
2102
2103 if input.peek(token::Brace) {
2104 let block: ExprBlock = input.parse()?;
2105 return Ok(GenericMethodArgument::Const(Expr::Block(block)));
2106 }
2107
2108 input.parse().map(GenericMethodArgument::Type)
2109 }
2110 }
2111
2112 #[cfg(feature = "full")]
2113 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2114 impl Parse for MethodTurbofish {
2115 fn parse(input: ParseStream) -> Result<Self> {
2116 Ok(MethodTurbofish {
2117 colon2_token: input.parse()?,
2118 lt_token: input.parse()?,
2119 args: {
2120 let mut args = Punctuated::new();
2121 loop {
2122 if input.peek(Token![>]) {
2123 break;
2124 }
2125 let value: GenericMethodArgument = input.parse()?;
2126 args.push_value(value);
2127 if input.peek(Token![>]) {
2128 break;
2129 }
2130 let punct = input.parse()?;
2131 args.push_punct(punct);
2132 }
2133 args
2134 },
2135 gt_token: input.parse()?,
2136 })
2137 }
2138 }
2139
2140 #[cfg(feature = "full")]
2141 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2142 impl Parse for ExprLet {
2143 fn parse(input: ParseStream) -> Result<Self> {
2144 Ok(ExprLet {
2145 attrs: Vec::new(),
2146 let_token: input.parse()?,
2147 pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2148 eq_token: input.parse()?,
2149 expr: Box::new({
2150 let allow_struct = AllowStruct(false);
2151 let lhs = unary_expr(input, allow_struct)?;
2152 parse_expr(input, lhs, allow_struct, Precedence::Compare)?
2153 }),
2154 })
2155 }
2156 }
2157
2158 #[cfg(feature = "full")]
2159 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2160 impl Parse for ExprIf {
2161 fn parse(input: ParseStream) -> Result<Self> {
2162 let attrs = input.call(Attribute::parse_outer)?;
2163 Ok(ExprIf {
2164 attrs,
2165 if_token: input.parse()?,
2166 cond: Box::new(input.call(Expr::parse_without_eager_brace)?),
2167 then_branch: input.parse()?,
2168 else_branch: {
2169 if input.peek(Token![else]) {
2170 Some(input.call(else_block)?)
2171 } else {
2172 None
2173 }
2174 },
2175 })
2176 }
2177 }
2178
2179 #[cfg(feature = "full")]
2180 fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
2181 let else_token: Token![else] = input.parse()?;
2182
2183 let lookahead = input.lookahead1();
2184 let else_branch = if input.peek(Token![if]) {
2185 input.parse().map(Expr::If)?
2186 } else if input.peek(token::Brace) {
2187 Expr::Block(ExprBlock {
2188 attrs: Vec::new(),
2189 label: None,
2190 block: input.parse()?,
2191 })
2192 } else {
2193 return Err(lookahead.error());
2194 };
2195
2196 Ok((else_token, Box::new(else_branch)))
2197 }
2198
2199 #[cfg(feature = "full")]
2200 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2201 impl Parse for ExprForLoop {
2202 fn parse(input: ParseStream) -> Result<Self> {
2203 let mut attrs = input.call(Attribute::parse_outer)?;
2204 let label: Option<Label> = input.parse()?;
2205 let for_token: Token![for] = input.parse()?;
2206
2207 let pat = pat::parsing::multi_pat_with_leading_vert(input)?;
2208
2209 let in_token: Token![in] = input.parse()?;
2210 let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2211
2212 let content;
2213 let brace_token = braced!(content in input);
2214 attr::parsing::parse_inner(&content, &mut attrs)?;
2215 let stmts = content.call(Block::parse_within)?;
2216
2217 Ok(ExprForLoop {
2218 attrs,
2219 label,
2220 for_token,
2221 pat,
2222 in_token,
2223 expr: Box::new(expr),
2224 body: Block { brace_token, stmts },
2225 })
2226 }
2227 }
2228
2229 #[cfg(feature = "full")]
2230 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2231 impl Parse for ExprLoop {
2232 fn parse(input: ParseStream) -> Result<Self> {
2233 let mut attrs = input.call(Attribute::parse_outer)?;
2234 let label: Option<Label> = input.parse()?;
2235 let loop_token: Token![loop] = input.parse()?;
2236
2237 let content;
2238 let brace_token = braced!(content in input);
2239 attr::parsing::parse_inner(&content, &mut attrs)?;
2240 let stmts = content.call(Block::parse_within)?;
2241
2242 Ok(ExprLoop {
2243 attrs,
2244 label,
2245 loop_token,
2246 body: Block { brace_token, stmts },
2247 })
2248 }
2249 }
2250
2251 #[cfg(feature = "full")]
2252 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2253 impl Parse for ExprMatch {
2254 fn parse(input: ParseStream) -> Result<Self> {
2255 let mut attrs = input.call(Attribute::parse_outer)?;
2256 let match_token: Token![match] = input.parse()?;
2257 let expr = Expr::parse_without_eager_brace(input)?;
2258
2259 let content;
2260 let brace_token = braced!(content in input);
2261 attr::parsing::parse_inner(&content, &mut attrs)?;
2262
2263 let mut arms = Vec::new();
2264 while !content.is_empty() {
2265 arms.push(content.call(Arm::parse)?);
2266 }
2267
2268 Ok(ExprMatch {
2269 attrs,
2270 match_token,
2271 expr: Box::new(expr),
2272 brace_token,
2273 arms,
2274 })
2275 }
2276 }
2277
2278 macro_rules! impl_by_parsing_expr {
2279 (
2280 $(
2281 $expr_type:ty, $variant:ident, $msg:expr,
2282 )*
2283 ) => {
2284 $(
2285 #[cfg(all(feature = "full", feature = "printing"))]
2286 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2287 impl Parse for $expr_type {
2288 fn parse(input: ParseStream) -> Result<Self> {
2289 let mut expr: Expr = input.parse()?;
2290 loop {
2291 match expr {
2292 Expr::$variant(inner) => return Ok(inner),
2293 Expr::Group(next) => expr = *next.expr,
2294 _ => return Err(Error::new_spanned(expr, $msg)),
2295 }
2296 }
2297 }
2298 }
2299 )*
2300 };
2301 }
2302
2303 impl_by_parsing_expr! {
2304 ExprAssign, Assign, "expected assignment expression",
2305 ExprAssignOp, AssignOp, "expected compound assignment expression",
2306 ExprAwait, Await, "expected await expression",
2307 ExprBinary, Binary, "expected binary operation",
2308 ExprCall, Call, "expected function call expression",
2309 ExprCast, Cast, "expected cast expression",
2310 ExprField, Field, "expected struct field access",
2311 ExprIndex, Index, "expected indexing expression",
2312 ExprMethodCall, MethodCall, "expected method call expression",
2313 ExprRange, Range, "expected range expression",
2314 ExprTry, Try, "expected try expression",
2315 ExprTuple, Tuple, "expected tuple expression",
2316 ExprType, Type, "expected type ascription expression",
2317 }
2318
2319 #[cfg(feature = "full")]
2320 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2321 impl Parse for ExprBox {
2322 fn parse(input: ParseStream) -> Result<Self> {
2323 let attrs = Vec::new();
2324 let allow_struct = AllowStruct(true);
2325 expr_box(input, attrs, allow_struct)
2326 }
2327 }
2328
2329 #[cfg(feature = "full")]
2330 fn expr_box(
2331 input: ParseStream,
2332 attrs: Vec<Attribute>,
2333 allow_struct: AllowStruct,
2334 ) -> Result<ExprBox> {
2335 Ok(ExprBox {
2336 attrs,
2337 box_token: input.parse()?,
2338 expr: Box::new(unary_expr(input, allow_struct)?),
2339 })
2340 }
2341
2342 #[cfg(feature = "full")]
2343 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2344 impl Parse for ExprUnary {
2345 fn parse(input: ParseStream) -> Result<Self> {
2346 let attrs = Vec::new();
2347 let allow_struct = AllowStruct(true);
2348 expr_unary(input, attrs, allow_struct)
2349 }
2350 }
2351
2352 #[cfg(feature = "full")]
2353 fn expr_unary(
2354 input: ParseStream,
2355 attrs: Vec<Attribute>,
2356 allow_struct: AllowStruct,
2357 ) -> Result<ExprUnary> {
2358 Ok(ExprUnary {
2359 attrs,
2360 op: input.parse()?,
2361 expr: Box::new(unary_expr(input, allow_struct)?),
2362 })
2363 }
2364
2365 #[cfg(feature = "full")]
2366 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2367 impl Parse for ExprClosure {
2368 fn parse(input: ParseStream) -> Result<Self> {
2369 let allow_struct = AllowStruct(true);
2370 expr_closure(input, allow_struct)
2371 }
2372 }
2373
2374 #[cfg(feature = "full")]
2375 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2376 impl Parse for ExprReference {
2377 fn parse(input: ParseStream) -> Result<Self> {
2378 let allow_struct = AllowStruct(true);
2379 Ok(ExprReference {
2380 attrs: Vec::new(),
2381 and_token: input.parse()?,
2382 raw: Reserved::default(),
2383 mutability: input.parse()?,
2384 expr: Box::new(unary_expr(input, allow_struct)?),
2385 })
2386 }
2387 }
2388
2389 #[cfg(feature = "full")]
2390 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2391 impl Parse for ExprBreak {
2392 fn parse(input: ParseStream) -> Result<Self> {
2393 let allow_struct = AllowStruct(true);
2394 expr_break(input, allow_struct)
2395 }
2396 }
2397
2398 #[cfg(feature = "full")]
2399 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2400 impl Parse for ExprReturn {
2401 fn parse(input: ParseStream) -> Result<Self> {
2402 let allow_struct = AllowStruct(true);
2403 expr_ret(input, allow_struct)
2404 }
2405 }
2406
2407 #[cfg(feature = "full")]
2408 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2409 impl Parse for ExprTryBlock {
2410 fn parse(input: ParseStream) -> Result<Self> {
2411 Ok(ExprTryBlock {
2412 attrs: Vec::new(),
2413 try_token: input.parse()?,
2414 block: input.parse()?,
2415 })
2416 }
2417 }
2418
2419 #[cfg(feature = "full")]
2420 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2421 impl Parse for ExprYield {
2422 fn parse(input: ParseStream) -> Result<Self> {
2423 Ok(ExprYield {
2424 attrs: Vec::new(),
2425 yield_token: input.parse()?,
2426 expr: {
2427 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
2428 Some(input.parse()?)
2429 } else {
2430 None
2431 }
2432 },
2433 })
2434 }
2435 }
2436
2437 #[cfg(feature = "full")]
2438 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2439 let movability: Option<Token![static]> = input.parse()?;
2440 let asyncness: Option<Token![async]> = input.parse()?;
2441 let capture: Option<Token![move]> = input.parse()?;
2442 let or1_token: Token![|] = input.parse()?;
2443
2444 let mut inputs = Punctuated::new();
2445 loop {
2446 if input.peek(Token![|]) {
2447 break;
2448 }
2449 let value = closure_arg(input)?;
2450 inputs.push_value(value);
2451 if input.peek(Token![|]) {
2452 break;
2453 }
2454 let punct: Token![,] = input.parse()?;
2455 inputs.push_punct(punct);
2456 }
2457
2458 let or2_token: Token![|] = input.parse()?;
2459
2460 let (output, body) = if input.peek(Token![->]) {
2461 let arrow_token: Token![->] = input.parse()?;
2462 let ty: Type = input.parse()?;
2463 let body: Block = input.parse()?;
2464 let output = ReturnType::Type(arrow_token, Box::new(ty));
2465 let block = Expr::Block(ExprBlock {
2466 attrs: Vec::new(),
2467 label: None,
2468 block: body,
2469 });
2470 (output, block)
2471 } else {
2472 let body = ambiguous_expr(input, allow_struct)?;
2473 (ReturnType::Default, body)
2474 };
2475
2476 Ok(ExprClosure {
2477 attrs: Vec::new(),
2478 movability,
2479 asyncness,
2480 capture,
2481 or1_token,
2482 inputs,
2483 or2_token,
2484 output,
2485 body: Box::new(body),
2486 })
2487 }
2488
2489 #[cfg(feature = "full")]
2490 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2491 impl Parse for ExprAsync {
2492 fn parse(input: ParseStream) -> Result<Self> {
2493 Ok(ExprAsync {
2494 attrs: Vec::new(),
2495 async_token: input.parse()?,
2496 capture: input.parse()?,
2497 block: input.parse()?,
2498 })
2499 }
2500 }
2501
2502 #[cfg(feature = "full")]
2503 fn closure_arg(input: ParseStream) -> Result<Pat> {
2504 let attrs = input.call(Attribute::parse_outer)?;
2505 let mut pat: Pat = input.parse()?;
2506
2507 if input.peek(Token![:]) {
2508 Ok(Pat::Type(PatType {
2509 attrs,
2510 pat: Box::new(pat),
2511 colon_token: input.parse()?,
2512 ty: input.parse()?,
2513 }))
2514 } else {
2515 match &mut pat {
2516 Pat::Box(pat) => pat.attrs = attrs,
2517 Pat::Ident(pat) => pat.attrs = attrs,
2518 Pat::Lit(pat) => pat.attrs = attrs,
2519 Pat::Macro(pat) => pat.attrs = attrs,
2520 Pat::Or(pat) => pat.attrs = attrs,
2521 Pat::Path(pat) => pat.attrs = attrs,
2522 Pat::Range(pat) => pat.attrs = attrs,
2523 Pat::Reference(pat) => pat.attrs = attrs,
2524 Pat::Rest(pat) => pat.attrs = attrs,
2525 Pat::Slice(pat) => pat.attrs = attrs,
2526 Pat::Struct(pat) => pat.attrs = attrs,
2527 Pat::Tuple(pat) => pat.attrs = attrs,
2528 Pat::TupleStruct(pat) => pat.attrs = attrs,
2529 Pat::Type(_) => unreachable!(),
2530 Pat::Verbatim(_) => {}
2531 Pat::Wild(pat) => pat.attrs = attrs,
2532
2533 #[cfg(syn_no_non_exhaustive)]
2534 _ => unreachable!(),
2535 }
2536 Ok(pat)
2537 }
2538 }
2539
2540 #[cfg(feature = "full")]
2541 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2542 impl Parse for ExprWhile {
2543 fn parse(input: ParseStream) -> Result<Self> {
2544 let mut attrs = input.call(Attribute::parse_outer)?;
2545 let label: Option<Label> = input.parse()?;
2546 let while_token: Token![while] = input.parse()?;
2547 let cond = Expr::parse_without_eager_brace(input)?;
2548
2549 let content;
2550 let brace_token = braced!(content in input);
2551 attr::parsing::parse_inner(&content, &mut attrs)?;
2552 let stmts = content.call(Block::parse_within)?;
2553
2554 Ok(ExprWhile {
2555 attrs,
2556 label,
2557 while_token,
2558 cond: Box::new(cond),
2559 body: Block { brace_token, stmts },
2560 })
2561 }
2562 }
2563
2564 #[cfg(feature = "full")]
2565 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2566 impl Parse for Label {
2567 fn parse(input: ParseStream) -> Result<Self> {
2568 Ok(Label {
2569 name: input.parse()?,
2570 colon_token: input.parse()?,
2571 })
2572 }
2573 }
2574
2575 #[cfg(feature = "full")]
2576 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2577 impl Parse for Option<Label> {
2578 fn parse(input: ParseStream) -> Result<Self> {
2579 if input.peek(Lifetime) {
2580 input.parse().map(Some)
2581 } else {
2582 Ok(None)
2583 }
2584 }
2585 }
2586
2587 #[cfg(feature = "full")]
2588 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2589 impl Parse for ExprContinue {
2590 fn parse(input: ParseStream) -> Result<Self> {
2591 Ok(ExprContinue {
2592 attrs: Vec::new(),
2593 continue_token: input.parse()?,
2594 label: input.parse()?,
2595 })
2596 }
2597 }
2598
2599 #[cfg(feature = "full")]
2600 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2601 Ok(ExprBreak {
2602 attrs: Vec::new(),
2603 break_token: input.parse()?,
2604 label: input.parse()?,
2605 expr: {
2606 if input.is_empty()
2607 || input.peek(Token![,])
2608 || input.peek(Token![;])
2609 || !allow_struct.0 && input.peek(token::Brace)
2610 {
2611 None
2612 } else {
2613 let expr = ambiguous_expr(input, allow_struct)?;
2614 Some(Box::new(expr))
2615 }
2616 },
2617 })
2618 }
2619
2620 #[cfg(feature = "full")]
2621 fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2622 Ok(ExprReturn {
2623 attrs: Vec::new(),
2624 return_token: input.parse()?,
2625 expr: {
2626 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2627 None
2628 } else {
2629 let expr = ambiguous_expr(input, allow_struct)?;
2635 Some(Box::new(expr))
2636 }
2637 },
2638 })
2639 }
2640
2641 #[cfg(feature = "full")]
2642 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2643 impl Parse for FieldValue {
2644 fn parse(input: ParseStream) -> Result<Self> {
2645 let attrs = input.call(Attribute::parse_outer)?;
2646 let member: Member = input.parse()?;
2647 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2648 let colon_token: Token![:] = input.parse()?;
2649 let value: Expr = input.parse()?;
2650 (Some(colon_token), value)
2651 } else if let Member::Named(ident) = &member {
2652 let value = Expr::Path(ExprPath {
2653 attrs: Vec::new(),
2654 qself: None,
2655 path: Path::from(ident.clone()),
2656 });
2657 (None, value)
2658 } else {
2659 unreachable!()
2660 };
2661
2662 Ok(FieldValue {
2663 attrs,
2664 member,
2665 colon_token,
2666 expr: value,
2667 })
2668 }
2669 }
2670
2671 #[cfg(feature = "full")]
2672 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2673 impl Parse for ExprStruct {
2674 fn parse(input: ParseStream) -> Result<Self> {
2675 let path: Path = input.parse()?;
2676 expr_struct_helper(input, path)
2677 }
2678 }
2679
2680 #[cfg(feature = "full")]
2681 fn expr_struct_helper(input: ParseStream, path: Path) -> Result<ExprStruct> {
2682 let content;
2683 let brace_token = braced!(content in input);
2684
2685 let mut fields = Punctuated::new();
2686 while !content.is_empty() {
2687 if content.peek(Token![..]) {
2688 return Ok(ExprStruct {
2689 attrs: Vec::new(),
2690 brace_token,
2691 path,
2692 fields,
2693 dot2_token: Some(content.parse()?),
2694 rest: if content.is_empty() {
2695 None
2696 } else {
2697 Some(Box::new(content.parse()?))
2698 },
2699 });
2700 }
2701
2702 fields.push(content.parse()?);
2703 if content.is_empty() {
2704 break;
2705 }
2706 let punct: Token![,] = content.parse()?;
2707 fields.push_punct(punct);
2708 }
2709
2710 Ok(ExprStruct {
2711 attrs: Vec::new(),
2712 brace_token,
2713 path,
2714 fields,
2715 dot2_token: None,
2716 rest: None,
2717 })
2718 }
2719
2720 #[cfg(feature = "full")]
2721 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2722 impl Parse for ExprUnsafe {
2723 fn parse(input: ParseStream) -> Result<Self> {
2724 let unsafe_token: Token![unsafe] = input.parse()?;
2725
2726 let content;
2727 let brace_token = braced!(content in input);
2728 let inner_attrs = content.call(Attribute::parse_inner)?;
2729 let stmts = content.call(Block::parse_within)?;
2730
2731 Ok(ExprUnsafe {
2732 attrs: inner_attrs,
2733 unsafe_token,
2734 block: Block { brace_token, stmts },
2735 })
2736 }
2737 }
2738
2739 #[cfg(feature = "full")]
2740 pub(crate) fn expr_const(input: ParseStream) -> Result<TokenStream> {
2741 let begin = input.fork();
2742 input.parse::<Token![const]>()?;
2743
2744 let content;
2745 braced!(content in input);
2746 content.call(Attribute::parse_inner)?;
2747 content.call(Block::parse_within)?;
2748
2749 Ok(verbatim::between(begin, input))
2750 }
2751
2752 #[cfg(feature = "full")]
2753 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2754 impl Parse for ExprBlock {
2755 fn parse(input: ParseStream) -> Result<Self> {
2756 let mut attrs = input.call(Attribute::parse_outer)?;
2757 let label: Option<Label> = input.parse()?;
2758
2759 let content;
2760 let brace_token = braced!(content in input);
2761 attr::parsing::parse_inner(&content, &mut attrs)?;
2762 let stmts = content.call(Block::parse_within)?;
2763
2764 Ok(ExprBlock {
2765 attrs,
2766 label,
2767 block: Block { brace_token, stmts },
2768 })
2769 }
2770 }
2771
2772 #[cfg(feature = "full")]
2773 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2774 Ok(ExprRange {
2775 attrs: Vec::new(),
2776 from: None,
2777 limits: input.parse()?,
2778 to: {
2779 if input.is_empty()
2780 || input.peek(Token![,])
2781 || input.peek(Token![;])
2782 || input.peek(Token![.]) && !input.peek(Token![..])
2783 || !allow_struct.0 && input.peek(token::Brace)
2784 {
2785 None
2786 } else {
2787 let to = ambiguous_expr(input, allow_struct)?;
2788 Some(Box::new(to))
2789 }
2790 },
2791 })
2792 }
2793
2794 #[cfg(feature = "full")]
2795 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2796 impl Parse for RangeLimits {
2797 fn parse(input: ParseStream) -> Result<Self> {
2798 let lookahead = input.lookahead1();
2799 if lookahead.peek(Token![..=]) {
2800 input.parse().map(RangeLimits::Closed)
2801 } else if lookahead.peek(Token![...]) {
2802 let dot3: Token![...] = input.parse()?;
2803 Ok(RangeLimits::Closed(Token))
2804 } else if lookahead.peek(Token![..]) {
2805 input.parse().map(RangeLimits::HalfOpen)
2806 } else {
2807 Err(lookahead.error())
2808 }
2809 }
2810 }
2811
2812 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2813 impl Parse for ExprPath {
2814 fn parse(input: ParseStream) -> Result<Self> {
2815 #[cfg(not(feature = "full"))]
2816 let attrs = Vec::new();
2817 #[cfg(feature = "full")]
2818 let attrs = input.call(Attribute::parse_outer)?;
2819
2820 let (qself, path) = path::parsing::qpath(input, true)?;
2821
2822 Ok(ExprPath { attrs, qself, path })
2823 }
2824 }
2825
2826 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2827 impl Parse for Member {
2828 fn parse(input: ParseStream) -> Result<Self> {
2829 if input.peek(Ident) {
2830 input.parse().map(Member::Named)
2831 } else if input.peek(LitInt) {
2832 input.parse().map(Member::Unnamed)
2833 } else {
2834 Err(input.error("expected identifier or integer"))
2835 }
2836 }
2837 }
2838
2839 #[cfg(feature = "full")]
2840 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2841 impl Parse for Arm {
2842 fn parse(input: ParseStream) -> Result<Arm> {
2843 let requires_comma;
2844 Ok(Arm {
2845 attrs: input.call(Attribute::parse_outer)?,
2846 pat: pat::parsing::multi_pat_with_leading_vert(input)?,
2847 guard: {
2848 if input.peek(Token![if]) {
2849 let if_token: Token![if] = input.parse()?;
2850 let guard: Expr = input.parse()?;
2851 Some((if_token, Box::new(guard)))
2852 } else {
2853 None
2854 }
2855 },
2856 fat_arrow_token: input.parse()?,
2857 body: {
2858 let body = input.call(expr_early)?;
2859 requires_comma = requires_terminator(&body);
2860 Box::new(body)
2861 },
2862 comma: {
2863 if requires_comma && !input.is_empty() {
2864 Some(input.parse()?)
2865 } else {
2866 input.parse()?
2867 }
2868 },
2869 })
2870 }
2871 }
2872
2873 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
2874 impl Parse for Index {
2875 fn parse(input: ParseStream) -> Result<Self> {
2876 let lit: LitInt = input.parse()?;
2877 if lit.suffix().is_empty() {
2878 Ok(Index {
2879 index: lit
2880 .base10_digits()
2881 .parse()
2882 .map_err(|err| Error::new(lit.span(), err))?,
2883 span: lit.span(),
2884 })
2885 } else {
2886 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2887 }
2888 }
2889 }
2890
2891 fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
2892 let mut float_repr = float.to_string();
2893 let trailing_dot = float_repr.ends_with('.');
2894 if trailing_dot {
2895 float_repr.truncate(float_repr.len() - 1);
2896 }
2897 for part in float_repr.split('.') {
2898 let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?;
2899 #[cfg(not(syn_no_const_vec_new))]
2900 let base = mem::replace(e, Expr::DUMMY);
2901 #[cfg(syn_no_const_vec_new)]
2902 let base = mem::replace(e, Expr::Verbatim(TokenStream::new()));
2903 *e = Expr::Field(ExprField {
2904 attrs: Vec::new(),
2905 base: Box::new(base),
2906 dot_token: Token,
2907 member: Member::Unnamed(index),
2908 });
2909 *dot_token = Token);
2910 }
2911 Ok(!trailing_dot)
2912 }
2913
2914 #[cfg(feature = "full")]
2915 impl Member {
2916 fn is_named(&self) -> bool {
2917 match *self {
2918 Member::Named(_) => true,
2919 Member::Unnamed(_) => false,
2920 }
2921 }
2922 }
2923
2924 fn check_cast(input: ParseStream) -> Result<()> {
2925 let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
2926 if input.peek2(token::Await) {
2927 "`.await`"
2928 } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
2929 "a method call"
2930 } else {
2931 "a field access"
2932 }
2933 } else if input.peek(Token![?]) {
2934 "`?`"
2935 } else if input.peek(token::Bracket) {
2936 "indexing"
2937 } else if input.peek(token::Paren) {
2938 "a function call"
2939 } else {
2940 return Ok(());
2941 };
2942 let msg = format!("casts cannot be followed by {}", kind);
2943 Err(input.error(msg))
2944 }
2945}
2946
2947#[cfg(feature = "printing")]
2948pub(crate) mod printing {
2949 use super::*;
2950 #[cfg(feature = "full")]
2951 use crate::attr::FilterAttrs;
2952 use proc_macro2::{Literal, TokenStream};
2953 use quote::{ToTokens, TokenStreamExt};
2954
2955 #[cfg(feature = "full")]
2958 fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
2959 if let Expr::Struct(_) = *e {
2960 token::Paren::default().surround(tokens, |tokens| {
2961 e.to_tokens(tokens);
2962 });
2963 } else {
2964 e.to_tokens(tokens);
2965 }
2966 }
2967
2968 #[cfg(feature = "full")]
2969 pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2970 tokens.append_all(attrs.outer());
2971 }
2972
2973 #[cfg(feature = "full")]
2974 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
2975 tokens.append_all(attrs.inner());
2976 }
2977
2978 #[cfg(not(feature = "full"))]
2979 pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
2980
2981 #[cfg(feature = "full")]
2982 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2983 impl ToTokens for ExprBox {
2984 fn to_tokens(&self, tokens: &mut TokenStream) {
2985 outer_attrs_to_tokens(&self.attrs, tokens);
2986 self.box_token.to_tokens(tokens);
2987 self.expr.to_tokens(tokens);
2988 }
2989 }
2990
2991 #[cfg(feature = "full")]
2992 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
2993 impl ToTokens for ExprArray {
2994 fn to_tokens(&self, tokens: &mut TokenStream) {
2995 outer_attrs_to_tokens(&self.attrs, tokens);
2996 self.bracket_token.surround(tokens, |tokens| {
2997 self.elems.to_tokens(tokens);
2998 });
2999 }
3000 }
3001
3002 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3003 impl ToTokens for ExprCall {
3004 fn to_tokens(&self, tokens: &mut TokenStream) {
3005 outer_attrs_to_tokens(&self.attrs, tokens);
3006 self.func.to_tokens(tokens);
3007 self.paren_token.surround(tokens, |tokens| {
3008 self.args.to_tokens(tokens);
3009 });
3010 }
3011 }
3012
3013 #[cfg(feature = "full")]
3014 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3015 impl ToTokens for ExprMethodCall {
3016 fn to_tokens(&self, tokens: &mut TokenStream) {
3017 outer_attrs_to_tokens(&self.attrs, tokens);
3018 self.receiver.to_tokens(tokens);
3019 self.dot_token.to_tokens(tokens);
3020 self.method.to_tokens(tokens);
3021 self.turbofish.to_tokens(tokens);
3022 self.paren_token.surround(tokens, |tokens| {
3023 self.args.to_tokens(tokens);
3024 });
3025 }
3026 }
3027
3028 #[cfg(feature = "full")]
3029 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3030 impl ToTokens for MethodTurbofish {
3031 fn to_tokens(&self, tokens: &mut TokenStream) {
3032 self.colon2_token.to_tokens(tokens);
3033 self.lt_token.to_tokens(tokens);
3034 self.args.to_tokens(tokens);
3035 self.gt_token.to_tokens(tokens);
3036 }
3037 }
3038
3039 #[cfg(feature = "full")]
3040 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3041 impl ToTokens for GenericMethodArgument {
3042 fn to_tokens(&self, tokens: &mut TokenStream) {
3043 match self {
3044 GenericMethodArgument::Type(t) => t.to_tokens(tokens),
3045 GenericMethodArgument::Const(c) => c.to_tokens(tokens),
3046 }
3047 }
3048 }
3049
3050 #[cfg(feature = "full")]
3051 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3052 impl ToTokens for ExprTuple {
3053 fn to_tokens(&self, tokens: &mut TokenStream) {
3054 outer_attrs_to_tokens(&self.attrs, tokens);
3055 self.paren_token.surround(tokens, |tokens| {
3056 self.elems.to_tokens(tokens);
3057 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3060 <Token![,]>::default().to_tokens(tokens);
3061 }
3062 });
3063 }
3064 }
3065
3066 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3067 impl ToTokens for ExprBinary {
3068 fn to_tokens(&self, tokens: &mut TokenStream) {
3069 outer_attrs_to_tokens(&self.attrs, tokens);
3070 self.left.to_tokens(tokens);
3071 self.op.to_tokens(tokens);
3072 self.right.to_tokens(tokens);
3073 }
3074 }
3075
3076 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3077 impl ToTokens for ExprUnary {
3078 fn to_tokens(&self, tokens: &mut TokenStream) {
3079 outer_attrs_to_tokens(&self.attrs, tokens);
3080 self.op.to_tokens(tokens);
3081 self.expr.to_tokens(tokens);
3082 }
3083 }
3084
3085 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3086 impl ToTokens for ExprLit {
3087 fn to_tokens(&self, tokens: &mut TokenStream) {
3088 outer_attrs_to_tokens(&self.attrs, tokens);
3089 self.lit.to_tokens(tokens);
3090 }
3091 }
3092
3093 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3094 impl ToTokens for ExprCast {
3095 fn to_tokens(&self, tokens: &mut TokenStream) {
3096 outer_attrs_to_tokens(&self.attrs, tokens);
3097 self.expr.to_tokens(tokens);
3098 self.as_token.to_tokens(tokens);
3099 self.ty.to_tokens(tokens);
3100 }
3101 }
3102
3103 #[cfg(feature = "full")]
3104 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3105 impl ToTokens for ExprType {
3106 fn to_tokens(&self, tokens: &mut TokenStream) {
3107 outer_attrs_to_tokens(&self.attrs, tokens);
3108 self.expr.to_tokens(tokens);
3109 self.colon_token.to_tokens(tokens);
3110 self.ty.to_tokens(tokens);
3111 }
3112 }
3113
3114 #[cfg(feature = "full")]
3115 fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
3116 if let Some((else_token, else_)) = else_ {
3117 else_token.to_tokens(tokens);
3118
3119 match **else_ {
3122 Expr::If(_) | Expr::Block(_) => {
3123 else_.to_tokens(tokens);
3124 }
3125 _ => {
3126 token::Brace::default().surround(tokens, |tokens| {
3127 else_.to_tokens(tokens);
3128 });
3129 }
3130 }
3131 }
3132 }
3133
3134 #[cfg(feature = "full")]
3135 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3136 impl ToTokens for ExprLet {
3137 fn to_tokens(&self, tokens: &mut TokenStream) {
3138 outer_attrs_to_tokens(&self.attrs, tokens);
3139 self.let_token.to_tokens(tokens);
3140 self.pat.to_tokens(tokens);
3141 self.eq_token.to_tokens(tokens);
3142 wrap_bare_struct(tokens, &self.expr);
3143 }
3144 }
3145
3146 #[cfg(feature = "full")]
3147 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3148 impl ToTokens for ExprIf {
3149 fn to_tokens(&self, tokens: &mut TokenStream) {
3150 outer_attrs_to_tokens(&self.attrs, tokens);
3151 self.if_token.to_tokens(tokens);
3152 wrap_bare_struct(tokens, &self.cond);
3153 self.then_branch.to_tokens(tokens);
3154 maybe_wrap_else(tokens, &self.else_branch);
3155 }
3156 }
3157
3158 #[cfg(feature = "full")]
3159 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3160 impl ToTokens for ExprWhile {
3161 fn to_tokens(&self, tokens: &mut TokenStream) {
3162 outer_attrs_to_tokens(&self.attrs, tokens);
3163 self.label.to_tokens(tokens);
3164 self.while_token.to_tokens(tokens);
3165 wrap_bare_struct(tokens, &self.cond);
3166 self.body.brace_token.surround(tokens, |tokens| {
3167 inner_attrs_to_tokens(&self.attrs, tokens);
3168 tokens.append_all(&self.body.stmts);
3169 });
3170 }
3171 }
3172
3173 #[cfg(feature = "full")]
3174 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3175 impl ToTokens for ExprForLoop {
3176 fn to_tokens(&self, tokens: &mut TokenStream) {
3177 outer_attrs_to_tokens(&self.attrs, tokens);
3178 self.label.to_tokens(tokens);
3179 self.for_token.to_tokens(tokens);
3180 self.pat.to_tokens(tokens);
3181 self.in_token.to_tokens(tokens);
3182 wrap_bare_struct(tokens, &self.expr);
3183 self.body.brace_token.surround(tokens, |tokens| {
3184 inner_attrs_to_tokens(&self.attrs, tokens);
3185 tokens.append_all(&self.body.stmts);
3186 });
3187 }
3188 }
3189
3190 #[cfg(feature = "full")]
3191 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3192 impl ToTokens for ExprLoop {
3193 fn to_tokens(&self, tokens: &mut TokenStream) {
3194 outer_attrs_to_tokens(&self.attrs, tokens);
3195 self.label.to_tokens(tokens);
3196 self.loop_token.to_tokens(tokens);
3197 self.body.brace_token.surround(tokens, |tokens| {
3198 inner_attrs_to_tokens(&self.attrs, tokens);
3199 tokens.append_all(&self.body.stmts);
3200 });
3201 }
3202 }
3203
3204 #[cfg(feature = "full")]
3205 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3206 impl ToTokens for ExprMatch {
3207 fn to_tokens(&self, tokens: &mut TokenStream) {
3208 outer_attrs_to_tokens(&self.attrs, tokens);
3209 self.match_token.to_tokens(tokens);
3210 wrap_bare_struct(tokens, &self.expr);
3211 self.brace_token.surround(tokens, |tokens| {
3212 inner_attrs_to_tokens(&self.attrs, tokens);
3213 for (i, arm) in self.arms.iter().enumerate() {
3214 arm.to_tokens(tokens);
3215 let is_last = i == self.arms.len() - 1;
3218 if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3219 <Token![,]>::default().to_tokens(tokens);
3220 }
3221 }
3222 });
3223 }
3224 }
3225
3226 #[cfg(feature = "full")]
3227 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3228 impl ToTokens for ExprAsync {
3229 fn to_tokens(&self, tokens: &mut TokenStream) {
3230 outer_attrs_to_tokens(&self.attrs, tokens);
3231 self.async_token.to_tokens(tokens);
3232 self.capture.to_tokens(tokens);
3233 self.block.to_tokens(tokens);
3234 }
3235 }
3236
3237 #[cfg(feature = "full")]
3238 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3239 impl ToTokens for ExprAwait {
3240 fn to_tokens(&self, tokens: &mut TokenStream) {
3241 outer_attrs_to_tokens(&self.attrs, tokens);
3242 self.base.to_tokens(tokens);
3243 self.dot_token.to_tokens(tokens);
3244 self.await_token.to_tokens(tokens);
3245 }
3246 }
3247
3248 #[cfg(feature = "full")]
3249 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3250 impl ToTokens for ExprTryBlock {
3251 fn to_tokens(&self, tokens: &mut TokenStream) {
3252 outer_attrs_to_tokens(&self.attrs, tokens);
3253 self.try_token.to_tokens(tokens);
3254 self.block.to_tokens(tokens);
3255 }
3256 }
3257
3258 #[cfg(feature = "full")]
3259 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3260 impl ToTokens for ExprYield {
3261 fn to_tokens(&self, tokens: &mut TokenStream) {
3262 outer_attrs_to_tokens(&self.attrs, tokens);
3263 self.yield_token.to_tokens(tokens);
3264 self.expr.to_tokens(tokens);
3265 }
3266 }
3267
3268 #[cfg(feature = "full")]
3269 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3270 impl ToTokens for ExprClosure {
3271 fn to_tokens(&self, tokens: &mut TokenStream) {
3272 outer_attrs_to_tokens(&self.attrs, tokens);
3273 self.movability.to_tokens(tokens);
3274 self.asyncness.to_tokens(tokens);
3275 self.capture.to_tokens(tokens);
3276 self.or1_token.to_tokens(tokens);
3277 self.inputs.to_tokens(tokens);
3278 self.or2_token.to_tokens(tokens);
3279 self.output.to_tokens(tokens);
3280 self.body.to_tokens(tokens);
3281 }
3282 }
3283
3284 #[cfg(feature = "full")]
3285 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3286 impl ToTokens for ExprUnsafe {
3287 fn to_tokens(&self, tokens: &mut TokenStream) {
3288 outer_attrs_to_tokens(&self.attrs, tokens);
3289 self.unsafe_token.to_tokens(tokens);
3290 self.block.brace_token.surround(tokens, |tokens| {
3291 inner_attrs_to_tokens(&self.attrs, tokens);
3292 tokens.append_all(&self.block.stmts);
3293 });
3294 }
3295 }
3296
3297 #[cfg(feature = "full")]
3298 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3299 impl ToTokens for ExprBlock {
3300 fn to_tokens(&self, tokens: &mut TokenStream) {
3301 outer_attrs_to_tokens(&self.attrs, tokens);
3302 self.label.to_tokens(tokens);
3303 self.block.brace_token.surround(tokens, |tokens| {
3304 inner_attrs_to_tokens(&self.attrs, tokens);
3305 tokens.append_all(&self.block.stmts);
3306 });
3307 }
3308 }
3309
3310 #[cfg(feature = "full")]
3311 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3312 impl ToTokens for ExprAssign {
3313 fn to_tokens(&self, tokens: &mut TokenStream) {
3314 outer_attrs_to_tokens(&self.attrs, tokens);
3315 self.left.to_tokens(tokens);
3316 self.eq_token.to_tokens(tokens);
3317 self.right.to_tokens(tokens);
3318 }
3319 }
3320
3321 #[cfg(feature = "full")]
3322 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3323 impl ToTokens for ExprAssignOp {
3324 fn to_tokens(&self, tokens: &mut TokenStream) {
3325 outer_attrs_to_tokens(&self.attrs, tokens);
3326 self.left.to_tokens(tokens);
3327 self.op.to_tokens(tokens);
3328 self.right.to_tokens(tokens);
3329 }
3330 }
3331
3332 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3333 impl ToTokens for ExprField {
3334 fn to_tokens(&self, tokens: &mut TokenStream) {
3335 outer_attrs_to_tokens(&self.attrs, tokens);
3336 self.base.to_tokens(tokens);
3337 self.dot_token.to_tokens(tokens);
3338 self.member.to_tokens(tokens);
3339 }
3340 }
3341
3342 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3343 impl ToTokens for Member {
3344 fn to_tokens(&self, tokens: &mut TokenStream) {
3345 match self {
3346 Member::Named(ident) => ident.to_tokens(tokens),
3347 Member::Unnamed(index) => index.to_tokens(tokens),
3348 }
3349 }
3350 }
3351
3352 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3353 impl ToTokens for Index {
3354 fn to_tokens(&self, tokens: &mut TokenStream) {
3355 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3356 lit.set_span(self.span);
3357 tokens.append(lit);
3358 }
3359 }
3360
3361 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3362 impl ToTokens for ExprIndex {
3363 fn to_tokens(&self, tokens: &mut TokenStream) {
3364 outer_attrs_to_tokens(&self.attrs, tokens);
3365 self.expr.to_tokens(tokens);
3366 self.bracket_token.surround(tokens, |tokens| {
3367 self.index.to_tokens(tokens);
3368 });
3369 }
3370 }
3371
3372 #[cfg(feature = "full")]
3373 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3374 impl ToTokens for RangeLimits {
3375 fn to_tokens(&self, tokens: &mut TokenStream) {
3376 match self {
3377 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
3378 RangeLimits::Closed(t) => t.to_tokens(tokens),
3379 }
3380 }
3381 }
3382
3383 #[cfg(feature = "full")]
3384 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3385 impl ToTokens for ExprRange {
3386 fn to_tokens(&self, tokens: &mut TokenStream) {
3387 outer_attrs_to_tokens(&self.attrs, tokens);
3388 self.from.to_tokens(tokens);
3389 self.limits.to_tokens(tokens);
3390 self.to.to_tokens(tokens);
3391 }
3392 }
3393
3394 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3395 impl ToTokens for ExprPath {
3396 fn to_tokens(&self, tokens: &mut TokenStream) {
3397 outer_attrs_to_tokens(&self.attrs, tokens);
3398 path::printing::print_path(tokens, &self.qself, &self.path);
3399 }
3400 }
3401
3402 #[cfg(feature = "full")]
3403 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3404 impl ToTokens for ExprReference {
3405 fn to_tokens(&self, tokens: &mut TokenStream) {
3406 outer_attrs_to_tokens(&self.attrs, tokens);
3407 self.and_token.to_tokens(tokens);
3408 self.mutability.to_tokens(tokens);
3409 self.expr.to_tokens(tokens);
3410 }
3411 }
3412
3413 #[cfg(feature = "full")]
3414 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3415 impl ToTokens for ExprBreak {
3416 fn to_tokens(&self, tokens: &mut TokenStream) {
3417 outer_attrs_to_tokens(&self.attrs, tokens);
3418 self.break_token.to_tokens(tokens);
3419 self.label.to_tokens(tokens);
3420 self.expr.to_tokens(tokens);
3421 }
3422 }
3423
3424 #[cfg(feature = "full")]
3425 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3426 impl ToTokens for ExprContinue {
3427 fn to_tokens(&self, tokens: &mut TokenStream) {
3428 outer_attrs_to_tokens(&self.attrs, tokens);
3429 self.continue_token.to_tokens(tokens);
3430 self.label.to_tokens(tokens);
3431 }
3432 }
3433
3434 #[cfg(feature = "full")]
3435 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3436 impl ToTokens for ExprReturn {
3437 fn to_tokens(&self, tokens: &mut TokenStream) {
3438 outer_attrs_to_tokens(&self.attrs, tokens);
3439 self.return_token.to_tokens(tokens);
3440 self.expr.to_tokens(tokens);
3441 }
3442 }
3443
3444 #[cfg(feature = "full")]
3445 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3446 impl ToTokens for ExprMacro {
3447 fn to_tokens(&self, tokens: &mut TokenStream) {
3448 outer_attrs_to_tokens(&self.attrs, tokens);
3449 self.mac.to_tokens(tokens);
3450 }
3451 }
3452
3453 #[cfg(feature = "full")]
3454 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3455 impl ToTokens for ExprStruct {
3456 fn to_tokens(&self, tokens: &mut TokenStream) {
3457 outer_attrs_to_tokens(&self.attrs, tokens);
3458 self.path.to_tokens(tokens);
3459 self.brace_token.surround(tokens, |tokens| {
3460 self.fields.to_tokens(tokens);
3461 if let Some(dot2_token) = &self.dot2_token {
3462 dot2_token.to_tokens(tokens);
3463 } else if self.rest.is_some() {
3464 Token).to_tokens(tokens);
3465 }
3466 self.rest.to_tokens(tokens);
3467 });
3468 }
3469 }
3470
3471 #[cfg(feature = "full")]
3472 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3473 impl ToTokens for ExprRepeat {
3474 fn to_tokens(&self, tokens: &mut TokenStream) {
3475 outer_attrs_to_tokens(&self.attrs, tokens);
3476 self.bracket_token.surround(tokens, |tokens| {
3477 self.expr.to_tokens(tokens);
3478 self.semi_token.to_tokens(tokens);
3479 self.len.to_tokens(tokens);
3480 });
3481 }
3482 }
3483
3484 #[cfg(feature = "full")]
3485 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3486 impl ToTokens for ExprGroup {
3487 fn to_tokens(&self, tokens: &mut TokenStream) {
3488 outer_attrs_to_tokens(&self.attrs, tokens);
3489 self.group_token.surround(tokens, |tokens| {
3490 self.expr.to_tokens(tokens);
3491 });
3492 }
3493 }
3494
3495 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3496 impl ToTokens for ExprParen {
3497 fn to_tokens(&self, tokens: &mut TokenStream) {
3498 outer_attrs_to_tokens(&self.attrs, tokens);
3499 self.paren_token.surround(tokens, |tokens| {
3500 self.expr.to_tokens(tokens);
3501 });
3502 }
3503 }
3504
3505 #[cfg(feature = "full")]
3506 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3507 impl ToTokens for ExprTry {
3508 fn to_tokens(&self, tokens: &mut TokenStream) {
3509 outer_attrs_to_tokens(&self.attrs, tokens);
3510 self.expr.to_tokens(tokens);
3511 self.question_token.to_tokens(tokens);
3512 }
3513 }
3514
3515 #[cfg(feature = "full")]
3516 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3517 impl ToTokens for Label {
3518 fn to_tokens(&self, tokens: &mut TokenStream) {
3519 self.name.to_tokens(tokens);
3520 self.colon_token.to_tokens(tokens);
3521 }
3522 }
3523
3524 #[cfg(feature = "full")]
3525 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3526 impl ToTokens for FieldValue {
3527 fn to_tokens(&self, tokens: &mut TokenStream) {
3528 outer_attrs_to_tokens(&self.attrs, tokens);
3529 self.member.to_tokens(tokens);
3530 if let Some(colon_token) = &self.colon_token {
3531 colon_token.to_tokens(tokens);
3532 self.expr.to_tokens(tokens);
3533 }
3534 }
3535 }
3536
3537 #[cfg(feature = "full")]
3538 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
3539 impl ToTokens for Arm {
3540 fn to_tokens(&self, tokens: &mut TokenStream) {
3541 tokens.append_all(&self.attrs);
3542 self.pat.to_tokens(tokens);
3543 if let Some((if_token, guard)) = &self.guard {
3544 if_token.to_tokens(tokens);
3545 guard.to_tokens(tokens);
3546 }
3547 self.fat_arrow_token.to_tokens(tokens);
3548 self.body.to_tokens(tokens);
3549 self.comma.to_tokens(tokens);
3550 }
3551 }
3552}