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 Builtin(Builtin),
685 RawReference(RawReference),
686 }
687
688 struct Builtin {
689 attrs: Vec<Attribute>,
690 name: Ident,
691 args: TokenStream,
692 }
693
694 struct RawReference {
695 attrs: Vec<Attribute>,
696 mutable: bool,
697 expr: Expr,
698 }
699
700 mod kw {
701 syn::custom_keyword!(builtin);
702 syn::custom_keyword!(raw);
703 }
704
705 impl Parse for ExprVerbatim {
706 fn parse(input: ParseStream) -> Result<Self> {
707 let ahead = input.fork();
708 let attrs = ahead.call(Attribute::parse_outer)?;
709 let lookahead = ahead.lookahead1();
710 if input.is_empty() {
711 Ok(ExprVerbatim::Empty)
712 } else if lookahead.peek(kw::builtin) {
713 input.advance_to(&ahead);
714 input.parse::<kw::builtin>()?;
715 input.parse::<Token![#]>()?;
716 let name: Ident = input.parse()?;
717 let args;
718 parenthesized!(args in input);
719 let args: TokenStream = args.parse()?;
720 Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args }))
721 } else if lookahead.peek(Token![&]) {
722 input.advance_to(&ahead);
723 input.parse::<Token![&]>()?;
724 input.parse::<kw::raw>()?;
725 let mutable = input.parse::<Option<Token![mut]>>()?.is_some();
726 if !mutable {
727 input.parse::<Token![const]>()?;
728 }
729 let expr: Expr = input.parse()?;
730 Ok(ExprVerbatim::RawReference(RawReference {
731 attrs,
732 mutable,
733 expr,
734 }))
735 } else if lookahead.peek(Token![...]) {
736 input.parse::<Token![...]>()?;
737 Ok(ExprVerbatim::Ellipsis)
738 } else {
739 Err(lookahead.error())
740 }
741 }
742 }
743
744 let expr: ExprVerbatim = match syn::parse2(tokens.clone()) {
745 Ok(expr) => expr,
746 Err(_) => unimplemented!("Expr::Verbatim `{}`", tokens),
747 };
748
749 match expr {
750 ExprVerbatim::Empty => {}
751 ExprVerbatim::Ellipsis => {
752 self.word("...");
753 }
754 ExprVerbatim::Builtin(expr) => {
755 self.outer_attrs(&expr.attrs);
756 self.word("builtin # ");
757 self.ident(&expr.name);
758 self.word("(");
759 if !expr.args.is_empty() {
760 self.cbox(INDENT);
761 self.zerobreak();
762 self.ibox(0);
763 self.macro_rules_tokens(expr.args, false);
764 self.end();
765 self.zerobreak();
766 self.offset(-INDENT);
767 self.end();
768 }
769 self.word(")");
770 }
771 ExprVerbatim::RawReference(expr) => {
772 self.outer_attrs(&expr.attrs);
773 self.word("&raw ");
774 self.word(if expr.mutable { "mut " } else { "const " });
775 self.expr(&expr.expr);
776 }
777 }
778 }
779
780 fn expr_while(&mut self, expr: &ExprWhile) {
781 self.outer_attrs(&expr.attrs);
782 if let Some(label) = &expr.label {
783 self.label(label);
784 }
785 self.word("while ");
786 self.wrap_exterior_struct(&expr.cond);
787 self.word("{");
788 self.neverbreak();
789 self.cbox(INDENT);
790 self.hardbreak_if_nonempty();
791 self.inner_attrs(&expr.attrs);
792 for stmt in &expr.body.stmts {
793 self.stmt(stmt);
794 }
795 self.offset(-INDENT);
796 self.end();
797 self.word("}");
798 }
799
800 fn expr_yield(&mut self, expr: &ExprYield) {
801 self.outer_attrs(&expr.attrs);
802 self.word("yield");
803 if let Some(value) = &expr.expr {
804 self.nbsp();
805 self.expr(value);
806 }
807 }
808
809 fn label(&mut self, label: &Label) {
810 self.lifetime(&label.name);
811 self.word(": ");
812 }
813
814 fn field_value(&mut self, field_value: &FieldValue) {
815 self.outer_attrs(&field_value.attrs);
816 self.member(&field_value.member);
817 if field_value.colon_token.is_some() {
818 self.word(": ");
819 self.ibox(0);
820 self.expr(&field_value.expr);
821 self.end();
822 }
823 }
824
825 fn arm(&mut self, arm: &Arm) {
826 self.outer_attrs(&arm.attrs);
827 self.ibox(0);
828 self.pat(&arm.pat);
829 if let Some((_if_token, guard)) = &arm.guard {
830 self.word(" if ");
831 self.expr(guard);
832 }
833 self.word(" =>");
834 let empty_block;
835 let mut body = &*arm.body;
836 while let Expr::Block(expr) = body {
837 if expr.attrs.is_empty() && expr.label.is_none() {
838 let mut stmts = expr.block.stmts.iter();
839 if let (Some(Stmt::Expr(inner, None)), None) = (stmts.next(), stmts.next()) {
840 body = inner;
841 continue;
842 }
843 }
844 break;
845 }
846 if let Expr::Tuple(expr) = body {
847 if expr.elems.is_empty() && expr.attrs.is_empty() {
848 empty_block = Expr::Block(ExprBlock {
849 attrs: Vec::new(),
850 label: None,
851 block: Block {
852 brace_token: token::Brace::default(),
853 stmts: Vec::new(),
854 },
855 });
856 body = &empty_block;
857 }
858 }
859 if let Expr::Block(body) = body {
860 self.nbsp();
861 if let Some(label) = &body.label {
862 self.label(label);
863 }
864 self.word("{");
865 self.neverbreak();
866 self.cbox(INDENT);
867 self.hardbreak_if_nonempty();
868 self.inner_attrs(&body.attrs);
869 for stmt in &body.block.stmts {
870 self.stmt(stmt);
871 }
872 self.offset(-INDENT);
873 self.end();
874 self.word("}");
875 self.end();
876 } else {
877 self.nbsp();
878 self.neverbreak();
879 self.cbox(INDENT);
880 self.scan_break(BreakToken {
881 pre_break: Some('{'),
882 ..BreakToken::default()
883 });
884 self.expr_beginning_of_line(body, true);
885 self.scan_break(BreakToken {
886 offset: -INDENT,
887 pre_break: stmt::add_semi(body).then(|| ';'),
888 post_break: Some('}'),
889 no_break: requires_terminator(body).then(|| ','),
890 ..BreakToken::default()
891 });
892 self.end();
893 self.end();
894 }
895 }
896
897 fn call_args(&mut self, args: &Punctuated<Expr, Token![,]>) {
898 let mut iter = args.iter();
899 match (iter.next(), iter.next()) {
900 (Some(expr), None) if is_blocklike(expr) => {
901 self.expr(expr);
902 }
903 _ => {
904 self.cbox(INDENT);
905 self.zerobreak();
906 for arg in args.iter().delimited() {
907 self.expr(&arg);
908 self.trailing_comma(arg.is_last);
909 }
910 self.offset(-INDENT);
911 self.end();
912 }
913 }
914 }
915
916 pub fn small_block(&mut self, block: &Block, attrs: &[Attribute]) {
917 self.word("{");
918 if attr::has_inner(attrs) || !block.stmts.is_empty() {
919 self.space();
920 self.inner_attrs(attrs);
921 match block.stmts.as_slice() {
922 [Stmt::Expr(expr, None)] if stmt::break_after(expr) => {
923 self.ibox(0);
924 self.expr_beginning_of_line(expr, true);
925 self.end();
926 self.space();
927 }
928 _ => {
929 for stmt in &block.stmts {
930 self.stmt(stmt);
931 }
932 }
933 }
934 self.offset(-INDENT);
935 }
936 self.word("}");
937 }
938
939 pub fn member(&mut self, member: &Member) {
940 match member {
941 Member::Named(ident) => self.ident(ident),
942 Member::Unnamed(index) => self.index(index),
943 }
944 }
945
946 fn index(&mut self, member: &Index) {
947 self.word(member.index.to_string());
948 }
949
950 fn binary_operator(&mut self, op: &BinOp) {
951 self.word(
952 match op {
953 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
954 BinOp::Add(_) => "+",
955 BinOp::Sub(_) => "-",
956 BinOp::Mul(_) => "*",
957 BinOp::Div(_) => "/",
958 BinOp::Rem(_) => "%",
959 BinOp::And(_) => "&&",
960 BinOp::Or(_) => "||",
961 BinOp::BitXor(_) => "^",
962 BinOp::BitAnd(_) => "&",
963 BinOp::BitOr(_) => "|",
964 BinOp::Shl(_) => "<<",
965 BinOp::Shr(_) => ">>",
966 BinOp::Eq(_) => "==",
967 BinOp::Lt(_) => "<",
968 BinOp::Le(_) => "<=",
969 BinOp::Ne(_) => "!=",
970 BinOp::Ge(_) => ">=",
971 BinOp::Gt(_) => ">",
972 BinOp::AddAssign(_) => "+=",
973 BinOp::SubAssign(_) => "-=",
974 BinOp::MulAssign(_) => "*=",
975 BinOp::DivAssign(_) => "/=",
976 BinOp::RemAssign(_) => "%=",
977 BinOp::BitXorAssign(_) => "^=",
978 BinOp::BitAndAssign(_) => "&=",
979 BinOp::BitOrAssign(_) => "|=",
980 BinOp::ShlAssign(_) => "<<=",
981 BinOp::ShrAssign(_) => ">>=",
982 _ => unimplemented!("unknown BinOp"),
983 },
984 );
985 }
986
987 fn unary_operator(&mut self, op: &UnOp) {
988 self.word(
989 match op {
990 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
991 UnOp::Deref(_) => "*",
992 UnOp::Not(_) => "!",
993 UnOp::Neg(_) => "-",
994 _ => unimplemented!("unknown UnOp"),
995 },
996 );
997 }
998
999 fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) {
1000 if beginning_of_line && is_short_ident(expr) {
1001 return;
1002 }
1003 self.zerobreak();
1004 }
1005}
1006
1007fn requires_terminator(expr: &Expr) -> bool {
1008 match expr {
1010 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1011 Expr::If(_)
1012 | Expr::Match(_)
1013 | Expr::Block(_) | Expr::Unsafe(_) | Expr::While(_)
1015 | Expr::Loop(_)
1016 | Expr::ForLoop(_)
1017 | Expr::TryBlock(_)
1018 | Expr::Const(_) => false,
1019
1020 Expr::Array(_)
1021 | Expr::Assign(_)
1022 | Expr::Async(_)
1023 | Expr::Await(_)
1024 | Expr::Binary(_)
1025 | Expr::Break(_)
1026 | Expr::Call(_)
1027 | Expr::Cast(_)
1028 | Expr::Closure(_)
1029 | Expr::Continue(_)
1030 | Expr::Field(_)
1031 | Expr::Group(_)
1032 | Expr::Index(_)
1033 | Expr::Infer(_)
1034 | Expr::Let(_)
1035 | Expr::Lit(_)
1036 | Expr::Macro(_)
1037 | Expr::MethodCall(_)
1038 | Expr::Paren(_)
1039 | Expr::Path(_)
1040 | Expr::Range(_)
1041 | Expr::Reference(_)
1042 | Expr::Repeat(_)
1043 | Expr::Return(_)
1044 | Expr::Struct(_)
1045 | Expr::Try(_)
1046 | Expr::Tuple(_)
1047 | Expr::Unary(_)
1048 | Expr::Verbatim(_)
1049 | Expr::Yield(_) => true,
1050
1051 _ => true,
1052 }
1053}
1054
1055fn contains_exterior_struct_lit(expr: &Expr) -> bool {
1060 match expr {
1061 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1062 Expr::Struct(_) => true,
1063
1064 Expr::Assign(ExprAssign { left, right, .. })
1065 | Expr::Binary(ExprBinary { left, right, .. }) => {
1066 contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right)
1068 }
1069
1070 Expr::Await(ExprAwait { base: e, .. })
1071 | Expr::Cast(ExprCast { expr: e, .. })
1072 | Expr::Field(ExprField { base: e, .. })
1073 | Expr::Group(ExprGroup { expr: e, .. })
1074 | Expr::Index(ExprIndex { expr: e, .. })
1075 | Expr::MethodCall(ExprMethodCall { receiver: e, .. })
1076 | Expr::Reference(ExprReference { expr: e, .. })
1077 | Expr::Unary(ExprUnary { expr: e, .. }) => {
1078 contains_exterior_struct_lit(e)
1080 }
1081
1082 Expr::Array(_)
1083 | Expr::Async(_)
1084 | Expr::Block(_)
1085 | Expr::Break(_)
1086 | Expr::Call(_)
1087 | Expr::Closure(_)
1088 | Expr::Const(_)
1089 | Expr::Continue(_)
1090 | Expr::ForLoop(_)
1091 | Expr::If(_)
1092 | Expr::Infer(_)
1093 | Expr::Let(_)
1094 | Expr::Lit(_)
1095 | Expr::Loop(_)
1096 | Expr::Macro(_)
1097 | Expr::Match(_)
1098 | Expr::Paren(_)
1099 | Expr::Path(_)
1100 | Expr::Range(_)
1101 | Expr::Repeat(_)
1102 | Expr::Return(_)
1103 | Expr::Try(_)
1104 | Expr::TryBlock(_)
1105 | Expr::Tuple(_)
1106 | Expr::Unsafe(_)
1107 | Expr::Verbatim(_)
1108 | Expr::While(_)
1109 | Expr::Yield(_) => false,
1110
1111 _ => false,
1112 }
1113}
1114
1115fn needs_newline_if_wrap(expr: &Expr) -> bool {
1116 match expr {
1117 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1118 Expr::Array(_)
1119 | Expr::Async(_)
1120 | Expr::Block(_)
1121 | Expr::Break(ExprBreak { expr: None, .. })
1122 | Expr::Closure(_)
1123 | Expr::Const(_)
1124 | Expr::Continue(_)
1125 | Expr::ForLoop(_)
1126 | Expr::If(_)
1127 | Expr::Infer(_)
1128 | Expr::Lit(_)
1129 | Expr::Loop(_)
1130 | Expr::Macro(_)
1131 | Expr::Match(_)
1132 | Expr::Path(_)
1133 | Expr::Range(ExprRange { end: None, .. })
1134 | Expr::Repeat(_)
1135 | Expr::Return(ExprReturn { expr: None, .. })
1136 | Expr::Struct(_)
1137 | Expr::TryBlock(_)
1138 | Expr::Tuple(_)
1139 | Expr::Unsafe(_)
1140 | Expr::Verbatim(_)
1141 | Expr::While(_)
1142 | Expr::Yield(ExprYield { expr: None, .. }) => false,
1143
1144 Expr::Assign(_)
1145 | Expr::Await(_)
1146 | Expr::Binary(_)
1147 | Expr::Cast(_)
1148 | Expr::Field(_)
1149 | Expr::Index(_)
1150 | Expr::MethodCall(_) => true,
1151
1152 Expr::Break(ExprBreak { expr: Some(e), .. })
1153 | Expr::Call(ExprCall { func: e, .. })
1154 | Expr::Group(ExprGroup { expr: e, .. })
1155 | Expr::Let(ExprLet { expr: e, .. })
1156 | Expr::Paren(ExprParen { expr: e, .. })
1157 | Expr::Range(ExprRange { end: Some(e), .. })
1158 | Expr::Reference(ExprReference { expr: e, .. })
1159 | Expr::Return(ExprReturn { expr: Some(e), .. })
1160 | Expr::Try(ExprTry { expr: e, .. })
1161 | Expr::Unary(ExprUnary { expr: e, .. })
1162 | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1163
1164 _ => false,
1165 }
1166}
1167
1168fn is_short_ident(expr: &Expr) -> bool {
1169 if let Expr::Path(expr) = expr {
1170 return expr.attrs.is_empty()
1171 && expr.qself.is_none()
1172 && expr
1173 .path
1174 .get_ident()
1175 .map_or(false, |ident| ident.to_string().len() as isize <= INDENT);
1176 }
1177 false
1178}
1179
1180fn is_blocklike(expr: &Expr) -> bool {
1181 match expr {
1182 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1183 Expr::Array(ExprArray { attrs, .. })
1184 | Expr::Async(ExprAsync { attrs, .. })
1185 | Expr::Block(ExprBlock { attrs, .. })
1186 | Expr::Closure(ExprClosure { attrs, .. })
1187 | Expr::Const(ExprConst { attrs, .. })
1188 | Expr::Struct(ExprStruct { attrs, .. })
1189 | Expr::TryBlock(ExprTryBlock { attrs, .. })
1190 | Expr::Tuple(ExprTuple { attrs, .. })
1191 | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1192
1193 Expr::Assign(_)
1194 | Expr::Await(_)
1195 | Expr::Binary(_)
1196 | Expr::Break(_)
1197 | Expr::Call(_)
1198 | Expr::Cast(_)
1199 | Expr::Continue(_)
1200 | Expr::Field(_)
1201 | Expr::ForLoop(_)
1202 | Expr::Group(_)
1203 | Expr::If(_)
1204 | Expr::Index(_)
1205 | Expr::Infer(_)
1206 | Expr::Let(_)
1207 | Expr::Lit(_)
1208 | Expr::Loop(_)
1209 | Expr::Macro(_)
1210 | Expr::Match(_)
1211 | Expr::MethodCall(_)
1212 | Expr::Paren(_)
1213 | Expr::Path(_)
1214 | Expr::Range(_)
1215 | Expr::Reference(_)
1216 | Expr::Repeat(_)
1217 | Expr::Return(_)
1218 | Expr::Try(_)
1219 | Expr::Unary(_)
1220 | Expr::Verbatim(_)
1221 | Expr::While(_)
1222 | Expr::Yield(_) => false,
1223
1224 _ => false,
1225 }
1226}
1227
1228fn parseable_as_stmt(expr: &Expr) -> bool {
1233 match expr {
1234 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1235 Expr::Array(_)
1236 | Expr::Async(_)
1237 | Expr::Block(_)
1238 | Expr::Break(_)
1239 | Expr::Closure(_)
1240 | Expr::Const(_)
1241 | Expr::Continue(_)
1242 | Expr::ForLoop(_)
1243 | Expr::If(_)
1244 | Expr::Infer(_)
1245 | Expr::Let(_)
1246 | Expr::Lit(_)
1247 | Expr::Loop(_)
1248 | Expr::Macro(_)
1249 | Expr::Match(_)
1250 | Expr::Paren(_)
1251 | Expr::Path(_)
1252 | Expr::Reference(_)
1253 | Expr::Repeat(_)
1254 | Expr::Return(_)
1255 | Expr::Struct(_)
1256 | Expr::TryBlock(_)
1257 | Expr::Tuple(_)
1258 | Expr::Unary(_)
1259 | Expr::Unsafe(_)
1260 | Expr::Verbatim(_)
1261 | Expr::While(_)
1262 | Expr::Yield(_) => true,
1263
1264 Expr::Assign(expr) => parseable_as_stmt(&expr.left),
1265 Expr::Await(expr) => parseable_as_stmt(&expr.base),
1266 Expr::Binary(expr) => requires_terminator(&expr.left) && parseable_as_stmt(&expr.left),
1267 Expr::Call(expr) => requires_terminator(&expr.func) && parseable_as_stmt(&expr.func),
1268 Expr::Cast(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1269 Expr::Field(expr) => parseable_as_stmt(&expr.base),
1270 Expr::Group(expr) => parseable_as_stmt(&expr.expr),
1271 Expr::Index(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1272 Expr::MethodCall(expr) => parseable_as_stmt(&expr.receiver),
1273 Expr::Range(expr) => match &expr.start {
1274 None => true,
1275 Some(start) => requires_terminator(start) && parseable_as_stmt(start),
1276 },
1277 Expr::Try(expr) => parseable_as_stmt(&expr.expr),
1278
1279 _ => false,
1280 }
1281}