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