prettyplease/
expr.rs

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