• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::algorithm::{BreakToken, Printer};
2 use crate::attr;
3 use crate::classify;
4 use crate::fixup::FixupContext;
5 use crate::iter::IterDelimited;
6 use crate::path::PathKind;
7 use crate::precedence::Precedence;
8 use crate::stmt;
9 use crate::INDENT;
10 use proc_macro2::TokenStream;
11 use syn::punctuated::Punctuated;
12 use syn::{
13     token, Arm, Attribute, BinOp, Block, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait,
14     ExprBinary, ExprBlock, ExprBreak, ExprCall, ExprCast, ExprClosure, ExprConst, ExprContinue,
15     ExprField, ExprForLoop, ExprGroup, ExprIf, ExprIndex, ExprInfer, ExprLet, ExprLit, ExprLoop,
16     ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprRawAddr,
17     ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary,
18     ExprUnsafe, ExprWhile, ExprYield, FieldValue, Index, Label, Lit, Member, PointerMutability,
19     RangeLimits, ReturnType, Stmt, Token, UnOp,
20 };
21 
22 impl Printer {
expr(&mut self, expr: &Expr, mut fixup: FixupContext)23     pub fn expr(&mut self, expr: &Expr, mut fixup: FixupContext) {
24         let needs_paren = fixup.parenthesize(expr);
25         if needs_paren {
26             self.word("(");
27             fixup = FixupContext::NONE;
28         }
29 
30         let beginning_of_line = false;
31 
32         match expr {
33             #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
34             Expr::Array(expr) => self.expr_array(expr),
35             Expr::Assign(expr) => self.expr_assign(expr, fixup),
36             Expr::Async(expr) => self.expr_async(expr),
37             Expr::Await(expr) => self.expr_await(expr, beginning_of_line, fixup),
38             Expr::Binary(expr) => self.expr_binary(expr, fixup),
39             Expr::Block(expr) => self.expr_block(expr),
40             Expr::Break(expr) => self.expr_break(expr, fixup),
41             Expr::Call(expr) => self.expr_call(expr, beginning_of_line, fixup),
42             Expr::Cast(expr) => self.expr_cast(expr, fixup),
43             Expr::Closure(expr) => self.expr_closure(expr, fixup),
44             Expr::Const(expr) => self.expr_const(expr),
45             Expr::Continue(expr) => self.expr_continue(expr),
46             Expr::Field(expr) => self.expr_field(expr, beginning_of_line, fixup),
47             Expr::ForLoop(expr) => self.expr_for_loop(expr),
48             Expr::Group(expr) => self.expr_group(expr, fixup),
49             Expr::If(expr) => self.expr_if(expr),
50             Expr::Index(expr) => self.expr_index(expr, beginning_of_line, fixup),
51             Expr::Infer(expr) => self.expr_infer(expr),
52             Expr::Let(expr) => self.expr_let(expr, fixup),
53             Expr::Lit(expr) => self.expr_lit(expr),
54             Expr::Loop(expr) => self.expr_loop(expr),
55             Expr::Macro(expr) => self.expr_macro(expr),
56             Expr::Match(expr) => self.expr_match(expr),
57             Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line, fixup),
58             Expr::Paren(expr) => self.expr_paren(expr),
59             Expr::Path(expr) => self.expr_path(expr),
60             Expr::Range(expr) => self.expr_range(expr, fixup),
61             Expr::RawAddr(expr) => self.expr_raw_addr(expr, fixup),
62             Expr::Reference(expr) => self.expr_reference(expr, fixup),
63             Expr::Repeat(expr) => self.expr_repeat(expr),
64             Expr::Return(expr) => self.expr_return(expr, fixup),
65             Expr::Struct(expr) => self.expr_struct(expr),
66             Expr::Try(expr) => self.expr_try(expr, beginning_of_line, fixup),
67             Expr::TryBlock(expr) => self.expr_try_block(expr),
68             Expr::Tuple(expr) => self.expr_tuple(expr),
69             Expr::Unary(expr) => self.expr_unary(expr, fixup),
70             Expr::Unsafe(expr) => self.expr_unsafe(expr),
71             Expr::Verbatim(expr) => self.expr_verbatim(expr, fixup),
72             Expr::While(expr) => self.expr_while(expr),
73             Expr::Yield(expr) => self.expr_yield(expr, fixup),
74             _ => unimplemented!("unknown Expr"),
75         }
76 
77         if needs_paren {
78             self.word(")");
79         }
80     }
81 
expr_beginning_of_line( &mut self, expr: &Expr, mut needs_paren: bool, beginning_of_line: bool, mut fixup: FixupContext, )82     pub fn expr_beginning_of_line(
83         &mut self,
84         expr: &Expr,
85         mut needs_paren: bool,
86         beginning_of_line: bool,
87         mut fixup: FixupContext,
88     ) {
89         needs_paren |= fixup.parenthesize(expr);
90         if needs_paren {
91             self.word("(");
92             fixup = FixupContext::NONE;
93         }
94 
95         match expr {
96             Expr::Await(expr) => self.expr_await(expr, beginning_of_line, fixup),
97             Expr::Field(expr) => self.expr_field(expr, beginning_of_line, fixup),
98             Expr::Index(expr) => self.expr_index(expr, beginning_of_line, fixup),
99             Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line, fixup),
100             Expr::Try(expr) => self.expr_try(expr, beginning_of_line, fixup),
101             _ => self.expr(expr, fixup),
102         }
103 
104         if needs_paren {
105             self.word(")");
106         }
107     }
108 
prefix_subexpr( &mut self, expr: &Expr, mut needs_paren: bool, beginning_of_line: bool, mut fixup: FixupContext, )109     fn prefix_subexpr(
110         &mut self,
111         expr: &Expr,
112         mut needs_paren: bool,
113         beginning_of_line: bool,
114         mut fixup: FixupContext,
115     ) {
116         needs_paren |= fixup.parenthesize(expr);
117         if needs_paren {
118             self.word("(");
119             fixup = FixupContext::NONE;
120         }
121 
122         match expr {
123             Expr::Await(expr) => self.prefix_subexpr_await(expr, beginning_of_line, fixup),
124             Expr::Call(expr) => self.prefix_subexpr_call(expr, fixup),
125             Expr::Field(expr) => self.prefix_subexpr_field(expr, beginning_of_line, fixup),
126             Expr::Index(expr) => self.prefix_subexpr_index(expr, beginning_of_line, fixup),
127             Expr::MethodCall(expr) => {
128                 let unindent_call_args = false;
129                 self.prefix_subexpr_method_call(expr, beginning_of_line, unindent_call_args, fixup);
130             }
131             Expr::Try(expr) => self.prefix_subexpr_try(expr, beginning_of_line, fixup),
132             _ => {
133                 self.cbox(-INDENT);
134                 self.expr(expr, fixup);
135                 self.end();
136             }
137         }
138 
139         if needs_paren {
140             self.word(")");
141         }
142     }
143 
expr_condition(&mut self, expr: &Expr)144     fn expr_condition(&mut self, expr: &Expr) {
145         self.cbox(0);
146         self.expr(expr, FixupContext::new_condition());
147         if needs_newline_if_wrap(expr) {
148             self.space();
149         } else {
150             self.nbsp();
151         }
152         self.end();
153     }
154 
subexpr(&mut self, expr: &Expr, needs_paren: bool, mut fixup: FixupContext)155     pub fn subexpr(&mut self, expr: &Expr, needs_paren: bool, mut fixup: FixupContext) {
156         if needs_paren {
157             self.word("(");
158             fixup = FixupContext::NONE;
159         }
160 
161         self.expr(expr, fixup);
162 
163         if needs_paren {
164             self.word(")");
165         }
166     }
167 
expr_array(&mut self, expr: &ExprArray)168     fn expr_array(&mut self, expr: &ExprArray) {
169         self.outer_attrs(&expr.attrs);
170         if expr.elems.is_empty() {
171             self.word("[]");
172         } else if simple_array(&expr.elems) {
173             self.cbox(INDENT);
174             self.word("[");
175             self.zerobreak();
176             self.ibox(0);
177             for elem in expr.elems.iter().delimited() {
178                 self.expr(&elem, FixupContext::NONE);
179                 if !elem.is_last {
180                     self.word(",");
181                     self.space();
182                 }
183             }
184             self.end();
185             self.trailing_comma(true);
186             self.offset(-INDENT);
187             self.word("]");
188             self.end();
189         } else {
190             self.word("[");
191             self.cbox(INDENT);
192             self.zerobreak();
193             for elem in expr.elems.iter().delimited() {
194                 self.expr(&elem, FixupContext::NONE);
195                 self.trailing_comma(elem.is_last);
196             }
197             self.offset(-INDENT);
198             self.end();
199             self.word("]");
200         }
201     }
202 
expr_assign(&mut self, expr: &ExprAssign, fixup: FixupContext)203     fn expr_assign(&mut self, expr: &ExprAssign, fixup: FixupContext) {
204         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
205             &expr.left,
206             false,
207             false,
208             Precedence::Assign,
209         );
210         let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign);
211 
212         self.outer_attrs(&expr.attrs);
213         self.ibox(0);
214         self.subexpr(&expr.left, left_prec <= Precedence::Range, left_fixup);
215         self.word(" = ");
216         self.neverbreak();
217         self.expr(&expr.right, right_fixup);
218         self.end();
219     }
220 
expr_async(&mut self, expr: &ExprAsync)221     fn expr_async(&mut self, expr: &ExprAsync) {
222         self.outer_attrs(&expr.attrs);
223         self.word("async ");
224         if expr.capture.is_some() {
225             self.word("move ");
226         }
227         self.cbox(INDENT);
228         self.small_block(&expr.block, &expr.attrs);
229         self.end();
230     }
231 
expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool, fixup: FixupContext)232     fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool, fixup: FixupContext) {
233         self.outer_attrs(&expr.attrs);
234         self.cbox(INDENT);
235         self.prefix_subexpr_await(expr, beginning_of_line, fixup);
236         self.end();
237     }
238 
prefix_subexpr_await( &mut self, expr: &ExprAwait, beginning_of_line: bool, fixup: FixupContext, )239     fn prefix_subexpr_await(
240         &mut self,
241         expr: &ExprAwait,
242         beginning_of_line: bool,
243         fixup: FixupContext,
244     ) {
245         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.base);
246 
247         self.prefix_subexpr(
248             &expr.base,
249             left_prec < Precedence::Unambiguous,
250             beginning_of_line,
251             left_fixup,
252         );
253         if !(beginning_of_line && is_short_ident(&expr.base)) {
254             self.scan_break(BreakToken {
255                 no_break: self.ends_with('.').then_some(' '),
256                 ..BreakToken::default()
257             });
258         }
259         self.word(".await");
260     }
261 
expr_binary(&mut self, expr: &ExprBinary, fixup: FixupContext)262     fn expr_binary(&mut self, expr: &ExprBinary, fixup: FixupContext) {
263         let binop_prec = Precedence::of_binop(&expr.op);
264         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
265             &expr.left,
266             match &expr.op {
267                 BinOp::Sub(_)
268                 | BinOp::Mul(_)
269                 | BinOp::And(_)
270                 | BinOp::Or(_)
271                 | BinOp::BitAnd(_)
272                 | BinOp::BitOr(_)
273                 | BinOp::Shl(_)
274                 | BinOp::Lt(_) => true,
275                 _ => false,
276             },
277             match &expr.op {
278                 BinOp::Shl(_) | BinOp::Lt(_) => true,
279                 _ => false,
280             },
281             binop_prec,
282         );
283         let left_needs_group = match binop_prec {
284             Precedence::Assign => left_prec <= Precedence::Range,
285             Precedence::Compare => left_prec <= binop_prec,
286             _ => left_prec < binop_prec,
287         };
288         let right_fixup = fixup.rightmost_subexpression_fixup(false, false, binop_prec);
289         let right_needs_group = binop_prec != Precedence::Assign
290             && right_fixup.rightmost_subexpression_precedence(&expr.right) <= binop_prec;
291 
292         self.outer_attrs(&expr.attrs);
293         self.ibox(INDENT);
294         self.ibox(-INDENT);
295         self.subexpr(&expr.left, left_needs_group, left_fixup);
296         self.end();
297         self.space();
298         self.binary_operator(&expr.op);
299         self.nbsp();
300         self.subexpr(&expr.right, right_needs_group, right_fixup);
301         self.end();
302     }
303 
expr_block(&mut self, expr: &ExprBlock)304     pub fn expr_block(&mut self, expr: &ExprBlock) {
305         self.outer_attrs(&expr.attrs);
306         if let Some(label) = &expr.label {
307             self.label(label);
308         }
309         self.cbox(INDENT);
310         self.small_block(&expr.block, &expr.attrs);
311         self.end();
312     }
313 
expr_break(&mut self, expr: &ExprBreak, fixup: FixupContext)314     fn expr_break(&mut self, expr: &ExprBreak, fixup: FixupContext) {
315         self.outer_attrs(&expr.attrs);
316         self.word("break");
317         if let Some(lifetime) = &expr.label {
318             self.nbsp();
319             self.lifetime(lifetime);
320         }
321         if let Some(value) = &expr.expr {
322             self.nbsp();
323             self.subexpr(
324                 value,
325                 expr.label.is_none() && classify::expr_leading_label(value),
326                 fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump),
327             );
328         }
329     }
330 
expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool, fixup: FixupContext)331     fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool, fixup: FixupContext) {
332         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
333             &expr.func,
334             true,
335             false,
336             Precedence::Unambiguous,
337         );
338         let needs_paren = if let Expr::Field(func) = &*expr.func {
339             matches!(func.member, Member::Named(_))
340         } else {
341             left_prec < Precedence::Unambiguous
342         };
343 
344         self.outer_attrs(&expr.attrs);
345         self.expr_beginning_of_line(&expr.func, needs_paren, beginning_of_line, left_fixup);
346         self.word("(");
347         self.call_args(&expr.args);
348         self.word(")");
349     }
350 
prefix_subexpr_call(&mut self, expr: &ExprCall, fixup: FixupContext)351     fn prefix_subexpr_call(&mut self, expr: &ExprCall, fixup: FixupContext) {
352         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
353             &expr.func,
354             true,
355             false,
356             Precedence::Unambiguous,
357         );
358         let needs_paren = if let Expr::Field(func) = &*expr.func {
359             matches!(func.member, Member::Named(_))
360         } else {
361             left_prec < Precedence::Unambiguous
362         };
363 
364         let beginning_of_line = false;
365         self.prefix_subexpr(&expr.func, needs_paren, beginning_of_line, left_fixup);
366         self.word("(");
367         self.call_args(&expr.args);
368         self.word(")");
369     }
370 
expr_cast(&mut self, expr: &ExprCast, fixup: FixupContext)371     fn expr_cast(&mut self, expr: &ExprCast, fixup: FixupContext) {
372         let (left_prec, left_fixup) =
373             fixup.leftmost_subexpression_with_operator(&expr.expr, false, false, Precedence::Cast);
374 
375         self.outer_attrs(&expr.attrs);
376         self.ibox(INDENT);
377         self.ibox(-INDENT);
378         self.subexpr(&expr.expr, left_prec < Precedence::Cast, left_fixup);
379         self.end();
380         self.space();
381         self.word("as ");
382         self.ty(&expr.ty);
383         self.end();
384     }
385 
expr_closure(&mut self, expr: &ExprClosure, fixup: FixupContext)386     fn expr_closure(&mut self, expr: &ExprClosure, fixup: FixupContext) {
387         self.outer_attrs(&expr.attrs);
388         self.ibox(0);
389         if let Some(bound_lifetimes) = &expr.lifetimes {
390             self.bound_lifetimes(bound_lifetimes);
391         }
392         if expr.constness.is_some() {
393             self.word("const ");
394         }
395         if expr.movability.is_some() {
396             self.word("static ");
397         }
398         if expr.asyncness.is_some() {
399             self.word("async ");
400         }
401         if expr.capture.is_some() {
402             self.word("move ");
403         }
404         self.cbox(INDENT);
405         self.word("|");
406         for pat in expr.inputs.iter().delimited() {
407             if pat.is_first {
408                 self.zerobreak();
409             }
410             self.pat(&pat);
411             if !pat.is_last {
412                 self.word(",");
413                 self.space();
414             }
415         }
416         match &expr.output {
417             ReturnType::Default => {
418                 self.word("|");
419                 self.space();
420                 self.offset(-INDENT);
421                 self.end();
422                 self.neverbreak();
423                 let wrap_in_brace = match &*expr.body {
424                     Expr::Match(ExprMatch { attrs, .. }) | Expr::Call(ExprCall { attrs, .. }) => {
425                         attr::has_outer(attrs)
426                     }
427                     body => !is_blocklike(body),
428                 };
429                 if wrap_in_brace {
430                     self.cbox(INDENT);
431                     let okay_to_brace = parseable_as_stmt(&expr.body);
432                     self.scan_break(BreakToken {
433                         pre_break: Some(if okay_to_brace { '{' } else { '(' }),
434                         ..BreakToken::default()
435                     });
436                     self.expr(
437                         &expr.body,
438                         fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
439                     );
440                     self.scan_break(BreakToken {
441                         offset: -INDENT,
442                         pre_break: (okay_to_brace && stmt::add_semi(&expr.body)).then_some(';'),
443                         post_break: if okay_to_brace { "}" } else { ")" },
444                         ..BreakToken::default()
445                     });
446                     self.end();
447                 } else {
448                     self.expr(
449                         &expr.body,
450                         fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
451                     );
452                 }
453             }
454             ReturnType::Type(_arrow, ty) => {
455                 if !expr.inputs.is_empty() {
456                     self.trailing_comma(true);
457                     self.offset(-INDENT);
458                 }
459                 self.word("|");
460                 self.end();
461                 self.word(" -> ");
462                 self.ty(ty);
463                 self.nbsp();
464                 self.neverbreak();
465                 if matches!(&*expr.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none())
466                 {
467                     self.expr(
468                         &expr.body,
469                         fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump),
470                     );
471                 } else {
472                     self.cbox(INDENT);
473                     self.expr_as_small_block(&expr.body, 0);
474                     self.end();
475                 }
476             }
477         }
478         self.end();
479     }
480 
expr_const(&mut self, expr: &ExprConst)481     pub fn expr_const(&mut self, expr: &ExprConst) {
482         self.outer_attrs(&expr.attrs);
483         self.word("const ");
484         self.cbox(INDENT);
485         self.small_block(&expr.block, &expr.attrs);
486         self.end();
487     }
488 
expr_continue(&mut self, expr: &ExprContinue)489     fn expr_continue(&mut self, expr: &ExprContinue) {
490         self.outer_attrs(&expr.attrs);
491         self.word("continue");
492         if let Some(lifetime) = &expr.label {
493             self.nbsp();
494             self.lifetime(lifetime);
495         }
496     }
497 
expr_field(&mut self, expr: &ExprField, beginning_of_line: bool, fixup: FixupContext)498     fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool, fixup: FixupContext) {
499         self.outer_attrs(&expr.attrs);
500         self.cbox(INDENT);
501         self.prefix_subexpr_field(expr, beginning_of_line, fixup);
502         self.end();
503     }
504 
prefix_subexpr_field( &mut self, expr: &ExprField, beginning_of_line: bool, fixup: FixupContext, )505     fn prefix_subexpr_field(
506         &mut self,
507         expr: &ExprField,
508         beginning_of_line: bool,
509         fixup: FixupContext,
510     ) {
511         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.base);
512 
513         self.prefix_subexpr(
514             &expr.base,
515             left_prec < Precedence::Unambiguous,
516             beginning_of_line,
517             left_fixup,
518         );
519         if !(beginning_of_line && is_short_ident(&expr.base)) {
520             self.scan_break(BreakToken {
521                 no_break: self.ends_with('.').then_some(' '),
522                 ..BreakToken::default()
523             });
524         }
525         self.word(".");
526         self.member(&expr.member);
527     }
528 
expr_for_loop(&mut self, expr: &ExprForLoop)529     fn expr_for_loop(&mut self, expr: &ExprForLoop) {
530         self.outer_attrs(&expr.attrs);
531         self.ibox(0);
532         if let Some(label) = &expr.label {
533             self.label(label);
534         }
535         self.word("for ");
536         self.pat(&expr.pat);
537         self.word(" in ");
538         self.neverbreak();
539         self.expr_condition(&expr.expr);
540         self.word("{");
541         self.neverbreak();
542         self.cbox(INDENT);
543         self.hardbreak_if_nonempty();
544         self.inner_attrs(&expr.attrs);
545         for stmt in expr.body.stmts.iter().delimited() {
546             self.stmt(&stmt, stmt.is_last);
547         }
548         self.offset(-INDENT);
549         self.end();
550         self.word("}");
551         self.end();
552     }
553 
expr_group(&mut self, expr: &ExprGroup, fixup: FixupContext)554     fn expr_group(&mut self, expr: &ExprGroup, fixup: FixupContext) {
555         self.outer_attrs(&expr.attrs);
556         self.expr(&expr.expr, fixup);
557     }
558 
expr_if(&mut self, expr: &ExprIf)559     fn expr_if(&mut self, expr: &ExprIf) {
560         self.outer_attrs(&expr.attrs);
561         self.cbox(INDENT);
562         self.word("if ");
563         self.cbox(-INDENT);
564         self.expr_condition(&expr.cond);
565         self.end();
566         if let Some((_else_token, else_branch)) = &expr.else_branch {
567             let mut else_branch = &**else_branch;
568             self.small_block(&expr.then_branch, &[]);
569             loop {
570                 self.word(" else ");
571                 match else_branch {
572                     Expr::If(expr) => {
573                         self.word("if ");
574                         self.cbox(-INDENT);
575                         self.expr_condition(&expr.cond);
576                         self.end();
577                         self.small_block(&expr.then_branch, &[]);
578                         if let Some((_else_token, next)) = &expr.else_branch {
579                             else_branch = next;
580                             continue;
581                         }
582                     }
583                     Expr::Block(expr) => {
584                         self.small_block(&expr.block, &[]);
585                     }
586                     // If not one of the valid expressions to exist in an else
587                     // clause, wrap in a block.
588                     other => self.expr_as_small_block(other, INDENT),
589                 }
590                 break;
591             }
592         } else if expr.then_branch.stmts.is_empty() {
593             self.word("{}");
594         } else {
595             self.word("{");
596             self.hardbreak();
597             for stmt in expr.then_branch.stmts.iter().delimited() {
598                 self.stmt(&stmt, stmt.is_last);
599             }
600             self.offset(-INDENT);
601             self.word("}");
602         }
603         self.end();
604     }
605 
expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool, fixup: FixupContext)606     fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool, fixup: FixupContext) {
607         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
608             &expr.expr,
609             true,
610             false,
611             Precedence::Unambiguous,
612         );
613 
614         self.outer_attrs(&expr.attrs);
615         self.expr_beginning_of_line(
616             &expr.expr,
617             left_prec < Precedence::Unambiguous,
618             beginning_of_line,
619             left_fixup,
620         );
621         self.word("[");
622         self.expr(&expr.index, FixupContext::NONE);
623         self.word("]");
624     }
625 
prefix_subexpr_index( &mut self, expr: &ExprIndex, beginning_of_line: bool, fixup: FixupContext, )626     fn prefix_subexpr_index(
627         &mut self,
628         expr: &ExprIndex,
629         beginning_of_line: bool,
630         fixup: FixupContext,
631     ) {
632         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_operator(
633             &expr.expr,
634             true,
635             false,
636             Precedence::Unambiguous,
637         );
638 
639         self.prefix_subexpr(
640             &expr.expr,
641             left_prec < Precedence::Unambiguous,
642             beginning_of_line,
643             left_fixup,
644         );
645         self.word("[");
646         self.expr(&expr.index, FixupContext::NONE);
647         self.word("]");
648     }
649 
expr_infer(&mut self, expr: &ExprInfer)650     fn expr_infer(&mut self, expr: &ExprInfer) {
651         self.outer_attrs(&expr.attrs);
652         self.word("_");
653     }
654 
expr_let(&mut self, expr: &ExprLet, fixup: FixupContext)655     fn expr_let(&mut self, expr: &ExprLet, fixup: FixupContext) {
656         let (right_prec, right_fixup) = fixup.rightmost_subexpression(&expr.expr, Precedence::Let);
657 
658         self.outer_attrs(&expr.attrs);
659         self.ibox(0);
660         self.word("let ");
661         self.ibox(0);
662         self.pat(&expr.pat);
663         self.end();
664         self.word(" = ");
665         self.neverbreak();
666         self.ibox(0);
667         self.subexpr(&expr.expr, right_prec < Precedence::Let, right_fixup);
668         self.end();
669         self.end();
670     }
671 
expr_lit(&mut self, expr: &ExprLit)672     pub fn expr_lit(&mut self, expr: &ExprLit) {
673         self.outer_attrs(&expr.attrs);
674         self.lit(&expr.lit);
675     }
676 
expr_loop(&mut self, expr: &ExprLoop)677     fn expr_loop(&mut self, expr: &ExprLoop) {
678         self.outer_attrs(&expr.attrs);
679         if let Some(label) = &expr.label {
680             self.label(label);
681         }
682         self.word("loop {");
683         self.cbox(INDENT);
684         self.hardbreak_if_nonempty();
685         self.inner_attrs(&expr.attrs);
686         for stmt in expr.body.stmts.iter().delimited() {
687             self.stmt(&stmt, stmt.is_last);
688         }
689         self.offset(-INDENT);
690         self.end();
691         self.word("}");
692     }
693 
expr_macro(&mut self, expr: &ExprMacro)694     pub fn expr_macro(&mut self, expr: &ExprMacro) {
695         self.outer_attrs(&expr.attrs);
696         let semicolon = false;
697         self.mac(&expr.mac, None, semicolon);
698     }
699 
expr_match(&mut self, expr: &ExprMatch)700     fn expr_match(&mut self, expr: &ExprMatch) {
701         self.outer_attrs(&expr.attrs);
702         self.ibox(0);
703         self.word("match ");
704         self.expr_condition(&expr.expr);
705         self.word("{");
706         self.neverbreak();
707         self.cbox(INDENT);
708         self.hardbreak_if_nonempty();
709         self.inner_attrs(&expr.attrs);
710         for arm in &expr.arms {
711             self.arm(arm);
712             self.hardbreak();
713         }
714         self.offset(-INDENT);
715         self.end();
716         self.word("}");
717         self.end();
718     }
719 
expr_method_call( &mut self, expr: &ExprMethodCall, beginning_of_line: bool, fixup: FixupContext, )720     fn expr_method_call(
721         &mut self,
722         expr: &ExprMethodCall,
723         beginning_of_line: bool,
724         fixup: FixupContext,
725     ) {
726         self.outer_attrs(&expr.attrs);
727         self.cbox(INDENT);
728         let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver);
729         self.prefix_subexpr_method_call(expr, beginning_of_line, unindent_call_args, fixup);
730         self.end();
731     }
732 
prefix_subexpr_method_call( &mut self, expr: &ExprMethodCall, beginning_of_line: bool, unindent_call_args: bool, fixup: FixupContext, )733     fn prefix_subexpr_method_call(
734         &mut self,
735         expr: &ExprMethodCall,
736         beginning_of_line: bool,
737         unindent_call_args: bool,
738         fixup: FixupContext,
739     ) {
740         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.receiver);
741 
742         self.prefix_subexpr(
743             &expr.receiver,
744             left_prec < Precedence::Unambiguous,
745             beginning_of_line,
746             left_fixup,
747         );
748         if !(beginning_of_line && is_short_ident(&expr.receiver)) {
749             self.scan_break(BreakToken {
750                 no_break: self.ends_with('.').then_some(' '),
751                 ..BreakToken::default()
752             });
753         }
754         self.word(".");
755         self.ident(&expr.method);
756         if let Some(turbofish) = &expr.turbofish {
757             self.angle_bracketed_generic_arguments(turbofish, PathKind::Expr);
758         }
759         self.cbox(if unindent_call_args { -INDENT } else { 0 });
760         self.word("(");
761         self.call_args(&expr.args);
762         self.word(")");
763         self.end();
764     }
765 
expr_paren(&mut self, expr: &ExprParen)766     fn expr_paren(&mut self, expr: &ExprParen) {
767         self.outer_attrs(&expr.attrs);
768         self.word("(");
769         self.expr(&expr.expr, FixupContext::NONE);
770         self.word(")");
771     }
772 
expr_path(&mut self, expr: &ExprPath)773     pub fn expr_path(&mut self, expr: &ExprPath) {
774         self.outer_attrs(&expr.attrs);
775         self.qpath(&expr.qself, &expr.path, PathKind::Expr);
776     }
777 
expr_range(&mut self, expr: &ExprRange, fixup: FixupContext)778     pub fn expr_range(&mut self, expr: &ExprRange, fixup: FixupContext) {
779         self.outer_attrs(&expr.attrs);
780         if let Some(start) = &expr.start {
781             let (left_prec, left_fixup) =
782                 fixup.leftmost_subexpression_with_operator(start, true, false, Precedence::Range);
783             self.subexpr(start, left_prec <= Precedence::Range, left_fixup);
784         } else if self.ends_with('.') {
785             self.nbsp();
786         }
787         self.word(match expr.limits {
788             RangeLimits::HalfOpen(_) => "..",
789             RangeLimits::Closed(_) => "..=",
790         });
791         if let Some(end) = &expr.end {
792             let right_fixup = fixup.rightmost_subexpression_fixup(false, true, Precedence::Range);
793             let right_prec = right_fixup.rightmost_subexpression_precedence(end);
794             self.subexpr(end, right_prec <= Precedence::Range, right_fixup);
795         }
796     }
797 
expr_raw_addr(&mut self, expr: &ExprRawAddr, fixup: FixupContext)798     fn expr_raw_addr(&mut self, expr: &ExprRawAddr, fixup: FixupContext) {
799         let (right_prec, right_fixup) =
800             fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix);
801 
802         self.outer_attrs(&expr.attrs);
803         self.word("&raw ");
804         self.pointer_mutability(&expr.mutability);
805         self.nbsp();
806         self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup);
807     }
808 
expr_reference(&mut self, expr: &ExprReference, fixup: FixupContext)809     fn expr_reference(&mut self, expr: &ExprReference, fixup: FixupContext) {
810         let (right_prec, right_fixup) =
811             fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix);
812 
813         self.outer_attrs(&expr.attrs);
814         self.word("&");
815         if expr.mutability.is_some() {
816             self.word("mut ");
817         }
818         self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup);
819     }
820 
expr_repeat(&mut self, expr: &ExprRepeat)821     fn expr_repeat(&mut self, expr: &ExprRepeat) {
822         self.outer_attrs(&expr.attrs);
823         self.word("[");
824         self.expr(&expr.expr, FixupContext::NONE);
825         self.word("; ");
826         self.expr(&expr.len, FixupContext::NONE);
827         self.word("]");
828     }
829 
expr_return(&mut self, expr: &ExprReturn, fixup: FixupContext)830     fn expr_return(&mut self, expr: &ExprReturn, fixup: FixupContext) {
831         self.outer_attrs(&expr.attrs);
832         self.word("return");
833         if let Some(value) = &expr.expr {
834             self.nbsp();
835             self.expr(
836                 value,
837                 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
838             );
839         }
840     }
841 
expr_struct(&mut self, expr: &ExprStruct)842     fn expr_struct(&mut self, expr: &ExprStruct) {
843         self.outer_attrs(&expr.attrs);
844         self.cbox(INDENT);
845         self.ibox(-INDENT);
846         self.qpath(&expr.qself, &expr.path, PathKind::Expr);
847         self.end();
848         self.word(" {");
849         self.space_if_nonempty();
850         for field_value in expr.fields.iter().delimited() {
851             self.field_value(&field_value);
852             self.trailing_comma_or_space(field_value.is_last && expr.rest.is_none());
853         }
854         if let Some(rest) = &expr.rest {
855             self.word("..");
856             self.expr(rest, FixupContext::NONE);
857             self.space();
858         }
859         self.offset(-INDENT);
860         self.end_with_max_width(34);
861         self.word("}");
862     }
863 
expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext)864     fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext) {
865         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.expr);
866 
867         self.outer_attrs(&expr.attrs);
868         self.expr_beginning_of_line(
869             &expr.expr,
870             left_prec < Precedence::Unambiguous,
871             beginning_of_line,
872             left_fixup,
873         );
874         self.word("?");
875     }
876 
prefix_subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext)877     fn prefix_subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool, fixup: FixupContext) {
878         let (left_prec, left_fixup) = fixup.leftmost_subexpression_with_dot(&expr.expr);
879 
880         self.prefix_subexpr(
881             &expr.expr,
882             left_prec < Precedence::Unambiguous,
883             beginning_of_line,
884             left_fixup,
885         );
886         self.word("?");
887     }
888 
expr_try_block(&mut self, expr: &ExprTryBlock)889     fn expr_try_block(&mut self, expr: &ExprTryBlock) {
890         self.outer_attrs(&expr.attrs);
891         self.word("try ");
892         self.cbox(INDENT);
893         self.small_block(&expr.block, &expr.attrs);
894         self.end();
895     }
896 
expr_tuple(&mut self, expr: &ExprTuple)897     fn expr_tuple(&mut self, expr: &ExprTuple) {
898         self.outer_attrs(&expr.attrs);
899         self.word("(");
900         self.cbox(INDENT);
901         self.zerobreak();
902         for elem in expr.elems.iter().delimited() {
903             self.expr(&elem, FixupContext::NONE);
904             if expr.elems.len() == 1 {
905                 self.word(",");
906                 self.zerobreak();
907             } else {
908                 self.trailing_comma(elem.is_last);
909             }
910         }
911         self.offset(-INDENT);
912         self.end();
913         self.word(")");
914     }
915 
expr_unary(&mut self, expr: &ExprUnary, fixup: FixupContext)916     fn expr_unary(&mut self, expr: &ExprUnary, fixup: FixupContext) {
917         let (right_prec, right_fixup) =
918             fixup.rightmost_subexpression(&expr.expr, Precedence::Prefix);
919 
920         self.outer_attrs(&expr.attrs);
921         self.unary_operator(&expr.op);
922         self.subexpr(&expr.expr, right_prec < Precedence::Prefix, right_fixup);
923     }
924 
expr_unsafe(&mut self, expr: &ExprUnsafe)925     fn expr_unsafe(&mut self, expr: &ExprUnsafe) {
926         self.outer_attrs(&expr.attrs);
927         self.word("unsafe ");
928         self.cbox(INDENT);
929         self.small_block(&expr.block, &expr.attrs);
930         self.end();
931     }
932 
933     #[cfg(not(feature = "verbatim"))]
expr_verbatim(&mut self, expr: &TokenStream, _fixup: FixupContext)934     fn expr_verbatim(&mut self, expr: &TokenStream, _fixup: FixupContext) {
935         if !expr.is_empty() {
936             unimplemented!("Expr::Verbatim `{}`", expr);
937         }
938     }
939 
940     #[cfg(feature = "verbatim")]
expr_verbatim(&mut self, tokens: &TokenStream, fixup: FixupContext)941     fn expr_verbatim(&mut self, tokens: &TokenStream, fixup: FixupContext) {
942         use syn::parse::discouraged::Speculative;
943         use syn::parse::{Parse, ParseStream, Result};
944         use syn::{parenthesized, Ident};
945 
946         enum ExprVerbatim {
947             Empty,
948             Ellipsis,
949             Become(Become),
950             Builtin(Builtin),
951         }
952 
953         struct Become {
954             attrs: Vec<Attribute>,
955             tail_call: Expr,
956         }
957 
958         struct Builtin {
959             attrs: Vec<Attribute>,
960             name: Ident,
961             args: TokenStream,
962         }
963 
964         mod kw {
965             syn::custom_keyword!(builtin);
966             syn::custom_keyword!(raw);
967         }
968 
969         impl Parse for ExprVerbatim {
970             fn parse(input: ParseStream) -> Result<Self> {
971                 let ahead = input.fork();
972                 let attrs = ahead.call(Attribute::parse_outer)?;
973                 let lookahead = ahead.lookahead1();
974                 if input.is_empty() {
975                     Ok(ExprVerbatim::Empty)
976                 } else if lookahead.peek(Token![become]) {
977                     input.advance_to(&ahead);
978                     input.parse::<Token![become]>()?;
979                     let tail_call: Expr = input.parse()?;
980                     Ok(ExprVerbatim::Become(Become { attrs, tail_call }))
981                 } else if lookahead.peek(kw::builtin) {
982                     input.advance_to(&ahead);
983                     input.parse::<kw::builtin>()?;
984                     input.parse::<Token![#]>()?;
985                     let name: Ident = input.parse()?;
986                     let args;
987                     parenthesized!(args in input);
988                     let args: TokenStream = args.parse()?;
989                     Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args }))
990                 } else if lookahead.peek(Token![...]) {
991                     input.parse::<Token![...]>()?;
992                     Ok(ExprVerbatim::Ellipsis)
993                 } else {
994                     Err(lookahead.error())
995                 }
996             }
997         }
998 
999         let expr: ExprVerbatim = match syn::parse2(tokens.clone()) {
1000             Ok(expr) => expr,
1001             Err(_) => unimplemented!("Expr::Verbatim `{}`", tokens),
1002         };
1003 
1004         match expr {
1005             ExprVerbatim::Empty => {}
1006             ExprVerbatim::Ellipsis => {
1007                 self.word("...");
1008             }
1009             ExprVerbatim::Become(expr) => {
1010                 self.outer_attrs(&expr.attrs);
1011                 self.word("become");
1012                 self.nbsp();
1013                 self.expr(
1014                     &expr.tail_call,
1015                     fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
1016                 );
1017             }
1018             ExprVerbatim::Builtin(expr) => {
1019                 self.outer_attrs(&expr.attrs);
1020                 self.word("builtin # ");
1021                 self.ident(&expr.name);
1022                 self.word("(");
1023                 if !expr.args.is_empty() {
1024                     self.cbox(INDENT);
1025                     self.zerobreak();
1026                     self.ibox(0);
1027                     self.macro_rules_tokens(expr.args, false);
1028                     self.end();
1029                     self.zerobreak();
1030                     self.offset(-INDENT);
1031                     self.end();
1032                 }
1033                 self.word(")");
1034             }
1035         }
1036     }
1037 
expr_while(&mut self, expr: &ExprWhile)1038     fn expr_while(&mut self, expr: &ExprWhile) {
1039         self.outer_attrs(&expr.attrs);
1040         if let Some(label) = &expr.label {
1041             self.label(label);
1042         }
1043         self.word("while ");
1044         self.expr_condition(&expr.cond);
1045         self.word("{");
1046         self.neverbreak();
1047         self.cbox(INDENT);
1048         self.hardbreak_if_nonempty();
1049         self.inner_attrs(&expr.attrs);
1050         for stmt in expr.body.stmts.iter().delimited() {
1051             self.stmt(&stmt, stmt.is_last);
1052         }
1053         self.offset(-INDENT);
1054         self.end();
1055         self.word("}");
1056     }
1057 
expr_yield(&mut self, expr: &ExprYield, fixup: FixupContext)1058     fn expr_yield(&mut self, expr: &ExprYield, fixup: FixupContext) {
1059         self.outer_attrs(&expr.attrs);
1060         self.word("yield");
1061         if let Some(value) = &expr.expr {
1062             self.nbsp();
1063             self.expr(
1064                 value,
1065                 fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump),
1066             );
1067         }
1068     }
1069 
label(&mut self, label: &Label)1070     fn label(&mut self, label: &Label) {
1071         self.lifetime(&label.name);
1072         self.word(": ");
1073     }
1074 
field_value(&mut self, field_value: &FieldValue)1075     fn field_value(&mut self, field_value: &FieldValue) {
1076         self.outer_attrs(&field_value.attrs);
1077         self.member(&field_value.member);
1078         if field_value.colon_token.is_some() {
1079             self.word(": ");
1080             self.ibox(0);
1081             self.expr(&field_value.expr, FixupContext::NONE);
1082             self.end();
1083         }
1084     }
1085 
arm(&mut self, arm: &Arm)1086     fn arm(&mut self, arm: &Arm) {
1087         self.outer_attrs(&arm.attrs);
1088         self.ibox(0);
1089         self.pat(&arm.pat);
1090         if let Some((_if_token, guard)) = &arm.guard {
1091             self.word(" if ");
1092             self.expr(guard, FixupContext::NONE);
1093         }
1094         self.word(" => ");
1095         let empty_block;
1096         let mut body = &*arm.body;
1097         while let Expr::Block(expr) = body {
1098             if expr.attrs.is_empty() && expr.label.is_none() {
1099                 let mut stmts = expr.block.stmts.iter();
1100                 if let (Some(Stmt::Expr(inner, None)), None) = (stmts.next(), stmts.next()) {
1101                     body = inner;
1102                     continue;
1103                 }
1104             }
1105             break;
1106         }
1107         if let Expr::Tuple(expr) = body {
1108             if expr.elems.is_empty() && expr.attrs.is_empty() {
1109                 empty_block = Expr::Block(ExprBlock {
1110                     attrs: Vec::new(),
1111                     label: None,
1112                     block: Block {
1113                         brace_token: token::Brace::default(),
1114                         stmts: Vec::new(),
1115                     },
1116                 });
1117                 body = &empty_block;
1118             }
1119         }
1120         if let Expr::Block(body) = body {
1121             if let Some(label) = &body.label {
1122                 self.label(label);
1123             }
1124             self.word("{");
1125             self.neverbreak();
1126             self.cbox(INDENT);
1127             self.hardbreak_if_nonempty();
1128             self.inner_attrs(&body.attrs);
1129             for stmt in body.block.stmts.iter().delimited() {
1130                 self.stmt(&stmt, stmt.is_last);
1131             }
1132             self.offset(-INDENT);
1133             self.end();
1134             self.word("}");
1135         } else {
1136             self.neverbreak();
1137             self.cbox(INDENT);
1138             let okay_to_brace = parseable_as_stmt(body);
1139             self.scan_break(BreakToken {
1140                 pre_break: Some(if okay_to_brace { '{' } else { '(' }),
1141                 ..BreakToken::default()
1142             });
1143             self.expr_beginning_of_line(body, false, true, FixupContext::new_match_arm());
1144             self.scan_break(BreakToken {
1145                 offset: -INDENT,
1146                 pre_break: (okay_to_brace && stmt::add_semi(body)).then_some(';'),
1147                 post_break: if okay_to_brace { "}" } else { ")," },
1148                 no_break: classify::requires_comma_to_be_match_arm(body).then_some(','),
1149                 ..BreakToken::default()
1150             });
1151             self.end();
1152         }
1153         self.end();
1154     }
1155 
call_args(&mut self, args: &Punctuated<Expr, Token![,]>)1156     fn call_args(&mut self, args: &Punctuated<Expr, Token![,]>) {
1157         let mut iter = args.iter();
1158         match (iter.next(), iter.next()) {
1159             (Some(expr), None) if is_blocklike(expr) => {
1160                 self.expr(expr, FixupContext::NONE);
1161             }
1162             _ => {
1163                 self.cbox(INDENT);
1164                 self.zerobreak();
1165                 for arg in args.iter().delimited() {
1166                     self.expr(&arg, FixupContext::NONE);
1167                     self.trailing_comma(arg.is_last);
1168                 }
1169                 self.offset(-INDENT);
1170                 self.end();
1171             }
1172         }
1173     }
1174 
small_block(&mut self, block: &Block, attrs: &[Attribute])1175     pub fn small_block(&mut self, block: &Block, attrs: &[Attribute]) {
1176         self.word("{");
1177         if attr::has_inner(attrs) || !block.stmts.is_empty() {
1178             self.space();
1179             self.inner_attrs(attrs);
1180             match block.stmts.as_slice() {
1181                 [Stmt::Expr(expr, None)] if stmt::break_after(expr) => {
1182                     self.ibox(0);
1183                     self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt());
1184                     self.end();
1185                     self.space();
1186                 }
1187                 _ => {
1188                     for stmt in block.stmts.iter().delimited() {
1189                         self.stmt(&stmt, stmt.is_last);
1190                     }
1191                 }
1192             }
1193             self.offset(-INDENT);
1194         }
1195         self.word("}");
1196     }
1197 
expr_as_small_block(&mut self, expr: &Expr, indent: isize)1198     pub fn expr_as_small_block(&mut self, expr: &Expr, indent: isize) {
1199         self.word("{");
1200         self.space();
1201         self.ibox(indent);
1202         self.expr_beginning_of_line(expr, false, true, FixupContext::new_stmt());
1203         self.end();
1204         self.space();
1205         self.offset(-INDENT);
1206         self.word("}");
1207     }
1208 
member(&mut self, member: &Member)1209     pub fn member(&mut self, member: &Member) {
1210         match member {
1211             Member::Named(ident) => self.ident(ident),
1212             Member::Unnamed(index) => self.index(index),
1213         }
1214     }
1215 
index(&mut self, member: &Index)1216     fn index(&mut self, member: &Index) {
1217         self.word(member.index.to_string());
1218     }
1219 
binary_operator(&mut self, op: &BinOp)1220     fn binary_operator(&mut self, op: &BinOp) {
1221         self.word(
1222             match op {
1223                 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1224                 BinOp::Add(_) => "+",
1225                 BinOp::Sub(_) => "-",
1226                 BinOp::Mul(_) => "*",
1227                 BinOp::Div(_) => "/",
1228                 BinOp::Rem(_) => "%",
1229                 BinOp::And(_) => "&&",
1230                 BinOp::Or(_) => "||",
1231                 BinOp::BitXor(_) => "^",
1232                 BinOp::BitAnd(_) => "&",
1233                 BinOp::BitOr(_) => "|",
1234                 BinOp::Shl(_) => "<<",
1235                 BinOp::Shr(_) => ">>",
1236                 BinOp::Eq(_) => "==",
1237                 BinOp::Lt(_) => "<",
1238                 BinOp::Le(_) => "<=",
1239                 BinOp::Ne(_) => "!=",
1240                 BinOp::Ge(_) => ">=",
1241                 BinOp::Gt(_) => ">",
1242                 BinOp::AddAssign(_) => "+=",
1243                 BinOp::SubAssign(_) => "-=",
1244                 BinOp::MulAssign(_) => "*=",
1245                 BinOp::DivAssign(_) => "/=",
1246                 BinOp::RemAssign(_) => "%=",
1247                 BinOp::BitXorAssign(_) => "^=",
1248                 BinOp::BitAndAssign(_) => "&=",
1249                 BinOp::BitOrAssign(_) => "|=",
1250                 BinOp::ShlAssign(_) => "<<=",
1251                 BinOp::ShrAssign(_) => ">>=",
1252                 _ => unimplemented!("unknown BinOp"),
1253             },
1254         );
1255     }
1256 
unary_operator(&mut self, op: &UnOp)1257     fn unary_operator(&mut self, op: &UnOp) {
1258         self.word(
1259             match op {
1260                 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1261                 UnOp::Deref(_) => "*",
1262                 UnOp::Not(_) => "!",
1263                 UnOp::Neg(_) => "-",
1264                 _ => unimplemented!("unknown UnOp"),
1265             },
1266         );
1267     }
1268 
pointer_mutability(&mut self, mutability: &PointerMutability)1269     fn pointer_mutability(&mut self, mutability: &PointerMutability) {
1270         match mutability {
1271             PointerMutability::Const(_) => self.word("const"),
1272             PointerMutability::Mut(_) => self.word("mut"),
1273         }
1274     }
1275 }
1276 
needs_newline_if_wrap(expr: &Expr) -> bool1277 fn needs_newline_if_wrap(expr: &Expr) -> bool {
1278     match expr {
1279         #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1280         Expr::Array(_)
1281         | Expr::Async(_)
1282         | Expr::Block(_)
1283         | Expr::Break(ExprBreak { expr: None, .. })
1284         | Expr::Closure(_)
1285         | Expr::Const(_)
1286         | Expr::Continue(_)
1287         | Expr::ForLoop(_)
1288         | Expr::If(_)
1289         | Expr::Infer(_)
1290         | Expr::Lit(_)
1291         | Expr::Loop(_)
1292         | Expr::Macro(_)
1293         | Expr::Match(_)
1294         | Expr::Path(_)
1295         | Expr::Range(ExprRange { end: None, .. })
1296         | Expr::Repeat(_)
1297         | Expr::Return(ExprReturn { expr: None, .. })
1298         | Expr::Struct(_)
1299         | Expr::TryBlock(_)
1300         | Expr::Tuple(_)
1301         | Expr::Unsafe(_)
1302         | Expr::Verbatim(_)
1303         | Expr::While(_)
1304         | Expr::Yield(ExprYield { expr: None, .. }) => false,
1305 
1306         Expr::Assign(_)
1307         | Expr::Await(_)
1308         | Expr::Binary(_)
1309         | Expr::Cast(_)
1310         | Expr::Field(_)
1311         | Expr::Index(_)
1312         | Expr::MethodCall(_) => true,
1313 
1314         Expr::Break(ExprBreak { expr: Some(e), .. })
1315         | Expr::Call(ExprCall { func: e, .. })
1316         | Expr::Group(ExprGroup { expr: e, .. })
1317         | Expr::Let(ExprLet { expr: e, .. })
1318         | Expr::Paren(ExprParen { expr: e, .. })
1319         | Expr::Range(ExprRange { end: Some(e), .. })
1320         | Expr::RawAddr(ExprRawAddr { expr: e, .. })
1321         | Expr::Reference(ExprReference { expr: e, .. })
1322         | Expr::Return(ExprReturn { expr: Some(e), .. })
1323         | Expr::Try(ExprTry { expr: e, .. })
1324         | Expr::Unary(ExprUnary { expr: e, .. })
1325         | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1326 
1327         _ => false,
1328     }
1329 }
1330 
is_short_ident(expr: &Expr) -> bool1331 fn is_short_ident(expr: &Expr) -> bool {
1332     if let Expr::Path(expr) = expr {
1333         return expr.attrs.is_empty()
1334             && expr.qself.is_none()
1335             && expr
1336                 .path
1337                 .get_ident()
1338                 .map_or(false, |ident| ident.to_string().len() as isize <= INDENT);
1339     }
1340     false
1341 }
1342 
is_blocklike(expr: &Expr) -> bool1343 fn is_blocklike(expr: &Expr) -> bool {
1344     match expr {
1345         #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1346         Expr::Array(ExprArray { attrs, .. })
1347         | Expr::Async(ExprAsync { attrs, .. })
1348         | Expr::Block(ExprBlock { attrs, .. })
1349         | Expr::Closure(ExprClosure { attrs, .. })
1350         | Expr::Const(ExprConst { attrs, .. })
1351         | Expr::Struct(ExprStruct { attrs, .. })
1352         | Expr::TryBlock(ExprTryBlock { attrs, .. })
1353         | Expr::Tuple(ExprTuple { attrs, .. })
1354         | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1355 
1356         Expr::Assign(_)
1357         | Expr::Await(_)
1358         | Expr::Binary(_)
1359         | Expr::Break(_)
1360         | Expr::Call(_)
1361         | Expr::Cast(_)
1362         | Expr::Continue(_)
1363         | Expr::Field(_)
1364         | Expr::ForLoop(_)
1365         | Expr::If(_)
1366         | Expr::Index(_)
1367         | Expr::Infer(_)
1368         | Expr::Let(_)
1369         | Expr::Lit(_)
1370         | Expr::Loop(_)
1371         | Expr::Macro(_)
1372         | Expr::Match(_)
1373         | Expr::MethodCall(_)
1374         | Expr::Paren(_)
1375         | Expr::Path(_)
1376         | Expr::Range(_)
1377         | Expr::RawAddr(_)
1378         | Expr::Reference(_)
1379         | Expr::Repeat(_)
1380         | Expr::Return(_)
1381         | Expr::Try(_)
1382         | Expr::Unary(_)
1383         | Expr::Verbatim(_)
1384         | Expr::While(_)
1385         | Expr::Yield(_) => false,
1386 
1387         Expr::Group(e) => is_blocklike(&e.expr),
1388 
1389         _ => false,
1390     }
1391 }
1392 
simple_block(expr: &Expr) -> Option<&ExprBlock>1393 pub fn simple_block(expr: &Expr) -> Option<&ExprBlock> {
1394     if let Expr::Block(expr) = expr {
1395         if expr.attrs.is_empty() && expr.label.is_none() {
1396             return Some(expr);
1397         }
1398     }
1399     None
1400 }
1401 
simple_array(elements: &Punctuated<Expr, Token![,]>) -> bool1402 pub fn simple_array(elements: &Punctuated<Expr, Token![,]>) -> bool {
1403     for expr in elements {
1404         if let Expr::Lit(expr) = expr {
1405             match expr.lit {
1406                 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1407                 Lit::Byte(_) | Lit::Char(_) | Lit::Int(_) | Lit::Bool(_) => {}
1408 
1409                 Lit::Str(_) | Lit::ByteStr(_) | Lit::CStr(_) | Lit::Float(_) | Lit::Verbatim(_) => {
1410                     return false;
1411                 }
1412 
1413                 _ => return false,
1414             }
1415         } else {
1416             return false;
1417         }
1418     }
1419     true
1420 }
1421 
1422 // Expressions for which `$expr` and `{ $expr }` mean the same thing.
1423 //
1424 // This is not the case for all expressions. For example `{} | x | x` has some
1425 // bitwise OR operators while `{ {} |x| x }` has a block followed by a closure.
parseable_as_stmt(mut expr: &Expr) -> bool1426 fn parseable_as_stmt(mut expr: &Expr) -> bool {
1427     loop {
1428         match expr {
1429             #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1430             Expr::Array(_)
1431             | Expr::Async(_)
1432             | Expr::Block(_)
1433             | Expr::Break(_)
1434             | Expr::Closure(_)
1435             | Expr::Const(_)
1436             | Expr::Continue(_)
1437             | Expr::ForLoop(_)
1438             | Expr::If(_)
1439             | Expr::Infer(_)
1440             | Expr::Lit(_)
1441             | Expr::Loop(_)
1442             | Expr::Macro(_)
1443             | Expr::Match(_)
1444             | Expr::Paren(_)
1445             | Expr::Path(_)
1446             | Expr::RawAddr(_)
1447             | Expr::Reference(_)
1448             | Expr::Repeat(_)
1449             | Expr::Return(_)
1450             | Expr::Struct(_)
1451             | Expr::TryBlock(_)
1452             | Expr::Tuple(_)
1453             | Expr::Unary(_)
1454             | Expr::Unsafe(_)
1455             | Expr::Verbatim(_)
1456             | Expr::While(_)
1457             | Expr::Yield(_) => return true,
1458 
1459             Expr::Let(_) => return false,
1460 
1461             Expr::Assign(e) => {
1462                 if !classify::requires_semi_to_be_stmt(&e.left) {
1463                     return false;
1464                 }
1465                 expr = &e.left;
1466             }
1467             Expr::Await(e) => expr = &e.base,
1468             Expr::Binary(e) => {
1469                 if !classify::requires_semi_to_be_stmt(&e.left) {
1470                     return false;
1471                 }
1472                 expr = &e.left;
1473             }
1474             Expr::Call(e) => {
1475                 if !classify::requires_semi_to_be_stmt(&e.func) {
1476                     return false;
1477                 }
1478                 expr = &e.func;
1479             }
1480             Expr::Cast(e) => {
1481                 if !classify::requires_semi_to_be_stmt(&e.expr) {
1482                     return false;
1483                 }
1484                 expr = &e.expr;
1485             }
1486             Expr::Field(e) => expr = &e.base,
1487             Expr::Group(e) => expr = &e.expr,
1488             Expr::Index(e) => {
1489                 if !classify::requires_semi_to_be_stmt(&e.expr) {
1490                     return false;
1491                 }
1492                 expr = &e.expr;
1493             }
1494             Expr::MethodCall(e) => expr = &e.receiver,
1495             Expr::Range(e) => match &e.start {
1496                 None => return true,
1497                 Some(start) => {
1498                     if !classify::requires_semi_to_be_stmt(start) {
1499                         return false;
1500                     }
1501                     expr = start;
1502                 }
1503             },
1504             Expr::Try(e) => expr = &e.expr,
1505 
1506             _ => return false,
1507         }
1508     }
1509 }
1510