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::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(ExprRange { end: Some(_), .. }) = lhs {
1319 break;
1322 } else if let Ok(op) = ahead.parse::<BinOp>() {
1323 let precedence = Precedence::of_binop(&op);
1324 if precedence < base {
1325 break;
1326 }
1327 if precedence == Precedence::Compare {
1328 if let Expr::Binary(lhs) = &lhs {
1329 if Precedence::of_binop(&lhs.op) == Precedence::Compare {
1330 return Err(input.error("comparison operators cannot be chained"));
1331 }
1332 }
1333 }
1334 input.advance_to(&ahead);
1335 let right = parse_binop_rhs(input, allow_struct, precedence)?;
1336 lhs = Expr::Binary(ExprBinary {
1337 attrs: Vec::new(),
1338 left: Box::new(lhs),
1339 op,
1340 right,
1341 });
1342 } else if Precedence::Assign >= base && input.peek(Token![=]) && !input.peek(Token![=>])
1343 {
1344 let eq_token: Token![=] = input.parse()?;
1345 let right = parse_binop_rhs(input, allow_struct, Precedence::Assign)?;
1346 lhs = Expr::Assign(ExprAssign {
1347 attrs: Vec::new(),
1348 left: Box::new(lhs),
1349 eq_token,
1350 right,
1351 });
1352 } else if Precedence::Range >= base && input.peek(Token![..]) {
1353 let limits: RangeLimits = input.parse()?;
1354 let end = parse_range_end(input, &limits, allow_struct)?;
1355 lhs = Expr::Range(ExprRange {
1356 attrs: Vec::new(),
1357 start: Some(Box::new(lhs)),
1358 limits,
1359 end,
1360 });
1361 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1362 let as_token: Token![as] = input.parse()?;
1363 let allow_plus = false;
1364 let allow_group_generic = false;
1365 let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
1366 check_cast(input)?;
1367 lhs = Expr::Cast(ExprCast {
1368 attrs: Vec::new(),
1369 expr: Box::new(lhs),
1370 as_token,
1371 ty: Box::new(ty),
1372 });
1373 } else {
1374 break;
1375 }
1376 }
1377 Ok(lhs)
1378 }
1379
1380 #[cfg(not(feature = "full"))]
1381 fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> {
1382 loop {
1383 let ahead = input.fork();
1384 if let Ok(op) = ahead.parse::<BinOp>() {
1385 let precedence = Precedence::of_binop(&op);
1386 if precedence < base {
1387 break;
1388 }
1389 if precedence == Precedence::Compare {
1390 if let Expr::Binary(lhs) = &lhs {
1391 if Precedence::of_binop(&lhs.op) == Precedence::Compare {
1392 return Err(input.error("comparison operators cannot be chained"));
1393 }
1394 }
1395 }
1396 input.advance_to(&ahead);
1397 let right = parse_binop_rhs(input, precedence)?;
1398 lhs = Expr::Binary(ExprBinary {
1399 attrs: Vec::new(),
1400 left: Box::new(lhs),
1401 op,
1402 right,
1403 });
1404 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1405 let as_token: Token![as] = input.parse()?;
1406 let allow_plus = false;
1407 let allow_group_generic = false;
1408 let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
1409 check_cast(input)?;
1410 lhs = Expr::Cast(ExprCast {
1411 attrs: Vec::new(),
1412 expr: Box::new(lhs),
1413 as_token,
1414 ty: Box::new(ty),
1415 });
1416 } else {
1417 break;
1418 }
1419 }
1420 Ok(lhs)
1421 }
1422
1423 fn parse_binop_rhs(
1424 input: ParseStream,
1425 #[cfg(feature = "full")] allow_struct: AllowStruct,
1426 precedence: Precedence,
1427 ) -> Result<Box<Expr>> {
1428 let mut rhs = unary_expr(
1429 input,
1430 #[cfg(feature = "full")]
1431 allow_struct,
1432 )?;
1433 loop {
1434 let next = peek_precedence(input);
1435 if next > precedence || next == precedence && precedence == Precedence::Assign {
1436 let cursor = input.cursor();
1437 rhs = parse_expr(
1438 input,
1439 rhs,
1440 #[cfg(feature = "full")]
1441 allow_struct,
1442 next,
1443 )?;
1444 if cursor == input.cursor() {
1445 break;
1450 }
1451 } else {
1452 break;
1453 }
1454 }
1455 Ok(Box::new(rhs))
1456 }
1457
1458 fn peek_precedence(input: ParseStream) -> Precedence {
1459 if let Ok(op) = input.fork().parse() {
1460 Precedence::of_binop(&op)
1461 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1462 Precedence::Assign
1463 } else if input.peek(Token![..]) {
1464 Precedence::Range
1465 } else if input.peek(Token![as]) {
1466 Precedence::Cast
1467 } else {
1468 Precedence::MIN
1469 }
1470 }
1471
1472 pub(super) fn ambiguous_expr(
1474 input: ParseStream,
1475 #[cfg(feature = "full")] allow_struct: AllowStruct,
1476 ) -> Result<Expr> {
1477 let lhs = unary_expr(
1478 input,
1479 #[cfg(feature = "full")]
1480 allow_struct,
1481 )?;
1482 parse_expr(
1483 input,
1484 lhs,
1485 #[cfg(feature = "full")]
1486 allow_struct,
1487 Precedence::MIN,
1488 )
1489 }
1490
1491 #[cfg(feature = "full")]
1492 fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
1493 let mut attrs = Vec::new();
1494 while !input.peek(token::Group) && input.peek(Token![#]) {
1495 attrs.push(input.call(attr::parsing::single_parse_outer)?);
1496 }
1497 Ok(attrs)
1498 }
1499
1500 #[cfg(feature = "full")]
1505 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1506 let begin = input.fork();
1507 let attrs = input.call(expr_attrs)?;
1508 if input.peek(token::Group) {
1509 return trailer_expr(begin, attrs, input, allow_struct);
1510 }
1511
1512 if input.peek(Token![&]) {
1513 let and_token: Token![&] = input.parse()?;
1514 let raw: Option<Token![raw]> = if input.peek(Token![raw])
1515 && (input.peek2(Token![mut]) || input.peek2(Token![const]))
1516 {
1517 Some(input.parse()?)
1518 } else {
1519 None
1520 };
1521 let mutability: Option<Token![mut]> = input.parse()?;
1522 let const_token: Option<Token![const]> = if raw.is_some() && mutability.is_none() {
1523 Some(input.parse()?)
1524 } else {
1525 None
1526 };
1527 let expr = Box::new(unary_expr(input, allow_struct)?);
1528 if let Some(raw) = raw {
1529 Ok(Expr::RawAddr(ExprRawAddr {
1530 attrs,
1531 and_token,
1532 raw,
1533 mutability: match mutability {
1534 Some(mut_token) => PointerMutability::Mut(mut_token),
1535 None => PointerMutability::Const(const_token.unwrap()),
1536 },
1537 expr,
1538 }))
1539 } else {
1540 Ok(Expr::Reference(ExprReference {
1541 attrs,
1542 and_token,
1543 mutability,
1544 expr,
1545 }))
1546 }
1547 } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1548 expr_unary(input, attrs, allow_struct).map(Expr::Unary)
1549 } else {
1550 trailer_expr(begin, attrs, input, allow_struct)
1551 }
1552 }
1553
1554 #[cfg(not(feature = "full"))]
1555 fn unary_expr(input: ParseStream) -> Result<Expr> {
1556 if input.peek(Token![&]) {
1557 Ok(Expr::Reference(ExprReference {
1558 attrs: Vec::new(),
1559 and_token: input.parse()?,
1560 mutability: input.parse()?,
1561 expr: Box::new(unary_expr(input)?),
1562 }))
1563 } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
1564 Ok(Expr::Unary(ExprUnary {
1565 attrs: Vec::new(),
1566 op: input.parse()?,
1567 expr: Box::new(unary_expr(input)?),
1568 }))
1569 } else {
1570 trailer_expr(input)
1571 }
1572 }
1573
1574 #[cfg(feature = "full")]
1581 fn trailer_expr(
1582 begin: ParseBuffer,
1583 mut attrs: Vec<Attribute>,
1584 input: ParseStream,
1585 allow_struct: AllowStruct,
1586 ) -> Result<Expr> {
1587 let atom = atom_expr(input, allow_struct)?;
1588 let mut e = trailer_helper(input, atom)?;
1589
1590 if let Expr::Verbatim(tokens) = &mut e {
1591 *tokens = verbatim::between(&begin, input);
1592 } else {
1593 let inner_attrs = e.replace_attrs(Vec::new());
1594 attrs.extend(inner_attrs);
1595 e.replace_attrs(attrs);
1596 }
1597
1598 Ok(e)
1599 }
1600
1601 #[cfg(feature = "full")]
1602 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1603 loop {
1604 if input.peek(token::Paren) {
1605 let content;
1606 e = Expr::Call(ExprCall {
1607 attrs: Vec::new(),
1608 func: Box::new(e),
1609 paren_token: parenthesized!(content in input),
1610 args: content.parse_terminated(Expr::parse, Token![,])?,
1611 });
1612 } else if input.peek(Token![.])
1613 && !input.peek(Token![..])
1614 && match e {
1615 Expr::Range(_) => false,
1616 _ => true,
1617 }
1618 {
1619 let mut dot_token: Token![.] = input.parse()?;
1620
1621 let float_token: Option<LitFloat> = input.parse()?;
1622 if let Some(float_token) = float_token {
1623 if multi_index(&mut e, &mut dot_token, float_token)? {
1624 continue;
1625 }
1626 }
1627
1628 let await_token: Option<Token![await]> = input.parse()?;
1629 if let Some(await_token) = await_token {
1630 e = Expr::Await(ExprAwait {
1631 attrs: Vec::new(),
1632 base: Box::new(e),
1633 dot_token,
1634 await_token,
1635 });
1636 continue;
1637 }
1638
1639 let member: Member = input.parse()?;
1640 let turbofish = if member.is_named() && input.peek(Token![::]) {
1641 Some(AngleBracketedGenericArguments::parse_turbofish(input)?)
1642 } else {
1643 None
1644 };
1645
1646 if turbofish.is_some() || input.peek(token::Paren) {
1647 if let Member::Named(method) = member {
1648 let content;
1649 e = Expr::MethodCall(ExprMethodCall {
1650 attrs: Vec::new(),
1651 receiver: Box::new(e),
1652 dot_token,
1653 method,
1654 turbofish,
1655 paren_token: parenthesized!(content in input),
1656 args: content.parse_terminated(Expr::parse, Token![,])?,
1657 });
1658 continue;
1659 }
1660 }
1661
1662 e = Expr::Field(ExprField {
1663 attrs: Vec::new(),
1664 base: Box::new(e),
1665 dot_token,
1666 member,
1667 });
1668 } else if input.peek(token::Bracket) {
1669 let content;
1670 e = Expr::Index(ExprIndex {
1671 attrs: Vec::new(),
1672 expr: Box::new(e),
1673 bracket_token: bracketed!(content in input),
1674 index: content.parse()?,
1675 });
1676 } else if input.peek(Token![?]) {
1677 e = Expr::Try(ExprTry {
1678 attrs: Vec::new(),
1679 expr: Box::new(e),
1680 question_token: input.parse()?,
1681 });
1682 } else {
1683 break;
1684 }
1685 }
1686 Ok(e)
1687 }
1688
1689 #[cfg(not(feature = "full"))]
1690 fn trailer_expr(input: ParseStream) -> Result<Expr> {
1691 let mut e = atom_expr(input)?;
1692
1693 loop {
1694 if input.peek(token::Paren) {
1695 let content;
1696 e = Expr::Call(ExprCall {
1697 attrs: Vec::new(),
1698 func: Box::new(e),
1699 paren_token: parenthesized!(content in input),
1700 args: content.parse_terminated(Expr::parse, Token![,])?,
1701 });
1702 } else if input.peek(Token![.])
1703 && !input.peek(Token![..])
1704 && !input.peek2(Token![await])
1705 {
1706 let mut dot_token: Token![.] = input.parse()?;
1707
1708 let float_token: Option<LitFloat> = input.parse()?;
1709 if let Some(float_token) = float_token {
1710 if multi_index(&mut e, &mut dot_token, float_token)? {
1711 continue;
1712 }
1713 }
1714
1715 let member: Member = input.parse()?;
1716 let turbofish = if member.is_named() && input.peek(Token![::]) {
1717 let colon2_token: Token![::] = input.parse()?;
1718 let turbofish =
1719 AngleBracketedGenericArguments::do_parse(Some(colon2_token), input)?;
1720 Some(turbofish)
1721 } else {
1722 None
1723 };
1724
1725 if turbofish.is_some() || input.peek(token::Paren) {
1726 if let Member::Named(method) = member {
1727 let content;
1728 e = Expr::MethodCall(ExprMethodCall {
1729 attrs: Vec::new(),
1730 receiver: Box::new(e),
1731 dot_token,
1732 method,
1733 turbofish,
1734 paren_token: parenthesized!(content in input),
1735 args: content.parse_terminated(Expr::parse, Token![,])?,
1736 });
1737 continue;
1738 }
1739 }
1740
1741 e = Expr::Field(ExprField {
1742 attrs: Vec::new(),
1743 base: Box::new(e),
1744 dot_token,
1745 member,
1746 });
1747 } else if input.peek(token::Bracket) {
1748 let content;
1749 e = Expr::Index(ExprIndex {
1750 attrs: Vec::new(),
1751 expr: Box::new(e),
1752 bracket_token: bracketed!(content in input),
1753 index: content.parse()?,
1754 });
1755 } else {
1756 break;
1757 }
1758 }
1759
1760 Ok(e)
1761 }
1762
1763 #[cfg(feature = "full")]
1766 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1767 if input.peek(token::Group) {
1768 expr_group(input, allow_struct)
1769 } else if input.peek(Lit) {
1770 input.parse().map(Expr::Lit)
1771 } else if input.peek(Token![async])
1772 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1773 {
1774 input.parse().map(Expr::Async)
1775 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1776 input.parse().map(Expr::TryBlock)
1777 } else if input.peek(Token![|])
1778 || input.peek(Token![move])
1779 || input.peek(Token![for])
1780 && input.peek2(Token![<])
1781 && (input.peek3(Lifetime) || input.peek3(Token![>]))
1782 || input.peek(Token![const]) && !input.peek2(token::Brace)
1783 || input.peek(Token![static])
1784 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1785 {
1786 expr_closure(input, allow_struct).map(Expr::Closure)
1787 } else if token::parsing::peek_keyword(input.cursor(), "builtin") && input.peek2(Token![#])
1788 {
1789 expr_builtin(input)
1790 } else if input.peek(Ident)
1791 || input.peek(Token![::])
1792 || input.peek(Token![<])
1793 || input.peek(Token![self])
1794 || input.peek(Token![Self])
1795 || input.peek(Token![super])
1796 || input.peek(Token![crate])
1797 || input.peek(Token![try]) && (input.peek2(Token![!]) || input.peek2(Token![::]))
1798 {
1799 path_or_macro_or_struct(input, allow_struct)
1800 } else if input.peek(token::Paren) {
1801 paren_or_tuple(input)
1802 } else if input.peek(Token![break]) {
1803 expr_break(input, allow_struct).map(Expr::Break)
1804 } else if input.peek(Token![continue]) {
1805 input.parse().map(Expr::Continue)
1806 } else if input.peek(Token![return]) {
1807 input.parse().map(Expr::Return)
1808 } else if input.peek(Token![become]) {
1809 expr_become(input)
1810 } else if input.peek(token::Bracket) {
1811 array_or_repeat(input)
1812 } else if input.peek(Token![let]) {
1813 expr_let(input, allow_struct).map(Expr::Let)
1814 } else if input.peek(Token![if]) {
1815 input.parse().map(Expr::If)
1816 } else if input.peek(Token![while]) {
1817 input.parse().map(Expr::While)
1818 } else if input.peek(Token![for]) {
1819 input.parse().map(Expr::ForLoop)
1820 } else if input.peek(Token![loop]) {
1821 input.parse().map(Expr::Loop)
1822 } else if input.peek(Token![match]) {
1823 input.parse().map(Expr::Match)
1824 } else if input.peek(Token![yield]) {
1825 input.parse().map(Expr::Yield)
1826 } else if input.peek(Token![unsafe]) {
1827 input.parse().map(Expr::Unsafe)
1828 } else if input.peek(Token![const]) {
1829 input.parse().map(Expr::Const)
1830 } else if input.peek(token::Brace) {
1831 input.parse().map(Expr::Block)
1832 } else if input.peek(Token![..]) {
1833 expr_range(input, allow_struct).map(Expr::Range)
1834 } else if input.peek(Token![_]) {
1835 input.parse().map(Expr::Infer)
1836 } else if input.peek(Lifetime) {
1837 atom_labeled(input)
1838 } else {
1839 Err(input.error("expected an expression"))
1840 }
1841 }
1842
1843 #[cfg(feature = "full")]
1844 fn atom_labeled(input: ParseStream) -> Result<Expr> {
1845 let the_label: Label = input.parse()?;
1846 let mut expr = if input.peek(Token![while]) {
1847 Expr::While(input.parse()?)
1848 } else if input.peek(Token![for]) {
1849 Expr::ForLoop(input.parse()?)
1850 } else if input.peek(Token![loop]) {
1851 Expr::Loop(input.parse()?)
1852 } else if input.peek(token::Brace) {
1853 Expr::Block(input.parse()?)
1854 } else {
1855 return Err(input.error("expected loop or block expression"));
1856 };
1857 match &mut expr {
1858 Expr::While(ExprWhile { label, .. })
1859 | Expr::ForLoop(ExprForLoop { label, .. })
1860 | Expr::Loop(ExprLoop { label, .. })
1861 | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
1862 _ => unreachable!(),
1863 }
1864 Ok(expr)
1865 }
1866
1867 #[cfg(not(feature = "full"))]
1868 fn atom_expr(input: ParseStream) -> Result<Expr> {
1869 if input.peek(token::Group) {
1870 expr_group(input)
1871 } else if input.peek(Lit) {
1872 input.parse().map(Expr::Lit)
1873 } else if input.peek(token::Paren) {
1874 paren_or_tuple(input)
1875 } else if input.peek(Ident)
1876 || input.peek(Token![::])
1877 || input.peek(Token![<])
1878 || input.peek(Token![self])
1879 || input.peek(Token![Self])
1880 || input.peek(Token![super])
1881 || input.peek(Token![crate])
1882 {
1883 path_or_macro_or_struct(input)
1884 } else if input.is_empty() {
1885 Err(input.error("expected an expression"))
1886 } else {
1887 if input.peek(token::Brace) {
1888 let scan = input.fork();
1889 let content;
1890 braced!(content in scan);
1891 if content.parse::<Expr>().is_ok() && content.is_empty() {
1892 let expr_block = verbatim::between(input, &scan);
1893 input.advance_to(&scan);
1894 return Ok(Expr::Verbatim(expr_block));
1895 }
1896 }
1897 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1898 }
1899 }
1900
1901 #[cfg(feature = "full")]
1902 fn expr_builtin(input: ParseStream) -> Result<Expr> {
1903 let begin = input.fork();
1904
1905 token::parsing::keyword(input, "builtin")?;
1906 input.parse::<Token![#]>()?;
1907 input.parse::<Ident>()?;
1908
1909 let args;
1910 parenthesized!(args in input);
1911 args.parse::<TokenStream>()?;
1912
1913 Ok(Expr::Verbatim(verbatim::between(&begin, input)))
1914 }
1915
1916 fn path_or_macro_or_struct(
1917 input: ParseStream,
1918 #[cfg(feature = "full")] allow_struct: AllowStruct,
1919 ) -> Result<Expr> {
1920 let expr_style = true;
1921 let (qself, path) = path::parsing::qpath(input, expr_style)?;
1922 rest_of_path_or_macro_or_struct(
1923 qself,
1924 path,
1925 input,
1926 #[cfg(feature = "full")]
1927 allow_struct,
1928 )
1929 }
1930
1931 fn rest_of_path_or_macro_or_struct(
1932 qself: Option<QSelf>,
1933 path: Path,
1934 input: ParseStream,
1935 #[cfg(feature = "full")] allow_struct: AllowStruct,
1936 ) -> Result<Expr> {
1937 if qself.is_none()
1938 && input.peek(Token![!])
1939 && !input.peek(Token![!=])
1940 && path.is_mod_style()
1941 {
1942 let bang_token: Token![!] = input.parse()?;
1943 let (delimiter, tokens) = mac::parse_delimiter(input)?;
1944 return Ok(Expr::Macro(ExprMacro {
1945 attrs: Vec::new(),
1946 mac: Macro {
1947 path,
1948 bang_token,
1949 delimiter,
1950 tokens,
1951 },
1952 }));
1953 }
1954
1955 #[cfg(not(feature = "full"))]
1956 let allow_struct = (true,);
1957 if allow_struct.0 && input.peek(token::Brace) {
1958 return expr_struct_helper(input, qself, path).map(Expr::Struct);
1959 }
1960
1961 Ok(Expr::Path(ExprPath {
1962 attrs: Vec::new(),
1963 qself,
1964 path,
1965 }))
1966 }
1967
1968 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1969 impl Parse for ExprMacro {
1970 fn parse(input: ParseStream) -> Result<Self> {
1971 Ok(ExprMacro {
1972 attrs: Vec::new(),
1973 mac: input.parse()?,
1974 })
1975 }
1976 }
1977
1978 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1979 let content;
1980 let paren_token = parenthesized!(content in input);
1981 if content.is_empty() {
1982 return Ok(Expr::Tuple(ExprTuple {
1983 attrs: Vec::new(),
1984 paren_token,
1985 elems: Punctuated::new(),
1986 }));
1987 }
1988
1989 let first: Expr = content.parse()?;
1990 if content.is_empty() {
1991 return Ok(Expr::Paren(ExprParen {
1992 attrs: Vec::new(),
1993 paren_token,
1994 expr: Box::new(first),
1995 }));
1996 }
1997
1998 let mut elems = Punctuated::new();
1999 elems.push_value(first);
2000 while !content.is_empty() {
2001 let punct = content.parse()?;
2002 elems.push_punct(punct);
2003 if content.is_empty() {
2004 break;
2005 }
2006 let value = content.parse()?;
2007 elems.push_value(value);
2008 }
2009 Ok(Expr::Tuple(ExprTuple {
2010 attrs: Vec::new(),
2011 paren_token,
2012 elems,
2013 }))
2014 }
2015
2016 #[cfg(feature = "full")]
2017 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
2018 let content;
2019 let bracket_token = bracketed!(content in input);
2020 if content.is_empty() {
2021 return Ok(Expr::Array(ExprArray {
2022 attrs: Vec::new(),
2023 bracket_token,
2024 elems: Punctuated::new(),
2025 }));
2026 }
2027
2028 let first: Expr = content.parse()?;
2029 if content.is_empty() || content.peek(Token![,]) {
2030 let mut elems = Punctuated::new();
2031 elems.push_value(first);
2032 while !content.is_empty() {
2033 let punct = content.parse()?;
2034 elems.push_punct(punct);
2035 if content.is_empty() {
2036 break;
2037 }
2038 let value = content.parse()?;
2039 elems.push_value(value);
2040 }
2041 Ok(Expr::Array(ExprArray {
2042 attrs: Vec::new(),
2043 bracket_token,
2044 elems,
2045 }))
2046 } else if content.peek(Token![;]) {
2047 let semi_token: Token![;] = content.parse()?;
2048 let len: Expr = content.parse()?;
2049 Ok(Expr::Repeat(ExprRepeat {
2050 attrs: Vec::new(),
2051 bracket_token,
2052 expr: Box::new(first),
2053 semi_token,
2054 len: Box::new(len),
2055 }))
2056 } else {
2057 Err(content.error("expected `,` or `;`"))
2058 }
2059 }
2060
2061 #[cfg(feature = "full")]
2062 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2063 impl Parse for ExprArray {
2064 fn parse(input: ParseStream) -> Result<Self> {
2065 let content;
2066 let bracket_token = bracketed!(content in input);
2067 let mut elems = Punctuated::new();
2068
2069 while !content.is_empty() {
2070 let first: Expr = content.parse()?;
2071 elems.push_value(first);
2072 if content.is_empty() {
2073 break;
2074 }
2075 let punct = content.parse()?;
2076 elems.push_punct(punct);
2077 }
2078
2079 Ok(ExprArray {
2080 attrs: Vec::new(),
2081 bracket_token,
2082 elems,
2083 })
2084 }
2085 }
2086
2087 #[cfg(feature = "full")]
2088 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2089 impl Parse for ExprRepeat {
2090 fn parse(input: ParseStream) -> Result<Self> {
2091 let content;
2092 Ok(ExprRepeat {
2093 bracket_token: bracketed!(content in input),
2094 attrs: Vec::new(),
2095 expr: content.parse()?,
2096 semi_token: content.parse()?,
2097 len: content.parse()?,
2098 })
2099 }
2100 }
2101
2102 #[cfg(feature = "full")]
2103 fn continue_parsing_early(mut expr: &Expr) -> bool {
2104 while let Expr::Group(group) = expr {
2105 expr = &group.expr;
2106 }
2107 match expr {
2108 Expr::If(_)
2109 | Expr::While(_)
2110 | Expr::ForLoop(_)
2111 | Expr::Loop(_)
2112 | Expr::Match(_)
2113 | Expr::TryBlock(_)
2114 | Expr::Unsafe(_)
2115 | Expr::Const(_)
2116 | Expr::Block(_) => false,
2117 _ => true,
2118 }
2119 }
2120
2121 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2122 impl Parse for ExprLit {
2123 fn parse(input: ParseStream) -> Result<Self> {
2124 Ok(ExprLit {
2125 attrs: Vec::new(),
2126 lit: input.parse()?,
2127 })
2128 }
2129 }
2130
2131 fn expr_group(
2132 input: ParseStream,
2133 #[cfg(feature = "full")] allow_struct: AllowStruct,
2134 ) -> Result<Expr> {
2135 let group = crate::group::parse_group(input)?;
2136 let mut inner: Expr = group.content.parse()?;
2137
2138 match inner {
2139 Expr::Path(mut expr) if expr.attrs.is_empty() => {
2140 let grouped_len = expr.path.segments.len();
2141 Path::parse_rest(input, &mut expr.path, true)?;
2142 match rest_of_path_or_macro_or_struct(
2143 expr.qself,
2144 expr.path,
2145 input,
2146 #[cfg(feature = "full")]
2147 allow_struct,
2148 )? {
2149 Expr::Path(expr) if expr.path.segments.len() == grouped_len => {
2150 inner = Expr::Path(expr);
2151 }
2152 extended => return Ok(extended),
2153 }
2154 }
2155 _ => {}
2156 }
2157
2158 Ok(Expr::Group(ExprGroup {
2159 attrs: Vec::new(),
2160 group_token: group.token,
2161 expr: Box::new(inner),
2162 }))
2163 }
2164
2165 #[cfg(feature = "full")]
2166 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2167 impl Parse for ExprParen {
2168 fn parse(input: ParseStream) -> Result<Self> {
2169 let content;
2170 Ok(ExprParen {
2171 attrs: Vec::new(),
2172 paren_token: parenthesized!(content in input),
2173 expr: content.parse()?,
2174 })
2175 }
2176 }
2177
2178 #[cfg(feature = "full")]
2179 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2180 impl Parse for ExprLet {
2181 fn parse(input: ParseStream) -> Result<Self> {
2182 let allow_struct = AllowStruct(true);
2183 expr_let(input, allow_struct)
2184 }
2185 }
2186
2187 #[cfg(feature = "full")]
2188 fn expr_let(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprLet> {
2189 Ok(ExprLet {
2190 attrs: Vec::new(),
2191 let_token: input.parse()?,
2192 pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
2193 eq_token: input.parse()?,
2194 expr: Box::new({
2195 let lhs = unary_expr(input, allow_struct)?;
2196 parse_expr(input, lhs, allow_struct, Precedence::Compare)?
2197 }),
2198 })
2199 }
2200
2201 #[cfg(feature = "full")]
2202 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2203 impl Parse for ExprIf {
2204 fn parse(input: ParseStream) -> Result<Self> {
2205 let attrs = input.call(Attribute::parse_outer)?;
2206
2207 let mut clauses = Vec::new();
2208 let mut expr;
2209 loop {
2210 let if_token: Token![if] = input.parse()?;
2211 let cond = input.call(Expr::parse_without_eager_brace)?;
2212 let then_branch: Block = input.parse()?;
2213
2214 expr = ExprIf {
2215 attrs: Vec::new(),
2216 if_token,
2217 cond: Box::new(cond),
2218 then_branch,
2219 else_branch: None,
2220 };
2221
2222 if !input.peek(Token![else]) {
2223 break;
2224 }
2225
2226 let else_token: Token![else] = input.parse()?;
2227 let lookahead = input.lookahead1();
2228 if lookahead.peek(Token![if]) {
2229 expr.else_branch = Some((else_token, Box::new(Expr::PLACEHOLDER)));
2230 clauses.push(expr);
2231 continue;
2232 } else if lookahead.peek(token::Brace) {
2233 expr.else_branch = Some((
2234 else_token,
2235 Box::new(Expr::Block(ExprBlock {
2236 attrs: Vec::new(),
2237 label: None,
2238 block: input.parse()?,
2239 })),
2240 ));
2241 break;
2242 } else {
2243 return Err(lookahead.error());
2244 }
2245 }
2246
2247 while let Some(mut prev) = clauses.pop() {
2248 *prev.else_branch.as_mut().unwrap().1 = Expr::If(expr);
2249 expr = prev;
2250 }
2251 expr.attrs = attrs;
2252 Ok(expr)
2253 }
2254 }
2255
2256 #[cfg(feature = "full")]
2257 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2258 impl Parse for ExprInfer {
2259 fn parse(input: ParseStream) -> Result<Self> {
2260 Ok(ExprInfer {
2261 attrs: input.call(Attribute::parse_outer)?,
2262 underscore_token: input.parse()?,
2263 })
2264 }
2265 }
2266
2267 #[cfg(feature = "full")]
2268 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2269 impl Parse for ExprForLoop {
2270 fn parse(input: ParseStream) -> Result<Self> {
2271 let mut attrs = input.call(Attribute::parse_outer)?;
2272 let label: Option<Label> = input.parse()?;
2273 let for_token: Token![for] = input.parse()?;
2274
2275 let pat = Pat::parse_multi_with_leading_vert(input)?;
2276
2277 let in_token: Token![in] = input.parse()?;
2278 let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
2279
2280 let content;
2281 let brace_token = braced!(content in input);
2282 attr::parsing::parse_inner(&content, &mut attrs)?;
2283 let stmts = content.call(Block::parse_within)?;
2284
2285 Ok(ExprForLoop {
2286 attrs,
2287 label,
2288 for_token,
2289 pat: Box::new(pat),
2290 in_token,
2291 expr: Box::new(expr),
2292 body: Block { brace_token, stmts },
2293 })
2294 }
2295 }
2296
2297 #[cfg(feature = "full")]
2298 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2299 impl Parse for ExprLoop {
2300 fn parse(input: ParseStream) -> Result<Self> {
2301 let mut attrs = input.call(Attribute::parse_outer)?;
2302 let label: Option<Label> = input.parse()?;
2303 let loop_token: Token![loop] = input.parse()?;
2304
2305 let content;
2306 let brace_token = braced!(content in input);
2307 attr::parsing::parse_inner(&content, &mut attrs)?;
2308 let stmts = content.call(Block::parse_within)?;
2309
2310 Ok(ExprLoop {
2311 attrs,
2312 label,
2313 loop_token,
2314 body: Block { brace_token, stmts },
2315 })
2316 }
2317 }
2318
2319 #[cfg(feature = "full")]
2320 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2321 impl Parse for ExprMatch {
2322 fn parse(input: ParseStream) -> Result<Self> {
2323 let mut attrs = input.call(Attribute::parse_outer)?;
2324 let match_token: Token![match] = input.parse()?;
2325 let expr = Expr::parse_without_eager_brace(input)?;
2326
2327 let content;
2328 let brace_token = braced!(content in input);
2329 attr::parsing::parse_inner(&content, &mut attrs)?;
2330
2331 let mut arms = Vec::new();
2332 while !content.is_empty() {
2333 arms.push(content.call(Arm::parse)?);
2334 }
2335
2336 Ok(ExprMatch {
2337 attrs,
2338 match_token,
2339 expr: Box::new(expr),
2340 brace_token,
2341 arms,
2342 })
2343 }
2344 }
2345
2346 macro_rules! impl_by_parsing_expr {
2347 (
2348 $(
2349 $expr_type:ty, $variant:ident, $msg:expr,
2350 )*
2351 ) => {
2352 $(
2353 #[cfg(all(feature = "full", feature = "printing"))]
2354 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2355 impl Parse for $expr_type {
2356 fn parse(input: ParseStream) -> Result<Self> {
2357 let mut expr: Expr = input.parse()?;
2358 loop {
2359 match expr {
2360 Expr::$variant(inner) => return Ok(inner),
2361 Expr::Group(next) => expr = *next.expr,
2362 _ => return Err(Error::new_spanned(expr, $msg)),
2363 }
2364 }
2365 }
2366 }
2367 )*
2368 };
2369 }
2370
2371 impl_by_parsing_expr! {
2372 ExprAssign, Assign, "expected assignment expression",
2373 ExprAwait, Await, "expected await expression",
2374 ExprBinary, Binary, "expected binary operation",
2375 ExprCall, Call, "expected function call expression",
2376 ExprCast, Cast, "expected cast expression",
2377 ExprField, Field, "expected struct field access",
2378 ExprIndex, Index, "expected indexing expression",
2379 ExprMethodCall, MethodCall, "expected method call expression",
2380 ExprRange, Range, "expected range expression",
2381 ExprTry, Try, "expected try expression",
2382 ExprTuple, Tuple, "expected tuple expression",
2383 }
2384
2385 #[cfg(feature = "full")]
2386 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2387 impl Parse for ExprUnary {
2388 fn parse(input: ParseStream) -> Result<Self> {
2389 let attrs = Vec::new();
2390 let allow_struct = AllowStruct(true);
2391 expr_unary(input, attrs, allow_struct)
2392 }
2393 }
2394
2395 #[cfg(feature = "full")]
2396 fn expr_unary(
2397 input: ParseStream,
2398 attrs: Vec<Attribute>,
2399 allow_struct: AllowStruct,
2400 ) -> Result<ExprUnary> {
2401 Ok(ExprUnary {
2402 attrs,
2403 op: input.parse()?,
2404 expr: Box::new(unary_expr(input, allow_struct)?),
2405 })
2406 }
2407
2408 #[cfg(feature = "full")]
2409 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2410 impl Parse for ExprClosure {
2411 fn parse(input: ParseStream) -> Result<Self> {
2412 let allow_struct = AllowStruct(true);
2413 expr_closure(input, allow_struct)
2414 }
2415 }
2416
2417 #[cfg(feature = "full")]
2418 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2419 impl Parse for ExprRawAddr {
2420 fn parse(input: ParseStream) -> Result<Self> {
2421 let allow_struct = AllowStruct(true);
2422 Ok(ExprRawAddr {
2423 attrs: Vec::new(),
2424 and_token: input.parse()?,
2425 raw: input.parse()?,
2426 mutability: input.parse()?,
2427 expr: Box::new(unary_expr(input, allow_struct)?),
2428 })
2429 }
2430 }
2431
2432 #[cfg(feature = "full")]
2433 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2434 impl Parse for ExprReference {
2435 fn parse(input: ParseStream) -> Result<Self> {
2436 let allow_struct = AllowStruct(true);
2437 Ok(ExprReference {
2438 attrs: Vec::new(),
2439 and_token: input.parse()?,
2440 mutability: input.parse()?,
2441 expr: Box::new(unary_expr(input, allow_struct)?),
2442 })
2443 }
2444 }
2445
2446 #[cfg(feature = "full")]
2447 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2448 impl Parse for ExprBreak {
2449 fn parse(input: ParseStream) -> Result<Self> {
2450 let allow_struct = AllowStruct(true);
2451 expr_break(input, allow_struct)
2452 }
2453 }
2454
2455 #[cfg(feature = "full")]
2456 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2457 impl Parse for ExprReturn {
2458 fn parse(input: ParseStream) -> Result<Self> {
2459 Ok(ExprReturn {
2460 attrs: Vec::new(),
2461 return_token: input.parse()?,
2462 expr: {
2463 if Expr::peek(input) {
2464 Some(input.parse()?)
2465 } else {
2466 None
2467 }
2468 },
2469 })
2470 }
2471 }
2472
2473 #[cfg(feature = "full")]
2474 fn expr_become(input: ParseStream) -> Result<Expr> {
2475 let begin = input.fork();
2476 input.parse::<Token![become]>()?;
2477 input.parse::<Expr>()?;
2478 Ok(Expr::Verbatim(verbatim::between(&begin, input)))
2479 }
2480
2481 #[cfg(feature = "full")]
2482 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2483 impl Parse for ExprTryBlock {
2484 fn parse(input: ParseStream) -> Result<Self> {
2485 Ok(ExprTryBlock {
2486 attrs: Vec::new(),
2487 try_token: input.parse()?,
2488 block: input.parse()?,
2489 })
2490 }
2491 }
2492
2493 #[cfg(feature = "full")]
2494 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2495 impl Parse for ExprYield {
2496 fn parse(input: ParseStream) -> Result<Self> {
2497 Ok(ExprYield {
2498 attrs: Vec::new(),
2499 yield_token: input.parse()?,
2500 expr: {
2501 if Expr::peek(input) {
2502 Some(input.parse()?)
2503 } else {
2504 None
2505 }
2506 },
2507 })
2508 }
2509 }
2510
2511 #[cfg(feature = "full")]
2512 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
2513 let lifetimes: Option<BoundLifetimes> = input.parse()?;
2514 let constness: Option<Token![const]> = input.parse()?;
2515 let movability: Option<Token![static]> = input.parse()?;
2516 let asyncness: Option<Token![async]> = input.parse()?;
2517 let capture: Option<Token![move]> = input.parse()?;
2518 let or1_token: Token![|] = input.parse()?;
2519
2520 let mut inputs = Punctuated::new();
2521 loop {
2522 if input.peek(Token![|]) {
2523 break;
2524 }
2525 let value = closure_arg(input)?;
2526 inputs.push_value(value);
2527 if input.peek(Token![|]) {
2528 break;
2529 }
2530 let punct: Token![,] = input.parse()?;
2531 inputs.push_punct(punct);
2532 }
2533
2534 let or2_token: Token![|] = input.parse()?;
2535
2536 let (output, body) = if input.peek(Token![->]) {
2537 let arrow_token: Token![->] = input.parse()?;
2538 let ty: Type = input.parse()?;
2539 let body: Block = input.parse()?;
2540 let output = ReturnType::Type(arrow_token, Box::new(ty));
2541 let block = Expr::Block(ExprBlock {
2542 attrs: Vec::new(),
2543 label: None,
2544 block: body,
2545 });
2546 (output, block)
2547 } else {
2548 let body = ambiguous_expr(input, allow_struct)?;
2549 (ReturnType::Default, body)
2550 };
2551
2552 Ok(ExprClosure {
2553 attrs: Vec::new(),
2554 lifetimes,
2555 constness,
2556 movability,
2557 asyncness,
2558 capture,
2559 or1_token,
2560 inputs,
2561 or2_token,
2562 output,
2563 body: Box::new(body),
2564 })
2565 }
2566
2567 #[cfg(feature = "full")]
2568 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2569 impl Parse for ExprAsync {
2570 fn parse(input: ParseStream) -> Result<Self> {
2571 Ok(ExprAsync {
2572 attrs: Vec::new(),
2573 async_token: input.parse()?,
2574 capture: input.parse()?,
2575 block: input.parse()?,
2576 })
2577 }
2578 }
2579
2580 #[cfg(feature = "full")]
2581 fn closure_arg(input: ParseStream) -> Result<Pat> {
2582 let attrs = input.call(Attribute::parse_outer)?;
2583 let mut pat = Pat::parse_single(input)?;
2584
2585 if input.peek(Token![:]) {
2586 Ok(Pat::Type(PatType {
2587 attrs,
2588 pat: Box::new(pat),
2589 colon_token: input.parse()?,
2590 ty: input.parse()?,
2591 }))
2592 } else {
2593 match &mut pat {
2594 Pat::Const(pat) => pat.attrs = attrs,
2595 Pat::Ident(pat) => pat.attrs = attrs,
2596 Pat::Lit(pat) => pat.attrs = attrs,
2597 Pat::Macro(pat) => pat.attrs = attrs,
2598 Pat::Or(pat) => pat.attrs = attrs,
2599 Pat::Paren(pat) => pat.attrs = attrs,
2600 Pat::Path(pat) => pat.attrs = attrs,
2601 Pat::Range(pat) => pat.attrs = attrs,
2602 Pat::Reference(pat) => pat.attrs = attrs,
2603 Pat::Rest(pat) => pat.attrs = attrs,
2604 Pat::Slice(pat) => pat.attrs = attrs,
2605 Pat::Struct(pat) => pat.attrs = attrs,
2606 Pat::Tuple(pat) => pat.attrs = attrs,
2607 Pat::TupleStruct(pat) => pat.attrs = attrs,
2608 Pat::Type(_) => unreachable!(),
2609 Pat::Verbatim(_) => {}
2610 Pat::Wild(pat) => pat.attrs = attrs,
2611 }
2612 Ok(pat)
2613 }
2614 }
2615
2616 #[cfg(feature = "full")]
2617 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2618 impl Parse for ExprWhile {
2619 fn parse(input: ParseStream) -> Result<Self> {
2620 let mut attrs = input.call(Attribute::parse_outer)?;
2621 let label: Option<Label> = input.parse()?;
2622 let while_token: Token![while] = input.parse()?;
2623 let cond = Expr::parse_without_eager_brace(input)?;
2624
2625 let content;
2626 let brace_token = braced!(content in input);
2627 attr::parsing::parse_inner(&content, &mut attrs)?;
2628 let stmts = content.call(Block::parse_within)?;
2629
2630 Ok(ExprWhile {
2631 attrs,
2632 label,
2633 while_token,
2634 cond: Box::new(cond),
2635 body: Block { brace_token, stmts },
2636 })
2637 }
2638 }
2639
2640 #[cfg(feature = "full")]
2641 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2642 impl Parse for ExprConst {
2643 fn parse(input: ParseStream) -> Result<Self> {
2644 let const_token: Token![const] = input.parse()?;
2645
2646 let content;
2647 let brace_token = braced!(content in input);
2648 let inner_attrs = content.call(Attribute::parse_inner)?;
2649 let stmts = content.call(Block::parse_within)?;
2650
2651 Ok(ExprConst {
2652 attrs: inner_attrs,
2653 const_token,
2654 block: Block { brace_token, stmts },
2655 })
2656 }
2657 }
2658
2659 #[cfg(feature = "full")]
2660 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2661 impl Parse for Label {
2662 fn parse(input: ParseStream) -> Result<Self> {
2663 Ok(Label {
2664 name: input.parse()?,
2665 colon_token: input.parse()?,
2666 })
2667 }
2668 }
2669
2670 #[cfg(feature = "full")]
2671 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2672 impl Parse for Option<Label> {
2673 fn parse(input: ParseStream) -> Result<Self> {
2674 if input.peek(Lifetime) {
2675 input.parse().map(Some)
2676 } else {
2677 Ok(None)
2678 }
2679 }
2680 }
2681
2682 #[cfg(feature = "full")]
2683 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2684 impl Parse for ExprContinue {
2685 fn parse(input: ParseStream) -> Result<Self> {
2686 Ok(ExprContinue {
2687 attrs: Vec::new(),
2688 continue_token: input.parse()?,
2689 label: input.parse()?,
2690 })
2691 }
2692 }
2693
2694 #[cfg(feature = "full")]
2695 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2696 let break_token: Token![break] = input.parse()?;
2697
2698 let ahead = input.fork();
2699 let label: Option<Lifetime> = ahead.parse()?;
2700 if label.is_some() && ahead.peek(Token![:]) {
2701 let _: Expr = input.parse()?;
2704 let start_span = label.unwrap().apostrophe;
2705 let end_span = input.cursor().prev_span();
2706 return Err(crate::error::new2(
2707 start_span,
2708 end_span,
2709 "parentheses required",
2710 ));
2711 }
2712
2713 input.advance_to(&ahead);
2714 let expr = if Expr::peek(input) && (allow_struct.0 || !input.peek(token::Brace)) {
2715 Some(input.parse()?)
2716 } else {
2717 None
2718 };
2719
2720 Ok(ExprBreak {
2721 attrs: Vec::new(),
2722 break_token,
2723 label,
2724 expr,
2725 })
2726 }
2727
2728 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2729 impl Parse for FieldValue {
2730 fn parse(input: ParseStream) -> Result<Self> {
2731 let attrs = input.call(Attribute::parse_outer)?;
2732 let member: Member = input.parse()?;
2733 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2734 let colon_token: Token![:] = input.parse()?;
2735 let value: Expr = input.parse()?;
2736 (Some(colon_token), value)
2737 } else if let Member::Named(ident) = &member {
2738 let value = Expr::Path(ExprPath {
2739 attrs: Vec::new(),
2740 qself: None,
2741 path: Path::from(ident.clone()),
2742 });
2743 (None, value)
2744 } else {
2745 unreachable!()
2746 };
2747
2748 Ok(FieldValue {
2749 attrs,
2750 member,
2751 colon_token,
2752 expr: value,
2753 })
2754 }
2755 }
2756
2757 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2758 impl Parse for ExprStruct {
2759 fn parse(input: ParseStream) -> Result<Self> {
2760 let expr_style = true;
2761 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2762 expr_struct_helper(input, qself, path)
2763 }
2764 }
2765
2766 fn expr_struct_helper(
2767 input: ParseStream,
2768 qself: Option<QSelf>,
2769 path: Path,
2770 ) -> Result<ExprStruct> {
2771 let content;
2772 let brace_token = braced!(content in input);
2773
2774 let mut fields = Punctuated::new();
2775 while !content.is_empty() {
2776 if content.peek(Token![..]) {
2777 return Ok(ExprStruct {
2778 attrs: Vec::new(),
2779 qself,
2780 path,
2781 brace_token,
2782 fields,
2783 dot2_token: Some(content.parse()?),
2784 rest: if content.is_empty() {
2785 None
2786 } else {
2787 Some(Box::new(content.parse()?))
2788 },
2789 });
2790 }
2791
2792 fields.push(content.parse()?);
2793 if content.is_empty() {
2794 break;
2795 }
2796 let punct: Token![,] = content.parse()?;
2797 fields.push_punct(punct);
2798 }
2799
2800 Ok(ExprStruct {
2801 attrs: Vec::new(),
2802 qself,
2803 path,
2804 brace_token,
2805 fields,
2806 dot2_token: None,
2807 rest: None,
2808 })
2809 }
2810
2811 #[cfg(feature = "full")]
2812 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2813 impl Parse for ExprUnsafe {
2814 fn parse(input: ParseStream) -> Result<Self> {
2815 let unsafe_token: Token![unsafe] = input.parse()?;
2816
2817 let content;
2818 let brace_token = braced!(content in input);
2819 let inner_attrs = content.call(Attribute::parse_inner)?;
2820 let stmts = content.call(Block::parse_within)?;
2821
2822 Ok(ExprUnsafe {
2823 attrs: inner_attrs,
2824 unsafe_token,
2825 block: Block { brace_token, stmts },
2826 })
2827 }
2828 }
2829
2830 #[cfg(feature = "full")]
2831 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2832 impl Parse for ExprBlock {
2833 fn parse(input: ParseStream) -> Result<Self> {
2834 let mut attrs = input.call(Attribute::parse_outer)?;
2835 let label: Option<Label> = input.parse()?;
2836
2837 let content;
2838 let brace_token = braced!(content in input);
2839 attr::parsing::parse_inner(&content, &mut attrs)?;
2840 let stmts = content.call(Block::parse_within)?;
2841
2842 Ok(ExprBlock {
2843 attrs,
2844 label,
2845 block: Block { brace_token, stmts },
2846 })
2847 }
2848 }
2849
2850 #[cfg(feature = "full")]
2851 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2852 let limits: RangeLimits = input.parse()?;
2853 let end = parse_range_end(input, &limits, allow_struct)?;
2854 Ok(ExprRange {
2855 attrs: Vec::new(),
2856 start: None,
2857 limits,
2858 end,
2859 })
2860 }
2861
2862 #[cfg(feature = "full")]
2863 fn parse_range_end(
2864 input: ParseStream,
2865 limits: &RangeLimits,
2866 allow_struct: AllowStruct,
2867 ) -> Result<Option<Box<Expr>>> {
2868 if matches!(limits, RangeLimits::HalfOpen(_))
2869 && (input.is_empty()
2870 || input.peek(Token![,])
2871 || input.peek(Token![;])
2872 || input.peek(Token![.]) && !input.peek(Token![..])
2873 || !allow_struct.0 && input.peek(token::Brace))
2874 {
2875 Ok(None)
2876 } else {
2877 let end = parse_binop_rhs(input, allow_struct, Precedence::Range)?;
2878 Ok(Some(end))
2879 }
2880 }
2881
2882 #[cfg(feature = "full")]
2883 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2884 impl Parse for RangeLimits {
2885 fn parse(input: ParseStream) -> Result<Self> {
2886 let lookahead = input.lookahead1();
2887 let dot_dot = lookahead.peek(Token![..]);
2888 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2889 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2890 if dot_dot_eq {
2891 input.parse().map(RangeLimits::Closed)
2892 } else if dot_dot && !dot_dot_dot {
2893 input.parse().map(RangeLimits::HalfOpen)
2894 } else {
2895 Err(lookahead.error())
2896 }
2897 }
2898 }
2899
2900 #[cfg(feature = "full")]
2901 impl RangeLimits {
2902 pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> {
2903 let lookahead = input.lookahead1();
2904 let dot_dot = lookahead.peek(Token![..]);
2905 let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
2906 let dot_dot_dot = dot_dot && input.peek(Token![...]);
2907 if dot_dot_eq {
2908 input.parse().map(RangeLimits::Closed)
2909 } else if dot_dot_dot {
2910 let dot3: Token![...] = input.parse()?;
2911 Ok(RangeLimits::Closed(Token))
2912 } else if dot_dot {
2913 input.parse().map(RangeLimits::HalfOpen)
2914 } else {
2915 Err(lookahead.error())
2916 }
2917 }
2918 }
2919
2920 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2921 impl Parse for ExprPath {
2922 fn parse(input: ParseStream) -> Result<Self> {
2923 #[cfg(not(feature = "full"))]
2924 let attrs = Vec::new();
2925 #[cfg(feature = "full")]
2926 let attrs = input.call(Attribute::parse_outer)?;
2927
2928 let expr_style = true;
2929 let (qself, path) = path::parsing::qpath(input, expr_style)?;
2930
2931 Ok(ExprPath { attrs, qself, path })
2932 }
2933 }
2934
2935 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2936 impl Parse for Member {
2937 fn parse(input: ParseStream) -> Result<Self> {
2938 if input.peek(Ident) {
2939 input.parse().map(Member::Named)
2940 } else if input.peek(LitInt) {
2941 input.parse().map(Member::Unnamed)
2942 } else {
2943 Err(input.error("expected identifier or integer"))
2944 }
2945 }
2946 }
2947
2948 #[cfg(feature = "full")]
2949 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2950 impl Parse for Arm {
2951 fn parse(input: ParseStream) -> Result<Arm> {
2952 let requires_comma;
2953 Ok(Arm {
2954 attrs: input.call(Attribute::parse_outer)?,
2955 pat: Pat::parse_multi_with_leading_vert(input)?,
2956 guard: {
2957 if input.peek(Token![if]) {
2958 let if_token: Token![if] = input.parse()?;
2959 let guard: Expr = input.parse()?;
2960 Some((if_token, Box::new(guard)))
2961 } else {
2962 None
2963 }
2964 },
2965 fat_arrow_token: input.parse()?,
2966 body: {
2967 let body = Expr::parse_with_earlier_boundary_rule(input)?;
2968 requires_comma = classify::requires_comma_to_be_match_arm(&body);
2969 Box::new(body)
2970 },
2971 comma: {
2972 if requires_comma && !input.is_empty() {
2973 Some(input.parse()?)
2974 } else {
2975 input.parse()?
2976 }
2977 },
2978 })
2979 }
2980 }
2981
2982 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
2983 impl Parse for Index {
2984 fn parse(input: ParseStream) -> Result<Self> {
2985 let lit: LitInt = input.parse()?;
2986 if lit.suffix().is_empty() {
2987 Ok(Index {
2988 index: lit
2989 .base10_digits()
2990 .parse()
2991 .map_err(|err| Error::new(lit.span(), err))?,
2992 span: lit.span(),
2993 })
2994 } else {
2995 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2996 }
2997 }
2998 }
2999
3000 fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
3001 let float_token = float.token();
3002 let float_span = float_token.span();
3003 let mut float_repr = float_token.to_string();
3004 let trailing_dot = float_repr.ends_with('.');
3005 if trailing_dot {
3006 float_repr.truncate(float_repr.len() - 1);
3007 }
3008
3009 let mut offset = 0;
3010 for part in float_repr.split('.') {
3011 let mut index: Index =
3012 crate::parse_str(part).map_err(|err| Error::new(float_span, err))?;
3013 let part_end = offset + part.len();
3014 index.span = float_token.subspan(offset..part_end).unwrap_or(float_span);
3015
3016 let base = mem::replace(e, Expr::PLACEHOLDER);
3017 *e = Expr::Field(ExprField {
3018 attrs: Vec::new(),
3019 base: Box::new(base),
3020 dot_token: Token,
3021 member: Member::Unnamed(index),
3022 });
3023
3024 let dot_span = float_token
3025 .subspan(part_end..part_end + 1)
3026 .unwrap_or(float_span);
3027 *dot_token = Token;
3028 offset = part_end + 1;
3029 }
3030
3031 Ok(!trailing_dot)
3032 }
3033
3034 #[cfg(feature = "full")]
3035 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
3036 impl Parse for PointerMutability {
3037 fn parse(input: ParseStream) -> Result<Self> {
3038 let lookahead = input.lookahead1();
3039 if lookahead.peek(Token![const]) {
3040 Ok(PointerMutability::Const(input.parse()?))
3041 } else if lookahead.peek(Token![mut]) {
3042 Ok(PointerMutability::Mut(input.parse()?))
3043 } else {
3044 Err(lookahead.error())
3045 }
3046 }
3047 }
3048
3049 fn check_cast(input: ParseStream) -> Result<()> {
3050 let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
3051 if input.peek2(Token![await]) {
3052 "`.await`"
3053 } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
3054 "a method call"
3055 } else {
3056 "a field access"
3057 }
3058 } else if input.peek(Token![?]) {
3059 "`?`"
3060 } else if input.peek(token::Bracket) {
3061 "indexing"
3062 } else if input.peek(token::Paren) {
3063 "a function call"
3064 } else {
3065 return Ok(());
3066 };
3067 let msg = format!("casts cannot be followed by {}", kind);
3068 Err(input.error(msg))
3069 }
3070}
3071
3072#[cfg(feature = "printing")]
3073pub(crate) mod printing {
3074 use crate::attr::Attribute;
3075 #[cfg(feature = "full")]
3076 use crate::attr::FilterAttrs;
3077 #[cfg(feature = "full")]
3078 use crate::classify;
3079 #[cfg(feature = "full")]
3080 use crate::expr::{
3081 Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
3082 ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
3083 ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
3084 ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
3085 };
3086 use crate::expr::{
3087 Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
3088 ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprTuple, ExprUnary,
3089 FieldValue, Index, Member,
3090 };
3091 use crate::fixup::FixupContext;
3092 use crate::op::BinOp;
3093 use crate::path;
3094 use crate::path::printing::PathStyle;
3095 use crate::precedence::Precedence;
3096 use crate::token;
3097 #[cfg(feature = "full")]
3098 use crate::ty::ReturnType;
3099 use proc_macro2::{Literal, Span, TokenStream};
3100 use quote::{ToTokens, TokenStreamExt};
3101
3102 #[cfg(feature = "full")]
3103 pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3104 tokens.append_all(attrs.outer());
3105 }
3106
3107 #[cfg(feature = "full")]
3108 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3109 tokens.append_all(attrs.inner());
3110 }
3111
3112 #[cfg(not(feature = "full"))]
3113 pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3114
3115 #[cfg(feature = "full")]
3116 fn print_condition(expr: &Expr, tokens: &mut TokenStream) {
3117 print_subexpression(
3118 expr,
3119 classify::confusable_with_adjacent_block(expr),
3120 tokens,
3121 FixupContext::new_condition(),
3122 );
3123 }
3124
3125 fn print_subexpression(
3126 expr: &Expr,
3127 needs_group: bool,
3128 tokens: &mut TokenStream,
3129 mut fixup: FixupContext,
3130 ) {
3131 if needs_group {
3132 fixup = FixupContext::NONE;
3144 }
3145
3146 let do_print_expr = |tokens: &mut TokenStream| print_expr(expr, tokens, fixup);
3147
3148 if needs_group {
3149 token::Paren::default().surround(tokens, do_print_expr);
3150 } else {
3151 do_print_expr(tokens);
3152 }
3153 }
3154
3155 pub(crate) fn print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext) {
3156 #[cfg(feature = "full")]
3157 let needs_group = fixup.would_cause_statement_boundary(expr);
3158 #[cfg(not(feature = "full"))]
3159 let needs_group = false;
3160
3161 if needs_group {
3162 fixup = FixupContext::NONE;
3163 }
3164
3165 let do_print_expr = |tokens: &mut TokenStream| match expr {
3166 #[cfg(feature = "full")]
3167 Expr::Array(e) => e.to_tokens(tokens),
3168 #[cfg(feature = "full")]
3169 Expr::Assign(e) => print_expr_assign(e, tokens, fixup),
3170 #[cfg(feature = "full")]
3171 Expr::Async(e) => e.to_tokens(tokens),
3172 #[cfg(feature = "full")]
3173 Expr::Await(e) => print_expr_await(e, tokens, fixup),
3174 Expr::Binary(e) => print_expr_binary(e, tokens, fixup),
3175 #[cfg(feature = "full")]
3176 Expr::Block(e) => e.to_tokens(tokens),
3177 #[cfg(feature = "full")]
3178 Expr::Break(e) => print_expr_break(e, tokens, fixup),
3179 Expr::Call(e) => print_expr_call(e, tokens, fixup),
3180 Expr::Cast(e) => print_expr_cast(e, tokens, fixup),
3181 #[cfg(feature = "full")]
3182 Expr::Closure(e) => e.to_tokens(tokens),
3183 #[cfg(feature = "full")]
3184 Expr::Const(e) => e.to_tokens(tokens),
3185 #[cfg(feature = "full")]
3186 Expr::Continue(e) => e.to_tokens(tokens),
3187 Expr::Field(e) => print_expr_field(e, tokens, fixup),
3188 #[cfg(feature = "full")]
3189 Expr::ForLoop(e) => e.to_tokens(tokens),
3190 Expr::Group(e) => e.to_tokens(tokens),
3191 #[cfg(feature = "full")]
3192 Expr::If(e) => e.to_tokens(tokens),
3193 #[cfg(feature = "full")]
3194 Expr::Index(e) => print_expr_index(e, tokens, fixup),
3195 #[cfg(feature = "full")]
3196 Expr::Infer(e) => e.to_tokens(tokens),
3197 #[cfg(feature = "full")]
3198 Expr::Let(e) => print_expr_let(e, tokens, fixup),
3199 Expr::Lit(e) => e.to_tokens(tokens),
3200 #[cfg(feature = "full")]
3201 Expr::Loop(e) => e.to_tokens(tokens),
3202 Expr::Macro(e) => e.to_tokens(tokens),
3203 #[cfg(feature = "full")]
3204 Expr::Match(e) => e.to_tokens(tokens),
3205 Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup),
3206 Expr::Paren(e) => e.to_tokens(tokens),
3207 Expr::Path(e) => e.to_tokens(tokens),
3208 #[cfg(feature = "full")]
3209 Expr::Range(e) => print_expr_range(e, tokens, fixup),
3210 #[cfg(feature = "full")]
3211 Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup),
3212 Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
3213 #[cfg(feature = "full")]
3214 Expr::Repeat(e) => e.to_tokens(tokens),
3215 #[cfg(feature = "full")]
3216 Expr::Return(e) => print_expr_return(e, tokens, fixup),
3217 Expr::Struct(e) => e.to_tokens(tokens),
3218 #[cfg(feature = "full")]
3219 Expr::Try(e) => print_expr_try(e, tokens, fixup),
3220 #[cfg(feature = "full")]
3221 Expr::TryBlock(e) => e.to_tokens(tokens),
3222 #[cfg(feature = "full")]
3223 Expr::Tuple(e) => e.to_tokens(tokens),
3224 Expr::Unary(e) => print_expr_unary(e, tokens, fixup),
3225 #[cfg(feature = "full")]
3226 Expr::Unsafe(e) => e.to_tokens(tokens),
3227 Expr::Verbatim(e) => e.to_tokens(tokens),
3228 #[cfg(feature = "full")]
3229 Expr::While(e) => e.to_tokens(tokens),
3230 #[cfg(feature = "full")]
3231 Expr::Yield(e) => print_expr_yield(e, tokens, fixup),
3232
3233 #[cfg(not(feature = "full"))]
3234 _ => unreachable!(),
3235 };
3236
3237 if needs_group {
3238 token::Paren::default().surround(tokens, do_print_expr);
3239 } else {
3240 do_print_expr(tokens);
3241 }
3242 }
3243
3244 #[cfg(feature = "full")]
3245 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3246 impl ToTokens for ExprArray {
3247 fn to_tokens(&self, tokens: &mut TokenStream) {
3248 outer_attrs_to_tokens(&self.attrs, tokens);
3249 self.bracket_token.surround(tokens, |tokens| {
3250 self.elems.to_tokens(tokens);
3251 });
3252 }
3253 }
3254
3255 #[cfg(feature = "full")]
3256 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3257 impl ToTokens for ExprAssign {
3258 fn to_tokens(&self, tokens: &mut TokenStream) {
3259 print_expr_assign(self, tokens, FixupContext::NONE);
3260 }
3261 }
3262
3263 #[cfg(feature = "full")]
3264 fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, fixup: FixupContext) {
3265 outer_attrs_to_tokens(&e.attrs, tokens);
3266 print_subexpression(
3267 &e.left,
3268 Precedence::of(&e.left) <= Precedence::Range,
3269 tokens,
3270 fixup.leftmost_subexpression(),
3271 );
3272 e.eq_token.to_tokens(tokens);
3273 print_subexpression(
3274 &e.right,
3275 fixup.trailing_precedence(&e.right) < Precedence::Assign,
3276 tokens,
3277 fixup.subsequent_subexpression(),
3278 );
3279 }
3280
3281 #[cfg(feature = "full")]
3282 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3283 impl ToTokens for ExprAsync {
3284 fn to_tokens(&self, tokens: &mut TokenStream) {
3285 outer_attrs_to_tokens(&self.attrs, tokens);
3286 self.async_token.to_tokens(tokens);
3287 self.capture.to_tokens(tokens);
3288 self.block.to_tokens(tokens);
3289 }
3290 }
3291
3292 #[cfg(feature = "full")]
3293 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3294 impl ToTokens for ExprAwait {
3295 fn to_tokens(&self, tokens: &mut TokenStream) {
3296 print_expr_await(self, tokens, FixupContext::NONE);
3297 }
3298 }
3299
3300 #[cfg(feature = "full")]
3301 fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) {
3302 outer_attrs_to_tokens(&e.attrs, tokens);
3303 print_subexpression(
3304 &e.base,
3305 Precedence::of(&e.base) < Precedence::Unambiguous,
3306 tokens,
3307 fixup.leftmost_subexpression_with_dot(),
3308 );
3309 e.dot_token.to_tokens(tokens);
3310 e.await_token.to_tokens(tokens);
3311 }
3312
3313 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3314 impl ToTokens for ExprBinary {
3315 fn to_tokens(&self, tokens: &mut TokenStream) {
3316 print_expr_binary(self, tokens, FixupContext::NONE);
3317 }
3318 }
3319
3320 fn print_expr_binary(e: &ExprBinary, tokens: &mut TokenStream, fixup: FixupContext) {
3321 outer_attrs_to_tokens(&e.attrs, tokens);
3322
3323 let left_fixup = fixup.leftmost_subexpression_with_begin_operator(
3324 #[cfg(feature = "full")]
3325 match &e.op {
3326 BinOp::Sub(_)
3327 | BinOp::Mul(_)
3328 | BinOp::And(_)
3329 | BinOp::Or(_)
3330 | BinOp::BitAnd(_)
3331 | BinOp::BitOr(_)
3332 | BinOp::Shl(_)
3333 | BinOp::Lt(_) => true,
3334 _ => false,
3335 },
3336 match &e.op {
3337 BinOp::Shl(_) | BinOp::Lt(_) => true,
3338 _ => false,
3339 },
3340 );
3341
3342 let binop_prec = Precedence::of_binop(&e.op);
3343 let left_prec = left_fixup.leading_precedence(&e.left);
3344 let right_prec = fixup.trailing_precedence(&e.right);
3345 let (left_needs_group, right_needs_group) = match binop_prec {
3346 Precedence::Assign => (left_prec <= Precedence::Range, right_prec < binop_prec),
3347 Precedence::Compare => (left_prec <= binop_prec, right_prec <= binop_prec),
3348 _ => (left_prec < binop_prec, right_prec <= binop_prec),
3349 };
3350
3351 print_subexpression(&e.left, left_needs_group, tokens, left_fixup);
3352 e.op.to_tokens(tokens);
3353 print_subexpression(
3354 &e.right,
3355 right_needs_group,
3356 tokens,
3357 fixup.subsequent_subexpression(),
3358 );
3359 }
3360
3361 #[cfg(feature = "full")]
3362 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3363 impl ToTokens for ExprBlock {
3364 fn to_tokens(&self, tokens: &mut TokenStream) {
3365 outer_attrs_to_tokens(&self.attrs, tokens);
3366 self.label.to_tokens(tokens);
3367 self.block.brace_token.surround(tokens, |tokens| {
3368 inner_attrs_to_tokens(&self.attrs, tokens);
3369 tokens.append_all(&self.block.stmts);
3370 });
3371 }
3372 }
3373
3374 #[cfg(feature = "full")]
3375 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3376 impl ToTokens for ExprBreak {
3377 fn to_tokens(&self, tokens: &mut TokenStream) {
3378 print_expr_break(self, tokens, FixupContext::NONE);
3379 }
3380 }
3381
3382 #[cfg(feature = "full")]
3383 fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) {
3384 outer_attrs_to_tokens(&e.attrs, tokens);
3385 e.break_token.to_tokens(tokens);
3386 e.label.to_tokens(tokens);
3387 if let Some(value) = &e.expr {
3388 print_subexpression(
3389 value,
3390 e.label.is_none() && classify::expr_leading_label(value),
3393 tokens,
3394 fixup.subsequent_subexpression(),
3395 );
3396 }
3397 }
3398
3399 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3400 impl ToTokens for ExprCall {
3401 fn to_tokens(&self, tokens: &mut TokenStream) {
3402 print_expr_call(self, tokens, FixupContext::NONE);
3403 }
3404 }
3405
3406 fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) {
3407 outer_attrs_to_tokens(&e.attrs, tokens);
3408
3409 let func_fixup = fixup.leftmost_subexpression_with_begin_operator(
3410 #[cfg(feature = "full")]
3411 true,
3412 false,
3413 );
3414 let needs_group = if let Expr::Field(func) = &*e.func {
3415 func.member.is_named()
3416 } else {
3417 func_fixup.leading_precedence(&e.func) < Precedence::Unambiguous
3418 };
3419 print_subexpression(&e.func, needs_group, tokens, func_fixup);
3420
3421 e.paren_token.surround(tokens, |tokens| {
3422 e.args.to_tokens(tokens);
3423 });
3424 }
3425
3426 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3427 impl ToTokens for ExprCast {
3428 fn to_tokens(&self, tokens: &mut TokenStream) {
3429 print_expr_cast(self, tokens, FixupContext::NONE);
3430 }
3431 }
3432
3433 fn print_expr_cast(e: &ExprCast, tokens: &mut TokenStream, fixup: FixupContext) {
3434 outer_attrs_to_tokens(&e.attrs, tokens);
3435 print_subexpression(
3436 &e.expr,
3437 Precedence::of(&e.expr) < Precedence::Cast,
3438 tokens,
3439 fixup.leftmost_subexpression(),
3440 );
3441 e.as_token.to_tokens(tokens);
3442 e.ty.to_tokens(tokens);
3443 }
3444
3445 #[cfg(feature = "full")]
3446 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3447 impl ToTokens for ExprClosure {
3448 fn to_tokens(&self, tokens: &mut TokenStream) {
3449 outer_attrs_to_tokens(&self.attrs, tokens);
3450 self.lifetimes.to_tokens(tokens);
3451 self.constness.to_tokens(tokens);
3452 self.movability.to_tokens(tokens);
3453 self.asyncness.to_tokens(tokens);
3454 self.capture.to_tokens(tokens);
3455 self.or1_token.to_tokens(tokens);
3456 self.inputs.to_tokens(tokens);
3457 self.or2_token.to_tokens(tokens);
3458 self.output.to_tokens(tokens);
3459 if matches!(self.output, ReturnType::Default) || matches!(*self.body, Expr::Block(_)) {
3460 self.body.to_tokens(tokens);
3461 } else {
3462 token::Brace::default().surround(tokens, |tokens| {
3463 print_expr(&self.body, tokens, FixupContext::new_stmt());
3464 });
3465 }
3466 }
3467 }
3468
3469 #[cfg(feature = "full")]
3470 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3471 impl ToTokens for ExprConst {
3472 fn to_tokens(&self, tokens: &mut TokenStream) {
3473 outer_attrs_to_tokens(&self.attrs, tokens);
3474 self.const_token.to_tokens(tokens);
3475 self.block.brace_token.surround(tokens, |tokens| {
3476 inner_attrs_to_tokens(&self.attrs, tokens);
3477 tokens.append_all(&self.block.stmts);
3478 });
3479 }
3480 }
3481
3482 #[cfg(feature = "full")]
3483 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3484 impl ToTokens for ExprContinue {
3485 fn to_tokens(&self, tokens: &mut TokenStream) {
3486 outer_attrs_to_tokens(&self.attrs, tokens);
3487 self.continue_token.to_tokens(tokens);
3488 self.label.to_tokens(tokens);
3489 }
3490 }
3491
3492 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3493 impl ToTokens for ExprField {
3494 fn to_tokens(&self, tokens: &mut TokenStream) {
3495 print_expr_field(self, tokens, FixupContext::NONE);
3496 }
3497 }
3498
3499 fn print_expr_field(e: &ExprField, tokens: &mut TokenStream, fixup: FixupContext) {
3500 outer_attrs_to_tokens(&e.attrs, tokens);
3501 print_subexpression(
3502 &e.base,
3503 Precedence::of(&e.base) < Precedence::Unambiguous,
3504 tokens,
3505 fixup.leftmost_subexpression_with_dot(),
3506 );
3507 e.dot_token.to_tokens(tokens);
3508 e.member.to_tokens(tokens);
3509 }
3510
3511 #[cfg(feature = "full")]
3512 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3513 impl ToTokens for ExprForLoop {
3514 fn to_tokens(&self, tokens: &mut TokenStream) {
3515 outer_attrs_to_tokens(&self.attrs, tokens);
3516 self.label.to_tokens(tokens);
3517 self.for_token.to_tokens(tokens);
3518 self.pat.to_tokens(tokens);
3519 self.in_token.to_tokens(tokens);
3520 print_condition(&self.expr, tokens);
3521 self.body.brace_token.surround(tokens, |tokens| {
3522 inner_attrs_to_tokens(&self.attrs, tokens);
3523 tokens.append_all(&self.body.stmts);
3524 });
3525 }
3526 }
3527
3528 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3529 impl ToTokens for ExprGroup {
3530 fn to_tokens(&self, tokens: &mut TokenStream) {
3531 outer_attrs_to_tokens(&self.attrs, tokens);
3532 self.group_token.surround(tokens, |tokens| {
3533 self.expr.to_tokens(tokens);
3534 });
3535 }
3536 }
3537
3538 #[cfg(feature = "full")]
3539 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3540 impl ToTokens for ExprIf {
3541 fn to_tokens(&self, tokens: &mut TokenStream) {
3542 outer_attrs_to_tokens(&self.attrs, tokens);
3543
3544 let mut expr = self;
3545 loop {
3546 expr.if_token.to_tokens(tokens);
3547 print_condition(&expr.cond, tokens);
3548 expr.then_branch.to_tokens(tokens);
3549
3550 let (else_token, else_) = match &expr.else_branch {
3551 Some(else_branch) => else_branch,
3552 None => break,
3553 };
3554
3555 else_token.to_tokens(tokens);
3556 match &**else_ {
3557 Expr::If(next) => {
3558 expr = next;
3559 }
3560 Expr::Block(last) => {
3561 last.to_tokens(tokens);
3562 break;
3563 }
3564 other => {
3567 token::Brace::default().surround(tokens, |tokens| {
3568 print_expr(other, tokens, FixupContext::new_stmt());
3569 });
3570 break;
3571 }
3572 }
3573 }
3574 }
3575 }
3576
3577 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3578 impl ToTokens for ExprIndex {
3579 fn to_tokens(&self, tokens: &mut TokenStream) {
3580 print_expr_index(self, tokens, FixupContext::NONE);
3581 }
3582 }
3583
3584 fn print_expr_index(e: &ExprIndex, tokens: &mut TokenStream, fixup: FixupContext) {
3585 outer_attrs_to_tokens(&e.attrs, tokens);
3586 let obj_fixup = fixup.leftmost_subexpression_with_begin_operator(
3587 #[cfg(feature = "full")]
3588 true,
3589 false,
3590 );
3591 print_subexpression(
3592 &e.expr,
3593 obj_fixup.leading_precedence(&e.expr) < Precedence::Unambiguous,
3594 tokens,
3595 obj_fixup,
3596 );
3597 e.bracket_token.surround(tokens, |tokens| {
3598 e.index.to_tokens(tokens);
3599 });
3600 }
3601
3602 #[cfg(feature = "full")]
3603 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3604 impl ToTokens for ExprInfer {
3605 fn to_tokens(&self, tokens: &mut TokenStream) {
3606 outer_attrs_to_tokens(&self.attrs, tokens);
3607 self.underscore_token.to_tokens(tokens);
3608 }
3609 }
3610
3611 #[cfg(feature = "full")]
3612 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3613 impl ToTokens for ExprLet {
3614 fn to_tokens(&self, tokens: &mut TokenStream) {
3615 print_expr_let(self, tokens, FixupContext::NONE);
3616 }
3617 }
3618
3619 #[cfg(feature = "full")]
3620 fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) {
3621 outer_attrs_to_tokens(&e.attrs, tokens);
3622 e.let_token.to_tokens(tokens);
3623 e.pat.to_tokens(tokens);
3624 e.eq_token.to_tokens(tokens);
3625 print_subexpression(
3626 &e.expr,
3627 fixup.needs_group_as_let_scrutinee(&e.expr),
3628 tokens,
3629 FixupContext::NONE,
3630 );
3631 }
3632
3633 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3634 impl ToTokens for ExprLit {
3635 fn to_tokens(&self, tokens: &mut TokenStream) {
3636 outer_attrs_to_tokens(&self.attrs, tokens);
3637 self.lit.to_tokens(tokens);
3638 }
3639 }
3640
3641 #[cfg(feature = "full")]
3642 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3643 impl ToTokens for ExprLoop {
3644 fn to_tokens(&self, tokens: &mut TokenStream) {
3645 outer_attrs_to_tokens(&self.attrs, tokens);
3646 self.label.to_tokens(tokens);
3647 self.loop_token.to_tokens(tokens);
3648 self.body.brace_token.surround(tokens, |tokens| {
3649 inner_attrs_to_tokens(&self.attrs, tokens);
3650 tokens.append_all(&self.body.stmts);
3651 });
3652 }
3653 }
3654
3655 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3656 impl ToTokens for ExprMacro {
3657 fn to_tokens(&self, tokens: &mut TokenStream) {
3658 outer_attrs_to_tokens(&self.attrs, tokens);
3659 self.mac.to_tokens(tokens);
3660 }
3661 }
3662
3663 #[cfg(feature = "full")]
3664 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3665 impl ToTokens for ExprMatch {
3666 fn to_tokens(&self, tokens: &mut TokenStream) {
3667 outer_attrs_to_tokens(&self.attrs, tokens);
3668 self.match_token.to_tokens(tokens);
3669 print_condition(&self.expr, tokens);
3670 self.brace_token.surround(tokens, |tokens| {
3671 inner_attrs_to_tokens(&self.attrs, tokens);
3672 for (i, arm) in self.arms.iter().enumerate() {
3673 arm.to_tokens(tokens);
3674 let is_last = i == self.arms.len() - 1;
3677 if !is_last
3678 && classify::requires_comma_to_be_match_arm(&arm.body)
3679 && arm.comma.is_none()
3680 {
3681 <Token![,]>::default().to_tokens(tokens);
3682 }
3683 }
3684 });
3685 }
3686 }
3687
3688 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3689 impl ToTokens for ExprMethodCall {
3690 fn to_tokens(&self, tokens: &mut TokenStream) {
3691 print_expr_method_call(self, tokens, FixupContext::NONE);
3692 }
3693 }
3694
3695 fn print_expr_method_call(e: &ExprMethodCall, tokens: &mut TokenStream, fixup: FixupContext) {
3696 outer_attrs_to_tokens(&e.attrs, tokens);
3697 print_subexpression(
3698 &e.receiver,
3699 Precedence::of(&e.receiver) < Precedence::Unambiguous,
3700 tokens,
3701 fixup.leftmost_subexpression_with_dot(),
3702 );
3703 e.dot_token.to_tokens(tokens);
3704 e.method.to_tokens(tokens);
3705 if let Some(turbofish) = &e.turbofish {
3706 path::printing::print_angle_bracketed_generic_arguments(
3707 tokens,
3708 turbofish,
3709 PathStyle::Expr,
3710 );
3711 }
3712 e.paren_token.surround(tokens, |tokens| {
3713 e.args.to_tokens(tokens);
3714 });
3715 }
3716
3717 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3718 impl ToTokens for ExprParen {
3719 fn to_tokens(&self, tokens: &mut TokenStream) {
3720 outer_attrs_to_tokens(&self.attrs, tokens);
3721 self.paren_token.surround(tokens, |tokens| {
3722 self.expr.to_tokens(tokens);
3723 });
3724 }
3725 }
3726
3727 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3728 impl ToTokens for ExprPath {
3729 fn to_tokens(&self, tokens: &mut TokenStream) {
3730 outer_attrs_to_tokens(&self.attrs, tokens);
3731 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3732 }
3733 }
3734
3735 #[cfg(feature = "full")]
3736 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3737 impl ToTokens for ExprRange {
3738 fn to_tokens(&self, tokens: &mut TokenStream) {
3739 print_expr_range(self, tokens, FixupContext::NONE);
3740 }
3741 }
3742
3743 #[cfg(feature = "full")]
3744 fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, fixup: FixupContext) {
3745 outer_attrs_to_tokens(&e.attrs, tokens);
3746 if let Some(start) = &e.start {
3747 print_subexpression(
3748 start,
3749 Precedence::of(start) <= Precedence::Range,
3750 tokens,
3751 fixup.leftmost_subexpression(),
3752 );
3753 }
3754 e.limits.to_tokens(tokens);
3755 if let Some(end) = &e.end {
3756 print_subexpression(
3757 end,
3758 fixup.trailing_precedence(end) <= Precedence::Range,
3759 tokens,
3760 fixup.subsequent_subexpression(),
3761 );
3762 }
3763 }
3764
3765 #[cfg(feature = "full")]
3766 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3767 impl ToTokens for ExprRawAddr {
3768 fn to_tokens(&self, tokens: &mut TokenStream) {
3769 print_expr_raw_addr(self, tokens, FixupContext::NONE);
3770 }
3771 }
3772
3773 #[cfg(feature = "full")]
3774 fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) {
3775 outer_attrs_to_tokens(&e.attrs, tokens);
3776 e.and_token.to_tokens(tokens);
3777 e.raw.to_tokens(tokens);
3778 e.mutability.to_tokens(tokens);
3779 print_subexpression(
3780 &e.expr,
3781 fixup.trailing_precedence(&e.expr) < Precedence::Prefix,
3782 tokens,
3783 fixup.subsequent_subexpression(),
3784 );
3785 }
3786
3787 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3788 impl ToTokens for ExprReference {
3789 fn to_tokens(&self, tokens: &mut TokenStream) {
3790 print_expr_reference(self, tokens, FixupContext::NONE);
3791 }
3792 }
3793
3794 fn print_expr_reference(e: &ExprReference, tokens: &mut TokenStream, fixup: FixupContext) {
3795 outer_attrs_to_tokens(&e.attrs, tokens);
3796 e.and_token.to_tokens(tokens);
3797 e.mutability.to_tokens(tokens);
3798 print_subexpression(
3799 &e.expr,
3800 fixup.trailing_precedence(&e.expr) < Precedence::Prefix,
3801 tokens,
3802 fixup.subsequent_subexpression(),
3803 );
3804 }
3805
3806 #[cfg(feature = "full")]
3807 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3808 impl ToTokens for ExprRepeat {
3809 fn to_tokens(&self, tokens: &mut TokenStream) {
3810 outer_attrs_to_tokens(&self.attrs, tokens);
3811 self.bracket_token.surround(tokens, |tokens| {
3812 self.expr.to_tokens(tokens);
3813 self.semi_token.to_tokens(tokens);
3814 self.len.to_tokens(tokens);
3815 });
3816 }
3817 }
3818
3819 #[cfg(feature = "full")]
3820 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3821 impl ToTokens for ExprReturn {
3822 fn to_tokens(&self, tokens: &mut TokenStream) {
3823 print_expr_return(self, tokens, FixupContext::NONE);
3824 }
3825 }
3826
3827 #[cfg(feature = "full")]
3828 fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) {
3829 outer_attrs_to_tokens(&e.attrs, tokens);
3830 e.return_token.to_tokens(tokens);
3831 if let Some(expr) = &e.expr {
3832 print_expr(expr, tokens, fixup.subsequent_subexpression());
3833 }
3834 }
3835
3836 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3837 impl ToTokens for ExprStruct {
3838 fn to_tokens(&self, tokens: &mut TokenStream) {
3839 outer_attrs_to_tokens(&self.attrs, tokens);
3840 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::Expr);
3841 self.brace_token.surround(tokens, |tokens| {
3842 self.fields.to_tokens(tokens);
3843 if let Some(dot2_token) = &self.dot2_token {
3844 dot2_token.to_tokens(tokens);
3845 } else if self.rest.is_some() {
3846 Token).to_tokens(tokens);
3847 }
3848 self.rest.to_tokens(tokens);
3849 });
3850 }
3851 }
3852
3853 #[cfg(feature = "full")]
3854 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3855 impl ToTokens for ExprTry {
3856 fn to_tokens(&self, tokens: &mut TokenStream) {
3857 print_expr_try(self, tokens, FixupContext::NONE);
3858 }
3859 }
3860
3861 #[cfg(feature = "full")]
3862 fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) {
3863 outer_attrs_to_tokens(&e.attrs, tokens);
3864 print_subexpression(
3865 &e.expr,
3866 Precedence::of(&e.expr) < Precedence::Unambiguous,
3867 tokens,
3868 fixup.leftmost_subexpression_with_dot(),
3869 );
3870 e.question_token.to_tokens(tokens);
3871 }
3872
3873 #[cfg(feature = "full")]
3874 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3875 impl ToTokens for ExprTryBlock {
3876 fn to_tokens(&self, tokens: &mut TokenStream) {
3877 outer_attrs_to_tokens(&self.attrs, tokens);
3878 self.try_token.to_tokens(tokens);
3879 self.block.to_tokens(tokens);
3880 }
3881 }
3882
3883 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3884 impl ToTokens for ExprTuple {
3885 fn to_tokens(&self, tokens: &mut TokenStream) {
3886 outer_attrs_to_tokens(&self.attrs, tokens);
3887 self.paren_token.surround(tokens, |tokens| {
3888 self.elems.to_tokens(tokens);
3889 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3892 <Token![,]>::default().to_tokens(tokens);
3893 }
3894 });
3895 }
3896 }
3897
3898 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3899 impl ToTokens for ExprUnary {
3900 fn to_tokens(&self, tokens: &mut TokenStream) {
3901 print_expr_unary(self, tokens, FixupContext::NONE);
3902 }
3903 }
3904
3905 fn print_expr_unary(e: &ExprUnary, tokens: &mut TokenStream, fixup: FixupContext) {
3906 outer_attrs_to_tokens(&e.attrs, tokens);
3907 e.op.to_tokens(tokens);
3908 print_subexpression(
3909 &e.expr,
3910 fixup.trailing_precedence(&e.expr) < Precedence::Prefix,
3911 tokens,
3912 fixup.subsequent_subexpression(),
3913 );
3914 }
3915
3916 #[cfg(feature = "full")]
3917 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3918 impl ToTokens for ExprUnsafe {
3919 fn to_tokens(&self, tokens: &mut TokenStream) {
3920 outer_attrs_to_tokens(&self.attrs, tokens);
3921 self.unsafe_token.to_tokens(tokens);
3922 self.block.brace_token.surround(tokens, |tokens| {
3923 inner_attrs_to_tokens(&self.attrs, tokens);
3924 tokens.append_all(&self.block.stmts);
3925 });
3926 }
3927 }
3928
3929 #[cfg(feature = "full")]
3930 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3931 impl ToTokens for ExprWhile {
3932 fn to_tokens(&self, tokens: &mut TokenStream) {
3933 outer_attrs_to_tokens(&self.attrs, tokens);
3934 self.label.to_tokens(tokens);
3935 self.while_token.to_tokens(tokens);
3936 print_condition(&self.cond, tokens);
3937 self.body.brace_token.surround(tokens, |tokens| {
3938 inner_attrs_to_tokens(&self.attrs, tokens);
3939 tokens.append_all(&self.body.stmts);
3940 });
3941 }
3942 }
3943
3944 #[cfg(feature = "full")]
3945 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3946 impl ToTokens for ExprYield {
3947 fn to_tokens(&self, tokens: &mut TokenStream) {
3948 print_expr_yield(self, tokens, FixupContext::NONE);
3949 }
3950 }
3951
3952 #[cfg(feature = "full")]
3953 fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) {
3954 outer_attrs_to_tokens(&e.attrs, tokens);
3955 e.yield_token.to_tokens(tokens);
3956 if let Some(expr) = &e.expr {
3957 print_expr(expr, tokens, fixup.subsequent_subexpression());
3958 }
3959 }
3960
3961 #[cfg(feature = "full")]
3962 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3963 impl ToTokens for Arm {
3964 fn to_tokens(&self, tokens: &mut TokenStream) {
3965 tokens.append_all(&self.attrs);
3966 self.pat.to_tokens(tokens);
3967 if let Some((if_token, guard)) = &self.guard {
3968 if_token.to_tokens(tokens);
3969 guard.to_tokens(tokens);
3970 }
3971 self.fat_arrow_token.to_tokens(tokens);
3972 print_expr(&self.body, tokens, FixupContext::new_match_arm());
3973 self.comma.to_tokens(tokens);
3974 }
3975 }
3976
3977 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3978 impl ToTokens for FieldValue {
3979 fn to_tokens(&self, tokens: &mut TokenStream) {
3980 outer_attrs_to_tokens(&self.attrs, tokens);
3981 self.member.to_tokens(tokens);
3982 if let Some(colon_token) = &self.colon_token {
3983 colon_token.to_tokens(tokens);
3984 self.expr.to_tokens(tokens);
3985 }
3986 }
3987 }
3988
3989 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
3990 impl ToTokens for Index {
3991 fn to_tokens(&self, tokens: &mut TokenStream) {
3992 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3993 lit.set_span(self.span);
3994 tokens.append(lit);
3995 }
3996 }
3997
3998 #[cfg(feature = "full")]
3999 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4000 impl ToTokens for Label {
4001 fn to_tokens(&self, tokens: &mut TokenStream) {
4002 self.name.to_tokens(tokens);
4003 self.colon_token.to_tokens(tokens);
4004 }
4005 }
4006
4007 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4008 impl ToTokens for Member {
4009 fn to_tokens(&self, tokens: &mut TokenStream) {
4010 match self {
4011 Member::Named(ident) => ident.to_tokens(tokens),
4012 Member::Unnamed(index) => index.to_tokens(tokens),
4013 }
4014 }
4015 }
4016
4017 #[cfg(feature = "full")]
4018 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4019 impl ToTokens for RangeLimits {
4020 fn to_tokens(&self, tokens: &mut TokenStream) {
4021 match self {
4022 RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
4023 RangeLimits::Closed(t) => t.to_tokens(tokens),
4024 }
4025 }
4026 }
4027
4028 #[cfg(feature = "full")]
4029 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
4030 impl ToTokens for PointerMutability {
4031 fn to_tokens(&self, tokens: &mut TokenStream) {
4032 match self {
4033 PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
4034 PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
4035 }
4036 }
4037 }
4038}