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