1use crate::attr::Attribute;
2#[cfg(all(feature = "parsing", feature = "full"))]
3use crate::error::Result;
4#[cfg(feature = "parsing")]
5use crate::ext::IdentExt as _;
6#[cfg(feature = "full")]
7use crate::generics::BoundLifetimes;
8use crate::ident::Ident;
9#[cfg(any(feature = "parsing", feature = "full"))]
10use crate::lifetime::Lifetime;
11use crate::lit::Lit;
12use crate::mac::Macro;
13use crate::op::{BinOp, UnOp};
14#[cfg(feature = "parsing")]
15use crate::parse::ParseStream;
16#[cfg(feature = "full")]
17use crate::pat::Pat;
18use crate::path::{AngleBracketedGenericArguments, Path, QSelf};
19use crate::punctuated::Punctuated;
20#[cfg(feature = "full")]
21use crate::stmt::Block;
22use crate::token;
23#[cfg(feature = "full")]
24use crate::ty::ReturnType;
25use crate::ty::Type;
26use proc_macro2::{Span, TokenStream};
27#[cfg(feature = "printing")]
28use quote::IdentFragment;
29#[cfg(feature = "printing")]
30use std::fmt::{self, Display};
31use std::hash::{Hash, Hasher};
32#[cfg(all(feature = "parsing", feature = "full"))]
33use std::mem;
34
35ast_enum_of_structs! {
36 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
111 #[non_exhaustive]
112 pub enum Expr {
113 Array(ExprArray),
115
116 Assign(ExprAssign),
118
119 Async(ExprAsync),
121
122 Await(ExprAwait),
124
125 Binary(ExprBinary),
127
128 Block(ExprBlock),
130
131 Break(ExprBreak),
134
135 Call(ExprCall),
137
138 Cast(ExprCast),
140
141 Closure(ExprClosure),
143
144 Const(ExprConst),
146
147 Continue(ExprContinue),
149
150 Field(ExprField),
153
154 ForLoop(ExprForLoop),
156
157 Group(ExprGroup),
163
164 If(ExprIf),
170
171 Index(ExprIndex),
173
174 Infer(ExprInfer),
176
177 Let(ExprLet),
179
180 Lit(ExprLit),
182
183 Loop(ExprLoop),
185
186 Macro(ExprMacro),
188
189 Match(ExprMatch),
191
192 MethodCall(ExprMethodCall),
194
195 Paren(ExprParen),
197
198 Path(ExprPath),
203
204 Range(ExprRange),
206
207 RawAddr(ExprRawAddr),
209
210 Reference(ExprReference),
212
213 Repeat(ExprRepeat),
215
216 Return(ExprReturn),
218
219 Struct(ExprStruct),
224
225 Try(ExprTry),
227
228 TryBlock(ExprTryBlock),
230
231 Tuple(ExprTuple),
233
234 Unary(ExprUnary),
236
237 Unsafe(ExprUnsafe),
239
240 Verbatim(TokenStream),
242
243 While(ExprWhile),
245
246 Yield(ExprYield),
248
249 }
267}
268
269ast_struct! {
270 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
272 pub struct ExprArray #full {
273 pub attrs: Vec<Attribute>,
274 pub bracket_token: token::Bracket,
275 pub elems: Punctuated<Expr, Token![,]>,
276 }
277}
278
279ast_struct! {
280 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
282 pub struct ExprAssign #full {
283 pub attrs: Vec<Attribute>,
284 pub left: Box<Expr>,
285 pub eq_token: Token![=],
286 pub right: Box<Expr>,
287 }
288}
289
290ast_struct! {
291 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
293 pub struct ExprAsync #full {
294 pub attrs: Vec<Attribute>,
295 pub async_token: Token![async],
296 pub capture: Option<Token![move]>,
297 pub block: Block,
298 }
299}
300
301ast_struct! {
302 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
304 pub struct ExprAwait #full {
305 pub attrs: Vec<Attribute>,
306 pub base: Box<Expr>,
307 pub dot_token: Token![.],
308 pub await_token: Token![await],
309 }
310}
311
312ast_struct! {
313 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
315 pub struct ExprBinary {
316 pub attrs: Vec<Attribute>,
317 pub left: Box<Expr>,
318 pub op: BinOp,
319 pub right: Box<Expr>,
320 }
321}
322
323ast_struct! {
324 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
326 pub struct ExprBlock #full {
327 pub attrs: Vec<Attribute>,
328 pub label: Option<Label>,
329 pub block: Block,
330 }
331}
332
333ast_struct! {
334 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
337 pub struct ExprBreak #full {
338 pub attrs: Vec<Attribute>,
339 pub break_token: Token![break],
340 pub label: Option<Lifetime>,
341 pub expr: Option<Box<Expr>>,
342 }
343}
344
345ast_struct! {
346 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
348 pub struct ExprCall {
349 pub attrs: Vec<Attribute>,
350 pub func: Box<Expr>,
351 pub paren_token: token::Paren,
352 pub args: Punctuated<Expr, Token![,]>,
353 }
354}
355
356ast_struct! {
357 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
359 pub struct ExprCast {
360 pub attrs: Vec<Attribute>,
361 pub expr: Box<Expr>,
362 pub as_token: Token![as],
363 pub ty: Box<Type>,
364 }
365}
366
367ast_struct! {
368 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
370 pub struct ExprClosure #full {
371 pub attrs: Vec<Attribute>,
372 pub lifetimes: Option<BoundLifetimes>,
373 pub constness: Option<Token![const]>,
374 pub movability: Option<Token![static]>,
375 pub asyncness: Option<Token![async]>,
376 pub capture: Option<Token![move]>,
377 pub or1_token: Token![|],
378 pub inputs: Punctuated<Pat, Token![,]>,
379 pub or2_token: Token![|],
380 pub output: ReturnType,
381 pub body: Box<Expr>,
382 }
383}
384
385ast_struct! {
386 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
388 pub struct ExprConst #full {
389 pub attrs: Vec<Attribute>,
390 pub const_token: Token![const],
391 pub block: Block,
392 }
393}
394
395ast_struct! {
396 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
398 pub struct ExprContinue #full {
399 pub attrs: Vec<Attribute>,
400 pub continue_token: Token![continue],
401 pub label: Option<Lifetime>,
402 }
403}
404
405ast_struct! {
406 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
409 pub struct ExprField {
410 pub attrs: Vec<Attribute>,
411 pub base: Box<Expr>,
412 pub dot_token: Token![.],
413 pub member: Member,
414 }
415}
416
417ast_struct! {
418 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
420 pub struct ExprForLoop #full {
421 pub attrs: Vec<Attribute>,
422 pub label: Option<Label>,
423 pub for_token: Token![for],
424 pub pat: Box<Pat>,
425 pub in_token: Token![in],
426 pub expr: Box<Expr>,
427 pub body: Block,
428 }
429}
430
431ast_struct! {
432 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
438 pub struct ExprGroup {
439 pub attrs: Vec<Attribute>,
440 pub group_token: token::Group,
441 pub expr: Box<Expr>,
442 }
443}
444
445ast_struct! {
446 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
452 pub struct ExprIf #full {
453 pub attrs: Vec<Attribute>,
454 pub if_token: Token![if],
455 pub cond: Box<Expr>,
456 pub then_branch: Block,
457 pub else_branch: Option<(Token![else], Box<Expr>)>,
458 }
459}
460
461ast_struct! {
462 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
464 pub struct ExprIndex {
465 pub attrs: Vec<Attribute>,
466 pub expr: Box<Expr>,
467 pub bracket_token: token::Bracket,
468 pub index: Box<Expr>,
469 }
470}
471
472ast_struct! {
473 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
475 pub struct ExprInfer #full {
476 pub attrs: Vec<Attribute>,
477 pub underscore_token: Token![_],
478 }
479}
480
481ast_struct! {
482 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
484 pub struct ExprLet #full {
485 pub attrs: Vec<Attribute>,
486 pub let_token: Token![let],
487 pub pat: Box<Pat>,
488 pub eq_token: Token![=],
489 pub expr: Box<Expr>,
490 }
491}
492
493ast_struct! {
494 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
496 pub struct ExprLit {
497 pub attrs: Vec<Attribute>,
498 pub lit: Lit,
499 }
500}
501
502ast_struct! {
503 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
505 pub struct ExprLoop #full {
506 pub attrs: Vec<Attribute>,
507 pub label: Option<Label>,
508 pub loop_token: Token![loop],
509 pub body: Block,
510 }
511}
512
513ast_struct! {
514 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
516 pub struct ExprMacro {
517 pub attrs: Vec<Attribute>,
518 pub mac: Macro,
519 }
520}
521
522ast_struct! {
523 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
525 pub struct ExprMatch #full {
526 pub attrs: Vec<Attribute>,
527 pub match_token: Token![match],
528 pub expr: Box<Expr>,
529 pub brace_token: token::Brace,
530 pub arms: Vec<Arm>,
531 }
532}
533
534ast_struct! {
535 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
537 pub struct ExprMethodCall {
538 pub attrs: Vec<Attribute>,
539 pub receiver: Box<Expr>,
540 pub dot_token: Token![.],
541 pub method: Ident,
542 pub turbofish: Option<AngleBracketedGenericArguments>,
543 pub paren_token: token::Paren,
544 pub args: Punctuated<Expr, Token![,]>,
545 }
546}
547
548ast_struct! {
549 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
551 pub struct ExprParen {
552 pub attrs: Vec<Attribute>,
553 pub paren_token: token::Paren,
554 pub expr: Box<Expr>,
555 }
556}
557
558ast_struct! {
559 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
564 pub struct ExprPath {
565 pub attrs: Vec<Attribute>,
566 pub qself: Option<QSelf>,
567 pub path: Path,
568 }
569}
570
571ast_struct! {
572 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
574 pub struct ExprRange #full {
575 pub attrs: Vec<Attribute>,
576 pub start: Option<Box<Expr>>,
577 pub limits: RangeLimits,
578 pub end: Option<Box<Expr>>,
579 }
580}
581
582ast_struct! {
583 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
585 pub struct ExprRawAddr #full {
586 pub attrs: Vec<Attribute>,
587 pub and_token: Token![&],
588 pub raw: Token![raw],
589 pub mutability: PointerMutability,
590 pub expr: Box<Expr>,
591 }
592}
593
594ast_struct! {
595 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
597 pub struct ExprReference {
598 pub attrs: Vec<Attribute>,
599 pub and_token: Token![&],
600 pub mutability: Option<Token![mut]>,
601 pub expr: Box<Expr>,
602 }
603}
604
605ast_struct! {
606 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
608 pub struct ExprRepeat #full {
609 pub attrs: Vec<Attribute>,
610 pub bracket_token: token::Bracket,
611 pub expr: Box<Expr>,
612 pub semi_token: Token![;],
613 pub len: Box<Expr>,
614 }
615}
616
617ast_struct! {
618 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
620 pub struct ExprReturn #full {
621 pub attrs: Vec<Attribute>,
622 pub return_token: Token![return],
623 pub expr: Option<Box<Expr>>,
624 }
625}
626
627ast_struct! {
628 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
633 pub struct ExprStruct {
634 pub attrs: Vec<Attribute>,
635 pub qself: Option<QSelf>,
636 pub path: Path,
637 pub brace_token: token::Brace,
638 pub fields: Punctuated<FieldValue, Token![,]>,
639 pub dot2_token: Option<Token![..]>,
640 pub rest: Option<Box<Expr>>,
641 }
642}
643
644ast_struct! {
645 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
647 pub struct ExprTry #full {
648 pub attrs: Vec<Attribute>,
649 pub expr: Box<Expr>,
650 pub question_token: Token![?],
651 }
652}
653
654ast_struct! {
655 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
657 pub struct ExprTryBlock #full {
658 pub attrs: Vec<Attribute>,
659 pub try_token: Token![try],
660 pub block: Block,
661 }
662}
663
664ast_struct! {
665 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
667 pub struct ExprTuple {
668 pub attrs: Vec<Attribute>,
669 pub paren_token: token::Paren,
670 pub elems: Punctuated<Expr, Token![,]>,
671 }
672}
673
674ast_struct! {
675 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
677 pub struct ExprUnary {
678 pub attrs: Vec<Attribute>,
679 pub op: UnOp,
680 pub expr: Box<Expr>,
681 }
682}
683
684ast_struct! {
685 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
687 pub struct ExprUnsafe #full {
688 pub attrs: Vec<Attribute>,
689 pub unsafe_token: Token![unsafe],
690 pub block: Block,
691 }
692}
693
694ast_struct! {
695 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
697 pub struct ExprWhile #full {
698 pub attrs: Vec<Attribute>,
699 pub label: Option<Label>,
700 pub while_token: Token![while],
701 pub cond: Box<Expr>,
702 pub body: Block,
703 }
704}
705
706ast_struct! {
707 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
709 pub struct ExprYield #full {
710 pub attrs: Vec<Attribute>,
711 pub yield_token: Token![yield],
712 pub expr: Option<Box<Expr>>,
713 }
714}
715
716impl Expr {
717 pub const PLACEHOLDER: Self = Expr::Path(ExprPath {
737 attrs: Vec::new(),
738 qself: None,
739 path: Path {
740 leading_colon: None,
741 segments: Punctuated::new(),
742 },
743 });
744
745 #[cfg(all(feature = "full", feature = "parsing"))]
827 #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))]
828 pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
829 parsing::ambiguous_expr(input, parsing::AllowStruct(false))
830 }
831
832 #[cfg(all(feature = "full", feature = "parsing"))]
889 #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))]
890 pub fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> {
891 parsing::parse_with_earlier_boundary_rule(input)
892 }
893
894 #[cfg(feature = "parsing")]
905 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
906 pub fn peek(input: ParseStream) -> bool {
907 input.peek(Ident::peek_any) && !input.peek(Token![as]) || input.peek(token::Paren) || input.peek(token::Bracket) || input.peek(token::Brace) || input.peek(Lit) || input.peek(Token![!]) && !input.peek(Token![!=]) || input.peek(Token![-]) && !input.peek(Token![-=]) && !input.peek(Token![->]) || input.peek(Token![*]) && !input.peek(Token![*=]) || input.peek(Token![|]) && !input.peek(Token![|=]) || input.peek(Token![&]) && !input.peek(Token![&=]) || input.peek(Token![..]) || input.peek(Token![<]) && !input.peek(Token![<=]) && !input.peek(Token![<<=]) || input.peek(Token![::]) || input.peek(Lifetime) || input.peek(Token![#]) }
923
924 #[cfg(all(feature = "parsing", feature = "full"))]
925 pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
926 match self {
927 Expr::Array(ExprArray { attrs, .. })
928 | Expr::Assign(ExprAssign { attrs, .. })
929 | Expr::Async(ExprAsync { attrs, .. })
930 | Expr::Await(ExprAwait { attrs, .. })
931 | Expr::Binary(ExprBinary { attrs, .. })
932 | Expr::Block(ExprBlock { attrs, .. })
933 | Expr::Break(ExprBreak { attrs, .. })
934 | Expr::Call(ExprCall { attrs, .. })
935 | Expr::Cast(ExprCast { attrs, .. })
936 | Expr::Closure(ExprClosure { attrs, .. })
937 | Expr::Const(ExprConst { attrs, .. })
938 | Expr::Continue(ExprContinue { attrs, .. })
939 | Expr::Field(ExprField { attrs, .. })
940 | Expr::ForLoop(ExprForLoop { attrs, .. })
941 | Expr::Group(ExprGroup { attrs, .. })
942 | Expr::If(ExprIf { attrs, .. })
943 | Expr::Index(ExprIndex { attrs, .. })
944 | Expr::Infer(ExprInfer { attrs, .. })
945 | Expr::Let(ExprLet { attrs, .. })
946 | Expr::Lit(ExprLit { attrs, .. })
947 | Expr::Loop(ExprLoop { attrs, .. })
948 | Expr::Macro(ExprMacro { attrs, .. })
949 | Expr::Match(ExprMatch { attrs, .. })
950 | Expr::MethodCall(ExprMethodCall { attrs, .. })
951 | Expr::Paren(ExprParen { attrs, .. })
952 | Expr::Path(ExprPath { attrs, .. })
953 | Expr::Range(ExprRange { attrs, .. })
954 | Expr::RawAddr(ExprRawAddr { attrs, .. })
955 | Expr::Reference(ExprReference { attrs, .. })
956 | Expr::Repeat(ExprRepeat { attrs, .. })
957 | Expr::Return(ExprReturn { attrs, .. })
958 | Expr::Struct(ExprStruct { attrs, .. })
959 | Expr::Try(ExprTry { attrs, .. })
960 | Expr::TryBlock(ExprTryBlock { attrs, .. })
961 | Expr::Tuple(ExprTuple { attrs, .. })
962 | Expr::Unary(ExprUnary { attrs, .. })
963 | Expr::Unsafe(ExprUnsafe { attrs, .. })
964 | Expr::While(ExprWhile { attrs, .. })
965 | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
966 Expr::Verbatim(_) => Vec::new(),
967 }
968 }
969}
970
971ast_enum! {
972 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
975 pub enum Member {
976 Named(Ident),
978 Unnamed(Index),
980 }
981}
982
983impl From<Ident> for Member {
984 fn from(ident: Ident) -> Member {
985 Member::Named(ident)
986 }
987}
988
989impl From<Index> for Member {
990 fn from(index: Index) -> Member {
991 Member::Unnamed(index)
992 }
993}
994
995impl From<usize> for Member {
996 fn from(index: usize) -> Member {
997 Member::Unnamed(Index::from(index))
998 }
999}
1000
1001impl Eq for Member {}
1002
1003impl PartialEq for Member {
1004 fn eq(&self, other: &Self) -> bool {
1005 match (self, other) {
1006 (Member::Named(this), Member::Named(other)) => this == other,
1007 (Member::Unnamed(this), Member::Unnamed(other)) => this == other,
1008 _ => false,
1009 }
1010 }
1011}
1012
1013impl Hash for Member {
1014 fn hash<H: Hasher>(&self, state: &mut H) {
1015 match self {
1016 Member::Named(m) => m.hash(state),
1017 Member::Unnamed(m) => m.hash(state),
1018 }
1019 }
1020}
1021
1022#[cfg(feature = "printing")]
1023impl IdentFragment for Member {
1024 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1025 match self {
1026 Member::Named(m) => Display::fmt(m, formatter),
1027 Member::Unnamed(m) => Display::fmt(&m.index, formatter),
1028 }
1029 }
1030
1031 fn span(&self) -> Option<Span> {
1032 match self {
1033 Member::Named(m) => Some(m.span()),
1034 Member::Unnamed(m) => Some(m.span),
1035 }
1036 }
1037}
1038
1039#[cfg(any(feature = "parsing", feature = "printing"))]
1040impl Member {
1041 pub(crate) fn is_named(&self) -> bool {
1042 match self {
1043 Member::Named(_) => true,
1044 Member::Unnamed(_) => false,
1045 }
1046 }
1047}
1048
1049ast_struct! {
1050 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
1052 pub struct Index {
1053 pub index: u32,
1054 pub span: Span,
1055 }
1056}
1057
1058impl From<usize> for Index {
1059 fn from(index: usize) -> Index {
1060 assert!(index < u32::MAX as usize);
1061 Index {
1062 index: index as u32,
1063 span: Span::call_site(),
1064 }
1065 }
1066}
1067
1068impl Eq for Index {}
1069
1070impl PartialEq for Index {
1071 fn eq(&self, other: &Self) -> bool {
1072 self.index == other.index
1073 }
1074}
1075
1076impl Hash for Index {
1077 fn hash<H: Hasher>(&self, state: &mut H) {
1078 self.index.hash(state);
1079 }
1080}
1081
1082#[cfg(feature = "printing")]
1083impl IdentFragment for Index {
1084 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1085 Display::fmt(&self.index, formatter)
1086 }
1087
1088 fn span(&self) -> Option<Span> {
1089 Some(self.span)
1090 }
1091}
1092
1093ast_struct! {
1094 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
1096 pub struct FieldValue {
1097 pub attrs: Vec<Attribute>,
1098 pub member: Member,
1099
1100 pub colon_token: Option<Token![:]>,
1103
1104 pub expr: Expr,
1105 }
1106}
1107
1108#[cfg(feature = "full")]
1109ast_struct! {
1110 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
1112 pub struct Label {
1113 pub name: Lifetime,
1114 pub colon_token: Token![:],
1115 }
1116}
1117
1118#[cfg(feature = "full")]
1119ast_struct! {
1120 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
1138 pub struct Arm {
1139 pub attrs: Vec<Attribute>,
1140 pub pat: Pat,
1141 pub guard: Option<(Token![if], Box<Expr>)>,
1142 pub fat_arrow_token: Token![=>],
1143 pub body: Box<Expr>,
1144 pub comma: Option<Token![,]>,
1145 }
1146}
1147
1148#[cfg(feature = "full")]
1149ast_enum! {
1150 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
1152 pub enum RangeLimits {
1153 HalfOpen(Token![..]),
1155 Closed(Token![..=]),
1157 }
1158}
1159
1160#[cfg(feature = "full")]
1161ast_enum! {
1162 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
1165 pub enum PointerMutability {
1166 Const(Token![const]),
1167 Mut(Token![mut]),
1168 }
1169}
1170
1171#[cfg(feature = "parsing")]
1172pub(crate) mod parsing {
1173 #[cfg(feature = "full")]
1174 use crate::attr;
1175 use crate::attr::Attribute;
1176 #[cfg(feature = "full")]
1177 use crate::classify;
1178 use crate::error::{Error, Result};
1179 #[cfg(feature = "full")]
1180 use crate::expr::{
1181 Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
1182 ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
1183 ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
1184 ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
1185 };
1186 use crate::expr::{
1187 Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
1188 ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary,
1189 FieldValue, Index, Member,
1190 };
1191 #[cfg(feature = "full")]
1192 use crate::generics::BoundLifetimes;
1193 use crate::ident::Ident;
1194 #[cfg(feature = "full")]
1195 use crate::lifetime::Lifetime;
1196 use crate::lit::{Lit, LitFloat, LitInt};
1197 use crate::mac::{self, Macro};
1198 use crate::op::BinOp;
1199 use crate::parse::discouraged::Speculative as _;
1200 #[cfg(feature = "full")]
1201 use crate::parse::ParseBuffer;
1202 use crate::parse::{Parse, ParseStream};
1203 #[cfg(feature = "full")]
1204 use crate::pat::{Pat, PatType};
1205 use crate::path::{self, AngleBracketedGenericArguments, Path, QSelf};
1206 use crate::precedence::Precedence;
1207 use crate::punctuated::Punctuated;
1208 #[cfg(feature = "full")]
1209 use crate::stmt::Block;
1210 use crate::token;
1211 use crate::ty;
1212 #[cfg(feature = "full")]
1213 use crate::ty::{ReturnType, Type};
1214 use crate::verbatim;
1215 #[cfg(feature = "full")]
1216 use proc_macro2::TokenStream;
1217 use std::mem;
1218
1219 #[cfg(feature = "full")]
1225 pub(super) struct AllowStruct(pub bool);
1226
1227 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1228 impl Parse for Expr {
1229 fn parse(input: ParseStream) -> Result<Self> {
1230 ambiguous_expr(
1231 input,
1232 #[cfg(feature = "full")]
1233 AllowStruct(true),
1234 )
1235 }
1236 }
1237
1238 #[cfg(feature = "full")]
1239 pub(super) fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> {
1240 let mut attrs = input.call(expr_attrs)?;
1241 let mut expr = if input.peek(token::Group) {
1242 let allow_struct = AllowStruct(true);
1243 let atom = expr_group(input, allow_struct)?;
1244 if continue_parsing_early(&atom) {
1245 trailer_helper(input, atom)?
1246 } else {
1247 atom
1248 }
1249 } else if input.peek(Token![if]) {
1250 Expr::If(input.parse()?)
1251 } else if input.peek(Token![while]) {
1252 Expr::While(input.parse()?)
1253 } else if input.peek(Token![for])
1254 && !(input.peek2(Token![<]) && (input.peek3(Lifetime) || input.peek3(Token![>])))
1255 {
1256 Expr::ForLoop(input.parse()?)
1257 } else if input.peek(Token![loop]) {
1258 Expr::Loop(input.parse()?)
1259 } else if input.peek(Token![match]) {
1260 Expr::Match(input.parse()?)
1261 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1262 Expr::TryBlock(input.parse()?)
1263 } else if input.peek(Token![unsafe]) {
1264 Expr::Unsafe(input.parse()?)
1265 } else if input.peek(Token![const]) && input.peek2(token::Brace) {
1266 Expr::Const(input.parse()?)
1267 } else if input.peek(token::Brace) {
1268 Expr::Block(input.parse()?)
1269 } else if input.peek(Lifetime) {
1270 atom_labeled(input)?
1271 } else {
1272 let allow_struct = AllowStruct(true);
1273 unary_expr(input, allow_struct)?
1274 };
1275
1276 if continue_parsing_early(&expr) {
1277 attrs.extend(expr.replace_attrs(Vec::new()));
1278 expr.replace_attrs(attrs);
1279
1280 let allow_struct = AllowStruct(true);
1281 return parse_expr(input, expr, allow_struct, Precedence::MIN);
1282 }
1283
1284 if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
1285 expr = trailer_helper(input, expr)?;
1286
1287 attrs.extend(expr.replace_attrs(Vec::new()));
1288 expr.replace_attrs(attrs);
1289
1290 let allow_struct = AllowStruct(true);
1291 return parse_expr(input, expr, allow_struct, Precedence::MIN);
1292 }
1293
1294 attrs.extend(expr.replace_attrs(Vec::new()));
1295 expr.replace_attrs(attrs);
1296 Ok(expr)
1297 }
1298
1299 #[cfg(feature = "full")]
1300 impl Copy for AllowStruct {}
1301
1302 #[cfg(feature = "full")]
1303 impl Clone for AllowStruct {
1304 fn clone(&self) -> Self {
1305 *self
1306 }
1307 }
1308
1309 #[cfg(feature = "full")]
1310 fn parse_expr(
1311 input: ParseStream,
1312 mut lhs: Expr,
1313 allow_struct: AllowStruct,
1314 base: Precedence,
1315 ) -> Result<Expr> {
1316 loop {
1317 let ahead = input.fork();
1318 if let Expr::Range(_) = lhs {
1319 break;
1321 } else if let Ok(op) = ahead.parse::<BinOp>() {
1322 let precedence = Precedence::of_binop(&op);
1323 if precedence < base {
1324 break;
1325 }
1326 if precedence == Precedence::Assign {
1327 if let Expr::Range(_) = lhs {
1328 break;
1329 }
1330 }
1331 if precedence == Precedence::Compare {
1332 if let Expr::Binary(lhs) = &lhs {
1333 if Precedence::of_binop(&lhs.op) == Precedence::Compare {
1334 return Err(input.error("comparison operators cannot be chained"));
1335 }
1336 }
1337 }
1338 input.advance_to(&ahead);
1339 let right = parse_binop_rhs(input, allow_struct, precedence)?;
1340 lhs = Expr::Binary(ExprBinary {
1341 attrs: Vec::new(),
1342 left: Box::new(lhs),
1343 op,
1344 right,
1345 });
1346 } else if Precedence::Assign >= base
1347 && input.peek(Token![=])
1348 && !input.peek(Token![=>])
1349 && match lhs {
1350 Expr::Range(_) => false,
1351 _ => true,
1352 }
1353 {
1354 let eq_token: Token![=] = input.parse()?;
1355 let right = parse_binop_rhs(input, allow_struct, Precedence::Assign)?;
1356 lhs = Expr::Assign(ExprAssign {
1357 attrs: Vec::new(),
1358 left: Box::new(lhs),
1359 eq_token,
1360 right,
1361 });
1362 } else if Precedence::Range >= base && input.peek(Token![..]) {
1363 let limits: RangeLimits = input.parse()?;
1364 let end = parse_range_end(input, &limits, allow_struct)?;
1365 lhs = Expr::Range(ExprRange {
1366 attrs: Vec::new(),
1367 start: Some(Box::new(lhs)),
1368 limits,
1369 end,
1370 });
1371 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1372 let as_token: Token![as] = input.parse()?;
1373 let allow_plus = false;
1374 let allow_group_generic = false;
1375 let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
1376 check_cast(input)?;
1377 lhs = Expr::Cast(ExprCast {
1378 attrs: Vec::new(),
1379 expr: Box::new(lhs),
1380 as_token,
1381 ty: Box::new(ty),
1382 });
1383 } else {
1384 break;
1385 }
1386 }
1387 Ok(lhs)
1388 }
1389
1390 #[cfg(not(feature = "full"))]
1391 fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> {
1392 loop {
1393 let ahead = input.fork();
1394 if let Ok(op) = ahead.parse::<BinOp>() {
1395 let precedence = Precedence::of_binop(&op);
1396 if precedence < base {
1397 break;
1398 }
1399 if precedence == Precedence::Compare {
1400 if let Expr::Binary(lhs) = &lhs {
1401 if Precedence::of_binop(&lhs.op) == Precedence::Compare {
1402 return Err(input.error("comparison operators cannot be chained"));
1403 }
1404 }
1405 }
1406 input.advance_to(&ahead);
1407 let right = parse_binop_rhs(input, precedence)?;
1408 lhs = Expr::Binary(ExprBinary {
1409 attrs: Vec::new(),
1410 left: Box::new(lhs),
1411 op,
1412 right,
1413 });
1414 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1415 let as_token: Token![as] = input.parse()?;
1416 let allow_plus = false;
1417 let allow_group_generic = false;
1418 let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
1419 check_cast(input)?;
1420 lhs = Expr::Cast(ExprCast {
1421 attrs: Vec::new(),
1422 expr: Box::new(lhs),
1423 as_token,
1424 ty: Box::new(ty),
1425 });
1426 } else {
1427 break;
1428 }
1429 }
1430 Ok(lhs)
1431 }
1432
1433 fn parse_binop_rhs(
1434 input: ParseStream,
1435 #[cfg(feature = "full")] allow_struct: AllowStruct,
1436 precedence: Precedence,
1437 ) -> Result<Box<Expr>> {
1438 let mut rhs = unary_expr(
1439 input,
1440 #[cfg(feature = "full")]
1441 allow_struct,
1442 )?;
1443 loop {
1444 let next = peek_precedence(input);
1445 if next > precedence || next == precedence && precedence == Precedence::Assign {
1446 let cursor = input.cursor();
1447 rhs = parse_expr(
1448 input,
1449 rhs,
1450 #[cfg(feature = "full")]
1451 allow_struct,
1452 next,
1453 )?;
1454 if cursor == input.cursor() {
1455 break;
1460 }
1461 } else {
1462 break;
1463 }
1464 }
1465 Ok(Box::new(rhs))
1466 }
1467
1468 fn peek_precedence(input: ParseStream) -> Precedence {
1469 if let Ok(op) = input.fork().parse() {
1470 Precedence::of_binop(&op)
1471 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1472 Precedence::Assign
1473 } else if input.peek(Token![..]) {
1474 Precedence::Range
1475 } else if input.peek(Token![as]) {
1476 Precedence::Cast
1477 } else {
1478 Precedence::MIN
1479 }
1480 }
1481
1482 pub(super) fn ambiguous_expr(
1484 input: ParseStream,
1485 #[cfg(feature = "full")] allow_struct: AllowStruct,
1486 ) -> Result<Expr> {
1487 let lhs = unary_expr(
1488 input,
1489 #[cfg(feature = "full")]
1490 allow_struct,
1491 )?;
1492 parse_expr(
1493 input,
1494 lhs,
1495 #[cfg(feature = "full")]
1496 allow_struct,
1497 Precedence::MIN,
1498 )
1499 }
1500
1501 #[cfg(feature = "full")]
1502 fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
1503 let mut attrs = Vec::new();
1504 while !input.peek(token::Group) && input.peek(Token![#]) {
1505 attrs.push(input.call(attr::parsing::single_parse_outer)?);
1506 }
1507 Ok(attrs)
1508 }
1509
1510 #[cfg(feature = "full")]
1515 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1516 let begin = input.fork();
1517 let attrs = input.call(expr_attrs)?;
1518 if input.peek(token::Group) {
1519 return trailer_expr(begin, attrs, input, allow_struct);
1520 }
1521
1522 if input.peek(Token![&]) {
1523 let and_token: Token![&] = input.parse()?;
1524 let raw: Option<Token![raw]> = if input.peek(Token![raw])
1525 && (input.peek2(Token![mut]) || input.peek2(Token![const]))
1526 {
1527 Some(input.parse()?)
1528 } else {
1529 None
1530 };
1531 let mutability: Option<Token![mut]> = input.parse()?;
1532 let const_token: Option<Token![const]> = if raw.is_some() && mutability.is_none() {
1533 Some(input.parse()?)
1534 } else {
1535 None
1536 };
1537 let expr = Box::new(unary_expr(input, allow_struct)?);
1538 if let Some(raw) = raw {
1539 Ok(Expr::RawAddr(ExprRawAddr {
1540 attrs,
1541 and_token,
1542 raw,
1543 mutability: match mutability {
1544 Some(mut_token) => PointerMutability::Mut(mut_token),
1545 None => PointerMutability::Const(const_token.unwrap()),
1546 },
1547 expr,
1548 }))
1549 } else {
1550 Ok(Expr::Reference(ExprReference {
1551 attrs,
1552 and_token,
1553 mutability,
1554 expr,
1555 }))
1556 }
1557 } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1558 expr_unary(input, attrs, allow_struct).map(Expr::Unary)
1559 } else {
1560 trailer_expr(begin, attrs, input, allow_struct)
1561 }
1562 }
1563
1564 #[cfg(not(feature = "full"))]
1565 fn unary_expr(input: ParseStream) -> Result<Expr> {
1566 if input.peek(Token![&]) {
1567 Ok(Expr::Reference(ExprReference {
1568 attrs: Vec::new(),
1569 and_token: input.parse()?,
1570 mutability: input.parse()?,
1571 expr: Box::new(unary_expr(input)?),
1572 }))
1573 } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1574 Ok(Expr::Unary(ExprUnary {
1575 attrs: Vec::new(),
1576 op: input.parse()?,
1577 expr: Box::new(unary_expr(input)?),
1578 }))
1579 } else {
1580 trailer_expr(input)
1581 }
1582 }
1583
1584 #[cfg(feature = "full")]
1591 fn trailer_expr(
1592 begin: ParseBuffer,
1593 mut attrs: Vec<Attribute>,
1594 input: ParseStream,
1595 allow_struct: AllowStruct,
1596 ) -> Result<Expr> {
1597 let atom = atom_expr(input, allow_struct)?;
1598 let mut e = trailer_helper(input, atom)?;
1599
1600 if let Expr::Verbatim(tokens) = &mut e {
1601 *tokens = verbatim::between(&begin, input);
1602 } else {
1603 let inner_attrs = e.replace_attrs(Vec::new());
1604 attrs.extend(inner_attrs);
1605 e.replace_attrs(attrs);
1606 }
1607
1608 Ok(e)
1609 }
1610
1611 #[cfg(feature = "full")]
1612 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1613 loop {
1614 if input.peek(token::Paren) {
1615 let content;
1616 e = Expr::Call(ExprCall {
1617 attrs: Vec::new(),
1618 func: Box::new(e),
1619 paren_token: parenthesized!(content in input),
1620 args: content.parse_terminated(Expr::parse, Token![,])?,
1621 });
1622 } else if input.peek(Token![.])
1623 && !input.peek(Token![..])
1624 && match e {
1625 Expr::Range(_) => false,
1626 _ => true,
1627 }
1628 {
1629 let mut dot_token: Token![.] = input.parse()?;
1630
1631 let float_token: Option<LitFloat> = input.parse()?;
1632 if let Some(float_token) = float_token {
1633 if multi_index(&mut e, &mut dot_token, float_token)? {
1634 continue;
1635 }
1636 }
1637
1638 let await_token: Option<Token![await]> = input.parse()?;
1639 if let Some(await_token) = await_token {
1640 e = Expr::Await(ExprAwait {
1641 attrs: Vec::new(),
1642 base: Box::new(e),
1643 dot_token,
1644 await_token,
1645 });
1646 continue;
1647 }
1648
1649 let member: Member = input.parse()?;
1650 let turbofish = if member.is_named() && input.peek(Token![::]) {
1651 Some(AngleBracketedGenericArguments::parse_turbofish(input)?)
1652 } else {
1653 None
1654 };
1655
1656 if turbofish.is_some() || input.peek(token::Paren) {
1657 if let Member::Named(method) = member {
1658 let content;
1659 e = Expr::MethodCall(ExprMethodCall {
1660 attrs: Vec::new(),
1661 receiver: Box::new(e),
1662 dot_token,
1663 method,
1664 turbofish,
1665 paren_token: parenthesized!(content in input),
1666 args: content.parse_terminated(Expr::parse, Token![,])?,
1667 });
1668 continue;
1669 }
1670 }
1671
1672 e = Expr::Field(ExprField {
1673 attrs: Vec::new(),
1674 base: Box::new(e),
1675 dot_token,
1676 member,
1677 });
1678 } else if input.peek(token::Bracket) {
1679 let content;
1680 e = Expr::Index(ExprIndex {
1681 attrs: Vec::new(),
1682 expr: Box::new(e),
1683 bracket_token: bracketed!(content in input),
1684 index: content.parse()?,
1685 });
1686 } else if input.peek(Token![?])
1687 && match e {
1688 Expr::Range(_) => false,
1689 _ => true,
1690 }
1691 {
1692 e = Expr::Try(ExprTry {
1693 attrs: Vec::new(),
1694 expr: Box::new(e),
1695 question_token: input.parse()?,
1696 });
1697 } else {
1698 break;
1699 }
1700 }
1701 Ok(e)
1702 }
1703
1704 #[cfg(not(feature = "full"))]
1705 fn trailer_expr(input: ParseStream) -> Result<Expr> {
1706 let mut e = atom_expr(input)?;
1707
1708 loop {
1709 if input.peek(token::Paren) {
1710 let content;
1711 e = Expr::Call(ExprCall {
1712 attrs: Vec::new(),
1713 func: Box::new(e),
1714 paren_token: parenthesized!(content in input),
1715 args: content.parse_terminated(Expr::parse, Token![,])?,
1716 });
1717 } else if input.peek(Token![.])
1718 && !input.peek(Token![..])
1719 && !input.peek2(Token![await])
1720 {
1721 let mut dot_token: Token![.] = input.parse()?;
1722
1723 let float_token: Option<LitFloat> = input.parse()?;
1724 if let Some(float_token) = float_token {
1725 if multi_index(&mut e, &mut dot_token, float_token)? {
1726 continue;
1727 }
1728 }
1729
1730 let member: Member = input.parse()?;
1731 let turbofish = if member.is_named() && input.peek(Token![::]) {
1732 let colon2_token: Token![::] = input.parse()?;
1733 let turbofish =
1734 AngleBracketedGenericArguments::do_parse(Some(colon2_token), input)?;
1735 Some(turbofish)
1736 } else {
1737 None
1738 };
1739
1740 if turbofish.is_some() || input.peek(token::Paren) {
1741 if let Member::Named(method) = member {
1742 let content;
1743 e = Expr::MethodCall(ExprMethodCall {
1744 attrs: Vec::new(),
1745 receiver: Box::new(e),
1746 dot_token,
1747 method,
1748 turbofish,
1749 paren_token: parenthesized!(content in input),
1750 args: content.parse_terminated(Expr::parse, Token![,])?,
1751 });
1752 continue;
1753 }
1754 }
1755
1756 e = Expr::Field(ExprField {
1757 attrs: Vec::new(),
1758 base: Box::new(e),
1759 dot_token,
1760 member,
1761 });
1762 } else if input.peek(token::Bracket) {
1763 let content;
1764 e = Expr::Index(ExprIndex {
1765 attrs: Vec::new(),
1766 expr: Box::new(e),
1767 bracket_token: bracketed!(content in input),
1768 index: content.parse()?,
1769 });
1770 } else {
1771 break;
1772 }
1773 }
1774
1775 Ok(e)
1776 }
1777
1778 #[cfg(feature = "full")]
1781 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1782 if input.peek(token::Group) {
1783 expr_group(input, allow_struct)
1784 } else if input.peek(Lit) {
1785 input.parse().map(Expr::Lit)
1786 } else if input.peek(Token![async])
1787 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1788 {
1789 input.parse().map(Expr::Async)
1790 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1791 input.parse().map(Expr::TryBlock)
1792 } else if input.peek(Token![|])
1793 || input.peek(Token![move])
1794 || input.peek(Token![for])
1795 && input.peek2(Token![<])
1796 && (input.peek3(Lifetime) || input.peek3(Token![>]))
1797 || input.peek(Token![const]) && !input.peek2(token::Brace)
1798 || input.peek(Token![static])
1799 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1800 {
1801 expr_closure(input, allow_struct).map(Expr::Closure)
1802 } else if token::parsing::peek_keyword(input.cursor(), "builtin") && input.peek2(Token![#])
1803 {
1804 expr_builtin(input)
1805 } else if input.peek(Ident)
1806 || input.peek(Token![::])
1807 || input.peek(Token![<])
1808 || input.peek(Token![self])
1809 || input.peek(Token![Self])
1810 || input.peek(Token![super])
1811 || input.peek(Token![crate])
1812 || input.peek(Token![try]) && (input.peek2(Token![!]) || input.peek2(Token![::]))
1813 {
1814 path_or_macro_or_struct(input, allow_struct)
1815 } else if input.peek(token::Paren) {
1816 paren_or_tuple(input)
1817 } else if input.peek(Token![break]) {
1818 expr_break(input, allow_struct).map(Expr::Break)
1819 } else if input.peek(Token![continue]) {
1820 input.parse().map(Expr::Continue)
1821 } else if input.peek(Token![return]) {
1822 input.parse().map(Expr::Return)
1823 } else if input.peek(Token![become]) {
1824 expr_become(input)
1825 } else if input.peek(token::Bracket) {
1826 array_or_repeat(input)
1827 } else if input.peek(Token![let]) {
1828 expr_let(input, allow_struct).map(Expr::Let)
1829 } else if input.peek(Token![if]) {
1830 input.parse().map(Expr::If)
1831 } else if input.peek(Token![while]) {
1832 input.parse().map(Expr::While)
1833 } else if input.peek(Token![for]) {
1834 input.parse().map(Expr::ForLoop)
1835 } else if input.peek(Token![loop]) {
1836 input.parse().map(Expr::Loop)
1837 } else if input.peek(Token![match]) {
1838 input.parse().map(Expr::Match)
1839 } else if input.peek(Token![yield]) {
1840 input.parse().map(Expr::Yield)
1841 } else if input.peek(Token![unsafe]) {
1842 input.parse().map(Expr::Unsafe)
1843 } else if input.peek(Token![const]) {
1844 input.parse().map(Expr::Const)
1845 } else if input.peek(token::Brace) {
1846 input.parse().map(Expr::Block)
1847 } else if input.peek(Token![..]) {
1848 expr_range(input, allow_struct).map(Expr::Range)
1849 } else if input.peek(Token![_]) {
1850 input.parse().map(Expr::Infer)
1851 } else if input.peek(Lifetime) {
1852 atom_labeled(input)
1853 } else {
1854 Err(input.error("expected an expression"))
1855 }
1856 }
1857
1858 #[cfg(feature = "full")]
1859 fn atom_labeled(input: ParseStream) -> Result<Expr> {
1860 let the_label: Label = input.parse()?;
1861 let mut expr = if input.peek(Token![while]) {
1862 Expr::While(input.parse()?)
1863 } else if input.peek(Token![for]) {
1864 Expr::ForLoop(input.parse()?)
1865 } else if input.peek(Token![loop]) {
1866 Expr::Loop(input.parse()?)
1867 } else if input.peek(token::Brace) {
1868 Expr::Block(input.parse()?)
1869 } else {
1870 return Err(input.error("expected loop or block expression"));
1871 };
1872 match &mut expr {
1873 Expr::While(ExprWhile { label, .. })
1874 | Expr::ForLoop(ExprForLoop { label, .. })
1875 | Expr::Loop(ExprLoop { label, .. })
1876 | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
1877 _ => unreachable!(),
1878 }
1879 Ok(expr)
1880 }
1881
1882 #[cfg(not(feature = "full"))]
1883 fn atom_expr(input: ParseStream) -> Result<Expr> {
1884 if input.peek(token::Group) {
1885 expr_group(input)
1886 } else if input.peek(Lit) {
1887 input.parse().map(Expr::Lit)
1888 } else if input.peek(token::Paren) {
1889 paren_or_tuple(input)
1890 } else if input.peek(Ident)
1891 || input.peek(Token![::])
1892 || input.peek(Token![<])
1893 || input.peek(Token![self])
1894 || input.peek(Token![Self])
1895 || input.peek(Token![super])
1896 || input.peek(Token![crate])
1897 {
1898 path_or_macro_or_struct(input)
1899 } else if input.is_empty() {
1900 Err(input.error("expected an expression"))
1901 } else {
1902 if input.peek(token::Brace) {
1903 let scan = input.fork();
1904 let content;
1905 braced!(content in scan);
1906 if content.parse::<Expr>().is_ok() && content.is_empty() {
1907 let expr_block = verbatim::between(input, &scan);
1908 input.advance_to(&scan);
1909 return Ok(Expr::Verbatim(expr_block));
1910 }
1911 }
1912 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1913 }
1914 }
1915
1916 #[cfg(feature = "full")]
1917 fn expr_builtin(input: ParseStream) -> Result<Expr> {
1918 let begin = input.fork();
1919
1920 token::parsing::keyword(input, "builtin")?;
1921 input.parse::<Token![#]>()?;
1922 input.parse::<Ident>()?;
1923
1924 let args;
1925 parenthesized!(args in input);
1926 args.parse::<TokenStream>()?;
1927
1928 Ok(Expr::Verbatim(verbatim::between(&begin, input)))
1929 }
1930
1931 fn path_or_macro_or_struct(
1932 input: ParseStream,
1933 #[cfg(feature = "full")] allow_struct: AllowStruct,
1934 ) -> Result<Expr> {
1935 let expr_style = true;
1936 let (qself, path) = path::parsing::qpath(input, expr_style)?;
1937 rest_of_path_or_macro_or_struct(
1938 qself,
1939 path,
1940 input,
1941 #[cfg(feature = "full")]
1942 allow_struct,
1943 )
1944 }
1945
1946 fn rest_of_path_or_macro_or_struct(
1947 qself: Option<QSelf>,
1948 path: Path,
1949 input: ParseStream,
1950 #[cfg(feature = "full")] allow_struct: AllowStruct,
1951 ) -> Result<Expr> {
1952 if qself.is_none()
1953 && input.peek(Token![!])
1954 && !input.peek(Token![!=])
1955 && path.is_mod_style()
1956 {
1957 let bang_token: Token![!] = input.parse()?;
1958 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1959 return Ok(Expr::Macro(ExprMacro {
1960 attrs: Vec::new(),
1961 mac: Macro {
1962 path,
1963 bang_token,
1964 delimiter,
1965 tokens,
1966 },
1967 }));
1968 }
1969
1970 #[cfg(not(feature = "full"))]
1971 let allow_struct = (true,);
1972 if allow_struct.0 && input.peek(token::Brace) {
1973 return expr_struct_helper(input, qself, path).map(Expr::Struct);
1974 }
1975
1976 Ok(Expr::Path(ExprPath {
1977 attrs: Vec::new(),
1978 qself,
1979 path,
1980 }))
1981 }
1982
1983 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1984 impl Parse for ExprMacro {
1985 fn parse(input: ParseStream) -> Result<Self> {
1986 Ok(ExprMacro {
1987 attrs: Vec::new(),
1988 mac: input.parse()?,
1989 })
1990 }
1991 }
1992
1993 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1994 let content;
1995 let paren_token = parenthesized!(content in input);
1996 if content.is_empty() {
1997 return Ok(Expr::Tuple(ExprTuple {
1998 attrs: Vec::new(),
1999 paren_token,
2000 elems: Punctuated::new(),
2001 }));
2002 }
2003
2004 let first: Expr = content.parse()?;
2005 if content.is_empty() {
2006 return Ok(Expr::Paren(ExprParen {
2007 attrs: Vec::new(),
2008 paren_token,
2009 expr: Box::new(first),
2010 }));
2011 }
2012
2013 let mut elems = Punctuated::new();
2014 elems.push_value(first);
2015 while !content.is_empty() {
2016 let punct = content.parse()?;
2017 elems.push_punct(punct);
2018 if content.is_empty() {
2019 break;
2020 }
2021 let value = content.parse()?;
2022 elems.push_value(value);
2023 }
2024 Ok(Expr::Tuple(ExprTuple {
2025 attrs: Vec::new(),
2026 paren_token,
2027 elems,
2028 }))
2029 }
2030
2031 #[cfg(feature = "full")]
2032 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
2033 let content;
2034 let bracket_token = bracketed!(content in input);
2035 if content.is_empty() {
2036 return Ok(Expr::Array(ExprArray {
2037 attrs: Vec::new(),
2038 bracket_token,
2039 elems: Punctuated::new(),
2040 }));
2041 }
2042
2043 let first: Expr = content.parse()?;
2044 if content.is_empty() || content.peek(Token![,]) {
2045 let mut elems = Punctuated::new();
2046 elems.push_value(first);
2047 while !content.is_empty() {
2048 let punct = content.parse()?;
2049 elems.push_punct(punct);
2050 if content.is_empty() {
2051 break;
2052 }
2053 let value = content.parse()?;
2054 elems.push_value(value);
2055 }
2056 Ok(Expr::Array(ExprArray {
2057 attrs: Vec::new(),
2058 bracket_token,
2059 elems,
2060 }))
2061 } else if content.peek(Token![;]) {
2062 let semi_token: Token![;] = content.parse()?;
2063 let len: Expr = content.parse()?;
2064 Ok(Expr::Repeat(ExprRepeat {
2065 attrs: Vec::new(),
2066 bracket_token,
2067 expr: Box::new(first),
2068 semi_token,
2069 len: Box::new(len),
2070 }))
2071 } else {
2072 Err(content.error("expected `,` or `;`"))
2073 }
2074 }
2075
2076 #[cfg(feature = "full")]
2077 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2078 impl Parse for ExprArray {
2079 fn parse(input: ParseStream) -> Result<Self> {
2080 let content;
2081 let bracket_token = bracketed!(content in input);
2082 let mut elems = Punctuated::new();
2083
2084 while !content.is_empty() {
2085 let first: Expr = content.parse()?;
2086 elems.push_value(first);
2087 if content.is_empty() {
2088 break;
2089 }
2090 let punct = content.parse()?;
2091 elems.push_punct(punct);
2092 }
2093
2094 Ok(ExprArray {
2095 attrs: Vec::new(),
2096 bracket_token,
2097 elems,
2098 })
2099 }
2100 }
2101
2102 #[cfg(feature = "full")]
2103 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2104 impl Parse for ExprRepeat {
2105 fn parse(input: ParseStream) -> Result<Self> {
2106 let content;
2107 Ok(ExprRepeat {
2108 bracket_token: bracketed!(content in input),
2109 attrs: Vec::new(),
2110 expr: content.parse()?,
2111 semi_token: content.parse()?,
2112 len: content.parse()?,
2113 })
2114 }
2115 }
2116
2117 #[cfg(feature = "full")]
2118 fn continue_parsing_early(mut expr: &Expr) -> bool {
2119 while let Expr::Group(group) = expr {
2120 expr = &group.expr;
2121 }
2122 match expr {
2123 Expr::If(_)
2124 | Expr::While(_)
2125 | Expr::ForLoop(_)
2126 | Expr::Loop(_)
2127 | Expr::Match(_)
2128 | Expr::TryBlock(_)
2129 | Expr::Unsafe(_)
2130 | Expr::Const(_)
2131 | Expr::Block(_) => false,
2132 _ => true,
2133 }
2134 }
2135
2136 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2137 impl Parse for ExprLit {
2138 fn parse(input: ParseStream) -> Result<Self> {
2139 Ok(ExprLit {
2140 attrs: Vec::new(),
2141 lit: input.parse()?,
2142 })
2143 }
2144 }
2145
2146 fn expr_group(
2147 input: ParseStream,
2148 #[cfg(feature = "full")] allow_struct: AllowStruct,
2149 ) -> Result<Expr> {
2150 let group = crate::group::parse_group(input)?;
2151 let mut inner: Expr = group.content.parse()?;
2152
2153 match inner {
2154 Expr::Path(mut expr) if expr.attrs.is_empty() => {
2155 let grouped_len = expr.path.segments.len();
2156 Path::parse_rest(input, &mut expr.path, true)?;
2157 match rest_of_path_or_macro_or_struct(
2158 expr.qself,
2159 expr.path,
2160 input,
2161 #[cfg(feature = "full")]
2162 allow_struct,
2163 )? {
2164 Expr::Path(expr) if expr.path.segments.len() == grouped_len => {
2165 inner = Expr::Path(expr);
2166 }
2167 extended => return Ok(extended),
2168 }
2169 }
2170 _ => {}
2171 }
2172
2173 Ok(Expr::Group(ExprGroup {
2174 attrs: Vec::new(),
2175 group_token: group.token,
2176 expr: Box::new(inner),
2177 }))
2178 }
2179
2180 #[cfg(feature = "full")]
2181 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2182 impl Parse for ExprParen {
2183 fn parse(input: ParseStream) -> Result<Self> {
2184 let content;
2185 Ok(ExprParen {
2186 attrs: Vec::new(),
2187 paren_token: parenthesized!(content in input),
2188 expr: content.parse()?,
2189 })
2190 }
2191 }
2192
2193 #[cfg(feature = "full")]
2194 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2195 impl Parse for ExprLet {
2196 fn parse(input: ParseStream) -> Result<Self> {
2197 let allow_struct = AllowStruct(true);
2198 expr_let(input, allow_struct)
2199 }
2200 }
2201
2202 #[cfg(feature = "full")]
2203 fn expr_let(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprLet> {
2204 Ok(ExprLet {
2205 attrs: Vec::new(),
2206 let_token: input.parse()?,
2207 pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
2208 eq_token: input.parse()?,
2209 expr: Box::new({
2210 let lhs = unary_expr(input, allow_struct)?;
2211 parse_expr(input, lhs, allow_struct, Precedence::Compare)?
2212 }),
2213 })
2214 }
2215
2216 #[cfg(feature = "full")]
2217 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2218 impl Parse for ExprIf {
2219 fn parse(input: ParseStream) -> Result<Self> {
2220 let attrs = input.call(Attribute::parse_outer)?;
2221
2222 let mut clauses = Vec::new();
2223 let mut expr;
2224 loop {
2225 let if_token: Token![if] = input.parse()?;
2226 let cond = input.call(Expr::parse_without_eager_brace)?;
2227 let then_branch: Block = input.parse()?;
2228
2229 expr = ExprIf {
2230 attrs: Vec::new(),
2231 if_token,
2232 cond: Box::new(cond),
2233 then_branch,
2234 else_branch: None,
2235 };
2236
2237 if !input.peek(Token![else]) {
2238 break;
2239 }
2240
2241 let else_token: Token![else] = input.parse()?;
2242 let lookahead = input.lookahead1();
2243 if lookahead.peek(Token![if]) {
2244 expr.else_branch = Some((else_token, Box::new(Expr::PLACEHOLDER)));
2245 clauses.push(expr);
2246 } else if lookahead.peek(token::Brace) {
2247 expr.else_branch = Some((
2248 else_token,
2249 Box::new(Expr::Block(ExprBlock {
2250 attrs: Vec::new(),
2251 label: None,
2252 block: input.parse()?,
2253 })),
2254 ));
2255 break;
2256 } else {
2257 return Err(lookahead.error());
2258 }
2259 }
2260
2261 while let Some(mut prev) = clauses.pop() {
2262 *prev.else_branch.as_mut().unwrap().1 = Expr::If(expr);
2263 expr = prev;
2264 }
2265 expr.attrs = attrs;
2266 Ok(expr)
2267 }
2268 }
2269
2270 #[cfg(feature = "full")]
2271 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2272 impl Parse for ExprInfer {
2273 fn parse(input: ParseStream) -> Result<Self> {
2274 Ok(ExprInfer {
2275 attrs: input.call(Attribute::parse_outer)?,
2276 underscore_token: input.parse()?,
2277 })
2278 }
2279 }
2280
2281 #[cfg(feature = "full")]
2282 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2283 impl Parse for ExprForLoop {
2284 fn parse(input: ParseStream) -> Result<Self> {
2285 let mut attrs = input.call(Attribute::parse_outer)?;
2286 let label: Option<Label> = input.parse()?;
2287 let for_token: Token![for] = input.parse()?;
2288
2289 let pat = Pat::parse_multi_with_leading_vert(input)?;
2290
2291 let in_token: Token![in] = input.parse()?;
2292 let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2293
2294 let content;
2295 let brace_token = braced!(content in input);
2296 attr::parsing::parse_inner(&content, &mut attrs)?;
2297 let stmts = content.call(Block::parse_within)?;
2298
2299 Ok(ExprForLoop {
2300 attrs,
2301 label,
2302 for_token,
2303 pat: Box::new(pat),
2304 in_token,
2305 expr: Box::new(expr),
2306 body: Block { brace_token, stmts },
2307 })
2308 }
2309 }
2310
2311 #[cfg(feature = "full")]
2312 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2313 impl Parse for ExprLoop {
2314 fn parse(input: ParseStream) -> Result<Self> {
2315 let mut attrs = input.call(Attribute::parse_outer)?;
2316 let label: Option<Label> = input.parse()?;
2317 let loop_token: Token![loop] = input.parse()?;
2318
2319 let content;
2320 let brace_token = braced!(content in input);
2321 attr::parsing::parse_inner(&content, &mut attrs)?;
2322 let stmts = content.call(Block::parse_within)?;
2323
2324 Ok(ExprLoop {
2325 attrs,
2326 label,
2327 loop_token,
2328 body: Block { brace_token, stmts },
2329 })
2330 }
2331 }
2332
2333 #[cfg(feature = "full")]
2334 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2335 impl Parse for ExprMatch {
2336 fn parse(input: ParseStream) -> Result<Self> {
2337 let mut attrs = input.call(Attribute::parse_outer)?;
2338 let match_token: Token![match] = input.parse()?;
2339 let expr = Expr::parse_without_eager_brace(input)?;
2340
2341 let content;
2342 let brace_token = braced!(content in input);
2343 attr::parsing::parse_inner(&content, &mut attrs)?;
2344
2345 let arms = Arm::parse_multiple(&content)?;
2346
2347 Ok(ExprMatch {
2348 attrs,
2349 match_token,
2350 expr: Box::new(expr),
2351 brace_token,
2352 arms,
2353 })
2354 }
2355 }
2356
2357 macro_rules! impl_by_parsing_expr {
2358 (
2359 $(
2360 $expr_type:ty, $variant:ident, $msg:expr,
2361 )*
2362 ) => {
2363 $(
2364 #[cfg(all(feature = "full", feature = "printing"))]
2365 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2366 impl Parse for $expr_type {
2367 fn parse(input: ParseStream) -> Result<Self> {
2368 let mut expr: Expr = input.parse()?;
2369 loop {
2370 match expr {
2371 Expr::$variant(inner) => return Ok(inner),
2372 Expr::Group(next) => expr = *next.expr,
2373 _ => return Err(Error::new_spanned(expr, $msg)),
2374 }
2375 }
2376 }
2377 }
2378 )*
2379 };
2380 }
2381
2382 impl_by_parsing_expr! {
2383 ExprAssign, Assign, "expected assignment expression",
2384 ExprAwait, Await, "expected await expression",
2385 ExprBinary, Binary, "expected binary operation",
2386 ExprCall, Call, "expected function call expression",
2387 ExprCast, Cast, "expected cast expression",
2388 ExprField, Field, "expected struct field access",
2389 ExprIndex, Index, "expected indexing expression",
2390 ExprMethodCall, MethodCall, "expected method call expression",
2391 ExprRange, Range, "expected range expression",
2392 ExprTry, Try, "expected try expression",
2393 ExprTuple, Tuple, "expected tuple expression",
2394 }
2395
2396 #[cfg(feature = "full")]
2397 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2398 impl Parse for ExprUnary {
2399 fn parse(input: ParseStream) -> Result<Self> {
2400 let attrs = Vec::new();
2401 let allow_struct = AllowStruct(true);
2402 expr_unary(input, attrs, allow_struct)
2403 }
2404 }
2405
2406 #[cfg(feature = "full")]
2407 fn expr_unary(
2408 input: ParseStream,
2409 attrs: Vec<Attribute>,
2410 allow_struct: AllowStruct,
2411 ) -> Result<ExprUnary> {
2412 Ok(ExprUnary {
2413 attrs,
2414 op: input.parse()?,
2415 expr: Box::new(unary_expr(input, allow_struct)?),
2416 })
2417 }
2418
2419 #[cfg(feature = "full")]
2420 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2421 impl Parse for ExprClosure {
2422 fn parse(input: ParseStream) -> Result<Self> {
2423 let allow_struct = AllowStruct(true);
2424 expr_closure(input, allow_struct)
2425 }
2426 }
2427
2428 #[cfg(feature = "full")]
2429 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2430 impl Parse for ExprRawAddr {
2431 fn parse(input: ParseStream) -> Result<Self> {
2432 let allow_struct = AllowStruct(true);
2433 Ok(ExprRawAddr {
2434 attrs: Vec::new(),
2435 and_token: input.parse()?,
2436 raw: input.parse()?,
2437 mutability: input.parse()?,
2438 expr: Box::new(unary_expr(input, allow_struct)?),
2439 })
2440 }
2441 }
2442
2443 #[cfg(feature = "full")]
2444 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2445 impl Parse for ExprReference {
2446 fn parse(input: ParseStream) -> Result<Self> {
2447 let allow_struct = AllowStruct(true);
2448 Ok(ExprReference {
2449 attrs: Vec::new(),
2450 and_token: input.parse()?,
2451 mutability: input.parse()?,
2452 expr: Box::new(unary_expr(input, allow_struct)?),
2453 })
2454 }
2455 }
2456
2457 #[cfg(feature = "full")]
2458 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2459 impl Parse for ExprBreak {
2460 fn parse(input: ParseStream) -> Result<Self> {
2461 let allow_struct = AllowStruct(true);
2462 expr_break(input, allow_struct)
2463 }
2464 }
2465
2466 #[cfg(feature = "full")]
2467 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2468 impl Parse for ExprReturn {
2469 fn parse(input: ParseStream) -> Result<Self> {
2470 Ok(ExprReturn {
2471 attrs: Vec::new(),
2472 return_token: input.parse()?,
2473 expr: {
2474 if Expr::peek(input) {
2475 Some(input.parse()?)
2476 } else {
2477 None
2478 }
2479 },
2480 })
2481 }
2482 }
2483
2484 #[cfg(feature = "full")]
2485 fn expr_become(input: ParseStream) -> Result<Expr> {
2486 let begin = input.fork();
2487 input.parse::<Token![become]>()?;
2488 input.parse::<Expr>()?;
2489 Ok(Expr::Verbatim(verbatim::between(&begin, input)))
2490 }
2491
2492 #[cfg(feature = "full")]
2493 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2494 impl Parse for ExprTryBlock {
2495 fn parse(input: ParseStream) -> Result<Self> {
2496 Ok(ExprTryBlock {
2497 attrs: Vec::new(),
2498 try_token: input.parse()?,
2499 block: input.parse()?,
2500 })
2501 }
2502 }
2503
2504 #[cfg(feature = "full")]
2505 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2506 impl Parse for ExprYield {
2507 fn parse(input: ParseStream) -> Result<Self> {
2508 Ok(ExprYield {
2509 attrs: Vec::new(),
2510 yield_token: input.parse()?,
2511 expr: {
2512 if Expr::peek(input) {
2513 Some(input.parse()?)
2514 } else {
2515 None
2516 }
2517 },
2518 })
2519 }
2520 }
2521
2522 #[cfg(feature = "full")]
2523 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2524 let lifetimes: Option<BoundLifetimes> = input.parse()?;
2525 let constness: Option<Token![const]> = input.parse()?;
2526 let movability: Option<Token![static]> = input.parse()?;
2527 let asyncness: Option<Token![async]> = input.parse()?;
2528 let capture: Option<Token![move]> = input.parse()?;
2529 let or1_token: Token![|] = input.parse()?;
2530
2531 let mut inputs = Punctuated::new();
2532 loop {
2533 if input.peek(Token![|]) {
2534 break;
2535 }
2536 let value = closure_arg(input)?;
2537 inputs.push_value(value);
2538 if input.peek(Token![|]) {
2539 break;
2540 }
2541 let punct: Token![,] = input.parse()?;
2542 inputs.push_punct(punct);
2543 }
2544
2545 let or2_token: Token![|] = input.parse()?;
2546
2547 let (output, body) = if input.peek(Token![->]) {
2548 let arrow_token: Token![->] = input.parse()?;
2549 let ty: Type = input.parse()?;
2550 let body: Block = input.parse()?;
2551 let output = ReturnType::Type(arrow_token, Box::new(ty));
2552 let block = Expr::Block(ExprBlock {
2553 attrs: Vec::new(),
2554 label: None,
2555 block: body,
2556 });
2557 (output, block)
2558 } else {
2559 let body = ambiguous_expr(input, allow_struct)?;
2560 (ReturnType::Default, body)
2561 };
2562
2563 Ok(ExprClosure {
2564 attrs: Vec::new(),
2565 lifetimes,
2566 constness,
2567 movability,
2568 asyncness,
2569 capture,
2570 or1_token,
2571 inputs,
2572 or2_token,
2573 output,
2574 body: Box::new(body),
2575 })
2576 }
2577
2578 #[cfg(feature = "full")]
2579 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2580 impl Parse for ExprAsync {
2581 fn parse(input: ParseStream) -> Result<Self> {
2582 Ok(ExprAsync {
2583 attrs: Vec::new(),
2584 async_token: input.parse()?,
2585 capture: input.parse()?,
2586 block: input.parse()?,
2587 })
2588 }
2589 }
2590
2591 #[cfg(feature = "full")]
2592 fn closure_arg(input: ParseStream) -> Result<Pat> {
2593 let attrs = input.call(Attribute::parse_outer)?;
2594 let mut pat = Pat::parse_single(input)?;
2595
2596 if input.peek(Token![:]) {
2597 Ok(Pat::Type(PatType {
2598 attrs,
2599 pat: Box::new(pat),
2600 colon_token: input.parse()?,
2601 ty: input.parse()?,
2602 }))
2603 } else {
2604 match &mut pat {
2605 Pat::Const(pat) => pat.attrs = attrs,
2606 Pat::Ident(pat) => pat.attrs = attrs,
2607 Pat::Lit(pat) => pat.attrs = attrs,
2608 Pat::Macro(pat) => pat.attrs = attrs,
2609 Pat::Or(pat) => pat.attrs = attrs,
2610 Pat::Paren(pat) => pat.attrs = attrs,
2611 Pat::Path(pat) => pat.attrs = attrs,
2612 Pat::Range(pat) => pat.attrs = attrs,
2613 Pat::Reference(pat) => pat.attrs = attrs,
2614 Pat::Rest(pat) => pat.attrs = attrs,
2615 Pat::Slice(pat) => pat.attrs = attrs,
2616 Pat::Struct(pat) => pat.attrs = attrs,
2617 Pat::Tuple(pat) => pat.attrs = attrs,
2618 Pat::TupleStruct(pat) => pat.attrs = attrs,
2619 Pat::Type(_) => unreachable!(),
2620 Pat::Verbatim(_) => {}
2621 Pat::Wild(pat) => pat.attrs = attrs,
2622 }
2623 Ok(pat)
2624 }
2625 }
2626
2627 #[cfg(feature = "full")]
2628 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2629 impl Parse for ExprWhile {
2630 fn parse(input: ParseStream) -> Result<Self> {
2631 let mut attrs = input.call(Attribute::parse_outer)?;
2632 let label: Option<Label> = input.parse()?;
2633 let while_token: Token![while] = input.parse()?;
2634 let cond = Expr::parse_without_eager_brace(input)?;
2635
2636 let content;
2637 let brace_token = braced!(content in input);
2638 attr::parsing::parse_inner(&content, &mut attrs)?;
2639 let stmts = content.call(Block::parse_within)?;
2640
2641 Ok(ExprWhile {
2642 attrs,
2643 label,
2644 while_token,
2645 cond: Box::new(cond),
2646 body: Block { brace_token, stmts },
2647 })
2648 }
2649 }
2650
2651 #[cfg(feature = "full")]
2652 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2653 impl Parse for ExprConst {
2654 fn parse(input: ParseStream) -> Result<Self> {
2655 let const_token: Token![const] = input.parse()?;
2656
2657 let content;
2658 let brace_token = braced!(content in input);
2659 let inner_attrs = content.call(Attribute::parse_inner)?;
2660 let stmts = content.call(Block::parse_within)?;
2661
2662 Ok(ExprConst {
2663 attrs: inner_attrs,
2664 const_token,
2665 block: Block { brace_token, stmts },
2666 })
2667 }
2668 }
2669
2670 #[cfg(feature = "full")]
2671 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2672 impl Parse for Label {
2673 fn parse(input: ParseStream) -> Result<Self> {
2674 Ok(Label {
2675 name: input.parse()?,
2676 colon_token: input.parse()?,
2677 })
2678 }
2679 }
2680
2681 #[cfg(feature = "full")]
2682 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2683 impl Parse for Option<Label> {
2684 fn parse(input: ParseStream) -> Result<Self> {
2685 if input.peek(Lifetime) {
2686 input.parse().map(Some)
2687 } else {
2688 Ok(None)
2689 }
2690 }
2691 }
2692
2693 #[cfg(feature = "full")]
2694 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2695 impl Parse for ExprContinue {
2696 fn parse(input: ParseStream) -> Result<Self> {
2697 Ok(ExprContinue {
2698 attrs: Vec::new(),
2699 continue_token: input.parse()?,
2700 label: input.parse()?,
2701 })
2702 }
2703 }
2704
2705 #[cfg(feature = "full")]
2706 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2707 let break_token: Token![break] = input.parse()?;
2708
2709 let ahead = input.fork();
2710 let label: Option<Lifetime> = ahead.parse()?;
2711 if label.is_some() && ahead.peek(Token![:]) {
2712 let _: Expr = input.parse()?;
2715 let start_span = label.unwrap().apostrophe;
2716 let end_span = input.cursor().prev_span();
2717 return Err(crate::error::new2(
2718 start_span,
2719 end_span,
2720 "parentheses required",
2721 ));
2722 }
2723
2724 input.advance_to(&ahead);
2725 let expr = if Expr::peek(input) && (allow_struct.0 || !input.peek(token::Brace)) {
2726 Some(input.parse()?)
2727 } else {
2728 None
2729 };
2730
2731 Ok(ExprBreak {
2732 attrs: Vec::new(),
2733 break_token,
2734 label,
2735 expr,
2736 })
2737 }
2738
2739 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2740 impl Parse for FieldValue {
2741 fn parse(input: ParseStream) -> Result<Self> {
2742 let attrs = input.call(Attribute::parse_outer)?;
2743 let member: Member = input.parse()?;
2744 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2745 let colon_token: Token![:] = input.parse()?;
2746 let value: Expr = input.parse()?;
2747 (Some(colon_token), value)
2748 } else if let Member::Named(ident) = &member {
2749 let value = Expr::Path(ExprPath {
2750 attrs: Vec::new(),
2751 qself: None,
2752 path: Path::from(ident.clone()),
2753 });
2754 (None, value)
2755 } else {
2756 unreachable!()
2757 };
2758
2759 Ok(FieldValue {
2760 attrs,
2761 member,
2762 colon_token,
2763 expr: value,
2764 })
2765 }
2766 }
2767
2768 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2769 impl Parse for ExprStruct {
2770 fn parse(input: ParseStream) -> Result<Self> {
2771 let expr_style = true;
2772 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2773 expr_struct_helper(input, qself, path)
2774 }
2775 }
2776
2777 fn expr_struct_helper(
2778 input: ParseStream,
2779 qself: Option<QSelf>,
2780 path: Path,
2781 ) -> Result<ExprStruct> {
2782 let content;
2783 let brace_token = braced!(content in input);
2784
2785 let mut fields = Punctuated::new();
2786 while !content.is_empty() {
2787 if content.peek(Token![..]) {
2788 return Ok(ExprStruct {
2789 attrs: Vec::new(),
2790 qself,
2791 path,
2792 brace_token,
2793 fields,
2794 dot2_token: Some(content.parse()?),
2795 rest: if content.is_empty() {
2796 None
2797 } else {
2798 Some(Box::new(content.parse()?))
2799 },
2800 });
2801 }
2802
2803 fields.push(content.parse()?);
2804 if content.is_empty() {
2805 break;
2806 }
2807 let punct: Token![,] = content.parse()?;
2808 fields.push_punct(punct);
2809 }
2810
2811 Ok(ExprStruct {
2812 attrs: Vec::new(),
2813 qself,
2814 path,
2815 brace_token,
2816 fields,
2817 dot2_token: None,
2818 rest: None,
2819 })
2820 }
2821
2822 #[cfg(feature = "full")]
2823 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2824 impl Parse for ExprUnsafe {
2825 fn parse(input: ParseStream) -> Result<Self> {
2826 let unsafe_token: Token![unsafe] = input.parse()?;
2827
2828 let content;
2829 let brace_token = braced!(content in input);
2830 let inner_attrs = content.call(Attribute::parse_inner)?;
2831 let stmts = content.call(Block::parse_within)?;
2832
2833 Ok(ExprUnsafe {
2834 attrs: inner_attrs,
2835 unsafe_token,
2836 block: Block { brace_token, stmts },
2837 })
2838 }
2839 }
2840
2841 #[cfg(feature = "full")]
2842 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2843 impl Parse for ExprBlock {
2844 fn parse(input: ParseStream) -> Result<Self> {
2845 let mut attrs = input.call(Attribute::parse_outer)?;
2846 let label: Option<Label> = input.parse()?;
2847
2848 let content;
2849 let brace_token = braced!(content in input);
2850 attr::parsing::parse_inner(&content, &mut attrs)?;
2851 let stmts = content.call(Block::parse_within)?;
2852
2853 Ok(ExprBlock {
2854 attrs,
2855 label,
2856 block: Block { brace_token, stmts },
2857 })
2858 }
2859 }
2860
2861 #[cfg(feature = "full")]
2862 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2863 let limits: RangeLimits = input.parse()?;
2864 let end = parse_range_end(input, &limits, allow_struct)?;
2865 Ok(ExprRange {
2866 attrs: Vec::new(),
2867 start: None,
2868 limits,
2869 end,
2870 })
2871 }
2872
2873 #[cfg(feature = "full")]
2874 fn parse_range_end(
2875 input: ParseStream,
2876 limits: &RangeLimits,
2877 allow_struct: AllowStruct,
2878 ) -> Result<Option<Box<Expr>>> {
2879 if matches!(limits, RangeLimits::HalfOpen(_))
2880 && (input.is_empty()
2881 || input.peek(Token![,])
2882 || input.peek(Token![;])
2883 || input.peek(Token![.]) && !input.peek(Token![..])
2884 || input.peek(Token![?])
2885 || input.peek(Token![=>])
2886 || !allow_struct.0 && input.peek(token::Brace)
2887 || input.peek(Token![=])
2888 || input.peek(Token![+])
2889 || input.peek(Token![/])
2890 || input.peek(Token![%])
2891 || input.peek(Token![^])
2892 || input.peek(Token![>])
2893 || input.peek(Token![<=])
2894 || input.peek(Token![!=])
2895 || input.peek(Token![-=])
2896 || input.peek(Token![*=])
2897 || input.peek(Token![&=])
2898 || input.peek(Token![|=])
2899 || input.peek(Token![<<=])
2900 || input.peek(Token![as]))
2901 {
2902 Ok(None)
2903 } else {
2904 let end = parse_binop_rhs(input, allow_struct, Precedence::Range)?;
2905 Ok(Some(end))
2906 }
2907 }
2908
2909 #[cfg(feature = "full")]
2910 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2911 impl Parse for RangeLimits {
2912 fn parse(input: ParseStream) -> Result<Self> {
2913 let lookahead = input.lookahead1();
2914 let dot_dot = lookahead.peek(Token![..]);
2915 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2916 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2917 if dot_dot_eq {
2918 input.parse().map(RangeLimits::Closed)
2919 } else if dot_dot && !dot_dot_dot {
2920 input.parse().map(RangeLimits::HalfOpen)
2921 } else {
2922 Err(lookahead.error())
2923 }
2924 }
2925 }
2926
2927 #[cfg(feature = "full")]
2928 impl RangeLimits {
2929 pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> {
2930 let lookahead = input.lookahead1();
2931 let dot_dot = lookahead.peek(Token![..]);
2932 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2933 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2934 if dot_dot_eq {
2935 input.parse().map(RangeLimits::Closed)
2936 } else if dot_dot_dot {
2937 let dot3: Token![...] = input.parse()?;
2938 Ok(RangeLimits::Closed(Token))
2939 } else if dot_dot {
2940 input.parse().map(RangeLimits::HalfOpen)
2941 } else {
2942 Err(lookahead.error())
2943 }
2944 }
2945 }
2946
2947 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2948 impl Parse for ExprPath {
2949 fn parse(input: ParseStream) -> Result<Self> {
2950 #[cfg(not(feature = "full"))]
2951 let attrs = Vec::new();
2952 #[cfg(feature = "full")]
2953 let attrs = input.call(Attribute::parse_outer)?;
2954
2955 let expr_style = true;
2956 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2957
2958 Ok(ExprPath { attrs, qself, path })
2959 }
2960 }
2961
2962 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2963 impl Parse for Member {
2964 fn parse(input: ParseStream) -> Result<Self> {
2965 if input.peek(Ident) {
2966 input.parse().map(Member::Named)
2967 } else if input.peek(LitInt) {
2968 input.parse().map(Member::Unnamed)
2969 } else {
2970 Err(input.error("expected identifier or integer"))
2971 }
2972 }
2973 }
2974
2975 #[cfg(feature = "full")]
2976 impl Arm {
2977 pub(crate) fn parse_multiple(input: ParseStream) -> Result<Vec<Self>> {
2978 let mut arms = Vec::new();
2979 while !input.is_empty() {
2980 arms.push(input.call(Arm::parse)?);
2981 }
2982 Ok(arms)
2983 }
2984 }
2985
2986 #[cfg(feature = "full")]
2987 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2988 impl Parse for Arm {
2989 fn parse(input: ParseStream) -> Result<Arm> {
2990 let requires_comma;
2991 Ok(Arm {
2992 attrs: input.call(Attribute::parse_outer)?,
2993 pat: Pat::parse_multi_with_leading_vert(input)?,
2994 guard: {
2995 if input.peek(Token![if]) {
2996 let if_token: Token![if] = input.parse()?;
2997 let guard: Expr = input.parse()?;
2998 Some((if_token, Box::new(guard)))
2999 } else {
3000 None
3001 }
3002 },
3003 fat_arrow_token: input.parse()?,
3004 body: {
3005 let body = Expr::parse_with_earlier_boundary_rule(input)?;
3006 requires_comma = classify::requires_comma_to_be_match_arm(&body);
3007 Box::new(body)
3008 },
3009 comma: {
3010 if requires_comma && !input.is_empty() {
3011 Some(input.parse()?)
3012 } else {
3013 input.parse()?
3014 }
3015 },
3016 })
3017 }
3018 }
3019
3020 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
3021 impl Parse for Index {
3022 fn parse(input: ParseStream) -> Result<Self> {
3023 let lit: LitInt = input.parse()?;
3024 if lit.suffix().is_empty() {
3025 Ok(Index {
3026 index: lit
3027 .base10_digits()
3028 .parse()
3029 .map_err(|err| Error::new(lit.span(), err))?,
3030 span: lit.span(),
3031 })
3032 } else {
3033 Err(Error::new(lit.span(), "expected unsuffixed integer"))
3034 }
3035 }
3036 }
3037
3038 fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
3039 let float_token = float.token();
3040 let float_span = float_token.span();
3041 let mut float_repr = float_token.to_string();
3042 let trailing_dot = float_repr.ends_with('.');
3043 if trailing_dot {
3044 float_repr.truncate(float_repr.len() - 1);
3045 }
3046
3047 let mut offset = 0;
3048 for part in float_repr.split('.') {
3049 let mut index: Index =
3050 crate::parse_str(part).map_err(|err| Error::new(float_span, err))?;
3051 let part_end = offset + part.len();
3052 index.span = float_token.subspan(offset..part_end).unwrap_or(float_span);
3053
3054 let base = mem::replace(e, Expr::PLACEHOLDER);
3055 *e = Expr::Field(ExprField {
3056 attrs: Vec::new(),
3057 base: Box::new(base),
3058 dot_token: Token,
3059 member: Member::Unnamed(index),
3060 });
3061
3062 let dot_span = float_token
3063 .subspan(part_end..part_end + 1)
3064 .unwrap_or(float_span);
3065 *dot_token = Token;
3066 offset = part_end + 1;
3067 }
3068
3069 Ok(!trailing_dot)
3070 }
3071
3072 #[cfg(feature = "full")]
3073 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
3074 impl Parse for PointerMutability {
3075 fn parse(input: ParseStream) -> Result<Self> {
3076 let lookahead = input.lookahead1();
3077 if lookahead.peek(Token![const]) {
3078 Ok(PointerMutability::Const(input.parse()?))
3079 } else if lookahead.peek(Token![mut]) {
3080 Ok(PointerMutability::Mut(input.parse()?))
3081 } else {
3082 Err(lookahead.error())
3083 }
3084 }
3085 }
3086
3087 fn check_cast(input: ParseStream) -> Result<()> {
3088 let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
3089 if input.peek2(Token![await]) {
3090 "`.await`"
3091 } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
3092 "a method call"
3093 } else {
3094 "a field access"
3095 }
3096 } else if input.peek(Token![?]) {
3097 "`?`"
3098 } else if input.peek(token::Bracket) {
3099 "indexing"
3100 } else if input.peek(token::Paren) {
3101 "a function call"
3102 } else {
3103 return Ok(());
3104 };
3105 let msg = format!("casts cannot be followed by {}", kind);
3106 Err(input.error(msg))
3107 }
3108}
3109
3110#[cfg(feature = "printing")]
3111pub(crate) mod printing {
3112 use crate::attr::Attribute;
3113 #[cfg(feature = "full")]
3114 use crate::attr::FilterAttrs;
3115 #[cfg(feature = "full")]
3116 use crate::classify;
3117 #[cfg(feature = "full")]
3118 use crate::expr::{
3119 Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
3120 ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
3121 ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
3122 ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
3123 };
3124 use crate::expr::{
3125 Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
3126 ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary,
3127 FieldValue, Index, Member,
3128 };
3129 use crate::fixup::FixupContext;
3130 use crate::op::BinOp;
3131 use crate::path;
3132 use crate::path::printing::PathStyle;
3133 use crate::precedence::Precedence;
3134 use crate::token;
3135 #[cfg(feature = "full")]
3136 use crate::ty::ReturnType;
3137 use proc_macro2::{Literal, Span, TokenStream};
3138 use quote::{ToTokens, TokenStreamExt};
3139
3140 #[cfg(feature = "full")]
3141 pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3142 tokens.append_all(attrs.outer());
3143 }
3144
3145 #[cfg(feature = "full")]
3146 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3147 tokens.append_all(attrs.inner());
3148 }
3149
3150 #[cfg(not(feature = "full"))]
3151 pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3152
3153 pub(crate) fn print_subexpression(
3154 expr: &Expr,
3155 needs_group: bool,
3156 tokens: &mut TokenStream,
3157 mut fixup: FixupContext,
3158 ) {
3159 if needs_group {
3160 fixup = FixupContext::NONE;
3172 }
3173
3174 let do_print_expr = |tokens: &mut TokenStream| print_expr(expr, tokens, fixup);
3175
3176 if needs_group {
3177 token::Paren::default().surround(tokens, do_print_expr);
3178 } else {
3179 do_print_expr(tokens);
3180 }
3181 }
3182
3183 pub(crate) fn print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext) {
3184 #[cfg(feature = "full")]
3185 let needs_group = fixup.parenthesize(expr);
3186 #[cfg(not(feature = "full"))]
3187 let needs_group = false;
3188
3189 if needs_group {
3190 fixup = FixupContext::NONE;
3191 }
3192
3193 let do_print_expr = |tokens: &mut TokenStream| match expr {
3194 #[cfg(feature = "full")]
3195 Expr::Array(e) => e.to_tokens(tokens),
3196 #[cfg(feature = "full")]
3197 Expr::Assign(e) => print_expr_assign(e, tokens, fixup),
3198 #[cfg(feature = "full")]
3199 Expr::Async(e) => e.to_tokens(tokens),
3200 #[cfg(feature = "full")]
3201 Expr::Await(e) => print_expr_await(e, tokens, fixup),
3202 Expr::Binary(e) => print_expr_binary(e, tokens, fixup),
3203 #[cfg(feature = "full")]
3204 Expr::Block(e) => e.to_tokens(tokens),
3205 #[cfg(feature = "full")]
3206 Expr::Break(e) => print_expr_break(e, tokens, fixup),
3207 Expr::Call(e) => print_expr_call(e, tokens, fixup),
3208 Expr::Cast(e) => print_expr_cast(e, tokens, fixup),
3209 #[cfg(feature = "full")]
3210 Expr::Closure(e) => print_expr_closure(e, tokens, fixup),
3211 #[cfg(feature = "full")]
3212 Expr::Const(e) => e.to_tokens(tokens),
3213 #[cfg(feature = "full")]
3214 Expr::Continue(e) => e.to_tokens(tokens),
3215 Expr::Field(e) => print_expr_field(e, tokens, fixup),
3216 #[cfg(feature = "full")]
3217 Expr::ForLoop(e) => e.to_tokens(tokens),
3218 Expr::Group(e) => e.to_tokens(tokens),
3219 #[cfg(feature = "full")]
3220 Expr::If(e) => e.to_tokens(tokens),
3221 #[cfg(feature = "full")]
3222 Expr::Index(e) => print_expr_index(e, tokens, fixup),
3223 #[cfg(feature = "full")]
3224 Expr::Infer(e) => e.to_tokens(tokens),
3225 #[cfg(feature = "full")]
3226 Expr::Let(e) => print_expr_let(e, tokens, fixup),
3227 Expr::Lit(e) => e.to_tokens(tokens),
3228 #[cfg(feature = "full")]
3229 Expr::Loop(e) => e.to_tokens(tokens),
3230 Expr::Macro(e) => e.to_tokens(tokens),
3231 #[cfg(feature = "full")]
3232 Expr::Match(e) => e.to_tokens(tokens),
3233 Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup),
3234 Expr::Paren(e) => e.to_tokens(tokens),
3235 Expr::Path(e) => e.to_tokens(tokens),
3236 #[cfg(feature = "full")]
3237 Expr::Range(e) => print_expr_range(e, tokens, fixup),
3238 #[cfg(feature = "full")]
3239 Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup),
3240 Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
3241 #[cfg(feature = "full")]
3242 Expr::Repeat(e) => e.to_tokens(tokens),
3243 #[cfg(feature = "full")]
3244 Expr::Return(e) => print_expr_return(e, tokens, fixup),
3245 Expr::Struct(e) => e.to_tokens(tokens),
3246 #[cfg(feature = "full")]
3247 Expr::Try(e) => print_expr_try(e, tokens, fixup),
3248 #[cfg(feature = "full")]
3249 Expr::TryBlock(e) => e.to_tokens(tokens),
3250 #[cfg(feature = "full")]
3251 Expr::Tuple(e) => e.to_tokens(tokens),
3252 Expr::Unary(e) => print_expr_unary(e, tokens, fixup),
3253 #[cfg(feature = "full")]
3254 Expr::Unsafe(e) => e.to_tokens(tokens),
3255 Expr::Verbatim(e) => e.to_tokens(tokens),
3256 #[cfg(feature = "full")]
3257 Expr::While(e) => e.to_tokens(tokens),
3258 #[cfg(feature = "full")]
3259 Expr::Yield(e) => print_expr_yield(e, tokens, fixup),
3260
3261 #[cfg(not(feature = "full"))]
3262 _ => unreachable!(),
3263 };
3264
3265 if needs_group {
3266 token::Paren::default().surround(tokens, do_print_expr);
3267 } else {
3268 do_print_expr(tokens);
3269 }
3270 }
3271
3272 #[cfg(feature = "full")]
3273 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3274 impl ToTokens for ExprArray {
3275 fn to_tokens(&self, tokens: &mut TokenStream) {
3276 outer_attrs_to_tokens(&self.attrs, tokens);
3277 self.bracket_token.surround(tokens, |tokens| {
3278 self.elems.to_tokens(tokens);
3279 });
3280 }
3281 }
3282
3283 #[cfg(feature = "full")]
3284 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3285 impl ToTokens for ExprAssign {
3286 fn to_tokens(&self, tokens: &mut TokenStream) {
3287 print_expr_assign(self, tokens, FixupContext::NONE);
3288 }
3289 }
3290
3291 #[cfg(feature = "full")]
3292 fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, fixup: FixupContext) {
3293 outer_attrs_to_tokens(&e.attrs, tokens);
3294 let (left_prec, left_fixup) =
3295 fixup.leftmost_subexpression_with_operator(&e.left, false, false, Precedence::Assign);
3296 print_subexpression(&e.left, left_prec <= Precedence::Range, tokens, left_fixup);
3297 e.eq_token.to_tokens(tokens);
3298 print_expr(
3299 &e.right,
3300 tokens,
3301 fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign),
3302 );
3303 }
3304
3305 #[cfg(feature = "full")]
3306 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3307 impl ToTokens for ExprAsync {
3308 fn to_tokens(&self, tokens: &mut TokenStream) {
3309 outer_attrs_to_tokens(&self.attrs, tokens);
3310 self.async_token.to_tokens(tokens);
3311 self.capture.to_tokens(tokens);
3312 self.block.to_tokens(tokens);
3313 }
3314 }
3315
3316 #[cfg(feature = "full")]
3317 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3318 impl ToTokens for ExprAwait {
3319 fn to_tokens(&self, tokens: &mut TokenStream) {
3320 print_expr_await(self, tokens, FixupContext::NONE);
3321 }
3322 }
3323
3324 #[cfg(feature = "full")]
3325 fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) {
3326 outer_attrs_to_tokens(&e.attrs, tokens);
3327 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3328 print_subexpression(
3329 &e.base,
3330 left_prec < Precedence::Unambiguous,
3331 tokens,
3332 left_fixup,
3333 );
3334 e.dot_token.to_tokens(tokens);
3335 e.await_token.to_tokens(tokens);
3336 }
3337
3338 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3339 impl ToTokens for ExprBinary {
3340 fn to_tokens(&self, tokens: &mut TokenStream) {
3341 print_expr_binary(self, tokens, FixupContext::NONE);
3342 }
3343 }
3344
3345 fn print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, fixup: FixupContext) {
3346 outer_attrs_to_tokens(&e.attrs, tokens);
3347
3348 let binop_prec = Precedence::of_binop(&e.op);
3349 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3350 &e.left,
3351 #[cfg(feature = "full")]
3352 match &e.op {
3353 BinOp::Sub(_)
3354 | BinOp::Mul(_)
3355 | BinOp::And(_)
3356 | BinOp::Or(_)
3357 | BinOp::BitAnd(_)
3358 | BinOp::BitOr(_)
3359 | BinOp::Shl(_)
3360 | BinOp::Lt(_) => true,
3361 _ => false,
3362 },
3363 match &e.op {
3364 BinOp::Shl(_) | BinOp::Lt(_) => true,
3365 _ => false,
3366 },
3367 #[cfg(feature = "full")]
3368 binop_prec,
3369 );
3370 let left_needs_group = match binop_prec {
3371 Precedence::Assign => left_prec <= Precedence::Range,
3372 Precedence::Compare => left_prec <= binop_prec,
3373 _ => left_prec < binop_prec,
3374 };
3375
3376 let right_fixup = fixup.rightmost_subexpression_fixup(
3377 #[cfg(feature = "full")]
3378 false,
3379 #[cfg(feature = "full")]
3380 false,
3381 #[cfg(feature = "full")]
3382 binop_prec,
3383 );
3384 let right_needs_group = binop_prec != Precedence::Assign
3385 && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec;
3386
3387 print_subexpression(&e.left, left_needs_group, tokens, left_fixup);
3388 e.op.to_tokens(tokens);
3389 print_subexpression(&e.right, right_needs_group, tokens, right_fixup);
3390 }
3391
3392 #[cfg(feature = "full")]
3393 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3394 impl ToTokens for ExprBlock {
3395 fn to_tokens(&self, tokens: &mut TokenStream) {
3396 outer_attrs_to_tokens(&self.attrs, tokens);
3397 self.label.to_tokens(tokens);
3398 self.block.brace_token.surround(tokens, |tokens| {
3399 inner_attrs_to_tokens(&self.attrs, tokens);
3400 tokens.append_all(&self.block.stmts);
3401 });
3402 }
3403 }
3404
3405 #[cfg(feature = "full")]
3406 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3407 impl ToTokens for ExprBreak {
3408 fn to_tokens(&self, tokens: &mut TokenStream) {
3409 print_expr_break(self, tokens, FixupContext::NONE);
3410 }
3411 }
3412
3413 #[cfg(feature = "full")]
3414 fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) {
3415 outer_attrs_to_tokens(&e.attrs, tokens);
3416 e.break_token.to_tokens(tokens);
3417 e.label.to_tokens(tokens);
3418 if let Some(value) = &e.expr {
3419 print_subexpression(
3420 value,
3421 e.label.is_none() && classify::expr_leading_label(value),
3424 tokens,
3425 fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump),
3426 );
3427 }
3428 }
3429
3430 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3431 impl ToTokens for ExprCall {
3432 fn to_tokens(&self, tokens: &mut TokenStream) {
3433 print_expr_call(self, tokens, FixupContext::NONE);
3434 }
3435 }
3436
3437 fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) {
3438 outer_attrs_to_tokens(&e.attrs, tokens);
3439
3440 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3441 &e.func,
3442 #[cfg(feature = "full")]
3443 true,
3444 false,
3445 #[cfg(feature = "full")]
3446 Precedence::Unambiguous,
3447 );
3448 let needs_group = if let Expr::Field(func) = &*e.func {
3449 func.member.is_named()
3450 } else {
3451 left_prec < Precedence::Unambiguous
3452 };
3453 print_subexpression(&e.func, needs_group, tokens, left_fixup);
3454
3455 e.paren_token.surround(tokens, |tokens| {
3456 e.args.to_tokens(tokens);
3457 });
3458 }
3459
3460 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3461 impl ToTokens for ExprCast {
3462 fn to_tokens(&self, tokens: &mut TokenStream) {
3463 print_expr_cast(self, tokens, FixupContext::NONE);
3464 }
3465 }
3466
3467 fn print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, fixup: FixupContext) {
3468 outer_attrs_to_tokens(&e.attrs, tokens);
3469 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3470 &e.expr,
3471 #[cfg(feature = "full")]
3472 false,
3473 false,
3474 #[cfg(feature = "full")]
3475 Precedence::Cast,
3476 );
3477 print_subexpression(&e.expr, left_prec < Precedence::Cast, tokens, left_fixup);
3478 e.as_token.to_tokens(tokens);
3479 e.ty.to_tokens(tokens);
3480 }
3481
3482 #[cfg(feature = "full")]
3483 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3484 impl ToTokens for ExprClosure {
3485 fn to_tokens(&self, tokens: &mut TokenStream) {
3486 print_expr_closure(self, tokens, FixupContext::NONE);
3487 }
3488 }
3489
3490 #[cfg(feature = "full")]
3491 fn print_expr_closure(e: &ExprClosure, tokens: &mut TokenStream, fixup: FixupContext) {
3492 outer_attrs_to_tokens(&e.attrs, tokens);
3493 e.lifetimes.to_tokens(tokens);
3494 e.constness.to_tokens(tokens);
3495 e.movability.to_tokens(tokens);
3496 e.asyncness.to_tokens(tokens);
3497 e.capture.to_tokens(tokens);
3498 e.or1_token.to_tokens(tokens);
3499 e.inputs.to_tokens(tokens);
3500 e.or2_token.to_tokens(tokens);
3501 e.output.to_tokens(tokens);
3502 if matches!(e.output, ReturnType::Default)
3503 || matches!(&*e.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none())
3504 {
3505 print_expr(
3506 &e.body,
3507 tokens,
3508 fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
3509 );
3510 } else {
3511 token::Brace::default().surround(tokens, |tokens| {
3512 print_expr(&e.body, tokens, FixupContext::new_stmt());
3513 });
3514 }
3515 }
3516
3517 #[cfg(feature = "full")]
3518 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3519 impl ToTokens for ExprConst {
3520 fn to_tokens(&self, tokens: &mut TokenStream) {
3521 outer_attrs_to_tokens(&self.attrs, tokens);
3522 self.const_token.to_tokens(tokens);
3523 self.block.brace_token.surround(tokens, |tokens| {
3524 inner_attrs_to_tokens(&self.attrs, tokens);
3525 tokens.append_all(&self.block.stmts);
3526 });
3527 }
3528 }
3529
3530 #[cfg(feature = "full")]
3531 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3532 impl ToTokens for ExprContinue {
3533 fn to_tokens(&self, tokens: &mut TokenStream) {
3534 outer_attrs_to_tokens(&self.attrs, tokens);
3535 self.continue_token.to_tokens(tokens);
3536 self.label.to_tokens(tokens);
3537 }
3538 }
3539
3540 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3541 impl ToTokens for ExprField {
3542 fn to_tokens(&self, tokens: &mut TokenStream) {
3543 print_expr_field(self, tokens, FixupContext::NONE);
3544 }
3545 }
3546
3547 fn print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext) {
3548 outer_attrs_to_tokens(&e.attrs, tokens);
3549 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3550 print_subexpression(
3551 &e.base,
3552 left_prec < Precedence::Unambiguous,
3553 tokens,
3554 left_fixup,
3555 );
3556 e.dot_token.to_tokens(tokens);
3557 e.member.to_tokens(tokens);
3558 }
3559
3560 #[cfg(feature = "full")]
3561 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3562 impl ToTokens for ExprForLoop {
3563 fn to_tokens(&self, tokens: &mut TokenStream) {
3564 outer_attrs_to_tokens(&self.attrs, tokens);
3565 self.label.to_tokens(tokens);
3566 self.for_token.to_tokens(tokens);
3567 self.pat.to_tokens(tokens);
3568 self.in_token.to_tokens(tokens);
3569 print_expr(&self.expr, tokens, FixupContext::new_condition());
3570 self.body.brace_token.surround(tokens, |tokens| {
3571 inner_attrs_to_tokens(&self.attrs, tokens);
3572 tokens.append_all(&self.body.stmts);
3573 });
3574 }
3575 }
3576
3577 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3578 impl ToTokens for ExprGroup {
3579 fn to_tokens(&self, tokens: &mut TokenStream) {
3580 outer_attrs_to_tokens(&self.attrs, tokens);
3581 self.group_token.surround(tokens, |tokens| {
3582 self.expr.to_tokens(tokens);
3583 });
3584 }
3585 }
3586
3587 #[cfg(feature = "full")]
3588 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3589 impl ToTokens for ExprIf {
3590 fn to_tokens(&self, tokens: &mut TokenStream) {
3591 outer_attrs_to_tokens(&self.attrs, tokens);
3592
3593 let mut expr = self;
3594 loop {
3595 expr.if_token.to_tokens(tokens);
3596 print_expr(&expr.cond, tokens, FixupContext::new_condition());
3597 expr.then_branch.to_tokens(tokens);
3598
3599 let (else_token, else_) = match &expr.else_branch {
3600 Some(else_branch) => else_branch,
3601 None => break,
3602 };
3603
3604 else_token.to_tokens(tokens);
3605 match &**else_ {
3606 Expr::If(next) => {
3607 expr = next;
3608 }
3609 Expr::Block(last) => {
3610 last.to_tokens(tokens);
3611 break;
3612 }
3613 other => {
3616 token::Brace::default().surround(tokens, |tokens| {
3617 print_expr(other, tokens, FixupContext::new_stmt());
3618 });
3619 break;
3620 }
3621 }
3622 }
3623 }
3624 }
3625
3626 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3627 impl ToTokens for ExprIndex {
3628 fn to_tokens(&self, tokens: &mut TokenStream) {
3629 print_expr_index(self, tokens, FixupContext::NONE);
3630 }
3631 }
3632
3633 fn print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext) {
3634 outer_attrs_to_tokens(&e.attrs, tokens);
3635 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3636 &e.expr,
3637 #[cfg(feature = "full")]
3638 true,
3639 false,
3640 #[cfg(feature = "full")]
3641 Precedence::Unambiguous,
3642 );
3643 print_subexpression(
3644 &e.expr,
3645 left_prec < Precedence::Unambiguous,
3646 tokens,
3647 left_fixup,
3648 );
3649 e.bracket_token.surround(tokens, |tokens| {
3650 e.index.to_tokens(tokens);
3651 });
3652 }
3653
3654 #[cfg(feature = "full")]
3655 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3656 impl ToTokens for ExprInfer {
3657 fn to_tokens(&self, tokens: &mut TokenStream) {
3658 outer_attrs_to_tokens(&self.attrs, tokens);
3659 self.underscore_token.to_tokens(tokens);
3660 }
3661 }
3662
3663 #[cfg(feature = "full")]
3664 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3665 impl ToTokens for ExprLet {
3666 fn to_tokens(&self, tokens: &mut TokenStream) {
3667 print_expr_let(self, tokens, FixupContext::NONE);
3668 }
3669 }
3670
3671 #[cfg(feature = "full")]
3672 fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) {
3673 outer_attrs_to_tokens(&e.attrs, tokens);
3674 e.let_token.to_tokens(tokens);
3675 e.pat.to_tokens(tokens);
3676 e.eq_token.to_tokens(tokens);
3677 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Let);
3678 print_subexpression(&e.expr, right_prec < Precedence::Let, tokens, right_fixup);
3679 }
3680
3681 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3682 impl ToTokens for ExprLit {
3683 fn to_tokens(&self, tokens: &mut TokenStream) {
3684 outer_attrs_to_tokens(&self.attrs, tokens);
3685 self.lit.to_tokens(tokens);
3686 }
3687 }
3688
3689 #[cfg(feature = "full")]
3690 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3691 impl ToTokens for ExprLoop {
3692 fn to_tokens(&self, tokens: &mut TokenStream) {
3693 outer_attrs_to_tokens(&self.attrs, tokens);
3694 self.label.to_tokens(tokens);
3695 self.loop_token.to_tokens(tokens);
3696 self.body.brace_token.surround(tokens, |tokens| {
3697 inner_attrs_to_tokens(&self.attrs, tokens);
3698 tokens.append_all(&self.body.stmts);
3699 });
3700 }
3701 }
3702
3703 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3704 impl ToTokens for ExprMacro {
3705 fn to_tokens(&self, tokens: &mut TokenStream) {
3706 outer_attrs_to_tokens(&self.attrs, tokens);
3707 self.mac.to_tokens(tokens);
3708 }
3709 }
3710
3711 #[cfg(feature = "full")]
3712 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3713 impl ToTokens for ExprMatch {
3714 fn to_tokens(&self, tokens: &mut TokenStream) {
3715 outer_attrs_to_tokens(&self.attrs, tokens);
3716 self.match_token.to_tokens(tokens);
3717 print_expr(&self.expr, tokens, FixupContext::new_condition());
3718 self.brace_token.surround(tokens, |tokens| {
3719 inner_attrs_to_tokens(&self.attrs, tokens);
3720 for (i, arm) in self.arms.iter().enumerate() {
3721 arm.to_tokens(tokens);
3722 let is_last = i == self.arms.len() - 1;
3725 if !is_last
3726 && classify::requires_comma_to_be_match_arm(&arm.body)
3727 && arm.comma.is_none()
3728 {
3729 <Token![,]>::default().to_tokens(tokens);
3730 }
3731 }
3732 });
3733 }
3734 }
3735
3736 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3737 impl ToTokens for ExprMethodCall {
3738 fn to_tokens(&self, tokens: &mut TokenStream) {
3739 print_expr_method_call(self, tokens, FixupContext::NONE);
3740 }
3741 }
3742
3743 fn print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext) {
3744 outer_attrs_to_tokens(&e.attrs, tokens);
3745 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.receiver);
3746 print_subexpression(
3747 &e.receiver,
3748 left_prec < Precedence::Unambiguous,
3749 tokens,
3750 left_fixup,
3751 );
3752 e.dot_token.to_tokens(tokens);
3753 e.method.to_tokens(tokens);
3754 if let Some(turbofish) = &e.turbofish {
3755 path::printing::print_angle_bracketed_generic_arguments(
3756 tokens,
3757 turbofish,
3758 PathStyle::Expr,
3759 );
3760 }
3761 e.paren_token.surround(tokens, |tokens| {
3762 e.args.to_tokens(tokens);
3763 });
3764 }
3765
3766 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3767 impl ToTokens for ExprParen {
3768 fn to_tokens(&self, tokens: &mut TokenStream) {
3769 outer_attrs_to_tokens(&self.attrs, tokens);
3770 self.paren_token.surround(tokens, |tokens| {
3771 self.expr.to_tokens(tokens);
3772 });
3773 }
3774 }
3775
3776 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3777 impl ToTokens for ExprPath {
3778 fn to_tokens(&self, tokens: &mut TokenStream) {
3779 outer_attrs_to_tokens(&self.attrs, tokens);
3780 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3781 }
3782 }
3783
3784 #[cfg(feature = "full")]
3785 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3786 impl ToTokens for ExprRange {
3787 fn to_tokens(&self, tokens: &mut TokenStream) {
3788 print_expr_range(self, tokens, FixupContext::NONE);
3789 }
3790 }
3791
3792 #[cfg(feature = "full")]
3793 fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, fixup: FixupContext) {
3794 outer_attrs_to_tokens(&e.attrs, tokens);
3795 if let Some(start) = &e.start {
3796 let (left_prec, left_fixup) =
3797 fixup.leftmost_subexpression_with_operator(start, true, false, Precedence::Range);
3798 print_subexpression(start, left_prec <= Precedence::Range, tokens, left_fixup);
3799 }
3800 e.limits.to_tokens(tokens);
3801 if let Some(end) = &e.end {
3802 let right_fixup = fixup.rightmost_subexpression_fixup(false, true, Precedence::Range);
3803 let right_prec = right_fixup.rightmost_subexpression_precedence(end);
3804 print_subexpression(end, right_prec <= Precedence::Range, tokens, right_fixup);
3805 }
3806 }
3807
3808 #[cfg(feature = "full")]
3809 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3810 impl ToTokens for ExprRawAddr {
3811 fn to_tokens(&self, tokens: &mut TokenStream) {
3812 print_expr_raw_addr(self, tokens, FixupContext::NONE);
3813 }
3814 }
3815
3816 #[cfg(feature = "full")]
3817 fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) {
3818 outer_attrs_to_tokens(&e.attrs, tokens);
3819 e.and_token.to_tokens(tokens);
3820 e.raw.to_tokens(tokens);
3821 e.mutability.to_tokens(tokens);
3822 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Prefix);
3823 print_subexpression(
3824 &e.expr,
3825 right_prec < Precedence::Prefix,
3826 tokens,
3827 right_fixup,
3828 );
3829 }
3830
3831 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3832 impl ToTokens for ExprReference {
3833 fn to_tokens(&self, tokens: &mut TokenStream) {
3834 print_expr_reference(self, tokens, FixupContext::NONE);
3835 }
3836 }
3837
3838 fn print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext) {
3839 outer_attrs_to_tokens(&e.attrs, tokens);
3840 e.and_token.to_tokens(tokens);
3841 e.mutability.to_tokens(tokens);
3842 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3843 &e.expr,
3844 #[cfg(feature = "full")]
3845 Precedence::Prefix,
3846 );
3847 print_subexpression(
3848 &e.expr,
3849 right_prec < Precedence::Prefix,
3850 tokens,
3851 right_fixup,
3852 );
3853 }
3854
3855 #[cfg(feature = "full")]
3856 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3857 impl ToTokens for ExprRepeat {
3858 fn to_tokens(&self, tokens: &mut TokenStream) {
3859 outer_attrs_to_tokens(&self.attrs, tokens);
3860 self.bracket_token.surround(tokens, |tokens| {
3861 self.expr.to_tokens(tokens);
3862 self.semi_token.to_tokens(tokens);
3863 self.len.to_tokens(tokens);
3864 });
3865 }
3866 }
3867
3868 #[cfg(feature = "full")]
3869 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3870 impl ToTokens for ExprReturn {
3871 fn to_tokens(&self, tokens: &mut TokenStream) {
3872 print_expr_return(self, tokens, FixupContext::NONE);
3873 }
3874 }
3875
3876 #[cfg(feature = "full")]
3877 fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) {
3878 outer_attrs_to_tokens(&e.attrs, tokens);
3879 e.return_token.to_tokens(tokens);
3880 if let Some(expr) = &e.expr {
3881 print_expr(
3882 expr,
3883 tokens,
3884 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
3885 );
3886 }
3887 }
3888
3889 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3890 impl ToTokens for ExprStruct {
3891 fn to_tokens(&self, tokens: &mut TokenStream) {
3892 outer_attrs_to_tokens(&self.attrs, tokens);
3893 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3894 self.brace_token.surround(tokens, |tokens| {
3895 self.fields.to_tokens(tokens);
3896 if let Some(dot2_token) = &self.dot2_token {
3897 dot2_token.to_tokens(tokens);
3898 } else if self.rest.is_some() {
3899 Token).to_tokens(tokens);
3900 }
3901 self.rest.to_tokens(tokens);
3902 });
3903 }
3904 }
3905
3906 #[cfg(feature = "full")]
3907 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3908 impl ToTokens for ExprTry {
3909 fn to_tokens(&self, tokens: &mut TokenStream) {
3910 print_expr_try(self, tokens, FixupContext::NONE);
3911 }
3912 }
3913
3914 #[cfg(feature = "full")]
3915 fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) {
3916 outer_attrs_to_tokens(&e.attrs, tokens);
3917 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.expr);
3918 print_subexpression(
3919 &e.expr,
3920 left_prec < Precedence::Unambiguous,
3921 tokens,
3922 left_fixup,
3923 );
3924 e.question_token.to_tokens(tokens);
3925 }
3926
3927 #[cfg(feature = "full")]
3928 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3929 impl ToTokens for ExprTryBlock {
3930 fn to_tokens(&self, tokens: &mut TokenStream) {
3931 outer_attrs_to_tokens(&self.attrs, tokens);
3932 self.try_token.to_tokens(tokens);
3933 self.block.to_tokens(tokens);
3934 }
3935 }
3936
3937 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3938 impl ToTokens for ExprTuple {
3939 fn to_tokens(&self, tokens: &mut TokenStream) {
3940 outer_attrs_to_tokens(&self.attrs, tokens);
3941 self.paren_token.surround(tokens, |tokens| {
3942 self.elems.to_tokens(tokens);
3943 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3946 <Token![,]>::default().to_tokens(tokens);
3947 }
3948 });
3949 }
3950 }
3951
3952 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3953 impl ToTokens for ExprUnary {
3954 fn to_tokens(&self, tokens: &mut TokenStream) {
3955 print_expr_unary(self, tokens, FixupContext::NONE);
3956 }
3957 }
3958
3959 fn print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext) {
3960 outer_attrs_to_tokens(&e.attrs, tokens);
3961 e.op.to_tokens(tokens);
3962 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3963 &e.expr,
3964 #[cfg(feature = "full")]
3965 Precedence::Prefix,
3966 );
3967 print_subexpression(
3968 &e.expr,
3969 right_prec < Precedence::Prefix,
3970 tokens,
3971 right_fixup,
3972 );
3973 }
3974
3975 #[cfg(feature = "full")]
3976 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3977 impl ToTokens for ExprUnsafe {
3978 fn to_tokens(&self, tokens: &mut TokenStream) {
3979 outer_attrs_to_tokens(&self.attrs, tokens);
3980 self.unsafe_token.to_tokens(tokens);
3981 self.block.brace_token.surround(tokens, |tokens| {
3982 inner_attrs_to_tokens(&self.attrs, tokens);
3983 tokens.append_all(&self.block.stmts);
3984 });
3985 }
3986 }
3987
3988 #[cfg(feature = "full")]
3989 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3990 impl ToTokens for ExprWhile {
3991 fn to_tokens(&self, tokens: &mut TokenStream) {
3992 outer_attrs_to_tokens(&self.attrs, tokens);
3993 self.label.to_tokens(tokens);
3994 self.while_token.to_tokens(tokens);
3995 print_expr(&self.cond, tokens, FixupContext::new_condition());
3996 self.body.brace_token.surround(tokens, |tokens| {
3997 inner_attrs_to_tokens(&self.attrs, tokens);
3998 tokens.append_all(&self.body.stmts);
3999 });
4000 }
4001 }
4002
4003 #[cfg(feature = "full")]
4004 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4005 impl ToTokens for ExprYield {
4006 fn to_tokens(&self, tokens: &mut TokenStream) {
4007 print_expr_yield(self, tokens, FixupContext::NONE);
4008 }
4009 }
4010
4011 #[cfg(feature = "full")]
4012 fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) {
4013 outer_attrs_to_tokens(&e.attrs, tokens);
4014 e.yield_token.to_tokens(tokens);
4015 if let Some(expr) = &e.expr {
4016 print_expr(
4017 expr,
4018 tokens,
4019 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
4020 );
4021 }
4022 }
4023
4024 #[cfg(feature = "full")]
4025 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4026 impl ToTokens for Arm {
4027 fn to_tokens(&self, tokens: &mut TokenStream) {
4028 tokens.append_all(&self.attrs);
4029 self.pat.to_tokens(tokens);
4030 if let Some((if_token, guard)) = &self.guard {
4031 if_token.to_tokens(tokens);
4032 guard.to_tokens(tokens);
4033 }
4034 self.fat_arrow_token.to_tokens(tokens);
4035 print_expr(&self.body, tokens, FixupContext::new_match_arm());
4036 self.comma.to_tokens(tokens);
4037 }
4038 }
4039
4040 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4041 impl ToTokens for FieldValue {
4042 fn to_tokens(&self, tokens: &mut TokenStream) {
4043 outer_attrs_to_tokens(&self.attrs, tokens);
4044 self.member.to_tokens(tokens);
4045 if let Some(colon_token) = &self.colon_token {
4046 colon_token.to_tokens(tokens);
4047 self.expr.to_tokens(tokens);
4048 }
4049 }
4050 }
4051
4052 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4053 impl ToTokens for Index {
4054 fn to_tokens(&self, tokens: &mut TokenStream) {
4055 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
4056 lit.set_span(self.span);
4057 tokens.append(lit);
4058 }
4059 }
4060
4061 #[cfg(feature = "full")]
4062 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4063 impl ToTokens for Label {
4064 fn to_tokens(&self, tokens: &mut TokenStream) {
4065 self.name.to_tokens(tokens);
4066 self.colon_token.to_tokens(tokens);
4067 }
4068 }
4069
4070 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4071 impl ToTokens for Member {
4072 fn to_tokens(&self, tokens: &mut TokenStream) {
4073 match self {
4074 Member::Named(ident) => ident.to_tokens(tokens),
4075 Member::Unnamed(index) => index.to_tokens(tokens),
4076 }
4077 }
4078 }
4079
4080 #[cfg(feature = "full")]
4081 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4082 impl ToTokens for RangeLimits {
4083 fn to_tokens(&self, tokens: &mut TokenStream) {
4084 match self {
4085 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
4086 RangeLimits::Closed(t) => t.to_tokens(tokens),
4087 }
4088 }
4089 }
4090
4091 #[cfg(feature = "full")]
4092 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4093 impl ToTokens for PointerMutability {
4094 fn to_tokens(&self, tokens: &mut TokenStream) {
4095 match self {
4096 PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
4097 PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
4098 }
4099 }
4100 }
4101}