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, ExprRawAddr,
14 ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary,
15 ExprUnsafe, ExprWhile, ExprYield, FieldValue, Index, Label, Member, PointerMutability,
16 RangeLimits, ReturnType, Stmt, Token, UnOp,
17};
18
19impl Printer {
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::RawAddr(expr) => self.expr_raw_addr(expr),
52 Expr::Reference(expr) => self.expr_reference(expr),
53 Expr::Repeat(expr) => self.expr_repeat(expr),
54 Expr::Return(expr) => self.expr_return(expr),
55 Expr::Struct(expr) => self.expr_struct(expr),
56 Expr::Try(expr) => self.expr_try(expr, beginning_of_line),
57 Expr::TryBlock(expr) => self.expr_try_block(expr),
58 Expr::Tuple(expr) => self.expr_tuple(expr),
59 Expr::Unary(expr) => self.expr_unary(expr),
60 Expr::Unsafe(expr) => self.expr_unsafe(expr),
61 Expr::Verbatim(expr) => self.expr_verbatim(expr),
62 Expr::While(expr) => self.expr_while(expr),
63 Expr::Yield(expr) => self.expr_yield(expr),
64 _ => unimplemented!("unknown Expr"),
65 }
66 }
67
68 pub fn expr_beginning_of_line(&mut self, expr: &Expr, beginning_of_line: bool) {
69 match expr {
70 Expr::Await(expr) => self.expr_await(expr, beginning_of_line),
71 Expr::Field(expr) => self.expr_field(expr, beginning_of_line),
72 Expr::Index(expr) => self.expr_index(expr, beginning_of_line),
73 Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line),
74 Expr::Try(expr) => self.expr_try(expr, beginning_of_line),
75 _ => self.expr(expr),
76 }
77 }
78
79 fn subexpr(&mut self, expr: &Expr, beginning_of_line: bool) {
80 match expr {
81 Expr::Await(expr) => self.subexpr_await(expr, beginning_of_line),
82 Expr::Call(expr) => self.subexpr_call(expr),
83 Expr::Field(expr) => self.subexpr_field(expr, beginning_of_line),
84 Expr::Index(expr) => self.subexpr_index(expr, beginning_of_line),
85 Expr::MethodCall(expr) => {
86 let unindent_call_args = false;
87 self.subexpr_method_call(expr, beginning_of_line, unindent_call_args);
88 }
89 Expr::Try(expr) => self.subexpr_try(expr, beginning_of_line),
90 _ => {
91 self.cbox(-INDENT);
92 self.expr(expr);
93 self.end();
94 }
95 }
96 }
97
98 fn wrap_exterior_struct(&mut self, expr: &Expr) {
99 let needs_paren = contains_exterior_struct_lit(expr);
100 if needs_paren {
101 self.word("(");
102 }
103 self.cbox(0);
104 self.expr(expr);
105 if needs_paren {
106 self.word(")");
107 }
108 if needs_newline_if_wrap(expr) {
109 self.space();
110 } else {
111 self.nbsp();
112 }
113 self.end();
114 }
115
116 fn expr_array(&mut self, expr: &ExprArray) {
117 self.outer_attrs(&expr.attrs);
118 self.word("[");
119 self.cbox(INDENT);
120 self.zerobreak();
121 for element in expr.elems.iter().delimited() {
122 self.expr(&element);
123 self.trailing_comma(element.is_last);
124 }
125 self.offset(-INDENT);
126 self.end();
127 self.word("]");
128 }
129
130 fn expr_assign(&mut self, expr: &ExprAssign) {
131 self.outer_attrs(&expr.attrs);
132 self.ibox(0);
133 self.expr(&expr.left);
134 self.word(" = ");
135 self.neverbreak();
136 self.expr(&expr.right);
137 self.end();
138 }
139
140 fn expr_async(&mut self, expr: &ExprAsync) {
141 self.outer_attrs(&expr.attrs);
142 self.word("async ");
143 if expr.capture.is_some() {
144 self.word("move ");
145 }
146 self.cbox(INDENT);
147 self.small_block(&expr.block, &expr.attrs);
148 self.end();
149 }
150
151 fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
152 self.outer_attrs(&expr.attrs);
153 self.cbox(INDENT);
154 self.subexpr_await(expr, beginning_of_line);
155 self.end();
156 }
157
158 fn subexpr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
159 self.subexpr(&expr.base, beginning_of_line);
160 self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
161 self.word(".await");
162 }
163
164 fn expr_binary(&mut self, expr: &ExprBinary) {
165 self.outer_attrs(&expr.attrs);
166 self.ibox(INDENT);
167 self.ibox(-INDENT);
168 self.expr(&expr.left);
169 self.end();
170 self.space();
171 self.binary_operator(&expr.op);
172 self.nbsp();
173 self.expr(&expr.right);
174 self.end();
175 }
176
177 pub fn expr_block(&mut self, expr: &ExprBlock) {
178 self.outer_attrs(&expr.attrs);
179 if let Some(label) = &expr.label {
180 self.label(label);
181 }
182 self.cbox(INDENT);
183 self.small_block(&expr.block, &expr.attrs);
184 self.end();
185 }
186
187 fn expr_break(&mut self, expr: &ExprBreak) {
188 self.outer_attrs(&expr.attrs);
189 self.word("break");
190 if let Some(lifetime) = &expr.label {
191 self.nbsp();
192 self.lifetime(lifetime);
193 }
194 if let Some(value) = &expr.expr {
195 self.nbsp();
196 self.expr(value);
197 }
198 }
199
200 fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool) {
201 self.outer_attrs(&expr.attrs);
202 self.expr_beginning_of_line(&expr.func, beginning_of_line);
203 self.word("(");
204 self.call_args(&expr.args);
205 self.word(")");
206 }
207
208 fn subexpr_call(&mut self, expr: &ExprCall) {
209 let beginning_of_line = false;
210 self.subexpr(&expr.func, beginning_of_line);
211 self.word("(");
212 self.call_args(&expr.args);
213 self.word(")");
214 }
215
216 fn expr_cast(&mut self, expr: &ExprCast) {
217 self.outer_attrs(&expr.attrs);
218 self.ibox(INDENT);
219 self.ibox(-INDENT);
220 self.expr(&expr.expr);
221 self.end();
222 self.space();
223 self.word("as ");
224 self.ty(&expr.ty);
225 self.end();
226 }
227
228 fn expr_closure(&mut self, expr: &ExprClosure) {
229 self.outer_attrs(&expr.attrs);
230 self.ibox(0);
231 if let Some(bound_lifetimes) = &expr.lifetimes {
232 self.bound_lifetimes(bound_lifetimes);
233 }
234 if expr.constness.is_some() {
235 self.word("const ");
236 }
237 if expr.movability.is_some() {
238 self.word("static ");
239 }
240 if expr.asyncness.is_some() {
241 self.word("async ");
242 }
243 if expr.capture.is_some() {
244 self.word("move ");
245 }
246 self.cbox(INDENT);
247 self.word("|");
248 for pat in expr.inputs.iter().delimited() {
249 if pat.is_first {
250 self.zerobreak();
251 }
252 self.pat(&pat);
253 if !pat.is_last {
254 self.word(",");
255 self.space();
256 }
257 }
258 match &expr.output {
259 ReturnType::Default => {
260 self.word("|");
261 self.space();
262 self.offset(-INDENT);
263 self.end();
264 self.neverbreak();
265 let wrap_in_brace = match &*expr.body {
266 Expr::Match(ExprMatch { attrs, .. }) | Expr::Call(ExprCall { attrs, .. }) => {
267 attr::has_outer(attrs)
268 }
269 body => !is_blocklike(body),
270 };
271 if wrap_in_brace {
272 self.cbox(INDENT);
273 let okay_to_brace = parseable_as_stmt(&expr.body);
274 self.scan_break(BreakToken {
275 pre_break: Some(if okay_to_brace { '{' } else { '(' }),
276 ..BreakToken::default()
277 });
278 self.expr(&expr.body);
279 self.scan_break(BreakToken {
280 offset: -INDENT,
281 pre_break: (okay_to_brace && stmt::add_semi(&expr.body)).then(|| ';'),
282 post_break: Some(if okay_to_brace { '}' } else { ')' }),
283 ..BreakToken::default()
284 });
285 self.end();
286 } else {
287 self.expr(&expr.body);
288 }
289 }
290 ReturnType::Type(_arrow, ty) => {
291 if !expr.inputs.is_empty() {
292 self.trailing_comma(true);
293 self.offset(-INDENT);
294 }
295 self.word("|");
296 self.end();
297 self.word(" -> ");
298 self.ty(ty);
299 self.nbsp();
300 self.neverbreak();
301 self.expr(&expr.body);
302 }
303 }
304 self.end();
305 }
306
307 pub fn expr_const(&mut self, expr: &ExprConst) {
308 self.outer_attrs(&expr.attrs);
309 self.word("const ");
310 self.cbox(INDENT);
311 self.small_block(&expr.block, &expr.attrs);
312 self.end();
313 }
314
315 fn expr_continue(&mut self, expr: &ExprContinue) {
316 self.outer_attrs(&expr.attrs);
317 self.word("continue");
318 if let Some(lifetime) = &expr.label {
319 self.nbsp();
320 self.lifetime(lifetime);
321 }
322 }
323
324 fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
325 self.outer_attrs(&expr.attrs);
326 self.cbox(INDENT);
327 self.subexpr_field(expr, beginning_of_line);
328 self.end();
329 }
330
331 fn subexpr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
332 self.subexpr(&expr.base, beginning_of_line);
333 self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
334 self.word(".");
335 self.member(&expr.member);
336 }
337
338 fn expr_for_loop(&mut self, expr: &ExprForLoop) {
339 self.outer_attrs(&expr.attrs);
340 self.ibox(0);
341 if let Some(label) = &expr.label {
342 self.label(label);
343 }
344 self.word("for ");
345 self.pat(&expr.pat);
346 self.word(" in ");
347 self.neverbreak();
348 self.wrap_exterior_struct(&expr.expr);
349 self.word("{");
350 self.neverbreak();
351 self.cbox(INDENT);
352 self.hardbreak_if_nonempty();
353 self.inner_attrs(&expr.attrs);
354 for stmt in &expr.body.stmts {
355 self.stmt(stmt);
356 }
357 self.offset(-INDENT);
358 self.end();
359 self.word("}");
360 self.end();
361 }
362
363 fn expr_group(&mut self, expr: &ExprGroup) {
364 self.outer_attrs(&expr.attrs);
365 self.expr(&expr.expr);
366 }
367
368 fn expr_if(&mut self, expr: &ExprIf) {
369 self.outer_attrs(&expr.attrs);
370 self.cbox(INDENT);
371 self.word("if ");
372 self.cbox(-INDENT);
373 self.wrap_exterior_struct(&expr.cond);
374 self.end();
375 if let Some((_else_token, else_branch)) = &expr.else_branch {
376 let mut else_branch = &**else_branch;
377 self.small_block(&expr.then_branch, &[]);
378 loop {
379 self.word(" else ");
380 match else_branch {
381 Expr::If(expr) => {
382 self.word("if ");
383 self.cbox(-INDENT);
384 self.wrap_exterior_struct(&expr.cond);
385 self.end();
386 self.small_block(&expr.then_branch, &[]);
387 if let Some((_else_token, next)) = &expr.else_branch {
388 else_branch = next;
389 continue;
390 }
391 }
392 Expr::Block(expr) => {
393 self.small_block(&expr.block, &[]);
394 }
395 other => {
398 self.word("{");
399 self.space();
400 self.ibox(INDENT);
401 self.expr(other);
402 self.end();
403 self.space();
404 self.offset(-INDENT);
405 self.word("}");
406 }
407 }
408 break;
409 }
410 } else if expr.then_branch.stmts.is_empty() {
411 self.word("{}");
412 } else {
413 self.word("{");
414 self.hardbreak();
415 for stmt in &expr.then_branch.stmts {
416 self.stmt(stmt);
417 }
418 self.offset(-INDENT);
419 self.word("}");
420 }
421 self.end();
422 }
423
424 fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
425 self.outer_attrs(&expr.attrs);
426 self.expr_beginning_of_line(&expr.expr, beginning_of_line);
427 self.word("[");
428 self.expr(&expr.index);
429 self.word("]");
430 }
431
432 fn subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
433 self.subexpr(&expr.expr, beginning_of_line);
434 self.word("[");
435 self.expr(&expr.index);
436 self.word("]");
437 }
438
439 fn expr_infer(&mut self, expr: &ExprInfer) {
440 self.outer_attrs(&expr.attrs);
441 self.word("_");
442 }
443
444 fn expr_let(&mut self, expr: &ExprLet) {
445 self.outer_attrs(&expr.attrs);
446 self.ibox(0);
447 self.word("let ");
448 self.ibox(0);
449 self.pat(&expr.pat);
450 self.end();
451 self.word(" = ");
452 self.neverbreak();
453 self.ibox(0);
454 let needs_paren = contains_exterior_struct_lit(&expr.expr);
455 if needs_paren {
456 self.word("(");
457 }
458 self.expr(&expr.expr);
459 if needs_paren {
460 self.word(")");
461 }
462 self.end();
463 self.end();
464 }
465
466 pub fn expr_lit(&mut self, expr: &ExprLit) {
467 self.outer_attrs(&expr.attrs);
468 self.lit(&expr.lit);
469 }
470
471 fn expr_loop(&mut self, expr: &ExprLoop) {
472 self.outer_attrs(&expr.attrs);
473 if let Some(label) = &expr.label {
474 self.label(label);
475 }
476 self.word("loop {");
477 self.cbox(INDENT);
478 self.hardbreak_if_nonempty();
479 self.inner_attrs(&expr.attrs);
480 for stmt in &expr.body.stmts {
481 self.stmt(stmt);
482 }
483 self.offset(-INDENT);
484 self.end();
485 self.word("}");
486 }
487
488 pub fn expr_macro(&mut self, expr: &ExprMacro) {
489 self.outer_attrs(&expr.attrs);
490 let semicolon = false;
491 self.mac(&expr.mac, None, semicolon);
492 }
493
494 fn expr_match(&mut self, expr: &ExprMatch) {
495 self.outer_attrs(&expr.attrs);
496 self.ibox(0);
497 self.word("match ");
498 self.wrap_exterior_struct(&expr.expr);
499 self.word("{");
500 self.neverbreak();
501 self.cbox(INDENT);
502 self.hardbreak_if_nonempty();
503 self.inner_attrs(&expr.attrs);
504 for arm in &expr.arms {
505 self.arm(arm);
506 self.hardbreak();
507 }
508 self.offset(-INDENT);
509 self.end();
510 self.word("}");
511 self.end();
512 }
513
514 fn expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool) {
515 self.outer_attrs(&expr.attrs);
516 self.cbox(INDENT);
517 let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver);
518 self.subexpr_method_call(expr, beginning_of_line, unindent_call_args);
519 self.end();
520 }
521
522 fn subexpr_method_call(
523 &mut self,
524 expr: &ExprMethodCall,
525 beginning_of_line: bool,
526 unindent_call_args: bool,
527 ) {
528 self.subexpr(&expr.receiver, beginning_of_line);
529 self.zerobreak_unless_short_ident(beginning_of_line, &expr.receiver);
530 self.word(".");
531 self.ident(&expr.method);
532 if let Some(turbofish) = &expr.turbofish {
533 self.angle_bracketed_generic_arguments(turbofish, PathKind::Expr);
534 }
535 self.cbox(if unindent_call_args { -INDENT } else { 0 });
536 self.word("(");
537 self.call_args(&expr.args);
538 self.word(")");
539 self.end();
540 }
541
542 fn expr_paren(&mut self, expr: &ExprParen) {
543 self.outer_attrs(&expr.attrs);
544 self.word("(");
545 self.expr(&expr.expr);
546 self.word(")");
547 }
548
549 pub fn expr_path(&mut self, expr: &ExprPath) {
550 self.outer_attrs(&expr.attrs);
551 self.qpath(&expr.qself, &expr.path, PathKind::Expr);
552 }
553
554 pub fn expr_range(&mut self, expr: &ExprRange) {
555 self.outer_attrs(&expr.attrs);
556 if let Some(start) = &expr.start {
557 self.expr(start);
558 }
559 self.word(match expr.limits {
560 RangeLimits::HalfOpen(_) => "..",
561 RangeLimits::Closed(_) => "..=",
562 });
563 if let Some(end) = &expr.end {
564 self.expr(end);
565 }
566 }
567
568 fn expr_raw_addr(&mut self, expr: &ExprRawAddr) {
569 self.outer_attrs(&expr.attrs);
570 self.word("&raw ");
571 self.pointer_mutability(&expr.mutability);
572 self.nbsp();
573 self.expr(&expr.expr);
574 }
575
576 fn expr_reference(&mut self, expr: &ExprReference) {
577 self.outer_attrs(&expr.attrs);
578 self.word("&");
579 if expr.mutability.is_some() {
580 self.word("mut ");
581 }
582 self.expr(&expr.expr);
583 }
584
585 fn expr_repeat(&mut self, expr: &ExprRepeat) {
586 self.outer_attrs(&expr.attrs);
587 self.word("[");
588 self.expr(&expr.expr);
589 self.word("; ");
590 self.expr(&expr.len);
591 self.word("]");
592 }
593
594 fn expr_return(&mut self, expr: &ExprReturn) {
595 self.outer_attrs(&expr.attrs);
596 self.word("return");
597 if let Some(value) = &expr.expr {
598 self.nbsp();
599 self.expr(value);
600 }
601 }
602
603 fn expr_struct(&mut self, expr: &ExprStruct) {
604 self.outer_attrs(&expr.attrs);
605 self.cbox(INDENT);
606 self.ibox(-INDENT);
607 self.qpath(&expr.qself, &expr.path, PathKind::Expr);
608 self.end();
609 self.word(" {");
610 self.space_if_nonempty();
611 for field_value in expr.fields.iter().delimited() {
612 self.field_value(&field_value);
613 self.trailing_comma_or_space(field_value.is_last && expr.rest.is_none());
614 }
615 if let Some(rest) = &expr.rest {
616 self.word("..");
617 self.expr(rest);
618 self.space();
619 }
620 self.offset(-INDENT);
621 self.end_with_max_width(34);
622 self.word("}");
623 }
624
625 fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
626 self.outer_attrs(&expr.attrs);
627 self.expr_beginning_of_line(&expr.expr, beginning_of_line);
628 self.word("?");
629 }
630
631 fn subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
632 self.subexpr(&expr.expr, beginning_of_line);
633 self.word("?");
634 }
635
636 fn expr_try_block(&mut self, expr: &ExprTryBlock) {
637 self.outer_attrs(&expr.attrs);
638 self.word("try ");
639 self.cbox(INDENT);
640 self.small_block(&expr.block, &expr.attrs);
641 self.end();
642 }
643
644 fn expr_tuple(&mut self, expr: &ExprTuple) {
645 self.outer_attrs(&expr.attrs);
646 self.word("(");
647 self.cbox(INDENT);
648 self.zerobreak();
649 for elem in expr.elems.iter().delimited() {
650 self.expr(&elem);
651 if expr.elems.len() == 1 {
652 self.word(",");
653 self.zerobreak();
654 } else {
655 self.trailing_comma(elem.is_last);
656 }
657 }
658 self.offset(-INDENT);
659 self.end();
660 self.word(")");
661 }
662
663 fn expr_unary(&mut self, expr: &ExprUnary) {
664 self.outer_attrs(&expr.attrs);
665 self.unary_operator(&expr.op);
666 self.expr(&expr.expr);
667 }
668
669 fn expr_unsafe(&mut self, expr: &ExprUnsafe) {
670 self.outer_attrs(&expr.attrs);
671 self.word("unsafe ");
672 self.cbox(INDENT);
673 self.small_block(&expr.block, &expr.attrs);
674 self.end();
675 }
676
677 #[cfg(not(feature = "verbatim"))]
678 fn expr_verbatim(&mut self, expr: &TokenStream) {
679 if !expr.is_empty() {
680 unimplemented!("Expr::Verbatim `{}`", expr);
681 }
682 }
683
684 #[cfg(feature = "verbatim")]
685 fn expr_verbatim(&mut self, tokens: &TokenStream) {
686 use syn::parse::discouraged::Speculative;
687 use syn::parse::{Parse, ParseStream, Result};
688 use syn::{parenthesized, Ident};
689
690 enum ExprVerbatim {
691 Empty,
692 Ellipsis,
693 Become(Become),
694 Builtin(Builtin),
695 }
696
697 struct Become {
698 attrs: Vec<Attribute>,
699 tail_call: Expr,
700 }
701
702 struct Builtin {
703 attrs: Vec<Attribute>,
704 name: Ident,
705 args: TokenStream,
706 }
707
708 mod kw {
709 syn::custom_keyword!(builtin);
710 syn::custom_keyword!(raw);
711 }
712
713 impl Parse for ExprVerbatim {
714 fn parse(input: ParseStream) -> Result<Self> {
715 let ahead = input.fork();
716 let attrs = ahead.call(Attribute::parse_outer)?;
717 let lookahead = ahead.lookahead1();
718 if input.is_empty() {
719 Ok(ExprVerbatim::Empty)
720 } else if lookahead.peek(Token![become]) {
721 input.advance_to(&ahead);
722 input.parse::<Token![become]>()?;
723 let tail_call: Expr = input.parse()?;
724 Ok(ExprVerbatim::Become(Become { attrs, tail_call }))
725 } else if lookahead.peek(kw::builtin) {
726 input.advance_to(&ahead);
727 input.parse::<kw::builtin>()?;
728 input.parse::<Token![#]>()?;
729 let name: Ident = input.parse()?;
730 let args;
731 parenthesized!(args in input);
732 let args: TokenStream = args.parse()?;
733 Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args }))
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::Become(expr) => {
754 self.outer_attrs(&expr.attrs);
755 self.word("become");
756 self.nbsp();
757 self.expr(&expr.tail_call);
758 }
759 ExprVerbatim::Builtin(expr) => {
760 self.outer_attrs(&expr.attrs);
761 self.word("builtin # ");
762 self.ident(&expr.name);
763 self.word("(");
764 if !expr.args.is_empty() {
765 self.cbox(INDENT);
766 self.zerobreak();
767 self.ibox(0);
768 self.macro_rules_tokens(expr.args, false);
769 self.end();
770 self.zerobreak();
771 self.offset(-INDENT);
772 self.end();
773 }
774 self.word(")");
775 }
776 }
777 }
778
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
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
808 fn label(&mut self, label: &Label) {
809 self.lifetime(&label.name);
810 self.word(": ");
811 }
812
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
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
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
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
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
945 fn index(&mut self, member: &Index) {
946 self.word(member.index.to_string());
947 }
948
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
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
998 fn pointer_mutability(&mut self, mutability: &PointerMutability) {
999 match mutability {
1000 PointerMutability::Const(_) => self.word("const"),
1001 PointerMutability::Mut(_) => self.word("mut"),
1002 }
1003 }
1004
1005 fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) {
1006 if beginning_of_line && is_short_ident(expr) {
1007 return;
1008 }
1009 self.zerobreak();
1010 }
1011}
1012
1013fn requires_terminator(expr: &Expr) -> bool {
1014 match expr {
1016 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1017 Expr::If(_)
1018 | Expr::Match(_)
1019 | Expr::Block(_) | Expr::Unsafe(_) | Expr::While(_)
1021 | Expr::Loop(_)
1022 | Expr::ForLoop(_)
1023 | Expr::TryBlock(_)
1024 | Expr::Const(_) => false,
1025
1026 Expr::Array(_)
1027 | Expr::Assign(_)
1028 | Expr::Async(_)
1029 | Expr::Await(_)
1030 | Expr::Binary(_)
1031 | Expr::Break(_)
1032 | Expr::Call(_)
1033 | Expr::Cast(_)
1034 | Expr::Closure(_)
1035 | Expr::Continue(_)
1036 | Expr::Field(_)
1037 | Expr::Group(_)
1038 | Expr::Index(_)
1039 | Expr::Infer(_)
1040 | Expr::Let(_)
1041 | Expr::Lit(_)
1042 | Expr::Macro(_)
1043 | Expr::MethodCall(_)
1044 | Expr::Paren(_)
1045 | Expr::Path(_)
1046 | Expr::Range(_)
1047 | Expr::RawAddr(_)
1048 | Expr::Reference(_)
1049 | Expr::Repeat(_)
1050 | Expr::Return(_)
1051 | Expr::Struct(_)
1052 | Expr::Try(_)
1053 | Expr::Tuple(_)
1054 | Expr::Unary(_)
1055 | Expr::Verbatim(_)
1056 | Expr::Yield(_) => true,
1057
1058 _ => true,
1059 }
1060}
1061
1062fn contains_exterior_struct_lit(expr: &Expr) -> bool {
1067 match expr {
1068 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1069 Expr::Struct(_) => true,
1070
1071 Expr::Assign(ExprAssign { left, right, .. })
1072 | Expr::Binary(ExprBinary { left, right, .. }) => {
1073 contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right)
1075 }
1076
1077 Expr::Await(ExprAwait { base: e, .. })
1078 | Expr::Cast(ExprCast { expr: e, .. })
1079 | Expr::Field(ExprField { base: e, .. })
1080 | Expr::Group(ExprGroup { expr: e, .. })
1081 | Expr::Index(ExprIndex { expr: e, .. })
1082 | Expr::MethodCall(ExprMethodCall { receiver: e, .. })
1083 | Expr::RawAddr(ExprRawAddr { expr: e, .. })
1084 | Expr::Reference(ExprReference { expr: e, .. })
1085 | Expr::Unary(ExprUnary { expr: e, .. }) => {
1086 contains_exterior_struct_lit(e)
1088 }
1089
1090 Expr::Array(_)
1091 | Expr::Async(_)
1092 | Expr::Block(_)
1093 | Expr::Break(_)
1094 | Expr::Call(_)
1095 | Expr::Closure(_)
1096 | Expr::Const(_)
1097 | Expr::Continue(_)
1098 | Expr::ForLoop(_)
1099 | Expr::If(_)
1100 | Expr::Infer(_)
1101 | Expr::Let(_)
1102 | Expr::Lit(_)
1103 | Expr::Loop(_)
1104 | Expr::Macro(_)
1105 | Expr::Match(_)
1106 | Expr::Paren(_)
1107 | Expr::Path(_)
1108 | Expr::Range(_)
1109 | Expr::Repeat(_)
1110 | Expr::Return(_)
1111 | Expr::Try(_)
1112 | Expr::TryBlock(_)
1113 | Expr::Tuple(_)
1114 | Expr::Unsafe(_)
1115 | Expr::Verbatim(_)
1116 | Expr::While(_)
1117 | Expr::Yield(_) => false,
1118
1119 _ => false,
1120 }
1121}
1122
1123fn needs_newline_if_wrap(expr: &Expr) -> bool {
1124 match expr {
1125 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1126 Expr::Array(_)
1127 | Expr::Async(_)
1128 | Expr::Block(_)
1129 | Expr::Break(ExprBreak { expr: None, .. })
1130 | Expr::Closure(_)
1131 | Expr::Const(_)
1132 | Expr::Continue(_)
1133 | Expr::ForLoop(_)
1134 | Expr::If(_)
1135 | Expr::Infer(_)
1136 | Expr::Lit(_)
1137 | Expr::Loop(_)
1138 | Expr::Macro(_)
1139 | Expr::Match(_)
1140 | Expr::Path(_)
1141 | Expr::Range(ExprRange { end: None, .. })
1142 | Expr::Repeat(_)
1143 | Expr::Return(ExprReturn { expr: None, .. })
1144 | Expr::Struct(_)
1145 | Expr::TryBlock(_)
1146 | Expr::Tuple(_)
1147 | Expr::Unsafe(_)
1148 | Expr::Verbatim(_)
1149 | Expr::While(_)
1150 | Expr::Yield(ExprYield { expr: None, .. }) => false,
1151
1152 Expr::Assign(_)
1153 | Expr::Await(_)
1154 | Expr::Binary(_)
1155 | Expr::Cast(_)
1156 | Expr::Field(_)
1157 | Expr::Index(_)
1158 | Expr::MethodCall(_) => true,
1159
1160 Expr::Break(ExprBreak { expr: Some(e), .. })
1161 | Expr::Call(ExprCall { func: e, .. })
1162 | Expr::Group(ExprGroup { expr: e, .. })
1163 | Expr::Let(ExprLet { expr: e, .. })
1164 | Expr::Paren(ExprParen { expr: e, .. })
1165 | Expr::Range(ExprRange { end: Some(e), .. })
1166 | Expr::RawAddr(ExprRawAddr { expr: e, .. })
1167 | Expr::Reference(ExprReference { expr: e, .. })
1168 | Expr::Return(ExprReturn { expr: Some(e), .. })
1169 | Expr::Try(ExprTry { expr: e, .. })
1170 | Expr::Unary(ExprUnary { expr: e, .. })
1171 | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1172
1173 _ => false,
1174 }
1175}
1176
1177fn is_short_ident(expr: &Expr) -> bool {
1178 if let Expr::Path(expr) = expr {
1179 return expr.attrs.is_empty()
1180 && expr.qself.is_none()
1181 && expr
1182 .path
1183 .get_ident()
1184 .map_or(false, |ident| ident.to_string().len() as isize <= INDENT);
1185 }
1186 false
1187}
1188
1189fn is_blocklike(expr: &Expr) -> bool {
1190 match expr {
1191 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1192 Expr::Array(ExprArray { attrs, .. })
1193 | Expr::Async(ExprAsync { attrs, .. })
1194 | Expr::Block(ExprBlock { attrs, .. })
1195 | Expr::Closure(ExprClosure { attrs, .. })
1196 | Expr::Const(ExprConst { attrs, .. })
1197 | Expr::Struct(ExprStruct { attrs, .. })
1198 | Expr::TryBlock(ExprTryBlock { attrs, .. })
1199 | Expr::Tuple(ExprTuple { attrs, .. })
1200 | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1201
1202 Expr::Assign(_)
1203 | Expr::Await(_)
1204 | Expr::Binary(_)
1205 | Expr::Break(_)
1206 | Expr::Call(_)
1207 | Expr::Cast(_)
1208 | Expr::Continue(_)
1209 | Expr::Field(_)
1210 | Expr::ForLoop(_)
1211 | Expr::Group(_)
1212 | Expr::If(_)
1213 | Expr::Index(_)
1214 | Expr::Infer(_)
1215 | Expr::Let(_)
1216 | Expr::Lit(_)
1217 | Expr::Loop(_)
1218 | Expr::Macro(_)
1219 | Expr::Match(_)
1220 | Expr::MethodCall(_)
1221 | Expr::Paren(_)
1222 | Expr::Path(_)
1223 | Expr::Range(_)
1224 | Expr::RawAddr(_)
1225 | Expr::Reference(_)
1226 | Expr::Repeat(_)
1227 | Expr::Return(_)
1228 | Expr::Try(_)
1229 | Expr::Unary(_)
1230 | Expr::Verbatim(_)
1231 | Expr::While(_)
1232 | Expr::Yield(_) => false,
1233
1234 _ => false,
1235 }
1236}
1237
1238fn parseable_as_stmt(expr: &Expr) -> bool {
1243 match expr {
1244 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1245 Expr::Array(_)
1246 | Expr::Async(_)
1247 | Expr::Block(_)
1248 | Expr::Break(_)
1249 | Expr::Closure(_)
1250 | Expr::Const(_)
1251 | Expr::Continue(_)
1252 | Expr::ForLoop(_)
1253 | Expr::If(_)
1254 | Expr::Infer(_)
1255 | Expr::Let(_)
1256 | Expr::Lit(_)
1257 | Expr::Loop(_)
1258 | Expr::Macro(_)
1259 | Expr::Match(_)
1260 | Expr::Paren(_)
1261 | Expr::Path(_)
1262 | Expr::RawAddr(_)
1263 | Expr::Reference(_)
1264 | Expr::Repeat(_)
1265 | Expr::Return(_)
1266 | Expr::Struct(_)
1267 | Expr::TryBlock(_)
1268 | Expr::Tuple(_)
1269 | Expr::Unary(_)
1270 | Expr::Unsafe(_)
1271 | Expr::Verbatim(_)
1272 | Expr::While(_)
1273 | Expr::Yield(_) => true,
1274
1275 Expr::Assign(expr) => parseable_as_stmt(&expr.left),
1276 Expr::Await(expr) => parseable_as_stmt(&expr.base),
1277 Expr::Binary(expr) => requires_terminator(&expr.left) && parseable_as_stmt(&expr.left),
1278 Expr::Call(expr) => requires_terminator(&expr.func) && parseable_as_stmt(&expr.func),
1279 Expr::Cast(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1280 Expr::Field(expr) => parseable_as_stmt(&expr.base),
1281 Expr::Group(expr) => parseable_as_stmt(&expr.expr),
1282 Expr::Index(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1283 Expr::MethodCall(expr) => parseable_as_stmt(&expr.receiver),
1284 Expr::Range(expr) => match &expr.start {
1285 None => true,
1286 Some(start) => requires_terminator(start) && parseable_as_stmt(start),
1287 },
1288 Expr::Try(expr) => parseable_as_stmt(&expr.expr),
1289
1290 _ => false,
1291 }
1292}