• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::algorithm::{BreakToken, Printer};
2 use crate::attr;
3 use crate::iter::IterDelimited;
4 use crate::path::PathKind;
5 use crate::stmt;
6 use crate::INDENT;
7 use proc_macro2::TokenStream;
8 use syn::punctuated::Punctuated;
9 use syn::{
10     token, Arm, Attribute, BinOp, Block, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait,
11     ExprBinary, ExprBlock, ExprBreak, ExprCall, ExprCast, ExprClosure, ExprConst, ExprContinue,
12     ExprField, ExprForLoop, ExprGroup, ExprIf, ExprIndex, ExprInfer, ExprLet, ExprLit, ExprLoop,
13     ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprReference,
14     ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary, ExprUnsafe,
15     ExprWhile, ExprYield, FieldValue, Index, Label, Member, RangeLimits, ReturnType, Stmt, Token,
16     UnOp,
17 };
18 
19 impl Printer {
expr(&mut self, expr: &Expr)20     pub fn expr(&mut self, expr: &Expr) {
21         match expr {
22             Expr::Array(expr) => self.expr_array(expr),
23             Expr::Assign(expr) => self.expr_assign(expr),
24             Expr::Async(expr) => self.expr_async(expr),
25             Expr::Await(expr) => self.expr_await(expr, false),
26             Expr::Binary(expr) => self.expr_binary(expr),
27             Expr::Block(expr) => self.expr_block(expr),
28             Expr::Break(expr) => self.expr_break(expr),
29             Expr::Call(expr) => self.expr_call(expr, false),
30             Expr::Cast(expr) => self.expr_cast(expr),
31             Expr::Closure(expr) => self.expr_closure(expr),
32             Expr::Const(expr) => self.expr_const(expr),
33             Expr::Continue(expr) => self.expr_continue(expr),
34             Expr::Field(expr) => self.expr_field(expr, false),
35             Expr::ForLoop(expr) => self.expr_for_loop(expr),
36             Expr::Group(expr) => self.expr_group(expr),
37             Expr::If(expr) => self.expr_if(expr),
38             Expr::Index(expr) => self.expr_index(expr, false),
39             Expr::Infer(expr) => self.expr_infer(expr),
40             Expr::Let(expr) => self.expr_let(expr),
41             Expr::Lit(expr) => self.expr_lit(expr),
42             Expr::Loop(expr) => self.expr_loop(expr),
43             Expr::Macro(expr) => self.expr_macro(expr),
44             Expr::Match(expr) => self.expr_match(expr),
45             Expr::MethodCall(expr) => self.expr_method_call(expr, false),
46             Expr::Paren(expr) => self.expr_paren(expr),
47             Expr::Path(expr) => self.expr_path(expr),
48             Expr::Range(expr) => self.expr_range(expr),
49             Expr::Reference(expr) => self.expr_reference(expr),
50             Expr::Repeat(expr) => self.expr_repeat(expr),
51             Expr::Return(expr) => self.expr_return(expr),
52             Expr::Struct(expr) => self.expr_struct(expr),
53             Expr::Try(expr) => self.expr_try(expr, false),
54             Expr::TryBlock(expr) => self.expr_try_block(expr),
55             Expr::Tuple(expr) => self.expr_tuple(expr),
56             Expr::Unary(expr) => self.expr_unary(expr),
57             Expr::Unsafe(expr) => self.expr_unsafe(expr),
58             Expr::Verbatim(expr) => self.expr_verbatim(expr),
59             Expr::While(expr) => self.expr_while(expr),
60             Expr::Yield(expr) => self.expr_yield(expr),
61             #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
62             _ => unimplemented!("unknown Expr"),
63         }
64     }
65 
expr_beginning_of_line(&mut self, expr: &Expr, beginning_of_line: bool)66     pub fn expr_beginning_of_line(&mut self, expr: &Expr, beginning_of_line: bool) {
67         match expr {
68             Expr::Await(expr) => self.expr_await(expr, beginning_of_line),
69             Expr::Field(expr) => self.expr_field(expr, beginning_of_line),
70             Expr::Index(expr) => self.expr_index(expr, beginning_of_line),
71             Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line),
72             Expr::Try(expr) => self.expr_try(expr, beginning_of_line),
73             _ => self.expr(expr),
74         }
75     }
76 
subexpr(&mut self, expr: &Expr, beginning_of_line: bool)77     fn subexpr(&mut self, expr: &Expr, beginning_of_line: bool) {
78         match expr {
79             Expr::Await(expr) => self.subexpr_await(expr, beginning_of_line),
80             Expr::Call(expr) => self.subexpr_call(expr),
81             Expr::Field(expr) => self.subexpr_field(expr, beginning_of_line),
82             Expr::Index(expr) => self.subexpr_index(expr, beginning_of_line),
83             Expr::MethodCall(expr) => self.subexpr_method_call(expr, beginning_of_line, false),
84             Expr::Try(expr) => self.subexpr_try(expr, beginning_of_line),
85             _ => {
86                 self.cbox(-INDENT);
87                 self.expr(expr);
88                 self.end();
89             }
90         }
91     }
92 
wrap_exterior_struct(&mut self, expr: &Expr)93     fn wrap_exterior_struct(&mut self, expr: &Expr) {
94         let needs_paren = contains_exterior_struct_lit(expr);
95         if needs_paren {
96             self.word("(");
97         }
98         self.cbox(0);
99         self.expr(expr);
100         if needs_paren {
101             self.word(")");
102         }
103         if needs_newline_if_wrap(expr) {
104             self.space();
105         } else {
106             self.nbsp();
107         }
108         self.end();
109     }
110 
expr_array(&mut self, expr: &ExprArray)111     fn expr_array(&mut self, expr: &ExprArray) {
112         self.outer_attrs(&expr.attrs);
113         self.word("[");
114         self.cbox(INDENT);
115         self.zerobreak();
116         for element in expr.elems.iter().delimited() {
117             self.expr(&element);
118             self.trailing_comma(element.is_last);
119         }
120         self.offset(-INDENT);
121         self.end();
122         self.word("]");
123     }
124 
expr_assign(&mut self, expr: &ExprAssign)125     fn expr_assign(&mut self, expr: &ExprAssign) {
126         self.outer_attrs(&expr.attrs);
127         self.ibox(0);
128         self.expr(&expr.left);
129         self.word(" = ");
130         self.expr(&expr.right);
131         self.end();
132     }
133 
expr_async(&mut self, expr: &ExprAsync)134     fn expr_async(&mut self, expr: &ExprAsync) {
135         self.outer_attrs(&expr.attrs);
136         self.word("async ");
137         if expr.capture.is_some() {
138             self.word("move ");
139         }
140         self.cbox(INDENT);
141         self.small_block(&expr.block, &expr.attrs);
142         self.end();
143     }
144 
expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool)145     fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
146         self.outer_attrs(&expr.attrs);
147         self.cbox(INDENT);
148         self.subexpr_await(expr, beginning_of_line);
149         self.end();
150     }
151 
subexpr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool)152     fn subexpr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
153         self.subexpr(&expr.base, beginning_of_line);
154         self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
155         self.word(".await");
156     }
157 
expr_binary(&mut self, expr: &ExprBinary)158     fn expr_binary(&mut self, expr: &ExprBinary) {
159         self.outer_attrs(&expr.attrs);
160         self.ibox(INDENT);
161         self.ibox(-INDENT);
162         self.expr(&expr.left);
163         self.end();
164         self.space();
165         self.binary_operator(&expr.op);
166         self.nbsp();
167         self.expr(&expr.right);
168         self.end();
169     }
170 
expr_block(&mut self, expr: &ExprBlock)171     pub fn expr_block(&mut self, expr: &ExprBlock) {
172         self.outer_attrs(&expr.attrs);
173         if let Some(label) = &expr.label {
174             self.label(label);
175         }
176         self.cbox(INDENT);
177         self.small_block(&expr.block, &expr.attrs);
178         self.end();
179     }
180 
expr_break(&mut self, expr: &ExprBreak)181     fn expr_break(&mut self, expr: &ExprBreak) {
182         self.outer_attrs(&expr.attrs);
183         self.word("break");
184         if let Some(lifetime) = &expr.label {
185             self.nbsp();
186             self.lifetime(lifetime);
187         }
188         if let Some(value) = &expr.expr {
189             self.nbsp();
190             self.expr(value);
191         }
192     }
193 
expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool)194     fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool) {
195         self.outer_attrs(&expr.attrs);
196         self.expr_beginning_of_line(&expr.func, beginning_of_line);
197         self.word("(");
198         self.call_args(&expr.args);
199         self.word(")");
200     }
201 
subexpr_call(&mut self, expr: &ExprCall)202     fn subexpr_call(&mut self, expr: &ExprCall) {
203         self.subexpr(&expr.func, false);
204         self.word("(");
205         self.call_args(&expr.args);
206         self.word(")");
207     }
208 
expr_cast(&mut self, expr: &ExprCast)209     fn expr_cast(&mut self, expr: &ExprCast) {
210         self.outer_attrs(&expr.attrs);
211         self.ibox(INDENT);
212         self.ibox(-INDENT);
213         self.expr(&expr.expr);
214         self.end();
215         self.space();
216         self.word("as ");
217         self.ty(&expr.ty);
218         self.end();
219     }
220 
expr_closure(&mut self, expr: &ExprClosure)221     fn expr_closure(&mut self, expr: &ExprClosure) {
222         self.outer_attrs(&expr.attrs);
223         self.ibox(0);
224         if let Some(bound_lifetimes) = &expr.lifetimes {
225             self.bound_lifetimes(bound_lifetimes);
226         }
227         if expr.constness.is_some() {
228             self.word("const ");
229         }
230         if expr.movability.is_some() {
231             self.word("static ");
232         }
233         if expr.asyncness.is_some() {
234             self.word("async ");
235         }
236         if expr.capture.is_some() {
237             self.word("move ");
238         }
239         self.cbox(INDENT);
240         self.word("|");
241         for pat in expr.inputs.iter().delimited() {
242             if pat.is_first {
243                 self.zerobreak();
244             }
245             self.pat(&pat);
246             if !pat.is_last {
247                 self.word(",");
248                 self.space();
249             }
250         }
251         match &expr.output {
252             ReturnType::Default => {
253                 self.word("|");
254                 self.space();
255                 self.offset(-INDENT);
256                 self.end();
257                 self.neverbreak();
258                 let wrap_in_brace = match &*expr.body {
259                     Expr::Match(ExprMatch { attrs, .. }) | Expr::Call(ExprCall { attrs, .. }) => {
260                         attr::has_outer(attrs)
261                     }
262                     body => !is_blocklike(body),
263                 };
264                 if wrap_in_brace {
265                     self.cbox(INDENT);
266                     self.scan_break(BreakToken {
267                         pre_break: Some('{'),
268                         ..BreakToken::default()
269                     });
270                     self.expr(&expr.body);
271                     self.scan_break(BreakToken {
272                         offset: -INDENT,
273                         pre_break: stmt::add_semi(&expr.body).then(|| ';'),
274                         post_break: Some('}'),
275                         ..BreakToken::default()
276                     });
277                     self.end();
278                 } else {
279                     self.expr(&expr.body);
280                 }
281             }
282             ReturnType::Type(_arrow, ty) => {
283                 if !expr.inputs.is_empty() {
284                     self.trailing_comma(true);
285                     self.offset(-INDENT);
286                 }
287                 self.word("|");
288                 self.end();
289                 self.word(" -> ");
290                 self.ty(ty);
291                 self.nbsp();
292                 self.neverbreak();
293                 self.expr(&expr.body);
294             }
295         }
296         self.end();
297     }
298 
expr_const(&mut self, expr: &ExprConst)299     pub fn expr_const(&mut self, expr: &ExprConst) {
300         self.outer_attrs(&expr.attrs);
301         self.word("const ");
302         self.cbox(INDENT);
303         self.small_block(&expr.block, &expr.attrs);
304         self.end();
305     }
306 
expr_continue(&mut self, expr: &ExprContinue)307     fn expr_continue(&mut self, expr: &ExprContinue) {
308         self.outer_attrs(&expr.attrs);
309         self.word("continue");
310         if let Some(lifetime) = &expr.label {
311             self.nbsp();
312             self.lifetime(lifetime);
313         }
314     }
315 
expr_field(&mut self, expr: &ExprField, beginning_of_line: bool)316     fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
317         self.outer_attrs(&expr.attrs);
318         self.cbox(INDENT);
319         self.subexpr_field(expr, beginning_of_line);
320         self.end();
321     }
322 
subexpr_field(&mut self, expr: &ExprField, beginning_of_line: bool)323     fn subexpr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
324         self.subexpr(&expr.base, beginning_of_line);
325         self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
326         self.word(".");
327         self.member(&expr.member);
328     }
329 
expr_for_loop(&mut self, expr: &ExprForLoop)330     fn expr_for_loop(&mut self, expr: &ExprForLoop) {
331         self.outer_attrs(&expr.attrs);
332         self.ibox(0);
333         if let Some(label) = &expr.label {
334             self.label(label);
335         }
336         self.word("for ");
337         self.pat(&expr.pat);
338         self.word(" in ");
339         self.neverbreak();
340         self.wrap_exterior_struct(&expr.expr);
341         self.word("{");
342         self.neverbreak();
343         self.cbox(INDENT);
344         self.hardbreak_if_nonempty();
345         self.inner_attrs(&expr.attrs);
346         for stmt in &expr.body.stmts {
347             self.stmt(stmt);
348         }
349         self.offset(-INDENT);
350         self.end();
351         self.word("}");
352         self.end();
353     }
354 
expr_group(&mut self, expr: &ExprGroup)355     fn expr_group(&mut self, expr: &ExprGroup) {
356         self.outer_attrs(&expr.attrs);
357         self.expr(&expr.expr);
358     }
359 
expr_if(&mut self, expr: &ExprIf)360     fn expr_if(&mut self, expr: &ExprIf) {
361         self.outer_attrs(&expr.attrs);
362         self.cbox(INDENT);
363         self.word("if ");
364         self.cbox(-INDENT);
365         self.wrap_exterior_struct(&expr.cond);
366         self.end();
367         if let Some((_else_token, else_branch)) = &expr.else_branch {
368             let mut else_branch = &**else_branch;
369             self.small_block(&expr.then_branch, &[]);
370             loop {
371                 self.word(" else ");
372                 match else_branch {
373                     Expr::If(expr) => {
374                         self.word("if ");
375                         self.cbox(-INDENT);
376                         self.wrap_exterior_struct(&expr.cond);
377                         self.end();
378                         self.small_block(&expr.then_branch, &[]);
379                         if let Some((_else_token, next)) = &expr.else_branch {
380                             else_branch = next;
381                             continue;
382                         }
383                     }
384                     Expr::Block(expr) => {
385                         self.small_block(&expr.block, &[]);
386                     }
387                     // If not one of the valid expressions to exist in an else
388                     // clause, wrap in a block.
389                     other => {
390                         self.word("{");
391                         self.space();
392                         self.ibox(INDENT);
393                         self.expr(other);
394                         self.end();
395                         self.space();
396                         self.offset(-INDENT);
397                         self.word("}");
398                     }
399                 }
400                 break;
401             }
402         } else if expr.then_branch.stmts.is_empty() {
403             self.word("{}");
404         } else {
405             self.word("{");
406             self.hardbreak();
407             for stmt in &expr.then_branch.stmts {
408                 self.stmt(stmt);
409             }
410             self.offset(-INDENT);
411             self.word("}");
412         }
413         self.end();
414     }
415 
expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool)416     fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
417         self.outer_attrs(&expr.attrs);
418         self.expr_beginning_of_line(&expr.expr, beginning_of_line);
419         self.word("[");
420         self.expr(&expr.index);
421         self.word("]");
422     }
423 
subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool)424     fn subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
425         self.subexpr(&expr.expr, beginning_of_line);
426         self.word("[");
427         self.expr(&expr.index);
428         self.word("]");
429     }
430 
expr_infer(&mut self, expr: &ExprInfer)431     fn expr_infer(&mut self, expr: &ExprInfer) {
432         self.outer_attrs(&expr.attrs);
433         self.word("_");
434     }
435 
expr_let(&mut self, expr: &ExprLet)436     fn expr_let(&mut self, expr: &ExprLet) {
437         self.outer_attrs(&expr.attrs);
438         self.ibox(INDENT);
439         self.word("let ");
440         self.ibox(-INDENT);
441         self.pat(&expr.pat);
442         self.end();
443         self.space();
444         self.word("= ");
445         let needs_paren = contains_exterior_struct_lit(&expr.expr);
446         if needs_paren {
447             self.word("(");
448         }
449         self.expr(&expr.expr);
450         if needs_paren {
451             self.word(")");
452         }
453         self.end();
454     }
455 
expr_lit(&mut self, expr: &ExprLit)456     pub fn expr_lit(&mut self, expr: &ExprLit) {
457         self.outer_attrs(&expr.attrs);
458         self.lit(&expr.lit);
459     }
460 
expr_loop(&mut self, expr: &ExprLoop)461     fn expr_loop(&mut self, expr: &ExprLoop) {
462         self.outer_attrs(&expr.attrs);
463         if let Some(label) = &expr.label {
464             self.label(label);
465         }
466         self.word("loop {");
467         self.cbox(INDENT);
468         self.hardbreak_if_nonempty();
469         self.inner_attrs(&expr.attrs);
470         for stmt in &expr.body.stmts {
471             self.stmt(stmt);
472         }
473         self.offset(-INDENT);
474         self.end();
475         self.word("}");
476     }
477 
expr_macro(&mut self, expr: &ExprMacro)478     pub fn expr_macro(&mut self, expr: &ExprMacro) {
479         self.outer_attrs(&expr.attrs);
480         let semicolon = false;
481         self.mac(&expr.mac, None, semicolon);
482     }
483 
expr_match(&mut self, expr: &ExprMatch)484     fn expr_match(&mut self, expr: &ExprMatch) {
485         self.outer_attrs(&expr.attrs);
486         self.ibox(0);
487         self.word("match ");
488         self.wrap_exterior_struct(&expr.expr);
489         self.word("{");
490         self.neverbreak();
491         self.cbox(INDENT);
492         self.hardbreak_if_nonempty();
493         self.inner_attrs(&expr.attrs);
494         for arm in &expr.arms {
495             self.arm(arm);
496             self.hardbreak();
497         }
498         self.offset(-INDENT);
499         self.end();
500         self.word("}");
501         self.end();
502     }
503 
expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool)504     fn expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool) {
505         self.outer_attrs(&expr.attrs);
506         self.cbox(INDENT);
507         let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver);
508         self.subexpr_method_call(expr, beginning_of_line, unindent_call_args);
509         self.end();
510     }
511 
subexpr_method_call( &mut self, expr: &ExprMethodCall, beginning_of_line: bool, unindent_call_args: bool, )512     fn subexpr_method_call(
513         &mut self,
514         expr: &ExprMethodCall,
515         beginning_of_line: bool,
516         unindent_call_args: bool,
517     ) {
518         self.subexpr(&expr.receiver, beginning_of_line);
519         self.zerobreak_unless_short_ident(beginning_of_line, &expr.receiver);
520         self.word(".");
521         self.ident(&expr.method);
522         if let Some(turbofish) = &expr.turbofish {
523             self.angle_bracketed_generic_arguments(turbofish, PathKind::Expr);
524         }
525         self.cbox(if unindent_call_args { -INDENT } else { 0 });
526         self.word("(");
527         self.call_args(&expr.args);
528         self.word(")");
529         self.end();
530     }
531 
expr_paren(&mut self, expr: &ExprParen)532     fn expr_paren(&mut self, expr: &ExprParen) {
533         self.outer_attrs(&expr.attrs);
534         self.word("(");
535         self.expr(&expr.expr);
536         self.word(")");
537     }
538 
expr_path(&mut self, expr: &ExprPath)539     pub fn expr_path(&mut self, expr: &ExprPath) {
540         self.outer_attrs(&expr.attrs);
541         self.qpath(&expr.qself, &expr.path, PathKind::Expr);
542     }
543 
expr_range(&mut self, expr: &ExprRange)544     pub fn expr_range(&mut self, expr: &ExprRange) {
545         self.outer_attrs(&expr.attrs);
546         if let Some(start) = &expr.start {
547             self.expr(start);
548         }
549         self.word(match expr.limits {
550             RangeLimits::HalfOpen(_) => "..",
551             RangeLimits::Closed(_) => "..=",
552         });
553         if let Some(end) = &expr.end {
554             self.expr(end);
555         }
556     }
557 
expr_reference(&mut self, expr: &ExprReference)558     fn expr_reference(&mut self, expr: &ExprReference) {
559         self.outer_attrs(&expr.attrs);
560         self.word("&");
561         if expr.mutability.is_some() {
562             self.word("mut ");
563         }
564         self.expr(&expr.expr);
565     }
566 
expr_repeat(&mut self, expr: &ExprRepeat)567     fn expr_repeat(&mut self, expr: &ExprRepeat) {
568         self.outer_attrs(&expr.attrs);
569         self.word("[");
570         self.expr(&expr.expr);
571         self.word("; ");
572         self.expr(&expr.len);
573         self.word("]");
574     }
575 
expr_return(&mut self, expr: &ExprReturn)576     fn expr_return(&mut self, expr: &ExprReturn) {
577         self.outer_attrs(&expr.attrs);
578         self.word("return");
579         if let Some(value) = &expr.expr {
580             self.nbsp();
581             self.expr(value);
582         }
583     }
584 
expr_struct(&mut self, expr: &ExprStruct)585     fn expr_struct(&mut self, expr: &ExprStruct) {
586         self.outer_attrs(&expr.attrs);
587         self.cbox(INDENT);
588         self.ibox(-INDENT);
589         self.qpath(&expr.qself, &expr.path, PathKind::Expr);
590         self.end();
591         self.word(" {");
592         self.space_if_nonempty();
593         for field_value in expr.fields.iter().delimited() {
594             self.field_value(&field_value);
595             self.trailing_comma_or_space(field_value.is_last && expr.rest.is_none());
596         }
597         if let Some(rest) = &expr.rest {
598             self.word("..");
599             self.expr(rest);
600             self.space();
601         }
602         self.offset(-INDENT);
603         self.end_with_max_width(34);
604         self.word("}");
605     }
606 
expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool)607     fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
608         self.outer_attrs(&expr.attrs);
609         self.expr_beginning_of_line(&expr.expr, beginning_of_line);
610         self.word("?");
611     }
612 
subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool)613     fn subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
614         self.subexpr(&expr.expr, beginning_of_line);
615         self.word("?");
616     }
617 
expr_try_block(&mut self, expr: &ExprTryBlock)618     fn expr_try_block(&mut self, expr: &ExprTryBlock) {
619         self.outer_attrs(&expr.attrs);
620         self.word("try ");
621         self.cbox(INDENT);
622         self.small_block(&expr.block, &expr.attrs);
623         self.end();
624     }
625 
expr_tuple(&mut self, expr: &ExprTuple)626     fn expr_tuple(&mut self, expr: &ExprTuple) {
627         self.outer_attrs(&expr.attrs);
628         self.word("(");
629         self.cbox(INDENT);
630         self.zerobreak();
631         for elem in expr.elems.iter().delimited() {
632             self.expr(&elem);
633             if expr.elems.len() == 1 {
634                 self.word(",");
635                 self.zerobreak();
636             } else {
637                 self.trailing_comma(elem.is_last);
638             }
639         }
640         self.offset(-INDENT);
641         self.end();
642         self.word(")");
643     }
644 
expr_unary(&mut self, expr: &ExprUnary)645     fn expr_unary(&mut self, expr: &ExprUnary) {
646         self.outer_attrs(&expr.attrs);
647         self.unary_operator(&expr.op);
648         self.expr(&expr.expr);
649     }
650 
expr_unsafe(&mut self, expr: &ExprUnsafe)651     fn expr_unsafe(&mut self, expr: &ExprUnsafe) {
652         self.outer_attrs(&expr.attrs);
653         self.word("unsafe ");
654         self.cbox(INDENT);
655         self.small_block(&expr.block, &expr.attrs);
656         self.end();
657     }
658 
659     #[cfg(not(feature = "verbatim"))]
expr_verbatim(&mut self, expr: &TokenStream)660     fn expr_verbatim(&mut self, expr: &TokenStream) {
661         if !expr.is_empty() {
662             unimplemented!("Expr::Verbatim `{}`", expr);
663         }
664     }
665 
666     #[cfg(feature = "verbatim")]
expr_verbatim(&mut self, tokens: &TokenStream)667     fn expr_verbatim(&mut self, tokens: &TokenStream) {
668         use syn::parse::{Parse, ParseStream, Result};
669         use syn::{parenthesized, Ident};
670 
671         enum ExprVerbatim {
672             Empty,
673             Builtin(Builtin),
674             RawReference(RawReference),
675         }
676 
677         struct Builtin {
678             name: Ident,
679             args: TokenStream,
680         }
681 
682         struct RawReference {
683             mutable: bool,
684             expr: Expr,
685         }
686 
687         mod kw {
688             syn::custom_keyword!(builtin);
689             syn::custom_keyword!(raw);
690         }
691 
692         impl Parse for ExprVerbatim {
693             fn parse(input: ParseStream) -> Result<Self> {
694                 let lookahead = input.lookahead1();
695                 if input.is_empty() {
696                     Ok(ExprVerbatim::Empty)
697                 } else if lookahead.peek(kw::builtin) {
698                     input.parse::<kw::builtin>()?;
699                     input.parse::<Token![#]>()?;
700                     let name: Ident = input.parse()?;
701                     let args;
702                     parenthesized!(args in input);
703                     let args: TokenStream = args.parse()?;
704                     Ok(ExprVerbatim::Builtin(Builtin { name, args }))
705                 } else if lookahead.peek(Token![&]) {
706                     input.parse::<Token![&]>()?;
707                     input.parse::<kw::raw>()?;
708                     let mutable = input.parse::<Option<Token![mut]>>()?.is_some();
709                     if !mutable {
710                         input.parse::<Token![const]>()?;
711                     }
712                     let expr: Expr = input.parse()?;
713                     Ok(ExprVerbatim::RawReference(RawReference { mutable, expr }))
714                 } else {
715                     Err(lookahead.error())
716                 }
717             }
718         }
719 
720         let expr: ExprVerbatim = match syn::parse2(tokens.clone()) {
721             Ok(expr) => expr,
722             Err(_) => unimplemented!("Expr::Verbatim `{}`", tokens),
723         };
724 
725         match expr {
726             ExprVerbatim::Empty => {}
727             ExprVerbatim::Builtin(expr) => {
728                 self.word("builtin # ");
729                 self.ident(&expr.name);
730                 self.word("(");
731                 if !expr.args.is_empty() {
732                     self.cbox(INDENT);
733                     self.zerobreak();
734                     self.ibox(0);
735                     self.macro_rules_tokens(expr.args, false);
736                     self.end();
737                     self.zerobreak();
738                     self.offset(-INDENT);
739                     self.end();
740                 }
741                 self.word(")");
742             }
743             ExprVerbatim::RawReference(expr) => {
744                 self.word("&raw ");
745                 self.word(if expr.mutable { "mut " } else { "const " });
746                 self.expr(&expr.expr);
747             }
748         }
749     }
750 
expr_while(&mut self, expr: &ExprWhile)751     fn expr_while(&mut self, expr: &ExprWhile) {
752         self.outer_attrs(&expr.attrs);
753         if let Some(label) = &expr.label {
754             self.label(label);
755         }
756         self.word("while ");
757         self.wrap_exterior_struct(&expr.cond);
758         self.word("{");
759         self.neverbreak();
760         self.cbox(INDENT);
761         self.hardbreak_if_nonempty();
762         self.inner_attrs(&expr.attrs);
763         for stmt in &expr.body.stmts {
764             self.stmt(stmt);
765         }
766         self.offset(-INDENT);
767         self.end();
768         self.word("}");
769     }
770 
expr_yield(&mut self, expr: &ExprYield)771     fn expr_yield(&mut self, expr: &ExprYield) {
772         self.outer_attrs(&expr.attrs);
773         self.word("yield");
774         if let Some(value) = &expr.expr {
775             self.nbsp();
776             self.expr(value);
777         }
778     }
779 
label(&mut self, label: &Label)780     fn label(&mut self, label: &Label) {
781         self.lifetime(&label.name);
782         self.word(": ");
783     }
784 
field_value(&mut self, field_value: &FieldValue)785     fn field_value(&mut self, field_value: &FieldValue) {
786         self.outer_attrs(&field_value.attrs);
787         self.member(&field_value.member);
788         if field_value.colon_token.is_some() {
789             self.word(": ");
790             self.ibox(0);
791             self.expr(&field_value.expr);
792             self.end();
793         }
794     }
795 
arm(&mut self, arm: &Arm)796     fn arm(&mut self, arm: &Arm) {
797         self.outer_attrs(&arm.attrs);
798         self.ibox(0);
799         self.pat(&arm.pat);
800         if let Some((_if_token, guard)) = &arm.guard {
801             self.word(" if ");
802             self.expr(guard);
803         }
804         self.word(" =>");
805         let empty_block;
806         let mut body = &*arm.body;
807         while let Expr::Block(expr) = body {
808             if expr.attrs.is_empty() && expr.label.is_none() {
809                 let mut stmts = expr.block.stmts.iter();
810                 if let (Some(Stmt::Expr(inner, None)), None) = (stmts.next(), stmts.next()) {
811                     body = inner;
812                     continue;
813                 }
814             }
815             break;
816         }
817         if let Expr::Tuple(expr) = body {
818             if expr.elems.is_empty() && expr.attrs.is_empty() {
819                 empty_block = Expr::Block(ExprBlock {
820                     attrs: Vec::new(),
821                     label: None,
822                     block: Block {
823                         brace_token: token::Brace::default(),
824                         stmts: Vec::new(),
825                     },
826                 });
827                 body = &empty_block;
828             }
829         }
830         if let Expr::Block(body) = body {
831             self.nbsp();
832             if let Some(label) = &body.label {
833                 self.label(label);
834             }
835             self.word("{");
836             self.neverbreak();
837             self.cbox(INDENT);
838             self.hardbreak_if_nonempty();
839             self.inner_attrs(&body.attrs);
840             for stmt in &body.block.stmts {
841                 self.stmt(stmt);
842             }
843             self.offset(-INDENT);
844             self.end();
845             self.word("}");
846             self.end();
847         } else {
848             self.nbsp();
849             self.neverbreak();
850             self.cbox(INDENT);
851             self.scan_break(BreakToken {
852                 pre_break: Some('{'),
853                 ..BreakToken::default()
854             });
855             self.expr_beginning_of_line(body, true);
856             self.scan_break(BreakToken {
857                 offset: -INDENT,
858                 pre_break: stmt::add_semi(body).then(|| ';'),
859                 post_break: Some('}'),
860                 no_break: requires_terminator(body).then(|| ','),
861                 ..BreakToken::default()
862             });
863             self.end();
864             self.end();
865         }
866     }
867 
call_args(&mut self, args: &Punctuated<Expr, Token![,]>)868     fn call_args(&mut self, args: &Punctuated<Expr, Token![,]>) {
869         let mut iter = args.iter();
870         match (iter.next(), iter.next()) {
871             (Some(expr), None) if is_blocklike(expr) => {
872                 self.expr(expr);
873             }
874             _ => {
875                 self.cbox(INDENT);
876                 self.zerobreak();
877                 for arg in args.iter().delimited() {
878                     self.expr(&arg);
879                     self.trailing_comma(arg.is_last);
880                 }
881                 self.offset(-INDENT);
882                 self.end();
883             }
884         }
885     }
886 
small_block(&mut self, block: &Block, attrs: &[Attribute])887     pub fn small_block(&mut self, block: &Block, attrs: &[Attribute]) {
888         self.word("{");
889         if attr::has_inner(attrs) || !block.stmts.is_empty() {
890             self.space();
891             self.inner_attrs(attrs);
892             match (block.stmts.get(0), block.stmts.get(1)) {
893                 (Some(Stmt::Expr(expr, None)), None) if stmt::break_after(expr) => {
894                     self.ibox(0);
895                     self.expr_beginning_of_line(expr, true);
896                     self.end();
897                     self.space();
898                 }
899                 _ => {
900                     for stmt in &block.stmts {
901                         self.stmt(stmt);
902                     }
903                 }
904             }
905             self.offset(-INDENT);
906         }
907         self.word("}");
908     }
909 
member(&mut self, member: &Member)910     pub fn member(&mut self, member: &Member) {
911         match member {
912             Member::Named(ident) => self.ident(ident),
913             Member::Unnamed(index) => self.index(index),
914         }
915     }
916 
index(&mut self, member: &Index)917     fn index(&mut self, member: &Index) {
918         self.word(member.index.to_string());
919     }
920 
binary_operator(&mut self, op: &BinOp)921     fn binary_operator(&mut self, op: &BinOp) {
922         self.word(match op {
923             BinOp::Add(_) => "+",
924             BinOp::Sub(_) => "-",
925             BinOp::Mul(_) => "*",
926             BinOp::Div(_) => "/",
927             BinOp::Rem(_) => "%",
928             BinOp::And(_) => "&&",
929             BinOp::Or(_) => "||",
930             BinOp::BitXor(_) => "^",
931             BinOp::BitAnd(_) => "&",
932             BinOp::BitOr(_) => "|",
933             BinOp::Shl(_) => "<<",
934             BinOp::Shr(_) => ">>",
935             BinOp::Eq(_) => "==",
936             BinOp::Lt(_) => "<",
937             BinOp::Le(_) => "<=",
938             BinOp::Ne(_) => "!=",
939             BinOp::Ge(_) => ">=",
940             BinOp::Gt(_) => ">",
941             BinOp::AddAssign(_) => "+=",
942             BinOp::SubAssign(_) => "-=",
943             BinOp::MulAssign(_) => "*=",
944             BinOp::DivAssign(_) => "/=",
945             BinOp::RemAssign(_) => "%=",
946             BinOp::BitXorAssign(_) => "^=",
947             BinOp::BitAndAssign(_) => "&=",
948             BinOp::BitOrAssign(_) => "|=",
949             BinOp::ShlAssign(_) => "<<=",
950             BinOp::ShrAssign(_) => ">>=",
951             #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
952             _ => unimplemented!("unknown BinOp"),
953         });
954     }
955 
unary_operator(&mut self, op: &UnOp)956     fn unary_operator(&mut self, op: &UnOp) {
957         self.word(match op {
958             UnOp::Deref(_) => "*",
959             UnOp::Not(_) => "!",
960             UnOp::Neg(_) => "-",
961             #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
962             _ => unimplemented!("unknown UnOp"),
963         });
964     }
965 
zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr)966     fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) {
967         if beginning_of_line && is_short_ident(expr) {
968             return;
969         }
970         self.zerobreak();
971     }
972 }
973 
requires_terminator(expr: &Expr) -> bool974 pub fn requires_terminator(expr: &Expr) -> bool {
975     // see https://github.com/rust-lang/rust/blob/a266f1199/compiler/rustc_ast/src/util/classify.rs#L7-L26
976     match expr {
977         Expr::If(_)
978         | Expr::Match(_)
979         | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
980         | Expr::While(_)
981         | Expr::Loop(_)
982         | Expr::ForLoop(_)
983         | Expr::TryBlock(_)
984         | Expr::Const(_) => false,
985 
986         Expr::Array(_)
987         | Expr::Assign(_)
988         | Expr::Async(_)
989         | Expr::Await(_)
990         | Expr::Binary(_)
991         | Expr::Break(_)
992         | Expr::Call(_)
993         | Expr::Cast(_)
994         | Expr::Closure(_)
995         | Expr::Continue(_)
996         | Expr::Field(_)
997         | Expr::Group(_)
998         | Expr::Index(_)
999         | Expr::Infer(_)
1000         | Expr::Let(_)
1001         | Expr::Lit(_)
1002         | Expr::Macro(_)
1003         | Expr::MethodCall(_)
1004         | Expr::Paren(_)
1005         | Expr::Path(_)
1006         | Expr::Range(_)
1007         | Expr::Reference(_)
1008         | Expr::Repeat(_)
1009         | Expr::Return(_)
1010         | Expr::Struct(_)
1011         | Expr::Try(_)
1012         | Expr::Tuple(_)
1013         | Expr::Unary(_)
1014         | Expr::Verbatim(_)
1015         | Expr::Yield(_) => true,
1016 
1017         #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1018         _ => true,
1019     }
1020 }
1021 
1022 // Expressions that syntactically contain an "exterior" struct literal i.e. not
1023 // surrounded by any parens or other delimiters. For example `X { y: 1 }`, `X {
1024 // y: 1 }.method()`, `foo == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X
1025 // { y: 1 }) == foo` does not.
contains_exterior_struct_lit(expr: &Expr) -> bool1026 fn contains_exterior_struct_lit(expr: &Expr) -> bool {
1027     match expr {
1028         Expr::Struct(_) => true,
1029 
1030         Expr::Assign(ExprAssign { left, right, .. })
1031         | Expr::Binary(ExprBinary { left, right, .. }) => {
1032             // X { y: 1 } + X { y: 2 }
1033             contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right)
1034         }
1035 
1036         Expr::Await(ExprAwait { base: e, .. })
1037         | Expr::Cast(ExprCast { expr: e, .. })
1038         | Expr::Field(ExprField { base: e, .. })
1039         | Expr::Index(ExprIndex { expr: e, .. })
1040         | Expr::MethodCall(ExprMethodCall { receiver: e, .. })
1041         | Expr::Reference(ExprReference { expr: e, .. })
1042         | Expr::Unary(ExprUnary { expr: e, .. }) => {
1043             // &X { y: 1 }, X { y: 1 }.y
1044             contains_exterior_struct_lit(e)
1045         }
1046 
1047         Expr::Array(_)
1048         | Expr::Async(_)
1049         | Expr::Block(_)
1050         | Expr::Break(_)
1051         | Expr::Call(_)
1052         | Expr::Closure(_)
1053         | Expr::Const(_)
1054         | Expr::Continue(_)
1055         | Expr::ForLoop(_)
1056         | Expr::Group(_)
1057         | Expr::If(_)
1058         | Expr::Infer(_)
1059         | Expr::Let(_)
1060         | Expr::Lit(_)
1061         | Expr::Loop(_)
1062         | Expr::Macro(_)
1063         | Expr::Match(_)
1064         | Expr::Paren(_)
1065         | Expr::Path(_)
1066         | Expr::Range(_)
1067         | Expr::Repeat(_)
1068         | Expr::Return(_)
1069         | Expr::Try(_)
1070         | Expr::TryBlock(_)
1071         | Expr::Tuple(_)
1072         | Expr::Unsafe(_)
1073         | Expr::Verbatim(_)
1074         | Expr::While(_)
1075         | Expr::Yield(_) => false,
1076 
1077         #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1078         _ => false,
1079     }
1080 }
1081 
needs_newline_if_wrap(expr: &Expr) -> bool1082 fn needs_newline_if_wrap(expr: &Expr) -> bool {
1083     match expr {
1084         Expr::Array(_)
1085         | Expr::Async(_)
1086         | Expr::Block(_)
1087         | Expr::Break(ExprBreak { expr: None, .. })
1088         | Expr::Closure(_)
1089         | Expr::Const(_)
1090         | Expr::Continue(_)
1091         | Expr::ForLoop(_)
1092         | Expr::If(_)
1093         | Expr::Infer(_)
1094         | Expr::Lit(_)
1095         | Expr::Loop(_)
1096         | Expr::Macro(_)
1097         | Expr::Match(_)
1098         | Expr::Path(_)
1099         | Expr::Range(ExprRange { end: None, .. })
1100         | Expr::Repeat(_)
1101         | Expr::Return(ExprReturn { expr: None, .. })
1102         | Expr::Struct(_)
1103         | Expr::TryBlock(_)
1104         | Expr::Tuple(_)
1105         | Expr::Unsafe(_)
1106         | Expr::Verbatim(_)
1107         | Expr::While(_)
1108         | Expr::Yield(ExprYield { expr: None, .. }) => false,
1109 
1110         Expr::Assign(_)
1111         | Expr::Await(_)
1112         | Expr::Binary(_)
1113         | Expr::Cast(_)
1114         | Expr::Field(_)
1115         | Expr::Index(_)
1116         | Expr::MethodCall(_) => true,
1117 
1118         Expr::Break(ExprBreak { expr: Some(e), .. })
1119         | Expr::Call(ExprCall { func: e, .. })
1120         | Expr::Group(ExprGroup { expr: e, .. })
1121         | Expr::Let(ExprLet { expr: e, .. })
1122         | Expr::Paren(ExprParen { expr: e, .. })
1123         | Expr::Range(ExprRange { end: Some(e), .. })
1124         | Expr::Reference(ExprReference { expr: e, .. })
1125         | Expr::Return(ExprReturn { expr: Some(e), .. })
1126         | Expr::Try(ExprTry { expr: e, .. })
1127         | Expr::Unary(ExprUnary { expr: e, .. })
1128         | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1129 
1130         #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1131         _ => false,
1132     }
1133 }
1134 
is_short_ident(expr: &Expr) -> bool1135 fn is_short_ident(expr: &Expr) -> bool {
1136     if let Expr::Path(expr) = expr {
1137         return expr.attrs.is_empty()
1138             && expr.qself.is_none()
1139             && expr
1140                 .path
1141                 .get_ident()
1142                 .map_or(false, |ident| ident.to_string().len() as isize <= INDENT);
1143     }
1144     false
1145 }
1146 
is_blocklike(expr: &Expr) -> bool1147 fn is_blocklike(expr: &Expr) -> bool {
1148     match expr {
1149         Expr::Array(ExprArray { attrs, .. })
1150         | Expr::Async(ExprAsync { attrs, .. })
1151         | Expr::Block(ExprBlock { attrs, .. })
1152         | Expr::Closure(ExprClosure { attrs, .. })
1153         | Expr::Const(ExprConst { attrs, .. })
1154         | Expr::Struct(ExprStruct { attrs, .. })
1155         | Expr::TryBlock(ExprTryBlock { attrs, .. })
1156         | Expr::Tuple(ExprTuple { attrs, .. })
1157         | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1158 
1159         Expr::Assign(_)
1160         | Expr::Await(_)
1161         | Expr::Binary(_)
1162         | Expr::Break(_)
1163         | Expr::Call(_)
1164         | Expr::Cast(_)
1165         | Expr::Continue(_)
1166         | Expr::Field(_)
1167         | Expr::ForLoop(_)
1168         | Expr::Group(_)
1169         | Expr::If(_)
1170         | Expr::Index(_)
1171         | Expr::Infer(_)
1172         | Expr::Let(_)
1173         | Expr::Lit(_)
1174         | Expr::Loop(_)
1175         | Expr::Macro(_)
1176         | Expr::Match(_)
1177         | Expr::MethodCall(_)
1178         | Expr::Paren(_)
1179         | Expr::Path(_)
1180         | Expr::Range(_)
1181         | Expr::Reference(_)
1182         | Expr::Repeat(_)
1183         | Expr::Return(_)
1184         | Expr::Try(_)
1185         | Expr::Unary(_)
1186         | Expr::Verbatim(_)
1187         | Expr::While(_)
1188         | Expr::Yield(_) => false,
1189 
1190         #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1191         _ => false,
1192     }
1193 }
1194