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