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 continue;
2247 } else if lookahead.peek(token::Brace) {
2248 expr.else_branch = Some((
2249 else_token,
2250 Box::new(Expr::Block(ExprBlock {
2251 attrs: Vec::new(),
2252 label: None,
2253 block: input.parse()?,
2254 })),
2255 ));
2256 break;
2257 } else {
2258 return Err(lookahead.error());
2259 }
2260 }
2261
2262 while let Some(mut prev) = clauses.pop() {
2263 *prev.else_branch.as_mut().unwrap().1 = Expr::If(expr);
2264 expr = prev;
2265 }
2266 expr.attrs = attrs;
2267 Ok(expr)
2268 }
2269 }
2270
2271 #[cfg(feature = "full")]
2272 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2273 impl Parse for ExprInfer {
2274 fn parse(input: ParseStream) -> Result<Self> {
2275 Ok(ExprInfer {
2276 attrs: input.call(Attribute::parse_outer)?,
2277 underscore_token: input.parse()?,
2278 })
2279 }
2280 }
2281
2282 #[cfg(feature = "full")]
2283 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2284 impl Parse for ExprForLoop {
2285 fn parse(input: ParseStream) -> Result<Self> {
2286 let mut attrs = input.call(Attribute::parse_outer)?;
2287 let label: Option<Label> = input.parse()?;
2288 let for_token: Token![for] = input.parse()?;
2289
2290 let pat = Pat::parse_multi_with_leading_vert(input)?;
2291
2292 let in_token: Token![in] = input.parse()?;
2293 let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2294
2295 let content;
2296 let brace_token = braced!(content in input);
2297 attr::parsing::parse_inner(&content, &mut attrs)?;
2298 let stmts = content.call(Block::parse_within)?;
2299
2300 Ok(ExprForLoop {
2301 attrs,
2302 label,
2303 for_token,
2304 pat: Box::new(pat),
2305 in_token,
2306 expr: Box::new(expr),
2307 body: Block { brace_token, stmts },
2308 })
2309 }
2310 }
2311
2312 #[cfg(feature = "full")]
2313 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2314 impl Parse for ExprLoop {
2315 fn parse(input: ParseStream) -> Result<Self> {
2316 let mut attrs = input.call(Attribute::parse_outer)?;
2317 let label: Option<Label> = input.parse()?;
2318 let loop_token: Token![loop] = input.parse()?;
2319
2320 let content;
2321 let brace_token = braced!(content in input);
2322 attr::parsing::parse_inner(&content, &mut attrs)?;
2323 let stmts = content.call(Block::parse_within)?;
2324
2325 Ok(ExprLoop {
2326 attrs,
2327 label,
2328 loop_token,
2329 body: Block { brace_token, stmts },
2330 })
2331 }
2332 }
2333
2334 #[cfg(feature = "full")]
2335 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2336 impl Parse for ExprMatch {
2337 fn parse(input: ParseStream) -> Result<Self> {
2338 let mut attrs = input.call(Attribute::parse_outer)?;
2339 let match_token: Token![match] = input.parse()?;
2340 let expr = Expr::parse_without_eager_brace(input)?;
2341
2342 let content;
2343 let brace_token = braced!(content in input);
2344 attr::parsing::parse_inner(&content, &mut attrs)?;
2345
2346 let arms = Arm::parse_multiple(&content)?;
2347
2348 Ok(ExprMatch {
2349 attrs,
2350 match_token,
2351 expr: Box::new(expr),
2352 brace_token,
2353 arms,
2354 })
2355 }
2356 }
2357
2358 macro_rules! impl_by_parsing_expr {
2359 (
2360 $(
2361 $expr_type:ty, $variant:ident, $msg:expr,
2362 )*
2363 ) => {
2364 $(
2365 #[cfg(all(feature = "full", feature = "printing"))]
2366 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2367 impl Parse for $expr_type {
2368 fn parse(input: ParseStream) -> Result<Self> {
2369 let mut expr: Expr = input.parse()?;
2370 loop {
2371 match expr {
2372 Expr::$variant(inner) => return Ok(inner),
2373 Expr::Group(next) => expr = *next.expr,
2374 _ => return Err(Error::new_spanned(expr, $msg)),
2375 }
2376 }
2377 }
2378 }
2379 )*
2380 };
2381 }
2382
2383 impl_by_parsing_expr! {
2384 ExprAssign, Assign, "expected assignment expression",
2385 ExprAwait, Await, "expected await expression",
2386 ExprBinary, Binary, "expected binary operation",
2387 ExprCall, Call, "expected function call expression",
2388 ExprCast, Cast, "expected cast expression",
2389 ExprField, Field, "expected struct field access",
2390 ExprIndex, Index, "expected indexing expression",
2391 ExprMethodCall, MethodCall, "expected method call expression",
2392 ExprRange, Range, "expected range expression",
2393 ExprTry, Try, "expected try expression",
2394 ExprTuple, Tuple, "expected tuple expression",
2395 }
2396
2397 #[cfg(feature = "full")]
2398 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2399 impl Parse for ExprUnary {
2400 fn parse(input: ParseStream) -> Result<Self> {
2401 let attrs = Vec::new();
2402 let allow_struct = AllowStruct(true);
2403 expr_unary(input, attrs, allow_struct)
2404 }
2405 }
2406
2407 #[cfg(feature = "full")]
2408 fn expr_unary(
2409 input: ParseStream,
2410 attrs: Vec<Attribute>,
2411 allow_struct: AllowStruct,
2412 ) -> Result<ExprUnary> {
2413 Ok(ExprUnary {
2414 attrs,
2415 op: input.parse()?,
2416 expr: Box::new(unary_expr(input, allow_struct)?),
2417 })
2418 }
2419
2420 #[cfg(feature = "full")]
2421 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2422 impl Parse for ExprClosure {
2423 fn parse(input: ParseStream) -> Result<Self> {
2424 let allow_struct = AllowStruct(true);
2425 expr_closure(input, allow_struct)
2426 }
2427 }
2428
2429 #[cfg(feature = "full")]
2430 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2431 impl Parse for ExprRawAddr {
2432 fn parse(input: ParseStream) -> Result<Self> {
2433 let allow_struct = AllowStruct(true);
2434 Ok(ExprRawAddr {
2435 attrs: Vec::new(),
2436 and_token: input.parse()?,
2437 raw: input.parse()?,
2438 mutability: input.parse()?,
2439 expr: Box::new(unary_expr(input, allow_struct)?),
2440 })
2441 }
2442 }
2443
2444 #[cfg(feature = "full")]
2445 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2446 impl Parse for ExprReference {
2447 fn parse(input: ParseStream) -> Result<Self> {
2448 let allow_struct = AllowStruct(true);
2449 Ok(ExprReference {
2450 attrs: Vec::new(),
2451 and_token: input.parse()?,
2452 mutability: input.parse()?,
2453 expr: Box::new(unary_expr(input, allow_struct)?),
2454 })
2455 }
2456 }
2457
2458 #[cfg(feature = "full")]
2459 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2460 impl Parse for ExprBreak {
2461 fn parse(input: ParseStream) -> Result<Self> {
2462 let allow_struct = AllowStruct(true);
2463 expr_break(input, allow_struct)
2464 }
2465 }
2466
2467 #[cfg(feature = "full")]
2468 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2469 impl Parse for ExprReturn {
2470 fn parse(input: ParseStream) -> Result<Self> {
2471 Ok(ExprReturn {
2472 attrs: Vec::new(),
2473 return_token: input.parse()?,
2474 expr: {
2475 if Expr::peek(input) {
2476 Some(input.parse()?)
2477 } else {
2478 None
2479 }
2480 },
2481 })
2482 }
2483 }
2484
2485 #[cfg(feature = "full")]
2486 fn expr_become(input: ParseStream) -> Result<Expr> {
2487 let begin = input.fork();
2488 input.parse::<Token![become]>()?;
2489 input.parse::<Expr>()?;
2490 Ok(Expr::Verbatim(verbatim::between(&begin, input)))
2491 }
2492
2493 #[cfg(feature = "full")]
2494 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2495 impl Parse for ExprTryBlock {
2496 fn parse(input: ParseStream) -> Result<Self> {
2497 Ok(ExprTryBlock {
2498 attrs: Vec::new(),
2499 try_token: input.parse()?,
2500 block: input.parse()?,
2501 })
2502 }
2503 }
2504
2505 #[cfg(feature = "full")]
2506 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2507 impl Parse for ExprYield {
2508 fn parse(input: ParseStream) -> Result<Self> {
2509 Ok(ExprYield {
2510 attrs: Vec::new(),
2511 yield_token: input.parse()?,
2512 expr: {
2513 if Expr::peek(input) {
2514 Some(input.parse()?)
2515 } else {
2516 None
2517 }
2518 },
2519 })
2520 }
2521 }
2522
2523 #[cfg(feature = "full")]
2524 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2525 let lifetimes: Option<BoundLifetimes> = input.parse()?;
2526 let constness: Option<Token![const]> = input.parse()?;
2527 let movability: Option<Token![static]> = input.parse()?;
2528 let asyncness: Option<Token![async]> = input.parse()?;
2529 let capture: Option<Token![move]> = input.parse()?;
2530 let or1_token: Token![|] = input.parse()?;
2531
2532 let mut inputs = Punctuated::new();
2533 loop {
2534 if input.peek(Token![|]) {
2535 break;
2536 }
2537 let value = closure_arg(input)?;
2538 inputs.push_value(value);
2539 if input.peek(Token![|]) {
2540 break;
2541 }
2542 let punct: Token![,] = input.parse()?;
2543 inputs.push_punct(punct);
2544 }
2545
2546 let or2_token: Token![|] = input.parse()?;
2547
2548 let (output, body) = if input.peek(Token![->]) {
2549 let arrow_token: Token![->] = input.parse()?;
2550 let ty: Type = input.parse()?;
2551 let body: Block = input.parse()?;
2552 let output = ReturnType::Type(arrow_token, Box::new(ty));
2553 let block = Expr::Block(ExprBlock {
2554 attrs: Vec::new(),
2555 label: None,
2556 block: body,
2557 });
2558 (output, block)
2559 } else {
2560 let body = ambiguous_expr(input, allow_struct)?;
2561 (ReturnType::Default, body)
2562 };
2563
2564 Ok(ExprClosure {
2565 attrs: Vec::new(),
2566 lifetimes,
2567 constness,
2568 movability,
2569 asyncness,
2570 capture,
2571 or1_token,
2572 inputs,
2573 or2_token,
2574 output,
2575 body: Box::new(body),
2576 })
2577 }
2578
2579 #[cfg(feature = "full")]
2580 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2581 impl Parse for ExprAsync {
2582 fn parse(input: ParseStream) -> Result<Self> {
2583 Ok(ExprAsync {
2584 attrs: Vec::new(),
2585 async_token: input.parse()?,
2586 capture: input.parse()?,
2587 block: input.parse()?,
2588 })
2589 }
2590 }
2591
2592 #[cfg(feature = "full")]
2593 fn closure_arg(input: ParseStream) -> Result<Pat> {
2594 let attrs = input.call(Attribute::parse_outer)?;
2595 let mut pat = Pat::parse_single(input)?;
2596
2597 if input.peek(Token![:]) {
2598 Ok(Pat::Type(PatType {
2599 attrs,
2600 pat: Box::new(pat),
2601 colon_token: input.parse()?,
2602 ty: input.parse()?,
2603 }))
2604 } else {
2605 match &mut pat {
2606 Pat::Const(pat) => pat.attrs = attrs,
2607 Pat::Ident(pat) => pat.attrs = attrs,
2608 Pat::Lit(pat) => pat.attrs = attrs,
2609 Pat::Macro(pat) => pat.attrs = attrs,
2610 Pat::Or(pat) => pat.attrs = attrs,
2611 Pat::Paren(pat) => pat.attrs = attrs,
2612 Pat::Path(pat) => pat.attrs = attrs,
2613 Pat::Range(pat) => pat.attrs = attrs,
2614 Pat::Reference(pat) => pat.attrs = attrs,
2615 Pat::Rest(pat) => pat.attrs = attrs,
2616 Pat::Slice(pat) => pat.attrs = attrs,
2617 Pat::Struct(pat) => pat.attrs = attrs,
2618 Pat::Tuple(pat) => pat.attrs = attrs,
2619 Pat::TupleStruct(pat) => pat.attrs = attrs,
2620 Pat::Type(_) => unreachable!(),
2621 Pat::Verbatim(_) => {}
2622 Pat::Wild(pat) => pat.attrs = attrs,
2623 }
2624 Ok(pat)
2625 }
2626 }
2627
2628 #[cfg(feature = "full")]
2629 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2630 impl Parse for ExprWhile {
2631 fn parse(input: ParseStream) -> Result<Self> {
2632 let mut attrs = input.call(Attribute::parse_outer)?;
2633 let label: Option<Label> = input.parse()?;
2634 let while_token: Token![while] = input.parse()?;
2635 let cond = Expr::parse_without_eager_brace(input)?;
2636
2637 let content;
2638 let brace_token = braced!(content in input);
2639 attr::parsing::parse_inner(&content, &mut attrs)?;
2640 let stmts = content.call(Block::parse_within)?;
2641
2642 Ok(ExprWhile {
2643 attrs,
2644 label,
2645 while_token,
2646 cond: Box::new(cond),
2647 body: Block { brace_token, stmts },
2648 })
2649 }
2650 }
2651
2652 #[cfg(feature = "full")]
2653 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2654 impl Parse for ExprConst {
2655 fn parse(input: ParseStream) -> Result<Self> {
2656 let const_token: Token![const] = input.parse()?;
2657
2658 let content;
2659 let brace_token = braced!(content in input);
2660 let inner_attrs = content.call(Attribute::parse_inner)?;
2661 let stmts = content.call(Block::parse_within)?;
2662
2663 Ok(ExprConst {
2664 attrs: inner_attrs,
2665 const_token,
2666 block: Block { brace_token, stmts },
2667 })
2668 }
2669 }
2670
2671 #[cfg(feature = "full")]
2672 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2673 impl Parse for Label {
2674 fn parse(input: ParseStream) -> Result<Self> {
2675 Ok(Label {
2676 name: input.parse()?,
2677 colon_token: input.parse()?,
2678 })
2679 }
2680 }
2681
2682 #[cfg(feature = "full")]
2683 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2684 impl Parse for Option<Label> {
2685 fn parse(input: ParseStream) -> Result<Self> {
2686 if input.peek(Lifetime) {
2687 input.parse().map(Some)
2688 } else {
2689 Ok(None)
2690 }
2691 }
2692 }
2693
2694 #[cfg(feature = "full")]
2695 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2696 impl Parse for ExprContinue {
2697 fn parse(input: ParseStream) -> Result<Self> {
2698 Ok(ExprContinue {
2699 attrs: Vec::new(),
2700 continue_token: input.parse()?,
2701 label: input.parse()?,
2702 })
2703 }
2704 }
2705
2706 #[cfg(feature = "full")]
2707 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2708 let break_token: Token![break] = input.parse()?;
2709
2710 let ahead = input.fork();
2711 let label: Option<Lifetime> = ahead.parse()?;
2712 if label.is_some() && ahead.peek(Token![:]) {
2713 let _: Expr = input.parse()?;
2716 let start_span = label.unwrap().apostrophe;
2717 let end_span = input.cursor().prev_span();
2718 return Err(crate::error::new2(
2719 start_span,
2720 end_span,
2721 "parentheses required",
2722 ));
2723 }
2724
2725 input.advance_to(&ahead);
2726 let expr = if Expr::peek(input) && (allow_struct.0 || !input.peek(token::Brace)) {
2727 Some(input.parse()?)
2728 } else {
2729 None
2730 };
2731
2732 Ok(ExprBreak {
2733 attrs: Vec::new(),
2734 break_token,
2735 label,
2736 expr,
2737 })
2738 }
2739
2740 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2741 impl Parse for FieldValue {
2742 fn parse(input: ParseStream) -> Result<Self> {
2743 let attrs = input.call(Attribute::parse_outer)?;
2744 let member: Member = input.parse()?;
2745 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2746 let colon_token: Token![:] = input.parse()?;
2747 let value: Expr = input.parse()?;
2748 (Some(colon_token), value)
2749 } else if let Member::Named(ident) = &member {
2750 let value = Expr::Path(ExprPath {
2751 attrs: Vec::new(),
2752 qself: None,
2753 path: Path::from(ident.clone()),
2754 });
2755 (None, value)
2756 } else {
2757 unreachable!()
2758 };
2759
2760 Ok(FieldValue {
2761 attrs,
2762 member,
2763 colon_token,
2764 expr: value,
2765 })
2766 }
2767 }
2768
2769 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2770 impl Parse for ExprStruct {
2771 fn parse(input: ParseStream) -> Result<Self> {
2772 let expr_style = true;
2773 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2774 expr_struct_helper(input, qself, path)
2775 }
2776 }
2777
2778 fn expr_struct_helper(
2779 input: ParseStream,
2780 qself: Option<QSelf>,
2781 path: Path,
2782 ) -> Result<ExprStruct> {
2783 let content;
2784 let brace_token = braced!(content in input);
2785
2786 let mut fields = Punctuated::new();
2787 while !content.is_empty() {
2788 if content.peek(Token![..]) {
2789 return Ok(ExprStruct {
2790 attrs: Vec::new(),
2791 qself,
2792 path,
2793 brace_token,
2794 fields,
2795 dot2_token: Some(content.parse()?),
2796 rest: if content.is_empty() {
2797 None
2798 } else {
2799 Some(Box::new(content.parse()?))
2800 },
2801 });
2802 }
2803
2804 fields.push(content.parse()?);
2805 if content.is_empty() {
2806 break;
2807 }
2808 let punct: Token![,] = content.parse()?;
2809 fields.push_punct(punct);
2810 }
2811
2812 Ok(ExprStruct {
2813 attrs: Vec::new(),
2814 qself,
2815 path,
2816 brace_token,
2817 fields,
2818 dot2_token: None,
2819 rest: None,
2820 })
2821 }
2822
2823 #[cfg(feature = "full")]
2824 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2825 impl Parse for ExprUnsafe {
2826 fn parse(input: ParseStream) -> Result<Self> {
2827 let unsafe_token: Token![unsafe] = input.parse()?;
2828
2829 let content;
2830 let brace_token = braced!(content in input);
2831 let inner_attrs = content.call(Attribute::parse_inner)?;
2832 let stmts = content.call(Block::parse_within)?;
2833
2834 Ok(ExprUnsafe {
2835 attrs: inner_attrs,
2836 unsafe_token,
2837 block: Block { brace_token, stmts },
2838 })
2839 }
2840 }
2841
2842 #[cfg(feature = "full")]
2843 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2844 impl Parse for ExprBlock {
2845 fn parse(input: ParseStream) -> Result<Self> {
2846 let mut attrs = input.call(Attribute::parse_outer)?;
2847 let label: Option<Label> = input.parse()?;
2848
2849 let content;
2850 let brace_token = braced!(content in input);
2851 attr::parsing::parse_inner(&content, &mut attrs)?;
2852 let stmts = content.call(Block::parse_within)?;
2853
2854 Ok(ExprBlock {
2855 attrs,
2856 label,
2857 block: Block { brace_token, stmts },
2858 })
2859 }
2860 }
2861
2862 #[cfg(feature = "full")]
2863 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2864 let limits: RangeLimits = input.parse()?;
2865 let end = parse_range_end(input, &limits, allow_struct)?;
2866 Ok(ExprRange {
2867 attrs: Vec::new(),
2868 start: None,
2869 limits,
2870 end,
2871 })
2872 }
2873
2874 #[cfg(feature = "full")]
2875 fn parse_range_end(
2876 input: ParseStream,
2877 limits: &RangeLimits,
2878 allow_struct: AllowStruct,
2879 ) -> Result<Option<Box<Expr>>> {
2880 if matches!(limits, RangeLimits::HalfOpen(_))
2881 && (input.is_empty()
2882 || input.peek(Token![,])
2883 || input.peek(Token![;])
2884 || input.peek(Token![.]) && !input.peek(Token![..])
2885 || input.peek(Token![?])
2886 || input.peek(Token![=>])
2887 || !allow_struct.0 && input.peek(token::Brace)
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![<<=])
2901 || input.peek(Token![as]))
2902 {
2903 Ok(None)
2904 } else {
2905 let end = parse_binop_rhs(input, allow_struct, Precedence::Range)?;
2906 Ok(Some(end))
2907 }
2908 }
2909
2910 #[cfg(feature = "full")]
2911 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2912 impl Parse for RangeLimits {
2913 fn parse(input: ParseStream) -> Result<Self> {
2914 let lookahead = input.lookahead1();
2915 let dot_dot = lookahead.peek(Token![..]);
2916 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2917 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2918 if dot_dot_eq {
2919 input.parse().map(RangeLimits::Closed)
2920 } else if dot_dot && !dot_dot_dot {
2921 input.parse().map(RangeLimits::HalfOpen)
2922 } else {
2923 Err(lookahead.error())
2924 }
2925 }
2926 }
2927
2928 #[cfg(feature = "full")]
2929 impl RangeLimits {
2930 pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> {
2931 let lookahead = input.lookahead1();
2932 let dot_dot = lookahead.peek(Token![..]);
2933 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2934 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2935 if dot_dot_eq {
2936 input.parse().map(RangeLimits::Closed)
2937 } else if dot_dot_dot {
2938 let dot3: Token![...] = input.parse()?;
2939 Ok(RangeLimits::Closed(Token))
2940 } else if dot_dot {
2941 input.parse().map(RangeLimits::HalfOpen)
2942 } else {
2943 Err(lookahead.error())
2944 }
2945 }
2946 }
2947
2948 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2949 impl Parse for ExprPath {
2950 fn parse(input: ParseStream) -> Result<Self> {
2951 #[cfg(not(feature = "full"))]
2952 let attrs = Vec::new();
2953 #[cfg(feature = "full")]
2954 let attrs = input.call(Attribute::parse_outer)?;
2955
2956 let expr_style = true;
2957 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2958
2959 Ok(ExprPath { attrs, qself, path })
2960 }
2961 }
2962
2963 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2964 impl Parse for Member {
2965 fn parse(input: ParseStream) -> Result<Self> {
2966 if input.peek(Ident) {
2967 input.parse().map(Member::Named)
2968 } else if input.peek(LitInt) {
2969 input.parse().map(Member::Unnamed)
2970 } else {
2971 Err(input.error("expected identifier or integer"))
2972 }
2973 }
2974 }
2975
2976 #[cfg(feature = "full")]
2977 impl Arm {
2978 pub(crate) fn parse_multiple(input: ParseStream) -> Result<Vec<Self>> {
2979 let mut arms = Vec::new();
2980 while !input.is_empty() {
2981 arms.push(input.call(Arm::parse)?);
2982 }
2983 Ok(arms)
2984 }
2985 }
2986
2987 #[cfg(feature = "full")]
2988 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2989 impl Parse for Arm {
2990 fn parse(input: ParseStream) -> Result<Arm> {
2991 let requires_comma;
2992 Ok(Arm {
2993 attrs: input.call(Attribute::parse_outer)?,
2994 pat: Pat::parse_multi_with_leading_vert(input)?,
2995 guard: {
2996 if input.peek(Token![if]) {
2997 let if_token: Token![if] = input.parse()?;
2998 let guard: Expr = input.parse()?;
2999 Some((if_token, Box::new(guard)))
3000 } else {
3001 None
3002 }
3003 },
3004 fat_arrow_token: input.parse()?,
3005 body: {
3006 let body = Expr::parse_with_earlier_boundary_rule(input)?;
3007 requires_comma = classify::requires_comma_to_be_match_arm(&body);
3008 Box::new(body)
3009 },
3010 comma: {
3011 if requires_comma && !input.is_empty() {
3012 Some(input.parse()?)
3013 } else {
3014 input.parse()?
3015 }
3016 },
3017 })
3018 }
3019 }
3020
3021 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
3022 impl Parse for Index {
3023 fn parse(input: ParseStream) -> Result<Self> {
3024 let lit: LitInt = input.parse()?;
3025 if lit.suffix().is_empty() {
3026 Ok(Index {
3027 index: lit
3028 .base10_digits()
3029 .parse()
3030 .map_err(|err| Error::new(lit.span(), err))?,
3031 span: lit.span(),
3032 })
3033 } else {
3034 Err(Error::new(lit.span(), "expected unsuffixed integer"))
3035 }
3036 }
3037 }
3038
3039 fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
3040 let float_token = float.token();
3041 let float_span = float_token.span();
3042 let mut float_repr = float_token.to_string();
3043 let trailing_dot = float_repr.ends_with('.');
3044 if trailing_dot {
3045 float_repr.truncate(float_repr.len() - 1);
3046 }
3047
3048 let mut offset = 0;
3049 for part in float_repr.split('.') {
3050 let mut index: Index =
3051 crate::parse_str(part).map_err(|err| Error::new(float_span, err))?;
3052 let part_end = offset + part.len();
3053 index.span = float_token.subspan(offset..part_end).unwrap_or(float_span);
3054
3055 let base = mem::replace(e, Expr::PLACEHOLDER);
3056 *e = Expr::Field(ExprField {
3057 attrs: Vec::new(),
3058 base: Box::new(base),
3059 dot_token: Token,
3060 member: Member::Unnamed(index),
3061 });
3062
3063 let dot_span = float_token
3064 .subspan(part_end..part_end + 1)
3065 .unwrap_or(float_span);
3066 *dot_token = Token;
3067 offset = part_end + 1;
3068 }
3069
3070 Ok(!trailing_dot)
3071 }
3072
3073 #[cfg(feature = "full")]
3074 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
3075 impl Parse for PointerMutability {
3076 fn parse(input: ParseStream) -> Result<Self> {
3077 let lookahead = input.lookahead1();
3078 if lookahead.peek(Token![const]) {
3079 Ok(PointerMutability::Const(input.parse()?))
3080 } else if lookahead.peek(Token![mut]) {
3081 Ok(PointerMutability::Mut(input.parse()?))
3082 } else {
3083 Err(lookahead.error())
3084 }
3085 }
3086 }
3087
3088 fn check_cast(input: ParseStream) -> Result<()> {
3089 let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
3090 if input.peek2(Token![await]) {
3091 "`.await`"
3092 } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
3093 "a method call"
3094 } else {
3095 "a field access"
3096 }
3097 } else if input.peek(Token![?]) {
3098 "`?`"
3099 } else if input.peek(token::Bracket) {
3100 "indexing"
3101 } else if input.peek(token::Paren) {
3102 "a function call"
3103 } else {
3104 return Ok(());
3105 };
3106 let msg = format!("casts cannot be followed by {}", kind);
3107 Err(input.error(msg))
3108 }
3109}
3110
3111#[cfg(feature = "printing")]
3112pub(crate) mod printing {
3113 use crate::attr::Attribute;
3114 #[cfg(feature = "full")]
3115 use crate::attr::FilterAttrs;
3116 #[cfg(feature = "full")]
3117 use crate::classify;
3118 #[cfg(feature = "full")]
3119 use crate::expr::{
3120 Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
3121 ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
3122 ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
3123 ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
3124 };
3125 use crate::expr::{
3126 Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
3127 ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary,
3128 FieldValue, Index, Member,
3129 };
3130 use crate::fixup::FixupContext;
3131 use crate::op::BinOp;
3132 use crate::path;
3133 use crate::path::printing::PathStyle;
3134 use crate::precedence::Precedence;
3135 use crate::token;
3136 #[cfg(feature = "full")]
3137 use crate::ty::ReturnType;
3138 use proc_macro2::{Literal, Span, TokenStream};
3139 use quote::{ToTokens, TokenStreamExt};
3140
3141 #[cfg(feature = "full")]
3142 pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3143 tokens.append_all(attrs.outer());
3144 }
3145
3146 #[cfg(feature = "full")]
3147 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3148 tokens.append_all(attrs.inner());
3149 }
3150
3151 #[cfg(not(feature = "full"))]
3152 pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3153
3154 pub(crate) fn print_subexpression(
3155 expr: &Expr,
3156 needs_group: bool,
3157 tokens: &mut TokenStream,
3158 mut fixup: FixupContext,
3159 ) {
3160 if needs_group {
3161 fixup = FixupContext::NONE;
3173 }
3174
3175 let do_print_expr = |tokens: &mut TokenStream| print_expr(expr, tokens, fixup);
3176
3177 if needs_group {
3178 token::Paren::default().surround(tokens, do_print_expr);
3179 } else {
3180 do_print_expr(tokens);
3181 }
3182 }
3183
3184 pub(crate) fn print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext) {
3185 #[cfg(feature = "full")]
3186 let needs_group = fixup.parenthesize(expr);
3187 #[cfg(not(feature = "full"))]
3188 let needs_group = false;
3189
3190 if needs_group {
3191 fixup = FixupContext::NONE;
3192 }
3193
3194 let do_print_expr = |tokens: &mut TokenStream| match expr {
3195 #[cfg(feature = "full")]
3196 Expr::Array(e) => e.to_tokens(tokens),
3197 #[cfg(feature = "full")]
3198 Expr::Assign(e) => print_expr_assign(e, tokens, fixup),
3199 #[cfg(feature = "full")]
3200 Expr::Async(e) => e.to_tokens(tokens),
3201 #[cfg(feature = "full")]
3202 Expr::Await(e) => print_expr_await(e, tokens, fixup),
3203 Expr::Binary(e) => print_expr_binary(e, tokens, fixup),
3204 #[cfg(feature = "full")]
3205 Expr::Block(e) => e.to_tokens(tokens),
3206 #[cfg(feature = "full")]
3207 Expr::Break(e) => print_expr_break(e, tokens, fixup),
3208 Expr::Call(e) => print_expr_call(e, tokens, fixup),
3209 Expr::Cast(e) => print_expr_cast(e, tokens, fixup),
3210 #[cfg(feature = "full")]
3211 Expr::Closure(e) => print_expr_closure(e, tokens, fixup),
3212 #[cfg(feature = "full")]
3213 Expr::Const(e) => e.to_tokens(tokens),
3214 #[cfg(feature = "full")]
3215 Expr::Continue(e) => e.to_tokens(tokens),
3216 Expr::Field(e) => print_expr_field(e, tokens, fixup),
3217 #[cfg(feature = "full")]
3218 Expr::ForLoop(e) => e.to_tokens(tokens),
3219 Expr::Group(e) => e.to_tokens(tokens),
3220 #[cfg(feature = "full")]
3221 Expr::If(e) => e.to_tokens(tokens),
3222 #[cfg(feature = "full")]
3223 Expr::Index(e) => print_expr_index(e, tokens, fixup),
3224 #[cfg(feature = "full")]
3225 Expr::Infer(e) => e.to_tokens(tokens),
3226 #[cfg(feature = "full")]
3227 Expr::Let(e) => print_expr_let(e, tokens, fixup),
3228 Expr::Lit(e) => e.to_tokens(tokens),
3229 #[cfg(feature = "full")]
3230 Expr::Loop(e) => e.to_tokens(tokens),
3231 Expr::Macro(e) => e.to_tokens(tokens),
3232 #[cfg(feature = "full")]
3233 Expr::Match(e) => e.to_tokens(tokens),
3234 Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup),
3235 Expr::Paren(e) => e.to_tokens(tokens),
3236 Expr::Path(e) => e.to_tokens(tokens),
3237 #[cfg(feature = "full")]
3238 Expr::Range(e) => print_expr_range(e, tokens, fixup),
3239 #[cfg(feature = "full")]
3240 Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup),
3241 Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
3242 #[cfg(feature = "full")]
3243 Expr::Repeat(e) => e.to_tokens(tokens),
3244 #[cfg(feature = "full")]
3245 Expr::Return(e) => print_expr_return(e, tokens, fixup),
3246 Expr::Struct(e) => e.to_tokens(tokens),
3247 #[cfg(feature = "full")]
3248 Expr::Try(e) => print_expr_try(e, tokens, fixup),
3249 #[cfg(feature = "full")]
3250 Expr::TryBlock(e) => e.to_tokens(tokens),
3251 #[cfg(feature = "full")]
3252 Expr::Tuple(e) => e.to_tokens(tokens),
3253 Expr::Unary(e) => print_expr_unary(e, tokens, fixup),
3254 #[cfg(feature = "full")]
3255 Expr::Unsafe(e) => e.to_tokens(tokens),
3256 Expr::Verbatim(e) => e.to_tokens(tokens),
3257 #[cfg(feature = "full")]
3258 Expr::While(e) => e.to_tokens(tokens),
3259 #[cfg(feature = "full")]
3260 Expr::Yield(e) => print_expr_yield(e, tokens, fixup),
3261
3262 #[cfg(not(feature = "full"))]
3263 _ => unreachable!(),
3264 };
3265
3266 if needs_group {
3267 token::Paren::default().surround(tokens, do_print_expr);
3268 } else {
3269 do_print_expr(tokens);
3270 }
3271 }
3272
3273 #[cfg(feature = "full")]
3274 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3275 impl ToTokens for ExprArray {
3276 fn to_tokens(&self, tokens: &mut TokenStream) {
3277 outer_attrs_to_tokens(&self.attrs, tokens);
3278 self.bracket_token.surround(tokens, |tokens| {
3279 self.elems.to_tokens(tokens);
3280 });
3281 }
3282 }
3283
3284 #[cfg(feature = "full")]
3285 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3286 impl ToTokens for ExprAssign {
3287 fn to_tokens(&self, tokens: &mut TokenStream) {
3288 print_expr_assign(self, tokens, FixupContext::NONE);
3289 }
3290 }
3291
3292 #[cfg(feature = "full")]
3293 fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, fixup: FixupContext) {
3294 outer_attrs_to_tokens(&e.attrs, tokens);
3295 let (left_prec, left_fixup) =
3296 fixup.leftmost_subexpression_with_operator(&e.left, false, false, Precedence::Assign);
3297 print_subexpression(&e.left, left_prec <= Precedence::Range, tokens, left_fixup);
3298 e.eq_token.to_tokens(tokens);
3299 print_expr(
3300 &e.right,
3301 tokens,
3302 fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign),
3303 );
3304 }
3305
3306 #[cfg(feature = "full")]
3307 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3308 impl ToTokens for ExprAsync {
3309 fn to_tokens(&self, tokens: &mut TokenStream) {
3310 outer_attrs_to_tokens(&self.attrs, tokens);
3311 self.async_token.to_tokens(tokens);
3312 self.capture.to_tokens(tokens);
3313 self.block.to_tokens(tokens);
3314 }
3315 }
3316
3317 #[cfg(feature = "full")]
3318 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3319 impl ToTokens for ExprAwait {
3320 fn to_tokens(&self, tokens: &mut TokenStream) {
3321 print_expr_await(self, tokens, FixupContext::NONE);
3322 }
3323 }
3324
3325 #[cfg(feature = "full")]
3326 fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) {
3327 outer_attrs_to_tokens(&e.attrs, tokens);
3328 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3329 print_subexpression(
3330 &e.base,
3331 left_prec < Precedence::Unambiguous,
3332 tokens,
3333 left_fixup,
3334 );
3335 e.dot_token.to_tokens(tokens);
3336 e.await_token.to_tokens(tokens);
3337 }
3338
3339 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3340 impl ToTokens for ExprBinary {
3341 fn to_tokens(&self, tokens: &mut TokenStream) {
3342 print_expr_binary(self, tokens, FixupContext::NONE);
3343 }
3344 }
3345
3346 fn print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, fixup: FixupContext) {
3347 outer_attrs_to_tokens(&e.attrs, tokens);
3348
3349 let binop_prec = Precedence::of_binop(&e.op);
3350 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3351 &e.left,
3352 #[cfg(feature = "full")]
3353 match &e.op {
3354 BinOp::Sub(_)
3355 | BinOp::Mul(_)
3356 | BinOp::And(_)
3357 | BinOp::Or(_)
3358 | BinOp::BitAnd(_)
3359 | BinOp::BitOr(_)
3360 | BinOp::Shl(_)
3361 | BinOp::Lt(_) => true,
3362 _ => false,
3363 },
3364 match &e.op {
3365 BinOp::Shl(_) | BinOp::Lt(_) => true,
3366 _ => false,
3367 },
3368 #[cfg(feature = "full")]
3369 binop_prec,
3370 );
3371 let left_needs_group = match binop_prec {
3372 Precedence::Assign => left_prec <= Precedence::Range,
3373 Precedence::Compare => left_prec <= binop_prec,
3374 _ => left_prec < binop_prec,
3375 };
3376
3377 let right_fixup = fixup.rightmost_subexpression_fixup(
3378 #[cfg(feature = "full")]
3379 false,
3380 #[cfg(feature = "full")]
3381 false,
3382 #[cfg(feature = "full")]
3383 binop_prec,
3384 );
3385 let right_needs_group = binop_prec != Precedence::Assign
3386 && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec;
3387
3388 print_subexpression(&e.left, left_needs_group, tokens, left_fixup);
3389 e.op.to_tokens(tokens);
3390 print_subexpression(&e.right, right_needs_group, tokens, right_fixup);
3391 }
3392
3393 #[cfg(feature = "full")]
3394 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3395 impl ToTokens for ExprBlock {
3396 fn to_tokens(&self, tokens: &mut TokenStream) {
3397 outer_attrs_to_tokens(&self.attrs, tokens);
3398 self.label.to_tokens(tokens);
3399 self.block.brace_token.surround(tokens, |tokens| {
3400 inner_attrs_to_tokens(&self.attrs, tokens);
3401 tokens.append_all(&self.block.stmts);
3402 });
3403 }
3404 }
3405
3406 #[cfg(feature = "full")]
3407 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3408 impl ToTokens for ExprBreak {
3409 fn to_tokens(&self, tokens: &mut TokenStream) {
3410 print_expr_break(self, tokens, FixupContext::NONE);
3411 }
3412 }
3413
3414 #[cfg(feature = "full")]
3415 fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) {
3416 outer_attrs_to_tokens(&e.attrs, tokens);
3417 e.break_token.to_tokens(tokens);
3418 e.label.to_tokens(tokens);
3419 if let Some(value) = &e.expr {
3420 print_subexpression(
3421 value,
3422 e.label.is_none() && classify::expr_leading_label(value),
3425 tokens,
3426 fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump),
3427 );
3428 }
3429 }
3430
3431 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3432 impl ToTokens for ExprCall {
3433 fn to_tokens(&self, tokens: &mut TokenStream) {
3434 print_expr_call(self, tokens, FixupContext::NONE);
3435 }
3436 }
3437
3438 fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) {
3439 outer_attrs_to_tokens(&e.attrs, tokens);
3440
3441 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3442 &e.func,
3443 #[cfg(feature = "full")]
3444 true,
3445 false,
3446 #[cfg(feature = "full")]
3447 Precedence::Unambiguous,
3448 );
3449 let needs_group = if let Expr::Field(func) = &*e.func {
3450 func.member.is_named()
3451 } else {
3452 left_prec < Precedence::Unambiguous
3453 };
3454 print_subexpression(&e.func, needs_group, tokens, left_fixup);
3455
3456 e.paren_token.surround(tokens, |tokens| {
3457 e.args.to_tokens(tokens);
3458 });
3459 }
3460
3461 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3462 impl ToTokens for ExprCast {
3463 fn to_tokens(&self, tokens: &mut TokenStream) {
3464 print_expr_cast(self, tokens, FixupContext::NONE);
3465 }
3466 }
3467
3468 fn print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, fixup: FixupContext) {
3469 outer_attrs_to_tokens(&e.attrs, tokens);
3470 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3471 &e.expr,
3472 #[cfg(feature = "full")]
3473 false,
3474 false,
3475 #[cfg(feature = "full")]
3476 Precedence::Cast,
3477 );
3478 print_subexpression(&e.expr, left_prec < Precedence::Cast, tokens, left_fixup);
3479 e.as_token.to_tokens(tokens);
3480 e.ty.to_tokens(tokens);
3481 }
3482
3483 #[cfg(feature = "full")]
3484 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3485 impl ToTokens for ExprClosure {
3486 fn to_tokens(&self, tokens: &mut TokenStream) {
3487 print_expr_closure(self, tokens, FixupContext::NONE);
3488 }
3489 }
3490
3491 #[cfg(feature = "full")]
3492 fn print_expr_closure(e: &ExprClosure, tokens: &mut TokenStream, fixup: FixupContext) {
3493 outer_attrs_to_tokens(&e.attrs, tokens);
3494 e.lifetimes.to_tokens(tokens);
3495 e.constness.to_tokens(tokens);
3496 e.movability.to_tokens(tokens);
3497 e.asyncness.to_tokens(tokens);
3498 e.capture.to_tokens(tokens);
3499 e.or1_token.to_tokens(tokens);
3500 e.inputs.to_tokens(tokens);
3501 e.or2_token.to_tokens(tokens);
3502 e.output.to_tokens(tokens);
3503 if matches!(e.output, ReturnType::Default)
3504 || matches!(&*e.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none())
3505 {
3506 print_expr(
3507 &e.body,
3508 tokens,
3509 fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
3510 );
3511 } else {
3512 token::Brace::default().surround(tokens, |tokens| {
3513 print_expr(&e.body, tokens, FixupContext::new_stmt());
3514 });
3515 }
3516 }
3517
3518 #[cfg(feature = "full")]
3519 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3520 impl ToTokens for ExprConst {
3521 fn to_tokens(&self, tokens: &mut TokenStream) {
3522 outer_attrs_to_tokens(&self.attrs, tokens);
3523 self.const_token.to_tokens(tokens);
3524 self.block.brace_token.surround(tokens, |tokens| {
3525 inner_attrs_to_tokens(&self.attrs, tokens);
3526 tokens.append_all(&self.block.stmts);
3527 });
3528 }
3529 }
3530
3531 #[cfg(feature = "full")]
3532 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3533 impl ToTokens for ExprContinue {
3534 fn to_tokens(&self, tokens: &mut TokenStream) {
3535 outer_attrs_to_tokens(&self.attrs, tokens);
3536 self.continue_token.to_tokens(tokens);
3537 self.label.to_tokens(tokens);
3538 }
3539 }
3540
3541 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3542 impl ToTokens for ExprField {
3543 fn to_tokens(&self, tokens: &mut TokenStream) {
3544 print_expr_field(self, tokens, FixupContext::NONE);
3545 }
3546 }
3547
3548 fn print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext) {
3549 outer_attrs_to_tokens(&e.attrs, tokens);
3550 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.base);
3551 print_subexpression(
3552 &e.base,
3553 left_prec < Precedence::Unambiguous,
3554 tokens,
3555 left_fixup,
3556 );
3557 e.dot_token.to_tokens(tokens);
3558 e.member.to_tokens(tokens);
3559 }
3560
3561 #[cfg(feature = "full")]
3562 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3563 impl ToTokens for ExprForLoop {
3564 fn to_tokens(&self, tokens: &mut TokenStream) {
3565 outer_attrs_to_tokens(&self.attrs, tokens);
3566 self.label.to_tokens(tokens);
3567 self.for_token.to_tokens(tokens);
3568 self.pat.to_tokens(tokens);
3569 self.in_token.to_tokens(tokens);
3570 print_expr(&self.expr, tokens, FixupContext::new_condition());
3571 self.body.brace_token.surround(tokens, |tokens| {
3572 inner_attrs_to_tokens(&self.attrs, tokens);
3573 tokens.append_all(&self.body.stmts);
3574 });
3575 }
3576 }
3577
3578 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3579 impl ToTokens for ExprGroup {
3580 fn to_tokens(&self, tokens: &mut TokenStream) {
3581 outer_attrs_to_tokens(&self.attrs, tokens);
3582 self.group_token.surround(tokens, |tokens| {
3583 self.expr.to_tokens(tokens);
3584 });
3585 }
3586 }
3587
3588 #[cfg(feature = "full")]
3589 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3590 impl ToTokens for ExprIf {
3591 fn to_tokens(&self, tokens: &mut TokenStream) {
3592 outer_attrs_to_tokens(&self.attrs, tokens);
3593
3594 let mut expr = self;
3595 loop {
3596 expr.if_token.to_tokens(tokens);
3597 print_expr(&expr.cond, tokens, FixupContext::new_condition());
3598 expr.then_branch.to_tokens(tokens);
3599
3600 let (else_token, else_) = match &expr.else_branch {
3601 Some(else_branch) => else_branch,
3602 None => break,
3603 };
3604
3605 else_token.to_tokens(tokens);
3606 match &**else_ {
3607 Expr::If(next) => {
3608 expr = next;
3609 }
3610 Expr::Block(last) => {
3611 last.to_tokens(tokens);
3612 break;
3613 }
3614 other => {
3617 token::Brace::default().surround(tokens, |tokens| {
3618 print_expr(other, tokens, FixupContext::new_stmt());
3619 });
3620 break;
3621 }
3622 }
3623 }
3624 }
3625 }
3626
3627 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3628 impl ToTokens for ExprIndex {
3629 fn to_tokens(&self, tokens: &mut TokenStream) {
3630 print_expr_index(self, tokens, FixupContext::NONE);
3631 }
3632 }
3633
3634 fn print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext) {
3635 outer_attrs_to_tokens(&e.attrs, tokens);
3636 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
3637 &e.expr,
3638 #[cfg(feature = "full")]
3639 true,
3640 false,
3641 #[cfg(feature = "full")]
3642 Precedence::Unambiguous,
3643 );
3644 print_subexpression(
3645 &e.expr,
3646 left_prec < Precedence::Unambiguous,
3647 tokens,
3648 left_fixup,
3649 );
3650 e.bracket_token.surround(tokens, |tokens| {
3651 e.index.to_tokens(tokens);
3652 });
3653 }
3654
3655 #[cfg(feature = "full")]
3656 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3657 impl ToTokens for ExprInfer {
3658 fn to_tokens(&self, tokens: &mut TokenStream) {
3659 outer_attrs_to_tokens(&self.attrs, tokens);
3660 self.underscore_token.to_tokens(tokens);
3661 }
3662 }
3663
3664 #[cfg(feature = "full")]
3665 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3666 impl ToTokens for ExprLet {
3667 fn to_tokens(&self, tokens: &mut TokenStream) {
3668 print_expr_let(self, tokens, FixupContext::NONE);
3669 }
3670 }
3671
3672 #[cfg(feature = "full")]
3673 fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) {
3674 outer_attrs_to_tokens(&e.attrs, tokens);
3675 e.let_token.to_tokens(tokens);
3676 e.pat.to_tokens(tokens);
3677 e.eq_token.to_tokens(tokens);
3678 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Let);
3679 print_subexpression(&e.expr, right_prec < Precedence::Let, tokens, right_fixup);
3680 }
3681
3682 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3683 impl ToTokens for ExprLit {
3684 fn to_tokens(&self, tokens: &mut TokenStream) {
3685 outer_attrs_to_tokens(&self.attrs, tokens);
3686 self.lit.to_tokens(tokens);
3687 }
3688 }
3689
3690 #[cfg(feature = "full")]
3691 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3692 impl ToTokens for ExprLoop {
3693 fn to_tokens(&self, tokens: &mut TokenStream) {
3694 outer_attrs_to_tokens(&self.attrs, tokens);
3695 self.label.to_tokens(tokens);
3696 self.loop_token.to_tokens(tokens);
3697 self.body.brace_token.surround(tokens, |tokens| {
3698 inner_attrs_to_tokens(&self.attrs, tokens);
3699 tokens.append_all(&self.body.stmts);
3700 });
3701 }
3702 }
3703
3704 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3705 impl ToTokens for ExprMacro {
3706 fn to_tokens(&self, tokens: &mut TokenStream) {
3707 outer_attrs_to_tokens(&self.attrs, tokens);
3708 self.mac.to_tokens(tokens);
3709 }
3710 }
3711
3712 #[cfg(feature = "full")]
3713 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3714 impl ToTokens for ExprMatch {
3715 fn to_tokens(&self, tokens: &mut TokenStream) {
3716 outer_attrs_to_tokens(&self.attrs, tokens);
3717 self.match_token.to_tokens(tokens);
3718 print_expr(&self.expr, tokens, FixupContext::new_condition());
3719 self.brace_token.surround(tokens, |tokens| {
3720 inner_attrs_to_tokens(&self.attrs, tokens);
3721 for (i, arm) in self.arms.iter().enumerate() {
3722 arm.to_tokens(tokens);
3723 let is_last = i == self.arms.len() - 1;
3726 if !is_last
3727 && classify::requires_comma_to_be_match_arm(&arm.body)
3728 && arm.comma.is_none()
3729 {
3730 <Token![,]>::default().to_tokens(tokens);
3731 }
3732 }
3733 });
3734 }
3735 }
3736
3737 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3738 impl ToTokens for ExprMethodCall {
3739 fn to_tokens(&self, tokens: &mut TokenStream) {
3740 print_expr_method_call(self, tokens, FixupContext::NONE);
3741 }
3742 }
3743
3744 fn print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext) {
3745 outer_attrs_to_tokens(&e.attrs, tokens);
3746 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.receiver);
3747 print_subexpression(
3748 &e.receiver,
3749 left_prec < Precedence::Unambiguous,
3750 tokens,
3751 left_fixup,
3752 );
3753 e.dot_token.to_tokens(tokens);
3754 e.method.to_tokens(tokens);
3755 if let Some(turbofish) = &e.turbofish {
3756 path::printing::print_angle_bracketed_generic_arguments(
3757 tokens,
3758 turbofish,
3759 PathStyle::Expr,
3760 );
3761 }
3762 e.paren_token.surround(tokens, |tokens| {
3763 e.args.to_tokens(tokens);
3764 });
3765 }
3766
3767 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3768 impl ToTokens for ExprParen {
3769 fn to_tokens(&self, tokens: &mut TokenStream) {
3770 outer_attrs_to_tokens(&self.attrs, tokens);
3771 self.paren_token.surround(tokens, |tokens| {
3772 self.expr.to_tokens(tokens);
3773 });
3774 }
3775 }
3776
3777 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3778 impl ToTokens for ExprPath {
3779 fn to_tokens(&self, tokens: &mut TokenStream) {
3780 outer_attrs_to_tokens(&self.attrs, tokens);
3781 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3782 }
3783 }
3784
3785 #[cfg(feature = "full")]
3786 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3787 impl ToTokens for ExprRange {
3788 fn to_tokens(&self, tokens: &mut TokenStream) {
3789 print_expr_range(self, tokens, FixupContext::NONE);
3790 }
3791 }
3792
3793 #[cfg(feature = "full")]
3794 fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, fixup: FixupContext) {
3795 outer_attrs_to_tokens(&e.attrs, tokens);
3796 if let Some(start) = &e.start {
3797 let (left_prec, left_fixup) =
3798 fixup.leftmost_subexpression_with_operator(start, true, false, Precedence::Range);
3799 print_subexpression(start, left_prec <= Precedence::Range, tokens, left_fixup);
3800 }
3801 e.limits.to_tokens(tokens);
3802 if let Some(end) = &e.end {
3803 let right_fixup = fixup.rightmost_subexpression_fixup(false, true, Precedence::Range);
3804 let right_prec = right_fixup.rightmost_subexpression_precedence(end);
3805 print_subexpression(end, right_prec <= Precedence::Range, tokens, right_fixup);
3806 }
3807 }
3808
3809 #[cfg(feature = "full")]
3810 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3811 impl ToTokens for ExprRawAddr {
3812 fn to_tokens(&self, tokens: &mut TokenStream) {
3813 print_expr_raw_addr(self, tokens, FixupContext::NONE);
3814 }
3815 }
3816
3817 #[cfg(feature = "full")]
3818 fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) {
3819 outer_attrs_to_tokens(&e.attrs, tokens);
3820 e.and_token.to_tokens(tokens);
3821 e.raw.to_tokens(tokens);
3822 e.mutability.to_tokens(tokens);
3823 let (right_prec, right_fixup) = fixup.rightmost_subexpression(&e.expr, Precedence::Prefix);
3824 print_subexpression(
3825 &e.expr,
3826 right_prec < Precedence::Prefix,
3827 tokens,
3828 right_fixup,
3829 );
3830 }
3831
3832 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3833 impl ToTokens for ExprReference {
3834 fn to_tokens(&self, tokens: &mut TokenStream) {
3835 print_expr_reference(self, tokens, FixupContext::NONE);
3836 }
3837 }
3838
3839 fn print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext) {
3840 outer_attrs_to_tokens(&e.attrs, tokens);
3841 e.and_token.to_tokens(tokens);
3842 e.mutability.to_tokens(tokens);
3843 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3844 &e.expr,
3845 #[cfg(feature = "full")]
3846 Precedence::Prefix,
3847 );
3848 print_subexpression(
3849 &e.expr,
3850 right_prec < Precedence::Prefix,
3851 tokens,
3852 right_fixup,
3853 );
3854 }
3855
3856 #[cfg(feature = "full")]
3857 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3858 impl ToTokens for ExprRepeat {
3859 fn to_tokens(&self, tokens: &mut TokenStream) {
3860 outer_attrs_to_tokens(&self.attrs, tokens);
3861 self.bracket_token.surround(tokens, |tokens| {
3862 self.expr.to_tokens(tokens);
3863 self.semi_token.to_tokens(tokens);
3864 self.len.to_tokens(tokens);
3865 });
3866 }
3867 }
3868
3869 #[cfg(feature = "full")]
3870 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3871 impl ToTokens for ExprReturn {
3872 fn to_tokens(&self, tokens: &mut TokenStream) {
3873 print_expr_return(self, tokens, FixupContext::NONE);
3874 }
3875 }
3876
3877 #[cfg(feature = "full")]
3878 fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) {
3879 outer_attrs_to_tokens(&e.attrs, tokens);
3880 e.return_token.to_tokens(tokens);
3881 if let Some(expr) = &e.expr {
3882 print_expr(
3883 expr,
3884 tokens,
3885 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
3886 );
3887 }
3888 }
3889
3890 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3891 impl ToTokens for ExprStruct {
3892 fn to_tokens(&self, tokens: &mut TokenStream) {
3893 outer_attrs_to_tokens(&self.attrs, tokens);
3894 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3895 self.brace_token.surround(tokens, |tokens| {
3896 self.fields.to_tokens(tokens);
3897 if let Some(dot2_token) = &self.dot2_token {
3898 dot2_token.to_tokens(tokens);
3899 } else if self.rest.is_some() {
3900 Token).to_tokens(tokens);
3901 }
3902 self.rest.to_tokens(tokens);
3903 });
3904 }
3905 }
3906
3907 #[cfg(feature = "full")]
3908 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3909 impl ToTokens for ExprTry {
3910 fn to_tokens(&self, tokens: &mut TokenStream) {
3911 print_expr_try(self, tokens, FixupContext::NONE);
3912 }
3913 }
3914
3915 #[cfg(feature = "full")]
3916 fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) {
3917 outer_attrs_to_tokens(&e.attrs, tokens);
3918 let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&e.expr);
3919 print_subexpression(
3920 &e.expr,
3921 left_prec < Precedence::Unambiguous,
3922 tokens,
3923 left_fixup,
3924 );
3925 e.question_token.to_tokens(tokens);
3926 }
3927
3928 #[cfg(feature = "full")]
3929 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3930 impl ToTokens for ExprTryBlock {
3931 fn to_tokens(&self, tokens: &mut TokenStream) {
3932 outer_attrs_to_tokens(&self.attrs, tokens);
3933 self.try_token.to_tokens(tokens);
3934 self.block.to_tokens(tokens);
3935 }
3936 }
3937
3938 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3939 impl ToTokens for ExprTuple {
3940 fn to_tokens(&self, tokens: &mut TokenStream) {
3941 outer_attrs_to_tokens(&self.attrs, tokens);
3942 self.paren_token.surround(tokens, |tokens| {
3943 self.elems.to_tokens(tokens);
3944 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3947 <Token![,]>::default().to_tokens(tokens);
3948 }
3949 });
3950 }
3951 }
3952
3953 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3954 impl ToTokens for ExprUnary {
3955 fn to_tokens(&self, tokens: &mut TokenStream) {
3956 print_expr_unary(self, tokens, FixupContext::NONE);
3957 }
3958 }
3959
3960 fn print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext) {
3961 outer_attrs_to_tokens(&e.attrs, tokens);
3962 e.op.to_tokens(tokens);
3963 let (right_prec, right_fixup) = fixup.rightmost_subexpression(
3964 &e.expr,
3965 #[cfg(feature = "full")]
3966 Precedence::Prefix,
3967 );
3968 print_subexpression(
3969 &e.expr,
3970 right_prec < Precedence::Prefix,
3971 tokens,
3972 right_fixup,
3973 );
3974 }
3975
3976 #[cfg(feature = "full")]
3977 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3978 impl ToTokens for ExprUnsafe {
3979 fn to_tokens(&self, tokens: &mut TokenStream) {
3980 outer_attrs_to_tokens(&self.attrs, tokens);
3981 self.unsafe_token.to_tokens(tokens);
3982 self.block.brace_token.surround(tokens, |tokens| {
3983 inner_attrs_to_tokens(&self.attrs, tokens);
3984 tokens.append_all(&self.block.stmts);
3985 });
3986 }
3987 }
3988
3989 #[cfg(feature = "full")]
3990 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3991 impl ToTokens for ExprWhile {
3992 fn to_tokens(&self, tokens: &mut TokenStream) {
3993 outer_attrs_to_tokens(&self.attrs, tokens);
3994 self.label.to_tokens(tokens);
3995 self.while_token.to_tokens(tokens);
3996 print_expr(&self.cond, tokens, FixupContext::new_condition());
3997 self.body.brace_token.surround(tokens, |tokens| {
3998 inner_attrs_to_tokens(&self.attrs, tokens);
3999 tokens.append_all(&self.body.stmts);
4000 });
4001 }
4002 }
4003
4004 #[cfg(feature = "full")]
4005 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4006 impl ToTokens for ExprYield {
4007 fn to_tokens(&self, tokens: &mut TokenStream) {
4008 print_expr_yield(self, tokens, FixupContext::NONE);
4009 }
4010 }
4011
4012 #[cfg(feature = "full")]
4013 fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) {
4014 outer_attrs_to_tokens(&e.attrs, tokens);
4015 e.yield_token.to_tokens(tokens);
4016 if let Some(expr) = &e.expr {
4017 print_expr(
4018 expr,
4019 tokens,
4020 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
4021 );
4022 }
4023 }
4024
4025 #[cfg(feature = "full")]
4026 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4027 impl ToTokens for Arm {
4028 fn to_tokens(&self, tokens: &mut TokenStream) {
4029 tokens.append_all(&self.attrs);
4030 self.pat.to_tokens(tokens);
4031 if let Some((if_token, guard)) = &self.guard {
4032 if_token.to_tokens(tokens);
4033 guard.to_tokens(tokens);
4034 }
4035 self.fat_arrow_token.to_tokens(tokens);
4036 print_expr(&self.body, tokens, FixupContext::new_match_arm());
4037 self.comma.to_tokens(tokens);
4038 }
4039 }
4040
4041 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4042 impl ToTokens for FieldValue {
4043 fn to_tokens(&self, tokens: &mut TokenStream) {
4044 outer_attrs_to_tokens(&self.attrs, tokens);
4045 self.member.to_tokens(tokens);
4046 if let Some(colon_token) = &self.colon_token {
4047 colon_token.to_tokens(tokens);
4048 self.expr.to_tokens(tokens);
4049 }
4050 }
4051 }
4052
4053 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4054 impl ToTokens for Index {
4055 fn to_tokens(&self, tokens: &mut TokenStream) {
4056 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
4057 lit.set_span(self.span);
4058 tokens.append(lit);
4059 }
4060 }
4061
4062 #[cfg(feature = "full")]
4063 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4064 impl ToTokens for Label {
4065 fn to_tokens(&self, tokens: &mut TokenStream) {
4066 self.name.to_tokens(tokens);
4067 self.colon_token.to_tokens(tokens);
4068 }
4069 }
4070
4071 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4072 impl ToTokens for Member {
4073 fn to_tokens(&self, tokens: &mut TokenStream) {
4074 match self {
4075 Member::Named(ident) => ident.to_tokens(tokens),
4076 Member::Unnamed(index) => index.to_tokens(tokens),
4077 }
4078 }
4079 }
4080
4081 #[cfg(feature = "full")]
4082 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4083 impl ToTokens for RangeLimits {
4084 fn to_tokens(&self, tokens: &mut TokenStream) {
4085 match self {
4086 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
4087 RangeLimits::Closed(t) => t.to_tokens(tokens),
4088 }
4089 }
4090 }
4091
4092 #[cfg(feature = "full")]
4093 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4094 impl ToTokens for PointerMutability {
4095 fn to_tokens(&self, tokens: &mut TokenStream) {
4096 match self {
4097 PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
4098 PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
4099 }
4100 }
4101 }
4102}