1use crate::algorithm::{BreakToken, Printer};
2use crate::attr;
3use crate::iter::IterDelimited;
4use crate::path::PathKind;
5use crate::stmt;
6use crate::INDENT;
7use proc_macro2::TokenStream;
8use syn::punctuated::Punctuated;
9use 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
19impl Printer {
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
355 fn expr_group(&mut self, expr: &ExprGroup) {
356 self.outer_attrs(&expr.attrs);
357 self.expr(&expr.expr);
358 }
359
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 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
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
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
431 fn expr_infer(&mut self, expr: &ExprInfer) {
432 self.outer_attrs(&expr.attrs);
433 self.word("_");
434 }
435
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
456 pub fn expr_lit(&mut self, expr: &ExprLit) {
457 self.outer_attrs(&expr.attrs);
458 self.lit(&expr.lit);
459 }
460
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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"))]
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")]
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
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
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
780 fn label(&mut self, label: &Label) {
781 self.lifetime(&label.name);
782 self.word(": ");
783 }
784
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
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
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
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
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
917 fn index(&mut self, member: &Index) {
918 self.word(member.index.to_string());
919 }
920
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
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
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
974pub fn requires_terminator(expr: &Expr) -> bool {
975 match expr {
977 Expr::If(_)
978 | Expr::Match(_)
979 | Expr::Block(_) | Expr::Unsafe(_) | 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
1022fn 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 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 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
1082fn 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
1135fn 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
1147fn 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}