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 Expr::Index(e) => print_expr_index(e, tokens, fixup),
3222 #[cfg(feature = "full")]
3223 Expr::Infer(e) => e.to_tokens(tokens),
3224 #[cfg(feature = "full")]
3225 Expr::Let(e) => print_expr_let(e, tokens, fixup),
3226 Expr::Lit(e) => e.to_tokens(tokens),
3227 #[cfg(feature = "full")]
3228 Expr::Loop(e) => e.to_tokens(tokens),
3229 Expr::Macro(e) => e.to_tokens(tokens),
3230 #[cfg(feature = "full")]
3231 Expr::Match(e) => e.to_tokens(tokens),
3232 Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup),
3233 Expr::Paren(e) => e.to_tokens(tokens),
3234 Expr::Path(e) => e.to_tokens(tokens),
3235 #[cfg(feature = "full")]
3236 Expr::Range(e) => print_expr_range(e, tokens, fixup),
3237 #[cfg(feature = "full")]
3238 Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup),
3239 Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
3240 #[cfg(feature = "full")]
3241 Expr::Repeat(e) => e.to_tokens(tokens),
3242 #[cfg(feature = "full")]
3243 Expr::Return(e) => print_expr_return(e, tokens, fixup),
3244 Expr::Struct(e) => e.to_tokens(tokens),
3245 #[cfg(feature = "full")]
3246 Expr::Try(e) => print_expr_try(e, tokens, fixup),
3247 #[cfg(feature = "full")]
3248 Expr::TryBlock(e) => e.to_tokens(tokens),
3249 Expr::Tuple(e) => e.to_tokens(tokens),
3250 Expr::Unary(e) => print_expr_unary(e, tokens, fixup),
3251 #[cfg(feature = "full")]
3252 Expr::Unsafe(e) => e.to_tokens(tokens),
3253 Expr::Verbatim(e) => e.to_tokens(tokens),
3254 #[cfg(feature = "full")]
3255 Expr::While(e) => e.to_tokens(tokens),
3256 #[cfg(feature = "full")]
3257 Expr::Yield(e) => print_expr_yield(e, tokens, fixup),
3258
3259 #[cfg(not(feature = "full"))]
3260 _ => unreachable!(),
3261 };
3262
3263 if needs_group {
3264 token::Paren::default().surround(tokens, do_print_expr);
3265 } else {
3266 do_print_expr(tokens);
3267 }
3268 }
3269
3270 #[cfg(feature = "full")]
3271 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3272 impl ToTokens for ExprArray {
3273 fn to_tokens(&self, tokens: &mut TokenStream) {
3274 outer_attrs_to_tokens(&self.attrs, tokens);
3275 self.bracket_token.surround(tokens, |tokens| {
3276 self.elems.to_tokens(tokens);
3277 });
3278 }
3279 }
3280
3281 #[cfg(feature = "full")]
3282 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3283 impl ToTokens for ExprAssign {
3284 fn to_tokens(&self, tokens: &mut TokenStream) {
3285 print_expr_assign(self, tokens, FixupContext::NONE);
3286 }
3287 }
3288
3289 #[cfg(feature = "full")]
3290 fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, fixup: FixupContext) {
3291 outer_attrs_to_tokens(&e.attrs, tokens);
3292 let (left_prec, left_fixup) =
3293 fixup.leftmost_subexpression_with_operator(&e.left, false, false, Precedence::Assign);
3294 print_subexpression(&e.left, left_prec <= Precedence::Range, tokens, left_fixup);
3295 e.eq_token.to_tokens(tokens);
3296 print_expr(
3297 &e.right,
3298 tokens,
3299 fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign),
3300 );
3301 }
3302
3303 #[cfg(feature = "full")]
3304 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3305 impl ToTokens for ExprAsync {
3306 fn to_tokens(&self, tokens: &mut TokenStream) {
3307 outer_attrs_to_tokens(&self.attrs, tokens);
3308 self.async_token.to_tokens(tokens);
3309 self.capture.to_tokens(tokens);
3310 self.block.to_tokens(tokens);
3311 }
3312 }
3313
3314 #[cfg(feature = "full")]
3315 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3316 impl ToTokens for ExprAwait {
3317 fn to_tokens(&self, tokens: &mut TokenStream) {
3318 print_expr_await(self, tokens, FixupContext::NONE);
3319 }
3320 }
3321
3322 #[cfg(feature = "full")]
3323 fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) {
3324 outer_attrs_to_tokens(&e.attrs, tokens);
3325 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3326 print_subexpression(
3327 &e.base,
3328 left_prec < Precedence::Unambiguous,
3329 tokens,
3330 left_fixup,
3331 );
3332 e.dot_token.to_tokens(tokens);
3333 e.await_token.to_tokens(tokens);
3334 }
3335
3336 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3337 impl ToTokens for ExprBinary {
3338 fn to_tokens(&self, tokens: &mut TokenStream) {
3339 print_expr_binary(self, tokens, FixupContext::NONE);
3340 }
3341 }
3342
3343 fn print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, fixup: FixupContext) {
3344 outer_attrs_to_tokens(&e.attrs, tokens);
3345
3346 let binop_prec = Precedence::of_binop(&e.op);
3347 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3348 &e.left,
3349 #[cfg(feature = "full")]
3350 match &e.op {
3351 BinOp::Sub(_)
3352 | BinOp::Mul(_)
3353 | BinOp::And(_)
3354 | BinOp::Or(_)
3355 | BinOp::BitAnd(_)
3356 | BinOp::BitOr(_)
3357 | BinOp::Shl(_)
3358 | BinOp::Lt(_) => true,
3359 _ => false,
3360 },
3361 match &e.op {
3362 BinOp::Shl(_) | BinOp::Lt(_) => true,
3363 _ => false,
3364 },
3365 #[cfg(feature = "full")]
3366 binop_prec,
3367 );
3368 let left_needs_group = match binop_prec {
3369 Precedence::Assign => left_prec <= Precedence::Range,
3370 Precedence::Compare => left_prec <= binop_prec,
3371 _ => left_prec < binop_prec,
3372 };
3373
3374 let right_fixup = fixup.rightmost_subexpression_fixup(
3375 #[cfg(feature = "full")]
3376 false,
3377 #[cfg(feature = "full")]
3378 false,
3379 #[cfg(feature = "full")]
3380 binop_prec,
3381 );
3382 let right_needs_group = binop_prec != Precedence::Assign
3383 && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec;
3384
3385 print_subexpression(&e.left, left_needs_group, tokens, left_fixup);
3386 e.op.to_tokens(tokens);
3387 print_subexpression(&e.right, right_needs_group, tokens, right_fixup);
3388 }
3389
3390 #[cfg(feature = "full")]
3391 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3392 impl ToTokens for ExprBlock {
3393 fn to_tokens(&self, tokens: &mut TokenStream) {
3394 outer_attrs_to_tokens(&self.attrs, tokens);
3395 self.label.to_tokens(tokens);
3396 self.block.brace_token.surround(tokens, |tokens| {
3397 inner_attrs_to_tokens(&self.attrs, tokens);
3398 tokens.append_all(&self.block.stmts);
3399 });
3400 }
3401 }
3402
3403 #[cfg(feature = "full")]
3404 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3405 impl ToTokens for ExprBreak {
3406 fn to_tokens(&self, tokens: &mut TokenStream) {
3407 print_expr_break(self, tokens, FixupContext::NONE);
3408 }
3409 }
3410
3411 #[cfg(feature = "full")]
3412 fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) {
3413 outer_attrs_to_tokens(&e.attrs, tokens);
3414 e.break_token.to_tokens(tokens);
3415 e.label.to_tokens(tokens);
3416 if let Some(value) = &e.expr {
3417 print_subexpression(
3418 value,
3419 e.label.is_none() && classify::expr_leading_label(value),
3422 tokens,
3423 fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump),
3424 );
3425 }
3426 }
3427
3428 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3429 impl ToTokens for ExprCall {
3430 fn to_tokens(&self, tokens: &mut TokenStream) {
3431 print_expr_call(self, tokens, FixupContext::NONE);
3432 }
3433 }
3434
3435 fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) {
3436 outer_attrs_to_tokens(&e.attrs, tokens);
3437
3438 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3439 &e.func,
3440 #[cfg(feature = "full")]
3441 true,
3442 false,
3443 #[cfg(feature = "full")]
3444 Precedence::Unambiguous,
3445 );
3446 let needs_group = if let Expr::Field(func) = &*e.func {
3447 func.member.is_named()
3448 } else {
3449 left_prec < Precedence::Unambiguous
3450 };
3451 print_subexpression(&e.func, needs_group, tokens, left_fixup);
3452
3453 e.paren_token.surround(tokens, |tokens| {
3454 e.args.to_tokens(tokens);
3455 });
3456 }
3457
3458 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3459 impl ToTokens for ExprCast {
3460 fn to_tokens(&self, tokens: &mut TokenStream) {
3461 print_expr_cast(self, tokens, FixupContext::NONE);
3462 }
3463 }
3464
3465 fn print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, fixup: FixupContext) {
3466 outer_attrs_to_tokens(&e.attrs, tokens);
3467 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3468 &e.expr,
3469 #[cfg(feature = "full")]
3470 false,
3471 false,
3472 #[cfg(feature = "full")]
3473 Precedence::Cast,
3474 );
3475 print_subexpression(&e.expr, left_prec < Precedence::Cast, tokens, left_fixup);
3476 e.as_token.to_tokens(tokens);
3477 e.ty.to_tokens(tokens);
3478 }
3479
3480 #[cfg(feature = "full")]
3481 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3482 impl ToTokens for ExprClosure {
3483 fn to_tokens(&self, tokens: &mut TokenStream) {
3484 print_expr_closure(self, tokens, FixupContext::NONE);
3485 }
3486 }
3487
3488 #[cfg(feature = "full")]
3489 fn print_expr_closure(e: &ExprClosure, tokens: &mut TokenStream, fixup: FixupContext) {
3490 outer_attrs_to_tokens(&e.attrs, tokens);
3491 e.lifetimes.to_tokens(tokens);
3492 e.constness.to_tokens(tokens);
3493 e.movability.to_tokens(tokens);
3494 e.asyncness.to_tokens(tokens);
3495 e.capture.to_tokens(tokens);
3496 e.or1_token.to_tokens(tokens);
3497 e.inputs.to_tokens(tokens);
3498 e.or2_token.to_tokens(tokens);
3499 e.output.to_tokens(tokens);
3500 if matches!(e.output, ReturnType::Default)
3501 || matches!(&*e.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none())
3502 {
3503 print_expr(
3504 &e.body,
3505 tokens,
3506 fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
3507 );
3508 } else {
3509 token::Brace::default().surround(tokens, |tokens| {
3510 print_expr(&e.body, tokens, FixupContext::new_stmt());
3511 });
3512 }
3513 }
3514
3515 #[cfg(feature = "full")]
3516 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3517 impl ToTokens for ExprConst {
3518 fn to_tokens(&self, tokens: &mut TokenStream) {
3519 outer_attrs_to_tokens(&self.attrs, tokens);
3520 self.const_token.to_tokens(tokens);
3521 self.block.brace_token.surround(tokens, |tokens| {
3522 inner_attrs_to_tokens(&self.attrs, tokens);
3523 tokens.append_all(&self.block.stmts);
3524 });
3525 }
3526 }
3527
3528 #[cfg(feature = "full")]
3529 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3530 impl ToTokens for ExprContinue {
3531 fn to_tokens(&self, tokens: &mut TokenStream) {
3532 outer_attrs_to_tokens(&self.attrs, tokens);
3533 self.continue_token.to_tokens(tokens);
3534 self.label.to_tokens(tokens);
3535 }
3536 }
3537
3538 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3539 impl ToTokens for ExprField {
3540 fn to_tokens(&self, tokens: &mut TokenStream) {
3541 print_expr_field(self, tokens, FixupContext::NONE);
3542 }
3543 }
3544
3545 fn print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext) {
3546 outer_attrs_to_tokens(&e.attrs, tokens);
3547 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3548 print_subexpression(
3549 &e.base,
3550 left_prec < Precedence::Unambiguous,
3551 tokens,
3552 left_fixup,
3553 );
3554 e.dot_token.to_tokens(tokens);
3555 e.member.to_tokens(tokens);
3556 }
3557
3558 #[cfg(feature = "full")]
3559 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3560 impl ToTokens for ExprForLoop {
3561 fn to_tokens(&self, tokens: &mut TokenStream) {
3562 outer_attrs_to_tokens(&self.attrs, tokens);
3563 self.label.to_tokens(tokens);
3564 self.for_token.to_tokens(tokens);
3565 self.pat.to_tokens(tokens);
3566 self.in_token.to_tokens(tokens);
3567 print_expr(&self.expr, tokens, FixupContext::new_condition());
3568 self.body.brace_token.surround(tokens, |tokens| {
3569 inner_attrs_to_tokens(&self.attrs, tokens);
3570 tokens.append_all(&self.body.stmts);
3571 });
3572 }
3573 }
3574
3575 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3576 impl ToTokens for ExprGroup {
3577 fn to_tokens(&self, tokens: &mut TokenStream) {
3578 outer_attrs_to_tokens(&self.attrs, tokens);
3579 self.group_token.surround(tokens, |tokens| {
3580 self.expr.to_tokens(tokens);
3581 });
3582 }
3583 }
3584
3585 #[cfg(feature = "full")]
3586 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3587 impl ToTokens for ExprIf {
3588 fn to_tokens(&self, tokens: &mut TokenStream) {
3589 outer_attrs_to_tokens(&self.attrs, tokens);
3590
3591 let mut expr = self;
3592 loop {
3593 expr.if_token.to_tokens(tokens);
3594 print_expr(&expr.cond, tokens, FixupContext::new_condition());
3595 expr.then_branch.to_tokens(tokens);
3596
3597 let (else_token, else_) = match &expr.else_branch {
3598 Some(else_branch) => else_branch,
3599 None => break,
3600 };
3601
3602 else_token.to_tokens(tokens);
3603 match &**else_ {
3604 Expr::If(next) => {
3605 expr = next;
3606 }
3607 Expr::Block(last) => {
3608 last.to_tokens(tokens);
3609 break;
3610 }
3611 other => {
3614 token::Brace::default().surround(tokens, |tokens| {
3615 print_expr(other, tokens, FixupContext::new_stmt());
3616 });
3617 break;
3618 }
3619 }
3620 }
3621 }
3622 }
3623
3624 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3625 impl ToTokens for ExprIndex {
3626 fn to_tokens(&self, tokens: &mut TokenStream) {
3627 print_expr_index(self, tokens, FixupContext::NONE);
3628 }
3629 }
3630
3631 fn print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext) {
3632 outer_attrs_to_tokens(&e.attrs, tokens);
3633 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3634 &e.expr,
3635 #[cfg(feature = "full")]
3636 true,
3637 false,
3638 #[cfg(feature = "full")]
3639 Precedence::Unambiguous,
3640 );
3641 print_subexpression(
3642 &e.expr,
3643 left_prec < Precedence::Unambiguous,
3644 tokens,
3645 left_fixup,
3646 );
3647 e.bracket_token.surround(tokens, |tokens| {
3648 e.index.to_tokens(tokens);
3649 });
3650 }
3651
3652 #[cfg(feature = "full")]
3653 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3654 impl ToTokens for ExprInfer {
3655 fn to_tokens(&self, tokens: &mut TokenStream) {
3656 outer_attrs_to_tokens(&self.attrs, tokens);
3657 self.underscore_token.to_tokens(tokens);
3658 }
3659 }
3660
3661 #[cfg(feature = "full")]
3662 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3663 impl ToTokens for ExprLet {
3664 fn to_tokens(&self, tokens: &mut TokenStream) {
3665 print_expr_let(self, tokens, FixupContext::NONE);
3666 }
3667 }
3668
3669 #[cfg(feature = "full")]
3670 fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) {
3671 outer_attrs_to_tokens(&e.attrs, tokens);
3672 e.let_token.to_tokens(tokens);
3673 e.pat.to_tokens(tokens);
3674 e.eq_token.to_tokens(tokens);
3675 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Let);
3676 print_subexpression(&e.expr, right_prec < Precedence::Let, tokens, right_fixup);
3677 }
3678
3679 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3680 impl ToTokens for ExprLit {
3681 fn to_tokens(&self, tokens: &mut TokenStream) {
3682 outer_attrs_to_tokens(&self.attrs, tokens);
3683 self.lit.to_tokens(tokens);
3684 }
3685 }
3686
3687 #[cfg(feature = "full")]
3688 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3689 impl ToTokens for ExprLoop {
3690 fn to_tokens(&self, tokens: &mut TokenStream) {
3691 outer_attrs_to_tokens(&self.attrs, tokens);
3692 self.label.to_tokens(tokens);
3693 self.loop_token.to_tokens(tokens);
3694 self.body.brace_token.surround(tokens, |tokens| {
3695 inner_attrs_to_tokens(&self.attrs, tokens);
3696 tokens.append_all(&self.body.stmts);
3697 });
3698 }
3699 }
3700
3701 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3702 impl ToTokens for ExprMacro {
3703 fn to_tokens(&self, tokens: &mut TokenStream) {
3704 outer_attrs_to_tokens(&self.attrs, tokens);
3705 self.mac.to_tokens(tokens);
3706 }
3707 }
3708
3709 #[cfg(feature = "full")]
3710 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3711 impl ToTokens for ExprMatch {
3712 fn to_tokens(&self, tokens: &mut TokenStream) {
3713 outer_attrs_to_tokens(&self.attrs, tokens);
3714 self.match_token.to_tokens(tokens);
3715 print_expr(&self.expr, tokens, FixupContext::new_condition());
3716 self.brace_token.surround(tokens, |tokens| {
3717 inner_attrs_to_tokens(&self.attrs, tokens);
3718 for (i, arm) in self.arms.iter().enumerate() {
3719 arm.to_tokens(tokens);
3720 let is_last = i == self.arms.len() - 1;
3723 if !is_last
3724 && classify::requires_comma_to_be_match_arm(&arm.body)
3725 && arm.comma.is_none()
3726 {
3727 <Token![,]>::default().to_tokens(tokens);
3728 }
3729 }
3730 });
3731 }
3732 }
3733
3734 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3735 impl ToTokens for ExprMethodCall {
3736 fn to_tokens(&self, tokens: &mut TokenStream) {
3737 print_expr_method_call(self, tokens, FixupContext::NONE);
3738 }
3739 }
3740
3741 fn print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext) {
3742 outer_attrs_to_tokens(&e.attrs, tokens);
3743 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.receiver);
3744 print_subexpression(
3745 &e.receiver,
3746 left_prec < Precedence::Unambiguous,
3747 tokens,
3748 left_fixup,
3749 );
3750 e.dot_token.to_tokens(tokens);
3751 e.method.to_tokens(tokens);
3752 if let Some(turbofish) = &e.turbofish {
3753 path::printing::print_angle_bracketed_generic_arguments(
3754 tokens,
3755 turbofish,
3756 PathStyle::Expr,
3757 );
3758 }
3759 e.paren_token.surround(tokens, |tokens| {
3760 e.args.to_tokens(tokens);
3761 });
3762 }
3763
3764 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3765 impl ToTokens for ExprParen {
3766 fn to_tokens(&self, tokens: &mut TokenStream) {
3767 outer_attrs_to_tokens(&self.attrs, tokens);
3768 self.paren_token.surround(tokens, |tokens| {
3769 self.expr.to_tokens(tokens);
3770 });
3771 }
3772 }
3773
3774 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3775 impl ToTokens for ExprPath {
3776 fn to_tokens(&self, tokens: &mut TokenStream) {
3777 outer_attrs_to_tokens(&self.attrs, tokens);
3778 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3779 }
3780 }
3781
3782 #[cfg(feature = "full")]
3783 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3784 impl ToTokens for ExprRange {
3785 fn to_tokens(&self, tokens: &mut TokenStream) {
3786 print_expr_range(self, tokens, FixupContext::NONE);
3787 }
3788 }
3789
3790 #[cfg(feature = "full")]
3791 fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, fixup: FixupContext) {
3792 outer_attrs_to_tokens(&e.attrs, tokens);
3793 if let Some(start) = &e.start {
3794 let (left_prec, left_fixup) =
3795 fixup.leftmost_subexpression_with_operator(start, true, false, Precedence::Range);
3796 print_subexpression(start, left_prec <= Precedence::Range, tokens, left_fixup);
3797 }
3798 e.limits.to_tokens(tokens);
3799 if let Some(end) = &e.end {
3800 let right_fixup = fixup.rightmost_subexpression_fixup(false, true, Precedence::Range);
3801 let right_prec = right_fixup.rightmost_subexpression_precedence(end);
3802 print_subexpression(end, right_prec <= Precedence::Range, tokens, right_fixup);
3803 }
3804 }
3805
3806 #[cfg(feature = "full")]
3807 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3808 impl ToTokens for ExprRawAddr {
3809 fn to_tokens(&self, tokens: &mut TokenStream) {
3810 print_expr_raw_addr(self, tokens, FixupContext::NONE);
3811 }
3812 }
3813
3814 #[cfg(feature = "full")]
3815 fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) {
3816 outer_attrs_to_tokens(&e.attrs, tokens);
3817 e.and_token.to_tokens(tokens);
3818 e.raw.to_tokens(tokens);
3819 e.mutability.to_tokens(tokens);
3820 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Prefix);
3821 print_subexpression(
3822 &e.expr,
3823 right_prec < Precedence::Prefix,
3824 tokens,
3825 right_fixup,
3826 );
3827 }
3828
3829 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3830 impl ToTokens for ExprReference {
3831 fn to_tokens(&self, tokens: &mut TokenStream) {
3832 print_expr_reference(self, tokens, FixupContext::NONE);
3833 }
3834 }
3835
3836 fn print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext) {
3837 outer_attrs_to_tokens(&e.attrs, tokens);
3838 e.and_token.to_tokens(tokens);
3839 e.mutability.to_tokens(tokens);
3840 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3841 &e.expr,
3842 #[cfg(feature = "full")]
3843 Precedence::Prefix,
3844 );
3845 print_subexpression(
3846 &e.expr,
3847 right_prec < Precedence::Prefix,
3848 tokens,
3849 right_fixup,
3850 );
3851 }
3852
3853 #[cfg(feature = "full")]
3854 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3855 impl ToTokens for ExprRepeat {
3856 fn to_tokens(&self, tokens: &mut TokenStream) {
3857 outer_attrs_to_tokens(&self.attrs, tokens);
3858 self.bracket_token.surround(tokens, |tokens| {
3859 self.expr.to_tokens(tokens);
3860 self.semi_token.to_tokens(tokens);
3861 self.len.to_tokens(tokens);
3862 });
3863 }
3864 }
3865
3866 #[cfg(feature = "full")]
3867 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3868 impl ToTokens for ExprReturn {
3869 fn to_tokens(&self, tokens: &mut TokenStream) {
3870 print_expr_return(self, tokens, FixupContext::NONE);
3871 }
3872 }
3873
3874 #[cfg(feature = "full")]
3875 fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) {
3876 outer_attrs_to_tokens(&e.attrs, tokens);
3877 e.return_token.to_tokens(tokens);
3878 if let Some(expr) = &e.expr {
3879 print_expr(
3880 expr,
3881 tokens,
3882 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
3883 );
3884 }
3885 }
3886
3887 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3888 impl ToTokens for ExprStruct {
3889 fn to_tokens(&self, tokens: &mut TokenStream) {
3890 outer_attrs_to_tokens(&self.attrs, tokens);
3891 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3892 self.brace_token.surround(tokens, |tokens| {
3893 self.fields.to_tokens(tokens);
3894 if let Some(dot2_token) = &self.dot2_token {
3895 dot2_token.to_tokens(tokens);
3896 } else if self.rest.is_some() {
3897 Token).to_tokens(tokens);
3898 }
3899 self.rest.to_tokens(tokens);
3900 });
3901 }
3902 }
3903
3904 #[cfg(feature = "full")]
3905 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3906 impl ToTokens for ExprTry {
3907 fn to_tokens(&self, tokens: &mut TokenStream) {
3908 print_expr_try(self, tokens, FixupContext::NONE);
3909 }
3910 }
3911
3912 #[cfg(feature = "full")]
3913 fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) {
3914 outer_attrs_to_tokens(&e.attrs, tokens);
3915 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.expr);
3916 print_subexpression(
3917 &e.expr,
3918 left_prec < Precedence::Unambiguous,
3919 tokens,
3920 left_fixup,
3921 );
3922 e.question_token.to_tokens(tokens);
3923 }
3924
3925 #[cfg(feature = "full")]
3926 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3927 impl ToTokens for ExprTryBlock {
3928 fn to_tokens(&self, tokens: &mut TokenStream) {
3929 outer_attrs_to_tokens(&self.attrs, tokens);
3930 self.try_token.to_tokens(tokens);
3931 self.block.to_tokens(tokens);
3932 }
3933 }
3934
3935 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3936 impl ToTokens for ExprTuple {
3937 fn to_tokens(&self, tokens: &mut TokenStream) {
3938 outer_attrs_to_tokens(&self.attrs, tokens);
3939 self.paren_token.surround(tokens, |tokens| {
3940 self.elems.to_tokens(tokens);
3941 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3944 <Token![,]>::default().to_tokens(tokens);
3945 }
3946 });
3947 }
3948 }
3949
3950 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3951 impl ToTokens for ExprUnary {
3952 fn to_tokens(&self, tokens: &mut TokenStream) {
3953 print_expr_unary(self, tokens, FixupContext::NONE);
3954 }
3955 }
3956
3957 fn print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext) {
3958 outer_attrs_to_tokens(&e.attrs, tokens);
3959 e.op.to_tokens(tokens);
3960 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3961 &e.expr,
3962 #[cfg(feature = "full")]
3963 Precedence::Prefix,
3964 );
3965 print_subexpression(
3966 &e.expr,
3967 right_prec < Precedence::Prefix,
3968 tokens,
3969 right_fixup,
3970 );
3971 }
3972
3973 #[cfg(feature = "full")]
3974 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3975 impl ToTokens for ExprUnsafe {
3976 fn to_tokens(&self, tokens: &mut TokenStream) {
3977 outer_attrs_to_tokens(&self.attrs, tokens);
3978 self.unsafe_token.to_tokens(tokens);
3979 self.block.brace_token.surround(tokens, |tokens| {
3980 inner_attrs_to_tokens(&self.attrs, tokens);
3981 tokens.append_all(&self.block.stmts);
3982 });
3983 }
3984 }
3985
3986 #[cfg(feature = "full")]
3987 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3988 impl ToTokens for ExprWhile {
3989 fn to_tokens(&self, tokens: &mut TokenStream) {
3990 outer_attrs_to_tokens(&self.attrs, tokens);
3991 self.label.to_tokens(tokens);
3992 self.while_token.to_tokens(tokens);
3993 print_expr(&self.cond, tokens, FixupContext::new_condition());
3994 self.body.brace_token.surround(tokens, |tokens| {
3995 inner_attrs_to_tokens(&self.attrs, tokens);
3996 tokens.append_all(&self.body.stmts);
3997 });
3998 }
3999 }
4000
4001 #[cfg(feature = "full")]
4002 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4003 impl ToTokens for ExprYield {
4004 fn to_tokens(&self, tokens: &mut TokenStream) {
4005 print_expr_yield(self, tokens, FixupContext::NONE);
4006 }
4007 }
4008
4009 #[cfg(feature = "full")]
4010 fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) {
4011 outer_attrs_to_tokens(&e.attrs, tokens);
4012 e.yield_token.to_tokens(tokens);
4013 if let Some(expr) = &e.expr {
4014 print_expr(
4015 expr,
4016 tokens,
4017 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
4018 );
4019 }
4020 }
4021
4022 #[cfg(feature = "full")]
4023 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4024 impl ToTokens for Arm {
4025 fn to_tokens(&self, tokens: &mut TokenStream) {
4026 tokens.append_all(&self.attrs);
4027 self.pat.to_tokens(tokens);
4028 if let Some((if_token, guard)) = &self.guard {
4029 if_token.to_tokens(tokens);
4030 guard.to_tokens(tokens);
4031 }
4032 self.fat_arrow_token.to_tokens(tokens);
4033 print_expr(&self.body, tokens, FixupContext::new_match_arm());
4034 self.comma.to_tokens(tokens);
4035 }
4036 }
4037
4038 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4039 impl ToTokens for FieldValue {
4040 fn to_tokens(&self, tokens: &mut TokenStream) {
4041 outer_attrs_to_tokens(&self.attrs, tokens);
4042 self.member.to_tokens(tokens);
4043 if let Some(colon_token) = &self.colon_token {
4044 colon_token.to_tokens(tokens);
4045 self.expr.to_tokens(tokens);
4046 }
4047 }
4048 }
4049
4050 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4051 impl ToTokens for Index {
4052 fn to_tokens(&self, tokens: &mut TokenStream) {
4053 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
4054 lit.set_span(self.span);
4055 tokens.append(lit);
4056 }
4057 }
4058
4059 #[cfg(feature = "full")]
4060 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4061 impl ToTokens for Label {
4062 fn to_tokens(&self, tokens: &mut TokenStream) {
4063 self.name.to_tokens(tokens);
4064 self.colon_token.to_tokens(tokens);
4065 }
4066 }
4067
4068 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4069 impl ToTokens for Member {
4070 fn to_tokens(&self, tokens: &mut TokenStream) {
4071 match self {
4072 Member::Named(ident) => ident.to_tokens(tokens),
4073 Member::Unnamed(index) => index.to_tokens(tokens),
4074 }
4075 }
4076 }
4077
4078 #[cfg(feature = "full")]
4079 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4080 impl ToTokens for RangeLimits {
4081 fn to_tokens(&self, tokens: &mut TokenStream) {
4082 match self {
4083 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
4084 RangeLimits::Closed(t) => t.to_tokens(tokens),
4085 }
4086 }
4087 }
4088
4089 #[cfg(feature = "full")]
4090 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4091 impl ToTokens for PointerMutability {
4092 fn to_tokens(&self, tokens: &mut TokenStream) {
4093 match self {
4094 PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
4095 PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
4096 }
4097 }
4098 }
4099}