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