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 Expr::Array(expr) => self.expr_array(expr),
24 Expr::Assign(expr) => self.expr_assign(expr),
25 Expr::Async(expr) => self.expr_async(expr),
26 Expr::Await(expr) => self.expr_await(expr, beginning_of_line),
27 Expr::Binary(expr) => self.expr_binary(expr),
28 Expr::Block(expr) => self.expr_block(expr),
29 Expr::Break(expr) => self.expr_break(expr),
30 Expr::Call(expr) => self.expr_call(expr, beginning_of_line),
31 Expr::Cast(expr) => self.expr_cast(expr),
32 Expr::Closure(expr) => self.expr_closure(expr),
33 Expr::Const(expr) => self.expr_const(expr),
34 Expr::Continue(expr) => self.expr_continue(expr),
35 Expr::Field(expr) => self.expr_field(expr, beginning_of_line),
36 Expr::ForLoop(expr) => self.expr_for_loop(expr),
37 Expr::Group(expr) => self.expr_group(expr),
38 Expr::If(expr) => self.expr_if(expr),
39 Expr::Index(expr) => self.expr_index(expr, beginning_of_line),
40 Expr::Infer(expr) => self.expr_infer(expr),
41 Expr::Let(expr) => self.expr_let(expr),
42 Expr::Lit(expr) => self.expr_lit(expr),
43 Expr::Loop(expr) => self.expr_loop(expr),
44 Expr::Macro(expr) => self.expr_macro(expr),
45 Expr::Match(expr) => self.expr_match(expr),
46 Expr::MethodCall(expr) => self.expr_method_call(expr, beginning_of_line),
47 Expr::Paren(expr) => self.expr_paren(expr),
48 Expr::Path(expr) => self.expr_path(expr),
49 Expr::Range(expr) => self.expr_range(expr),
50 Expr::Reference(expr) => self.expr_reference(expr),
51 Expr::Repeat(expr) => self.expr_repeat(expr),
52 Expr::Return(expr) => self.expr_return(expr),
53 Expr::Struct(expr) => self.expr_struct(expr),
54 Expr::Try(expr) => self.expr_try(expr, beginning_of_line),
55 Expr::TryBlock(expr) => self.expr_try_block(expr),
56 Expr::Tuple(expr) => self.expr_tuple(expr),
57 Expr::Unary(expr) => self.expr_unary(expr),
58 Expr::Unsafe(expr) => self.expr_unsafe(expr),
59 Expr::Verbatim(expr) => self.expr_verbatim(expr),
60 Expr::While(expr) => self.expr_while(expr),
61 Expr::Yield(expr) => self.expr_yield(expr),
62 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
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.expr(&expr.right);
135 self.end();
136 }
137
138 fn expr_async(&mut self, expr: &ExprAsync) {
139 self.outer_attrs(&expr.attrs);
140 self.word("async ");
141 if expr.capture.is_some() {
142 self.word("move ");
143 }
144 self.cbox(INDENT);
145 self.small_block(&expr.block, &expr.attrs);
146 self.end();
147 }
148
149 fn expr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
150 self.outer_attrs(&expr.attrs);
151 self.cbox(INDENT);
152 self.subexpr_await(expr, beginning_of_line);
153 self.end();
154 }
155
156 fn subexpr_await(&mut self, expr: &ExprAwait, beginning_of_line: bool) {
157 self.subexpr(&expr.base, beginning_of_line);
158 self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
159 self.word(".await");
160 }
161
162 fn expr_binary(&mut self, expr: &ExprBinary) {
163 self.outer_attrs(&expr.attrs);
164 self.ibox(INDENT);
165 self.ibox(-INDENT);
166 self.expr(&expr.left);
167 self.end();
168 self.space();
169 self.binary_operator(&expr.op);
170 self.nbsp();
171 self.expr(&expr.right);
172 self.end();
173 }
174
175 pub fn expr_block(&mut self, expr: &ExprBlock) {
176 self.outer_attrs(&expr.attrs);
177 if let Some(label) = &expr.label {
178 self.label(label);
179 }
180 self.cbox(INDENT);
181 self.small_block(&expr.block, &expr.attrs);
182 self.end();
183 }
184
185 fn expr_break(&mut self, expr: &ExprBreak) {
186 self.outer_attrs(&expr.attrs);
187 self.word("break");
188 if let Some(lifetime) = &expr.label {
189 self.nbsp();
190 self.lifetime(lifetime);
191 }
192 if let Some(value) = &expr.expr {
193 self.nbsp();
194 self.expr(value);
195 }
196 }
197
198 fn expr_call(&mut self, expr: &ExprCall, beginning_of_line: bool) {
199 self.outer_attrs(&expr.attrs);
200 self.expr_beginning_of_line(&expr.func, beginning_of_line);
201 self.word("(");
202 self.call_args(&expr.args);
203 self.word(")");
204 }
205
206 fn subexpr_call(&mut self, expr: &ExprCall) {
207 let beginning_of_line = false;
208 self.subexpr(&expr.func, beginning_of_line);
209 self.word("(");
210 self.call_args(&expr.args);
211 self.word(")");
212 }
213
214 fn expr_cast(&mut self, expr: &ExprCast) {
215 self.outer_attrs(&expr.attrs);
216 self.ibox(INDENT);
217 self.ibox(-INDENT);
218 self.expr(&expr.expr);
219 self.end();
220 self.space();
221 self.word("as ");
222 self.ty(&expr.ty);
223 self.end();
224 }
225
226 fn expr_closure(&mut self, expr: &ExprClosure) {
227 self.outer_attrs(&expr.attrs);
228 self.ibox(0);
229 if let Some(bound_lifetimes) = &expr.lifetimes {
230 self.bound_lifetimes(bound_lifetimes);
231 }
232 if expr.constness.is_some() {
233 self.word("const ");
234 }
235 if expr.movability.is_some() {
236 self.word("static ");
237 }
238 if expr.asyncness.is_some() {
239 self.word("async ");
240 }
241 if expr.capture.is_some() {
242 self.word("move ");
243 }
244 self.cbox(INDENT);
245 self.word("|");
246 for pat in expr.inputs.iter().delimited() {
247 if pat.is_first {
248 self.zerobreak();
249 }
250 self.pat(&pat);
251 if !pat.is_last {
252 self.word(",");
253 self.space();
254 }
255 }
256 match &expr.output {
257 ReturnType::Default => {
258 self.word("|");
259 self.space();
260 self.offset(-INDENT);
261 self.end();
262 self.neverbreak();
263 let wrap_in_brace = match &*expr.body {
264 Expr::Match(ExprMatch { attrs, .. }) | Expr::Call(ExprCall { attrs, .. }) => {
265 attr::has_outer(attrs)
266 }
267 body => !is_blocklike(body),
268 };
269 if wrap_in_brace {
270 self.cbox(INDENT);
271 let okay_to_brace = parseable_as_stmt(&expr.body);
272 self.scan_break(BreakToken {
273 pre_break: Some(if okay_to_brace { '{' } else { '(' }),
274 ..BreakToken::default()
275 });
276 self.expr(&expr.body);
277 self.scan_break(BreakToken {
278 offset: -INDENT,
279 pre_break: (okay_to_brace && stmt::add_semi(&expr.body)).then(|| ';'),
280 post_break: Some(if okay_to_brace { '}' } else { ')' }),
281 ..BreakToken::default()
282 });
283 self.end();
284 } else {
285 self.expr(&expr.body);
286 }
287 }
288 ReturnType::Type(_arrow, ty) => {
289 if !expr.inputs.is_empty() {
290 self.trailing_comma(true);
291 self.offset(-INDENT);
292 }
293 self.word("|");
294 self.end();
295 self.word(" -> ");
296 self.ty(ty);
297 self.nbsp();
298 self.neverbreak();
299 self.expr(&expr.body);
300 }
301 }
302 self.end();
303 }
304
305 pub fn expr_const(&mut self, expr: &ExprConst) {
306 self.outer_attrs(&expr.attrs);
307 self.word("const ");
308 self.cbox(INDENT);
309 self.small_block(&expr.block, &expr.attrs);
310 self.end();
311 }
312
313 fn expr_continue(&mut self, expr: &ExprContinue) {
314 self.outer_attrs(&expr.attrs);
315 self.word("continue");
316 if let Some(lifetime) = &expr.label {
317 self.nbsp();
318 self.lifetime(lifetime);
319 }
320 }
321
322 fn expr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
323 self.outer_attrs(&expr.attrs);
324 self.cbox(INDENT);
325 self.subexpr_field(expr, beginning_of_line);
326 self.end();
327 }
328
329 fn subexpr_field(&mut self, expr: &ExprField, beginning_of_line: bool) {
330 self.subexpr(&expr.base, beginning_of_line);
331 self.zerobreak_unless_short_ident(beginning_of_line, &expr.base);
332 self.word(".");
333 self.member(&expr.member);
334 }
335
336 fn expr_for_loop(&mut self, expr: &ExprForLoop) {
337 self.outer_attrs(&expr.attrs);
338 self.ibox(0);
339 if let Some(label) = &expr.label {
340 self.label(label);
341 }
342 self.word("for ");
343 self.pat(&expr.pat);
344 self.word(" in ");
345 self.neverbreak();
346 self.wrap_exterior_struct(&expr.expr);
347 self.word("{");
348 self.neverbreak();
349 self.cbox(INDENT);
350 self.hardbreak_if_nonempty();
351 self.inner_attrs(&expr.attrs);
352 for stmt in &expr.body.stmts {
353 self.stmt(stmt);
354 }
355 self.offset(-INDENT);
356 self.end();
357 self.word("}");
358 self.end();
359 }
360
361 fn expr_group(&mut self, expr: &ExprGroup) {
362 self.outer_attrs(&expr.attrs);
363 self.expr(&expr.expr);
364 }
365
366 fn expr_if(&mut self, expr: &ExprIf) {
367 self.outer_attrs(&expr.attrs);
368 self.cbox(INDENT);
369 self.word("if ");
370 self.cbox(-INDENT);
371 self.wrap_exterior_struct(&expr.cond);
372 self.end();
373 if let Some((_else_token, else_branch)) = &expr.else_branch {
374 let mut else_branch = &**else_branch;
375 self.small_block(&expr.then_branch, &[]);
376 loop {
377 self.word(" else ");
378 match else_branch {
379 Expr::If(expr) => {
380 self.word("if ");
381 self.cbox(-INDENT);
382 self.wrap_exterior_struct(&expr.cond);
383 self.end();
384 self.small_block(&expr.then_branch, &[]);
385 if let Some((_else_token, next)) = &expr.else_branch {
386 else_branch = next;
387 continue;
388 }
389 }
390 Expr::Block(expr) => {
391 self.small_block(&expr.block, &[]);
392 }
393 // If not one of the valid expressions to exist in an else
394 // clause, wrap in a block.
395 other => {
396 self.word("{");
397 self.space();
398 self.ibox(INDENT);
399 self.expr(other);
400 self.end();
401 self.space();
402 self.offset(-INDENT);
403 self.word("}");
404 }
405 }
406 break;
407 }
408 } else if expr.then_branch.stmts.is_empty() {
409 self.word("{}");
410 } else {
411 self.word("{");
412 self.hardbreak();
413 for stmt in &expr.then_branch.stmts {
414 self.stmt(stmt);
415 }
416 self.offset(-INDENT);
417 self.word("}");
418 }
419 self.end();
420 }
421
422 fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
423 self.outer_attrs(&expr.attrs);
424 self.expr_beginning_of_line(&expr.expr, beginning_of_line);
425 self.word("[");
426 self.expr(&expr.index);
427 self.word("]");
428 }
429
430 fn subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
431 self.subexpr(&expr.expr, beginning_of_line);
432 self.word("[");
433 self.expr(&expr.index);
434 self.word("]");
435 }
436
437 fn expr_infer(&mut self, expr: &ExprInfer) {
438 self.outer_attrs(&expr.attrs);
439 self.word("_");
440 }
441
442 fn expr_let(&mut self, expr: &ExprLet) {
443 self.outer_attrs(&expr.attrs);
444 self.ibox(0);
445 self.word("let ");
446 self.ibox(0);
447 self.pat(&expr.pat);
448 self.end();
449 self.word(" = ");
450 self.neverbreak();
451 self.ibox(0);
452 let needs_paren = contains_exterior_struct_lit(&expr.expr);
453 if needs_paren {
454 self.word("(");
455 }
456 self.expr(&expr.expr);
457 if needs_paren {
458 self.word(")");
459 }
460 self.end();
461 self.end();
462 }
463
464 pub fn expr_lit(&mut self, expr: &ExprLit) {
465 self.outer_attrs(&expr.attrs);
466 self.lit(&expr.lit);
467 }
468
469 fn expr_loop(&mut self, expr: &ExprLoop) {
470 self.outer_attrs(&expr.attrs);
471 if let Some(label) = &expr.label {
472 self.label(label);
473 }
474 self.word("loop {");
475 self.cbox(INDENT);
476 self.hardbreak_if_nonempty();
477 self.inner_attrs(&expr.attrs);
478 for stmt in &expr.body.stmts {
479 self.stmt(stmt);
480 }
481 self.offset(-INDENT);
482 self.end();
483 self.word("}");
484 }
485
486 pub fn expr_macro(&mut self, expr: &ExprMacro) {
487 self.outer_attrs(&expr.attrs);
488 let semicolon = false;
489 self.mac(&expr.mac, None, semicolon);
490 }
491
492 fn expr_match(&mut self, expr: &ExprMatch) {
493 self.outer_attrs(&expr.attrs);
494 self.ibox(0);
495 self.word("match ");
496 self.wrap_exterior_struct(&expr.expr);
497 self.word("{");
498 self.neverbreak();
499 self.cbox(INDENT);
500 self.hardbreak_if_nonempty();
501 self.inner_attrs(&expr.attrs);
502 for arm in &expr.arms {
503 self.arm(arm);
504 self.hardbreak();
505 }
506 self.offset(-INDENT);
507 self.end();
508 self.word("}");
509 self.end();
510 }
511
512 fn expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool) {
513 self.outer_attrs(&expr.attrs);
514 self.cbox(INDENT);
515 let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver);
516 self.subexpr_method_call(expr, beginning_of_line, unindent_call_args);
517 self.end();
518 }
519
520 fn subexpr_method_call(
521 &mut self,
522 expr: &ExprMethodCall,
523 beginning_of_line: bool,
524 unindent_call_args: bool,
525 ) {
526 self.subexpr(&expr.receiver, beginning_of_line);
527 self.zerobreak_unless_short_ident(beginning_of_line, &expr.receiver);
528 self.word(".");
529 self.ident(&expr.method);
530 if let Some(turbofish) = &expr.turbofish {
531 self.angle_bracketed_generic_arguments(turbofish, PathKind::Expr);
532 }
533 self.cbox(if unindent_call_args { -INDENT } else { 0 });
534 self.word("(");
535 self.call_args(&expr.args);
536 self.word(")");
537 self.end();
538 }
539
540 fn expr_paren(&mut self, expr: &ExprParen) {
541 self.outer_attrs(&expr.attrs);
542 self.word("(");
543 self.expr(&expr.expr);
544 self.word(")");
545 }
546
547 pub fn expr_path(&mut self, expr: &ExprPath) {
548 self.outer_attrs(&expr.attrs);
549 self.qpath(&expr.qself, &expr.path, PathKind::Expr);
550 }
551
552 pub fn expr_range(&mut self, expr: &ExprRange) {
553 self.outer_attrs(&expr.attrs);
554 if let Some(start) = &expr.start {
555 self.expr(start);
556 }
557 self.word(match expr.limits {
558 RangeLimits::HalfOpen(_) => "..",
559 RangeLimits::Closed(_) => "..=",
560 });
561 if let Some(end) = &expr.end {
562 self.expr(end);
563 }
564 }
565
566 fn expr_reference(&mut self, expr: &ExprReference) {
567 self.outer_attrs(&expr.attrs);
568 self.word("&");
569 if expr.mutability.is_some() {
570 self.word("mut ");
571 }
572 self.expr(&expr.expr);
573 }
574
575 fn expr_repeat(&mut self, expr: &ExprRepeat) {
576 self.outer_attrs(&expr.attrs);
577 self.word("[");
578 self.expr(&expr.expr);
579 self.word("; ");
580 self.expr(&expr.len);
581 self.word("]");
582 }
583
584 fn expr_return(&mut self, expr: &ExprReturn) {
585 self.outer_attrs(&expr.attrs);
586 self.word("return");
587 if let Some(value) = &expr.expr {
588 self.nbsp();
589 self.expr(value);
590 }
591 }
592
593 fn expr_struct(&mut self, expr: &ExprStruct) {
594 self.outer_attrs(&expr.attrs);
595 self.cbox(INDENT);
596 self.ibox(-INDENT);
597 self.qpath(&expr.qself, &expr.path, PathKind::Expr);
598 self.end();
599 self.word(" {");
600 self.space_if_nonempty();
601 for field_value in expr.fields.iter().delimited() {
602 self.field_value(&field_value);
603 self.trailing_comma_or_space(field_value.is_last && expr.rest.is_none());
604 }
605 if let Some(rest) = &expr.rest {
606 self.word("..");
607 self.expr(rest);
608 self.space();
609 }
610 self.offset(-INDENT);
611 self.end_with_max_width(34);
612 self.word("}");
613 }
614
615 fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
616 self.outer_attrs(&expr.attrs);
617 self.expr_beginning_of_line(&expr.expr, beginning_of_line);
618 self.word("?");
619 }
620
621 fn subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
622 self.subexpr(&expr.expr, beginning_of_line);
623 self.word("?");
624 }
625
626 fn expr_try_block(&mut self, expr: &ExprTryBlock) {
627 self.outer_attrs(&expr.attrs);
628 self.word("try ");
629 self.cbox(INDENT);
630 self.small_block(&expr.block, &expr.attrs);
631 self.end();
632 }
633
634 fn expr_tuple(&mut self, expr: &ExprTuple) {
635 self.outer_attrs(&expr.attrs);
636 self.word("(");
637 self.cbox(INDENT);
638 self.zerobreak();
639 for elem in expr.elems.iter().delimited() {
640 self.expr(&elem);
641 if expr.elems.len() == 1 {
642 self.word(",");
643 self.zerobreak();
644 } else {
645 self.trailing_comma(elem.is_last);
646 }
647 }
648 self.offset(-INDENT);
649 self.end();
650 self.word(")");
651 }
652
653 fn expr_unary(&mut self, expr: &ExprUnary) {
654 self.outer_attrs(&expr.attrs);
655 self.unary_operator(&expr.op);
656 self.expr(&expr.expr);
657 }
658
659 fn expr_unsafe(&mut self, expr: &ExprUnsafe) {
660 self.outer_attrs(&expr.attrs);
661 self.word("unsafe ");
662 self.cbox(INDENT);
663 self.small_block(&expr.block, &expr.attrs);
664 self.end();
665 }
666
667 #[cfg(not(feature = "verbatim"))]
668 fn expr_verbatim(&mut self, expr: &TokenStream) {
669 if !expr.is_empty() {
670 unimplemented!("Expr::Verbatim `{}`", expr);
671 }
672 }
673
674 #[cfg(feature = "verbatim")]
675 fn expr_verbatim(&mut self, tokens: &TokenStream) {
676 use syn::parse::discouraged::Speculative;
677 use syn::parse::{Parse, ParseStream, Result};
678 use syn::{parenthesized, Ident};
679
680 enum ExprVerbatim {
681 Empty,
682 Ellipsis,
683 Builtin(Builtin),
684 RawReference(RawReference),
685 }
686
687 struct Builtin {
688 attrs: Vec<Attribute>,
689 name: Ident,
690 args: TokenStream,
691 }
692
693 struct RawReference {
694 attrs: Vec<Attribute>,
695 mutable: bool,
696 expr: Expr,
697 }
698
699 mod kw {
700 syn::custom_keyword!(builtin);
701 syn::custom_keyword!(raw);
702 }
703
704 impl Parse for ExprVerbatim {
705 fn parse(input: ParseStream) -> Result<Self> {
706 let ahead = input.fork();
707 let attrs = ahead.call(Attribute::parse_outer)?;
708 let lookahead = ahead.lookahead1();
709 if input.is_empty() {
710 Ok(ExprVerbatim::Empty)
711 } else if lookahead.peek(kw::builtin) {
712 input.advance_to(&ahead);
713 input.parse::<kw::builtin>()?;
714 input.parse::<Token![#]>()?;
715 let name: Ident = input.parse()?;
716 let args;
717 parenthesized!(args in input);
718 let args: TokenStream = args.parse()?;
719 Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args }))
720 } else if lookahead.peek(Token![&]) {
721 input.advance_to(&ahead);
722 input.parse::<Token![&]>()?;
723 input.parse::<kw::raw>()?;
724 let mutable = input.parse::<Option<Token![mut]>>()?.is_some();
725 if !mutable {
726 input.parse::<Token![const]>()?;
727 }
728 let expr: Expr = input.parse()?;
729 Ok(ExprVerbatim::RawReference(RawReference {
730 attrs,
731 mutable,
732 expr,
733 }))
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::Builtin(expr) => {
754 self.outer_attrs(&expr.attrs);
755 self.word("builtin # ");
756 self.ident(&expr.name);
757 self.word("(");
758 if !expr.args.is_empty() {
759 self.cbox(INDENT);
760 self.zerobreak();
761 self.ibox(0);
762 self.macro_rules_tokens(expr.args, false);
763 self.end();
764 self.zerobreak();
765 self.offset(-INDENT);
766 self.end();
767 }
768 self.word(")");
769 }
770 ExprVerbatim::RawReference(expr) => {
771 self.outer_attrs(&expr.attrs);
772 self.word("&raw ");
773 self.word(if expr.mutable { "mut " } else { "const " });
774 self.expr(&expr.expr);
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(match op {
951 BinOp::Add(_) => "+",
952 BinOp::Sub(_) => "-",
953 BinOp::Mul(_) => "*",
954 BinOp::Div(_) => "/",
955 BinOp::Rem(_) => "%",
956 BinOp::And(_) => "&&",
957 BinOp::Or(_) => "||",
958 BinOp::BitXor(_) => "^",
959 BinOp::BitAnd(_) => "&",
960 BinOp::BitOr(_) => "|",
961 BinOp::Shl(_) => "<<",
962 BinOp::Shr(_) => ">>",
963 BinOp::Eq(_) => "==",
964 BinOp::Lt(_) => "<",
965 BinOp::Le(_) => "<=",
966 BinOp::Ne(_) => "!=",
967 BinOp::Ge(_) => ">=",
968 BinOp::Gt(_) => ">",
969 BinOp::AddAssign(_) => "+=",
970 BinOp::SubAssign(_) => "-=",
971 BinOp::MulAssign(_) => "*=",
972 BinOp::DivAssign(_) => "/=",
973 BinOp::RemAssign(_) => "%=",
974 BinOp::BitXorAssign(_) => "^=",
975 BinOp::BitAndAssign(_) => "&=",
976 BinOp::BitOrAssign(_) => "|=",
977 BinOp::ShlAssign(_) => "<<=",
978 BinOp::ShrAssign(_) => ">>=",
979 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
980 _ => unimplemented!("unknown BinOp"),
981 });
982 }
983
984 fn unary_operator(&mut self, op: &UnOp) {
985 self.word(match op {
986 UnOp::Deref(_) => "*",
987 UnOp::Not(_) => "!",
988 UnOp::Neg(_) => "-",
989 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
990 _ => unimplemented!("unknown UnOp"),
991 });
992 }
993
994 fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) {
995 if beginning_of_line && is_short_ident(expr) {
996 return;
997 }
998 self.zerobreak();
999 }
1000}
1001
1002fn requires_terminator(expr: &Expr) -> bool {
1003 // see https://github.com/rust-lang/rust/blob/a266f1199/compiler/rustc_ast/src/util/classify.rs#L7-L26
1004 match expr {
1005 Expr::If(_)
1006 | Expr::Match(_)
1007 | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
1008 | Expr::While(_)
1009 | Expr::Loop(_)
1010 | Expr::ForLoop(_)
1011 | Expr::TryBlock(_)
1012 | Expr::Const(_) => false,
1013
1014 Expr::Array(_)
1015 | Expr::Assign(_)
1016 | Expr::Async(_)
1017 | Expr::Await(_)
1018 | Expr::Binary(_)
1019 | Expr::Break(_)
1020 | Expr::Call(_)
1021 | Expr::Cast(_)
1022 | Expr::Closure(_)
1023 | Expr::Continue(_)
1024 | Expr::Field(_)
1025 | Expr::Group(_)
1026 | Expr::Index(_)
1027 | Expr::Infer(_)
1028 | Expr::Let(_)
1029 | Expr::Lit(_)
1030 | Expr::Macro(_)
1031 | Expr::MethodCall(_)
1032 | Expr::Paren(_)
1033 | Expr::Path(_)
1034 | Expr::Range(_)
1035 | Expr::Reference(_)
1036 | Expr::Repeat(_)
1037 | Expr::Return(_)
1038 | Expr::Struct(_)
1039 | Expr::Try(_)
1040 | Expr::Tuple(_)
1041 | Expr::Unary(_)
1042 | Expr::Verbatim(_)
1043 | Expr::Yield(_) => true,
1044
1045 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1046 _ => true,
1047 }
1048}
1049
1050// Expressions that syntactically contain an "exterior" struct literal i.e. not
1051// surrounded by any parens or other delimiters. For example `X { y: 1 }`, `X {
1052// y: 1 }.method()`, `foo == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X
1053// { y: 1 }) == foo` does not.
1054fn contains_exterior_struct_lit(expr: &Expr) -> bool {
1055 match expr {
1056 Expr::Struct(_) => true,
1057
1058 Expr::Assign(ExprAssign { left, right, .. })
1059 | Expr::Binary(ExprBinary { left, right, .. }) => {
1060 // X { y: 1 } + X { y: 2 }
1061 contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right)
1062 }
1063
1064 Expr::Await(ExprAwait { base: e, .. })
1065 | Expr::Cast(ExprCast { expr: e, .. })
1066 | Expr::Field(ExprField { base: e, .. })
1067 | Expr::Group(ExprGroup { expr: e, .. })
1068 | Expr::Index(ExprIndex { expr: e, .. })
1069 | Expr::MethodCall(ExprMethodCall { receiver: e, .. })
1070 | Expr::Reference(ExprReference { expr: e, .. })
1071 | Expr::Unary(ExprUnary { expr: e, .. }) => {
1072 // &X { y: 1 }, X { y: 1 }.y
1073 contains_exterior_struct_lit(e)
1074 }
1075
1076 Expr::Array(_)
1077 | Expr::Async(_)
1078 | Expr::Block(_)
1079 | Expr::Break(_)
1080 | Expr::Call(_)
1081 | Expr::Closure(_)
1082 | Expr::Const(_)
1083 | Expr::Continue(_)
1084 | Expr::ForLoop(_)
1085 | Expr::If(_)
1086 | Expr::Infer(_)
1087 | Expr::Let(_)
1088 | Expr::Lit(_)
1089 | Expr::Loop(_)
1090 | Expr::Macro(_)
1091 | Expr::Match(_)
1092 | Expr::Paren(_)
1093 | Expr::Path(_)
1094 | Expr::Range(_)
1095 | Expr::Repeat(_)
1096 | Expr::Return(_)
1097 | Expr::Try(_)
1098 | Expr::TryBlock(_)
1099 | Expr::Tuple(_)
1100 | Expr::Unsafe(_)
1101 | Expr::Verbatim(_)
1102 | Expr::While(_)
1103 | Expr::Yield(_) => false,
1104
1105 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1106 _ => false,
1107 }
1108}
1109
1110fn needs_newline_if_wrap(expr: &Expr) -> bool {
1111 match expr {
1112 Expr::Array(_)
1113 | Expr::Async(_)
1114 | Expr::Block(_)
1115 | Expr::Break(ExprBreak { expr: None, .. })
1116 | Expr::Closure(_)
1117 | Expr::Const(_)
1118 | Expr::Continue(_)
1119 | Expr::ForLoop(_)
1120 | Expr::If(_)
1121 | Expr::Infer(_)
1122 | Expr::Lit(_)
1123 | Expr::Loop(_)
1124 | Expr::Macro(_)
1125 | Expr::Match(_)
1126 | Expr::Path(_)
1127 | Expr::Range(ExprRange { end: None, .. })
1128 | Expr::Repeat(_)
1129 | Expr::Return(ExprReturn { expr: None, .. })
1130 | Expr::Struct(_)
1131 | Expr::TryBlock(_)
1132 | Expr::Tuple(_)
1133 | Expr::Unsafe(_)
1134 | Expr::Verbatim(_)
1135 | Expr::While(_)
1136 | Expr::Yield(ExprYield { expr: None, .. }) => false,
1137
1138 Expr::Assign(_)
1139 | Expr::Await(_)
1140 | Expr::Binary(_)
1141 | Expr::Cast(_)
1142 | Expr::Field(_)
1143 | Expr::Index(_)
1144 | Expr::MethodCall(_) => true,
1145
1146 Expr::Break(ExprBreak { expr: Some(e), .. })
1147 | Expr::Call(ExprCall { func: e, .. })
1148 | Expr::Group(ExprGroup { expr: e, .. })
1149 | Expr::Let(ExprLet { expr: e, .. })
1150 | Expr::Paren(ExprParen { expr: e, .. })
1151 | Expr::Range(ExprRange { end: Some(e), .. })
1152 | Expr::Reference(ExprReference { expr: e, .. })
1153 | Expr::Return(ExprReturn { expr: Some(e), .. })
1154 | Expr::Try(ExprTry { expr: e, .. })
1155 | Expr::Unary(ExprUnary { expr: e, .. })
1156 | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1157
1158 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1159 _ => false,
1160 }
1161}
1162
1163fn is_short_ident(expr: &Expr) -> bool {
1164 if let Expr::Path(expr: &ExprPath) = expr {
1165 return expr.attrs.is_empty()
1166 && expr.qself.is_none()
1167 && expr
1168 .path
1169 .get_ident()
1170 .map_or(default:false, |ident: &Ident| ident.to_string().len() as isize <= INDENT);
1171 }
1172 false
1173}
1174
1175fn is_blocklike(expr: &Expr) -> bool {
1176 match expr {
1177 Expr::Array(ExprArray { attrs, .. })
1178 | Expr::Async(ExprAsync { attrs, .. })
1179 | Expr::Block(ExprBlock { attrs, .. })
1180 | Expr::Closure(ExprClosure { attrs, .. })
1181 | Expr::Const(ExprConst { attrs, .. })
1182 | Expr::Struct(ExprStruct { attrs, .. })
1183 | Expr::TryBlock(ExprTryBlock { attrs, .. })
1184 | Expr::Tuple(ExprTuple { attrs, .. })
1185 | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1186
1187 Expr::Assign(_)
1188 | Expr::Await(_)
1189 | Expr::Binary(_)
1190 | Expr::Break(_)
1191 | Expr::Call(_)
1192 | Expr::Cast(_)
1193 | Expr::Continue(_)
1194 | Expr::Field(_)
1195 | Expr::ForLoop(_)
1196 | Expr::Group(_)
1197 | Expr::If(_)
1198 | Expr::Index(_)
1199 | Expr::Infer(_)
1200 | Expr::Let(_)
1201 | Expr::Lit(_)
1202 | Expr::Loop(_)
1203 | Expr::Macro(_)
1204 | Expr::Match(_)
1205 | Expr::MethodCall(_)
1206 | Expr::Paren(_)
1207 | Expr::Path(_)
1208 | Expr::Range(_)
1209 | Expr::Reference(_)
1210 | Expr::Repeat(_)
1211 | Expr::Return(_)
1212 | Expr::Try(_)
1213 | Expr::Unary(_)
1214 | Expr::Verbatim(_)
1215 | Expr::While(_)
1216 | Expr::Yield(_) => false,
1217
1218 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1219 _ => false,
1220 }
1221}
1222
1223// Expressions for which `$expr` and `{ $expr }` mean the same thing.
1224//
1225// This is not the case for all expressions. For example `{} | x | x` has some
1226// bitwise OR operators while `{ {} |x| x }` has a block followed by a closure.
1227fn parseable_as_stmt(expr: &Expr) -> bool {
1228 match expr {
1229 Expr::Array(_)
1230 | Expr::Async(_)
1231 | Expr::Block(_)
1232 | Expr::Break(_)
1233 | Expr::Closure(_)
1234 | Expr::Const(_)
1235 | Expr::Continue(_)
1236 | Expr::ForLoop(_)
1237 | Expr::If(_)
1238 | Expr::Infer(_)
1239 | Expr::Let(_)
1240 | Expr::Lit(_)
1241 | Expr::Loop(_)
1242 | Expr::Macro(_)
1243 | Expr::Match(_)
1244 | Expr::Paren(_)
1245 | Expr::Path(_)
1246 | Expr::Reference(_)
1247 | Expr::Repeat(_)
1248 | Expr::Return(_)
1249 | Expr::Struct(_)
1250 | Expr::TryBlock(_)
1251 | Expr::Tuple(_)
1252 | Expr::Unary(_)
1253 | Expr::Unsafe(_)
1254 | Expr::Verbatim(_)
1255 | Expr::While(_)
1256 | Expr::Yield(_) => true,
1257
1258 Expr::Assign(expr) => parseable_as_stmt(&expr.left),
1259 Expr::Await(expr) => parseable_as_stmt(&expr.base),
1260 Expr::Binary(expr) => requires_terminator(&expr.left) && parseable_as_stmt(&expr.left),
1261 Expr::Call(expr) => requires_terminator(&expr.func) && parseable_as_stmt(&expr.func),
1262 Expr::Cast(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1263 Expr::Field(expr) => parseable_as_stmt(&expr.base),
1264 Expr::Group(expr) => parseable_as_stmt(&expr.expr),
1265 Expr::Index(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1266 Expr::MethodCall(expr) => parseable_as_stmt(&expr.receiver),
1267 Expr::Range(expr) => match &expr.start {
1268 None => true,
1269 Some(start) => requires_terminator(start) && parseable_as_stmt(start),
1270 },
1271 Expr::Try(expr) => parseable_as_stmt(&expr.expr),
1272
1273 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1274 _ => false,
1275 }
1276}
1277