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        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                    // If not one of the valid expressions to exist in an else
395                    // clause, wrap in a block.
396                    other => {
397                        self.word("{");
398                        self.space();
399                        self.ibox(INDENT);
400                        self.expr(other);
401                        self.end();
402                        self.space();
403                        self.offset(-INDENT);
404                        self.word("}");
405                    }
406                }
407                break;
408            }
409        } else if expr.then_branch.stmts.is_empty() {
410            self.word("{}");
411        } else {
412            self.word("{");
413            self.hardbreak();
414            for stmt in &expr.then_branch.stmts {
415                self.stmt(stmt);
416            }
417            self.offset(-INDENT);
418            self.word("}");
419        }
420        self.end();
421    }
422
423    fn expr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
424        self.outer_attrs(&expr.attrs);
425        self.expr_beginning_of_line(&expr.expr, beginning_of_line);
426        self.word("[");
427        self.expr(&expr.index);
428        self.word("]");
429    }
430
431    fn subexpr_index(&mut self, expr: &ExprIndex, beginning_of_line: bool) {
432        self.subexpr(&expr.expr, beginning_of_line);
433        self.word("[");
434        self.expr(&expr.index);
435        self.word("]");
436    }
437
438    fn expr_infer(&mut self, expr: &ExprInfer) {
439        self.outer_attrs(&expr.attrs);
440        self.word("_");
441    }
442
443    fn expr_let(&mut self, expr: &ExprLet) {
444        self.outer_attrs(&expr.attrs);
445        self.ibox(0);
446        self.word("let ");
447        self.ibox(0);
448        self.pat(&expr.pat);
449        self.end();
450        self.word(" = ");
451        self.neverbreak();
452        self.ibox(0);
453        let needs_paren = contains_exterior_struct_lit(&expr.expr);
454        if needs_paren {
455            self.word("(");
456        }
457        self.expr(&expr.expr);
458        if needs_paren {
459            self.word(")");
460        }
461        self.end();
462        self.end();
463    }
464
465    pub fn expr_lit(&mut self, expr: &ExprLit) {
466        self.outer_attrs(&expr.attrs);
467        self.lit(&expr.lit);
468    }
469
470    fn expr_loop(&mut self, expr: &ExprLoop) {
471        self.outer_attrs(&expr.attrs);
472        if let Some(label) = &expr.label {
473            self.label(label);
474        }
475        self.word("loop {");
476        self.cbox(INDENT);
477        self.hardbreak_if_nonempty();
478        self.inner_attrs(&expr.attrs);
479        for stmt in &expr.body.stmts {
480            self.stmt(stmt);
481        }
482        self.offset(-INDENT);
483        self.end();
484        self.word("}");
485    }
486
487    pub fn expr_macro(&mut self, expr: &ExprMacro) {
488        self.outer_attrs(&expr.attrs);
489        let semicolon = false;
490        self.mac(&expr.mac, None, semicolon);
491    }
492
493    fn expr_match(&mut self, expr: &ExprMatch) {
494        self.outer_attrs(&expr.attrs);
495        self.ibox(0);
496        self.word("match ");
497        self.wrap_exterior_struct(&expr.expr);
498        self.word("{");
499        self.neverbreak();
500        self.cbox(INDENT);
501        self.hardbreak_if_nonempty();
502        self.inner_attrs(&expr.attrs);
503        for arm in &expr.arms {
504            self.arm(arm);
505            self.hardbreak();
506        }
507        self.offset(-INDENT);
508        self.end();
509        self.word("}");
510        self.end();
511    }
512
513    fn expr_method_call(&mut self, expr: &ExprMethodCall, beginning_of_line: bool) {
514        self.outer_attrs(&expr.attrs);
515        self.cbox(INDENT);
516        let unindent_call_args = beginning_of_line && is_short_ident(&expr.receiver);
517        self.subexpr_method_call(expr, beginning_of_line, unindent_call_args);
518        self.end();
519    }
520
521    fn subexpr_method_call(
522        &mut self,
523        expr: &ExprMethodCall,
524        beginning_of_line: bool,
525        unindent_call_args: bool,
526    ) {
527        self.subexpr(&expr.receiver, beginning_of_line);
528        self.zerobreak_unless_short_ident(beginning_of_line, &expr.receiver);
529        self.word(".");
530        self.ident(&expr.method);
531        if let Some(turbofish) = &expr.turbofish {
532            self.angle_bracketed_generic_arguments(turbofish, PathKind::Expr);
533        }
534        self.cbox(if unindent_call_args { -INDENT } else { 0 });
535        self.word("(");
536        self.call_args(&expr.args);
537        self.word(")");
538        self.end();
539    }
540
541    fn expr_paren(&mut self, expr: &ExprParen) {
542        self.outer_attrs(&expr.attrs);
543        self.word("(");
544        self.expr(&expr.expr);
545        self.word(")");
546    }
547
548    pub fn expr_path(&mut self, expr: &ExprPath) {
549        self.outer_attrs(&expr.attrs);
550        self.qpath(&expr.qself, &expr.path, PathKind::Expr);
551    }
552
553    pub fn expr_range(&mut self, expr: &ExprRange) {
554        self.outer_attrs(&expr.attrs);
555        if let Some(start) = &expr.start {
556            self.expr(start);
557        }
558        self.word(match expr.limits {
559            RangeLimits::HalfOpen(_) => "..",
560            RangeLimits::Closed(_) => "..=",
561        });
562        if let Some(end) = &expr.end {
563            self.expr(end);
564        }
565    }
566
567    fn expr_reference(&mut self, expr: &ExprReference) {
568        self.outer_attrs(&expr.attrs);
569        self.word("&");
570        if expr.mutability.is_some() {
571            self.word("mut ");
572        }
573        self.expr(&expr.expr);
574    }
575
576    fn expr_repeat(&mut self, expr: &ExprRepeat) {
577        self.outer_attrs(&expr.attrs);
578        self.word("[");
579        self.expr(&expr.expr);
580        self.word("; ");
581        self.expr(&expr.len);
582        self.word("]");
583    }
584
585    fn expr_return(&mut self, expr: &ExprReturn) {
586        self.outer_attrs(&expr.attrs);
587        self.word("return");
588        if let Some(value) = &expr.expr {
589            self.nbsp();
590            self.expr(value);
591        }
592    }
593
594    fn expr_struct(&mut self, expr: &ExprStruct) {
595        self.outer_attrs(&expr.attrs);
596        self.cbox(INDENT);
597        self.ibox(-INDENT);
598        self.qpath(&expr.qself, &expr.path, PathKind::Expr);
599        self.end();
600        self.word(" {");
601        self.space_if_nonempty();
602        for field_value in expr.fields.iter().delimited() {
603            self.field_value(&field_value);
604            self.trailing_comma_or_space(field_value.is_last && expr.rest.is_none());
605        }
606        if let Some(rest) = &expr.rest {
607            self.word("..");
608            self.expr(rest);
609            self.space();
610        }
611        self.offset(-INDENT);
612        self.end_with_max_width(34);
613        self.word("}");
614    }
615
616    fn expr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
617        self.outer_attrs(&expr.attrs);
618        self.expr_beginning_of_line(&expr.expr, beginning_of_line);
619        self.word("?");
620    }
621
622    fn subexpr_try(&mut self, expr: &ExprTry, beginning_of_line: bool) {
623        self.subexpr(&expr.expr, beginning_of_line);
624        self.word("?");
625    }
626
627    fn expr_try_block(&mut self, expr: &ExprTryBlock) {
628        self.outer_attrs(&expr.attrs);
629        self.word("try ");
630        self.cbox(INDENT);
631        self.small_block(&expr.block, &expr.attrs);
632        self.end();
633    }
634
635    fn expr_tuple(&mut self, expr: &ExprTuple) {
636        self.outer_attrs(&expr.attrs);
637        self.word("(");
638        self.cbox(INDENT);
639        self.zerobreak();
640        for elem in expr.elems.iter().delimited() {
641            self.expr(&elem);
642            if expr.elems.len() == 1 {
643                self.word(",");
644                self.zerobreak();
645            } else {
646                self.trailing_comma(elem.is_last);
647            }
648        }
649        self.offset(-INDENT);
650        self.end();
651        self.word(")");
652    }
653
654    fn expr_unary(&mut self, expr: &ExprUnary) {
655        self.outer_attrs(&expr.attrs);
656        self.unary_operator(&expr.op);
657        self.expr(&expr.expr);
658    }
659
660    fn expr_unsafe(&mut self, expr: &ExprUnsafe) {
661        self.outer_attrs(&expr.attrs);
662        self.word("unsafe ");
663        self.cbox(INDENT);
664        self.small_block(&expr.block, &expr.attrs);
665        self.end();
666    }
667
668    #[cfg(not(feature = "verbatim"))]
669    fn expr_verbatim(&mut self, expr: &TokenStream) {
670        if !expr.is_empty() {
671            unimplemented!("Expr::Verbatim `{}`", expr);
672        }
673    }
674
675    #[cfg(feature = "verbatim")]
676    fn expr_verbatim(&mut self, tokens: &TokenStream) {
677        use syn::parse::discouraged::Speculative;
678        use syn::parse::{Parse, ParseStream, Result};
679        use syn::{parenthesized, Ident};
680
681        enum ExprVerbatim {
682            Empty,
683            Ellipsis,
684            Become(Become),
685            Builtin(Builtin),
686            RawReference(RawReference),
687        }
688
689        struct Become {
690            attrs: Vec<Attribute>,
691            tail_call: Expr,
692        }
693
694        struct Builtin {
695            attrs: Vec<Attribute>,
696            name: Ident,
697            args: TokenStream,
698        }
699
700        struct RawReference {
701            attrs: Vec<Attribute>,
702            mutable: bool,
703            expr: Expr,
704        }
705
706        mod kw {
707            syn::custom_keyword!(builtin);
708            syn::custom_keyword!(raw);
709        }
710
711        impl Parse for ExprVerbatim {
712            fn parse(input: ParseStream) -> Result<Self> {
713                let ahead = input.fork();
714                let attrs = ahead.call(Attribute::parse_outer)?;
715                let lookahead = ahead.lookahead1();
716                if input.is_empty() {
717                    Ok(ExprVerbatim::Empty)
718                } else if lookahead.peek(Token![become]) {
719                    input.advance_to(&ahead);
720                    input.parse::<Token![become]>()?;
721                    let tail_call: Expr = input.parse()?;
722                    Ok(ExprVerbatim::Become(Become { attrs, tail_call }))
723                } else if lookahead.peek(kw::builtin) {
724                    input.advance_to(&ahead);
725                    input.parse::<kw::builtin>()?;
726                    input.parse::<Token![#]>()?;
727                    let name: Ident = input.parse()?;
728                    let args;
729                    parenthesized!(args in input);
730                    let args: TokenStream = args.parse()?;
731                    Ok(ExprVerbatim::Builtin(Builtin { attrs, name, args }))
732                } else if lookahead.peek(Token![&]) {
733                    input.advance_to(&ahead);
734                    input.parse::<Token![&]>()?;
735                    input.parse::<kw::raw>()?;
736                    let mutable = input.parse::<Option<Token![mut]>>()?.is_some();
737                    if !mutable {
738                        input.parse::<Token![const]>()?;
739                    }
740                    let expr: Expr = input.parse()?;
741                    Ok(ExprVerbatim::RawReference(RawReference {
742                        attrs,
743                        mutable,
744                        expr,
745                    }))
746                } else if lookahead.peek(Token![...]) {
747                    input.parse::<Token![...]>()?;
748                    Ok(ExprVerbatim::Ellipsis)
749                } else {
750                    Err(lookahead.error())
751                }
752            }
753        }
754
755        let expr: ExprVerbatim = match syn::parse2(tokens.clone()) {
756            Ok(expr) => expr,
757            Err(_) => unimplemented!("Expr::Verbatim `{}`", tokens),
758        };
759
760        match expr {
761            ExprVerbatim::Empty => {}
762            ExprVerbatim::Ellipsis => {
763                self.word("...");
764            }
765            ExprVerbatim::Become(expr) => {
766                self.outer_attrs(&expr.attrs);
767                self.word("become");
768                self.nbsp();
769                self.expr(&expr.tail_call);
770            }
771            ExprVerbatim::Builtin(expr) => {
772                self.outer_attrs(&expr.attrs);
773                self.word("builtin # ");
774                self.ident(&expr.name);
775                self.word("(");
776                if !expr.args.is_empty() {
777                    self.cbox(INDENT);
778                    self.zerobreak();
779                    self.ibox(0);
780                    self.macro_rules_tokens(expr.args, false);
781                    self.end();
782                    self.zerobreak();
783                    self.offset(-INDENT);
784                    self.end();
785                }
786                self.word(")");
787            }
788            ExprVerbatim::RawReference(expr) => {
789                self.outer_attrs(&expr.attrs);
790                self.word("&raw ");
791                self.word(if expr.mutable { "mut " } else { "const " });
792                self.expr(&expr.expr);
793            }
794        }
795    }
796
797    fn expr_while(&mut self, expr: &ExprWhile) {
798        self.outer_attrs(&expr.attrs);
799        if let Some(label) = &expr.label {
800            self.label(label);
801        }
802        self.word("while ");
803        self.wrap_exterior_struct(&expr.cond);
804        self.word("{");
805        self.neverbreak();
806        self.cbox(INDENT);
807        self.hardbreak_if_nonempty();
808        self.inner_attrs(&expr.attrs);
809        for stmt in &expr.body.stmts {
810            self.stmt(stmt);
811        }
812        self.offset(-INDENT);
813        self.end();
814        self.word("}");
815    }
816
817    fn expr_yield(&mut self, expr: &ExprYield) {
818        self.outer_attrs(&expr.attrs);
819        self.word("yield");
820        if let Some(value) = &expr.expr {
821            self.nbsp();
822            self.expr(value);
823        }
824    }
825
826    fn label(&mut self, label: &Label) {
827        self.lifetime(&label.name);
828        self.word(": ");
829    }
830
831    fn field_value(&mut self, field_value: &FieldValue) {
832        self.outer_attrs(&field_value.attrs);
833        self.member(&field_value.member);
834        if field_value.colon_token.is_some() {
835            self.word(": ");
836            self.ibox(0);
837            self.expr(&field_value.expr);
838            self.end();
839        }
840    }
841
842    fn arm(&mut self, arm: &Arm) {
843        self.outer_attrs(&arm.attrs);
844        self.ibox(0);
845        self.pat(&arm.pat);
846        if let Some((_if_token, guard)) = &arm.guard {
847            self.word(" if ");
848            self.expr(guard);
849        }
850        self.word(" =>");
851        let empty_block;
852        let mut body = &*arm.body;
853        while let Expr::Block(expr) = body {
854            if expr.attrs.is_empty() && expr.label.is_none() {
855                let mut stmts = expr.block.stmts.iter();
856                if let (Some(Stmt::Expr(inner, None)), None) = (stmts.next(), stmts.next()) {
857                    body = inner;
858                    continue;
859                }
860            }
861            break;
862        }
863        if let Expr::Tuple(expr) = body {
864            if expr.elems.is_empty() && expr.attrs.is_empty() {
865                empty_block = Expr::Block(ExprBlock {
866                    attrs: Vec::new(),
867                    label: None,
868                    block: Block {
869                        brace_token: token::Brace::default(),
870                        stmts: Vec::new(),
871                    },
872                });
873                body = &empty_block;
874            }
875        }
876        if let Expr::Block(body) = body {
877            self.nbsp();
878            if let Some(label) = &body.label {
879                self.label(label);
880            }
881            self.word("{");
882            self.neverbreak();
883            self.cbox(INDENT);
884            self.hardbreak_if_nonempty();
885            self.inner_attrs(&body.attrs);
886            for stmt in &body.block.stmts {
887                self.stmt(stmt);
888            }
889            self.offset(-INDENT);
890            self.end();
891            self.word("}");
892            self.end();
893        } else {
894            self.nbsp();
895            self.neverbreak();
896            self.cbox(INDENT);
897            self.scan_break(BreakToken {
898                pre_break: Some('{'),
899                ..BreakToken::default()
900            });
901            self.expr_beginning_of_line(body, true);
902            self.scan_break(BreakToken {
903                offset: -INDENT,
904                pre_break: stmt::add_semi(body).then(|| ';'),
905                post_break: Some('}'),
906                no_break: requires_terminator(body).then(|| ','),
907                ..BreakToken::default()
908            });
909            self.end();
910            self.end();
911        }
912    }
913
914    fn call_args(&mut self, args: &Punctuated<Expr, Token![,]>) {
915        let mut iter = args.iter();
916        match (iter.next(), iter.next()) {
917            (Some(expr), None) if is_blocklike(expr) => {
918                self.expr(expr);
919            }
920            _ => {
921                self.cbox(INDENT);
922                self.zerobreak();
923                for arg in args.iter().delimited() {
924                    self.expr(&arg);
925                    self.trailing_comma(arg.is_last);
926                }
927                self.offset(-INDENT);
928                self.end();
929            }
930        }
931    }
932
933    pub fn small_block(&mut self, block: &Block, attrs: &[Attribute]) {
934        self.word("{");
935        if attr::has_inner(attrs) || !block.stmts.is_empty() {
936            self.space();
937            self.inner_attrs(attrs);
938            match block.stmts.as_slice() {
939                [Stmt::Expr(expr, None)] if stmt::break_after(expr) => {
940                    self.ibox(0);
941                    self.expr_beginning_of_line(expr, true);
942                    self.end();
943                    self.space();
944                }
945                _ => {
946                    for stmt in &block.stmts {
947                        self.stmt(stmt);
948                    }
949                }
950            }
951            self.offset(-INDENT);
952        }
953        self.word("}");
954    }
955
956    pub fn member(&mut self, member: &Member) {
957        match member {
958            Member::Named(ident) => self.ident(ident),
959            Member::Unnamed(index) => self.index(index),
960        }
961    }
962
963    fn index(&mut self, member: &Index) {
964        self.word(member.index.to_string());
965    }
966
967    fn binary_operator(&mut self, op: &BinOp) {
968        self.word(
969            match op {
970                #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
971                BinOp::Add(_) => "+",
972                BinOp::Sub(_) => "-",
973                BinOp::Mul(_) => "*",
974                BinOp::Div(_) => "/",
975                BinOp::Rem(_) => "%",
976                BinOp::And(_) => "&&",
977                BinOp::Or(_) => "||",
978                BinOp::BitXor(_) => "^",
979                BinOp::BitAnd(_) => "&",
980                BinOp::BitOr(_) => "|",
981                BinOp::Shl(_) => "<<",
982                BinOp::Shr(_) => ">>",
983                BinOp::Eq(_) => "==",
984                BinOp::Lt(_) => "<",
985                BinOp::Le(_) => "<=",
986                BinOp::Ne(_) => "!=",
987                BinOp::Ge(_) => ">=",
988                BinOp::Gt(_) => ">",
989                BinOp::AddAssign(_) => "+=",
990                BinOp::SubAssign(_) => "-=",
991                BinOp::MulAssign(_) => "*=",
992                BinOp::DivAssign(_) => "/=",
993                BinOp::RemAssign(_) => "%=",
994                BinOp::BitXorAssign(_) => "^=",
995                BinOp::BitAndAssign(_) => "&=",
996                BinOp::BitOrAssign(_) => "|=",
997                BinOp::ShlAssign(_) => "<<=",
998                BinOp::ShrAssign(_) => ">>=",
999                _ => unimplemented!("unknown BinOp"),
1000            },
1001        );
1002    }
1003
1004    fn unary_operator(&mut self, op: &UnOp) {
1005        self.word(
1006            match op {
1007                #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1008                UnOp::Deref(_) => "*",
1009                UnOp::Not(_) => "!",
1010                UnOp::Neg(_) => "-",
1011                _ => unimplemented!("unknown UnOp"),
1012            },
1013        );
1014    }
1015
1016    fn zerobreak_unless_short_ident(&mut self, beginning_of_line: bool, expr: &Expr) {
1017        if beginning_of_line && is_short_ident(expr) {
1018            return;
1019        }
1020        self.zerobreak();
1021    }
1022}
1023
1024fn requires_terminator(expr: &Expr) -> bool {
1025    // see https://github.com/rust-lang/rust/blob/a266f1199/compiler/rustc_ast/src/util/classify.rs#L7-L26
1026    match expr {
1027        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1028        Expr::If(_)
1029        | Expr::Match(_)
1030        | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
1031        | Expr::While(_)
1032        | Expr::Loop(_)
1033        | Expr::ForLoop(_)
1034        | Expr::TryBlock(_)
1035        | Expr::Const(_) => false,
1036
1037        Expr::Array(_)
1038        | Expr::Assign(_)
1039        | Expr::Async(_)
1040        | Expr::Await(_)
1041        | Expr::Binary(_)
1042        | Expr::Break(_)
1043        | Expr::Call(_)
1044        | Expr::Cast(_)
1045        | Expr::Closure(_)
1046        | Expr::Continue(_)
1047        | Expr::Field(_)
1048        | Expr::Group(_)
1049        | Expr::Index(_)
1050        | Expr::Infer(_)
1051        | Expr::Let(_)
1052        | Expr::Lit(_)
1053        | Expr::Macro(_)
1054        | Expr::MethodCall(_)
1055        | Expr::Paren(_)
1056        | Expr::Path(_)
1057        | Expr::Range(_)
1058        | Expr::Reference(_)
1059        | Expr::Repeat(_)
1060        | Expr::Return(_)
1061        | Expr::Struct(_)
1062        | Expr::Try(_)
1063        | Expr::Tuple(_)
1064        | Expr::Unary(_)
1065        | Expr::Verbatim(_)
1066        | Expr::Yield(_) => true,
1067
1068        _ => true,
1069    }
1070}
1071
1072// Expressions that syntactically contain an "exterior" struct literal i.e. not
1073// surrounded by any parens or other delimiters. For example `X { y: 1 }`, `X {
1074// y: 1 }.method()`, `foo == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X
1075// { y: 1 }) == foo` does not.
1076fn contains_exterior_struct_lit(expr: &Expr) -> bool {
1077    match expr {
1078        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1079        Expr::Struct(_) => true,
1080
1081        Expr::Assign(ExprAssign { left, right, .. })
1082        | Expr::Binary(ExprBinary { left, right, .. }) => {
1083            // X { y: 1 } + X { y: 2 }
1084            contains_exterior_struct_lit(left) || contains_exterior_struct_lit(right)
1085        }
1086
1087        Expr::Await(ExprAwait { base: e, .. })
1088        | Expr::Cast(ExprCast { expr: e, .. })
1089        | Expr::Field(ExprField { base: e, .. })
1090        | Expr::Group(ExprGroup { expr: e, .. })
1091        | Expr::Index(ExprIndex { expr: e, .. })
1092        | Expr::MethodCall(ExprMethodCall { receiver: e, .. })
1093        | Expr::Reference(ExprReference { expr: e, .. })
1094        | Expr::Unary(ExprUnary { expr: e, .. }) => {
1095            // &X { y: 1 }, X { y: 1 }.y
1096            contains_exterior_struct_lit(e)
1097        }
1098
1099        Expr::Array(_)
1100        | Expr::Async(_)
1101        | Expr::Block(_)
1102        | Expr::Break(_)
1103        | Expr::Call(_)
1104        | Expr::Closure(_)
1105        | Expr::Const(_)
1106        | Expr::Continue(_)
1107        | Expr::ForLoop(_)
1108        | Expr::If(_)
1109        | Expr::Infer(_)
1110        | Expr::Let(_)
1111        | Expr::Lit(_)
1112        | Expr::Loop(_)
1113        | Expr::Macro(_)
1114        | Expr::Match(_)
1115        | Expr::Paren(_)
1116        | Expr::Path(_)
1117        | Expr::Range(_)
1118        | Expr::Repeat(_)
1119        | Expr::Return(_)
1120        | Expr::Try(_)
1121        | Expr::TryBlock(_)
1122        | Expr::Tuple(_)
1123        | Expr::Unsafe(_)
1124        | Expr::Verbatim(_)
1125        | Expr::While(_)
1126        | Expr::Yield(_) => false,
1127
1128        _ => false,
1129    }
1130}
1131
1132fn needs_newline_if_wrap(expr: &Expr) -> bool {
1133    match expr {
1134        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1135        Expr::Array(_)
1136        | Expr::Async(_)
1137        | Expr::Block(_)
1138        | Expr::Break(ExprBreak { expr: None, .. })
1139        | Expr::Closure(_)
1140        | Expr::Const(_)
1141        | Expr::Continue(_)
1142        | Expr::ForLoop(_)
1143        | Expr::If(_)
1144        | Expr::Infer(_)
1145        | Expr::Lit(_)
1146        | Expr::Loop(_)
1147        | Expr::Macro(_)
1148        | Expr::Match(_)
1149        | Expr::Path(_)
1150        | Expr::Range(ExprRange { end: None, .. })
1151        | Expr::Repeat(_)
1152        | Expr::Return(ExprReturn { expr: None, .. })
1153        | Expr::Struct(_)
1154        | Expr::TryBlock(_)
1155        | Expr::Tuple(_)
1156        | Expr::Unsafe(_)
1157        | Expr::Verbatim(_)
1158        | Expr::While(_)
1159        | Expr::Yield(ExprYield { expr: None, .. }) => false,
1160
1161        Expr::Assign(_)
1162        | Expr::Await(_)
1163        | Expr::Binary(_)
1164        | Expr::Cast(_)
1165        | Expr::Field(_)
1166        | Expr::Index(_)
1167        | Expr::MethodCall(_) => true,
1168
1169        Expr::Break(ExprBreak { expr: Some(e), .. })
1170        | Expr::Call(ExprCall { func: e, .. })
1171        | Expr::Group(ExprGroup { expr: e, .. })
1172        | Expr::Let(ExprLet { expr: e, .. })
1173        | Expr::Paren(ExprParen { expr: e, .. })
1174        | Expr::Range(ExprRange { end: Some(e), .. })
1175        | Expr::Reference(ExprReference { expr: e, .. })
1176        | Expr::Return(ExprReturn { expr: Some(e), .. })
1177        | Expr::Try(ExprTry { expr: e, .. })
1178        | Expr::Unary(ExprUnary { expr: e, .. })
1179        | Expr::Yield(ExprYield { expr: Some(e), .. }) => needs_newline_if_wrap(e),
1180
1181        _ => false,
1182    }
1183}
1184
1185fn is_short_ident(expr: &Expr) -> bool {
1186    if let Expr::Path(expr) = expr {
1187        return expr.attrs.is_empty()
1188            && expr.qself.is_none()
1189            && expr
1190                .path
1191                .get_ident()
1192                .map_or(false, |ident| ident.to_string().len() as isize <= INDENT);
1193    }
1194    false
1195}
1196
1197fn is_blocklike(expr: &Expr) -> bool {
1198    match expr {
1199        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1200        Expr::Array(ExprArray { attrs, .. })
1201        | Expr::Async(ExprAsync { attrs, .. })
1202        | Expr::Block(ExprBlock { attrs, .. })
1203        | Expr::Closure(ExprClosure { attrs, .. })
1204        | Expr::Const(ExprConst { attrs, .. })
1205        | Expr::Struct(ExprStruct { attrs, .. })
1206        | Expr::TryBlock(ExprTryBlock { attrs, .. })
1207        | Expr::Tuple(ExprTuple { attrs, .. })
1208        | Expr::Unsafe(ExprUnsafe { attrs, .. }) => !attr::has_outer(attrs),
1209
1210        Expr::Assign(_)
1211        | Expr::Await(_)
1212        | Expr::Binary(_)
1213        | Expr::Break(_)
1214        | Expr::Call(_)
1215        | Expr::Cast(_)
1216        | Expr::Continue(_)
1217        | Expr::Field(_)
1218        | Expr::ForLoop(_)
1219        | Expr::Group(_)
1220        | Expr::If(_)
1221        | Expr::Index(_)
1222        | Expr::Infer(_)
1223        | Expr::Let(_)
1224        | Expr::Lit(_)
1225        | Expr::Loop(_)
1226        | Expr::Macro(_)
1227        | Expr::Match(_)
1228        | Expr::MethodCall(_)
1229        | Expr::Paren(_)
1230        | Expr::Path(_)
1231        | Expr::Range(_)
1232        | Expr::Reference(_)
1233        | Expr::Repeat(_)
1234        | Expr::Return(_)
1235        | Expr::Try(_)
1236        | Expr::Unary(_)
1237        | Expr::Verbatim(_)
1238        | Expr::While(_)
1239        | Expr::Yield(_) => false,
1240
1241        _ => false,
1242    }
1243}
1244
1245// Expressions for which `$expr` and `{ $expr }` mean the same thing.
1246//
1247// This is not the case for all expressions. For example `{} | x | x` has some
1248// bitwise OR operators while `{ {} |x| x }` has a block followed by a closure.
1249fn parseable_as_stmt(expr: &Expr) -> bool {
1250    match expr {
1251        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1252        Expr::Array(_)
1253        | Expr::Async(_)
1254        | Expr::Block(_)
1255        | Expr::Break(_)
1256        | Expr::Closure(_)
1257        | Expr::Const(_)
1258        | Expr::Continue(_)
1259        | Expr::ForLoop(_)
1260        | Expr::If(_)
1261        | Expr::Infer(_)
1262        | Expr::Let(_)
1263        | Expr::Lit(_)
1264        | Expr::Loop(_)
1265        | Expr::Macro(_)
1266        | Expr::Match(_)
1267        | Expr::Paren(_)
1268        | Expr::Path(_)
1269        | Expr::Reference(_)
1270        | Expr::Repeat(_)
1271        | Expr::Return(_)
1272        | Expr::Struct(_)
1273        | Expr::TryBlock(_)
1274        | Expr::Tuple(_)
1275        | Expr::Unary(_)
1276        | Expr::Unsafe(_)
1277        | Expr::Verbatim(_)
1278        | Expr::While(_)
1279        | Expr::Yield(_) => true,
1280
1281        Expr::Assign(expr) => parseable_as_stmt(&expr.left),
1282        Expr::Await(expr) => parseable_as_stmt(&expr.base),
1283        Expr::Binary(expr) => requires_terminator(&expr.left) && parseable_as_stmt(&expr.left),
1284        Expr::Call(expr) => requires_terminator(&expr.func) && parseable_as_stmt(&expr.func),
1285        Expr::Cast(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1286        Expr::Field(expr) => parseable_as_stmt(&expr.base),
1287        Expr::Group(expr) => parseable_as_stmt(&expr.expr),
1288        Expr::Index(expr) => requires_terminator(&expr.expr) && parseable_as_stmt(&expr.expr),
1289        Expr::MethodCall(expr) => parseable_as_stmt(&expr.receiver),
1290        Expr::Range(expr) => match &expr.start {
1291            None => true,
1292            Some(start) => requires_terminator(start) && parseable_as_stmt(start),
1293        },
1294        Expr::Try(expr) => parseable_as_stmt(&expr.expr),
1295
1296        _ => false,
1297    }
1298}