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