]>
Commit | Line | Data |
---|---|---|
5099ac24 FG |
1 | use crate::pp::Breaks::Inconsistent; |
2 | use crate::pprust::state::{AnnNode, IterDelimited, PrintState, State, INDENT_UNIT}; | |
3 | ||
4 | use rustc_ast::ptr::P; | |
5 | use rustc_ast::util::parser::{self, AssocOp, Fixity}; | |
6 | use rustc_ast::{self as ast, BlockCheckMode}; | |
7 | ||
8 | impl<'a> State<'a> { | |
9 | fn print_else(&mut self, els: Option<&ast::Expr>) { | |
10 | if let Some(_else) = els { | |
11 | match _else.kind { | |
12 | // Another `else if` block. | |
13 | ast::ExprKind::If(ref i, ref then, ref e) => { | |
14 | self.cbox(INDENT_UNIT - 1); | |
15 | self.ibox(0); | |
16 | self.word(" else if "); | |
17 | self.print_expr_as_cond(i); | |
18 | self.space(); | |
19 | self.print_block(then); | |
20 | self.print_else(e.as_deref()) | |
21 | } | |
22 | // Final `else` block. | |
23 | ast::ExprKind::Block(ref b, _) => { | |
24 | self.cbox(INDENT_UNIT - 1); | |
25 | self.ibox(0); | |
26 | self.word(" else "); | |
27 | self.print_block(b) | |
28 | } | |
29 | // Constraints would be great here! | |
30 | _ => { | |
31 | panic!("print_if saw if with weird alternative"); | |
32 | } | |
33 | } | |
34 | } | |
35 | } | |
36 | ||
37 | fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, elseopt: Option<&ast::Expr>) { | |
38 | self.head("if"); | |
39 | self.print_expr_as_cond(test); | |
40 | self.space(); | |
41 | self.print_block(blk); | |
42 | self.print_else(elseopt) | |
43 | } | |
44 | ||
45 | fn print_call_post(&mut self, args: &[P<ast::Expr>]) { | |
46 | self.popen(); | |
47 | self.commasep_exprs(Inconsistent, args); | |
48 | self.pclose() | |
49 | } | |
50 | ||
51 | fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) { | |
52 | self.print_expr_cond_paren(expr, expr.precedence().order() < prec) | |
53 | } | |
54 | ||
55 | /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in | |
56 | /// `if cond { ... }`. | |
57 | fn print_expr_as_cond(&mut self, expr: &ast::Expr) { | |
58 | self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) | |
59 | } | |
60 | ||
61 | // Does `expr` need parentheses when printed in a condition position? | |
62 | // | |
63 | // These cases need parens due to the parse error observed in #26461: `if return {}` | |
64 | // parses as the erroneous construct `if (return {})`, not `if (return) {}`. | |
65 | pub(super) fn cond_needs_par(expr: &ast::Expr) -> bool { | |
66 | match expr.kind { | |
67 | ast::ExprKind::Break(..) | ast::ExprKind::Closure(..) | ast::ExprKind::Ret(..) => true, | |
68 | _ => parser::contains_exterior_struct_lit(expr), | |
69 | } | |
70 | } | |
71 | ||
72 | /// Prints `expr` or `(expr)` when `needs_par` holds. | |
73 | pub(super) fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) { | |
74 | if needs_par { | |
75 | self.popen(); | |
76 | } | |
77 | self.print_expr(expr); | |
78 | if needs_par { | |
79 | self.pclose(); | |
80 | } | |
81 | } | |
82 | ||
83 | fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) { | |
84 | self.ibox(INDENT_UNIT); | |
85 | self.word("["); | |
86 | self.commasep_exprs(Inconsistent, exprs); | |
87 | self.word("]"); | |
88 | self.end(); | |
89 | } | |
90 | ||
91 | pub(super) fn print_expr_anon_const(&mut self, expr: &ast::AnonConst) { | |
92 | self.ibox(INDENT_UNIT); | |
93 | self.word("const"); | |
94 | self.print_expr(&expr.value); | |
95 | self.end(); | |
96 | } | |
97 | ||
98 | fn print_expr_repeat(&mut self, element: &ast::Expr, count: &ast::AnonConst) { | |
99 | self.ibox(INDENT_UNIT); | |
100 | self.word("["); | |
101 | self.print_expr(element); | |
102 | self.word_space(";"); | |
103 | self.print_expr(&count.value); | |
104 | self.word("]"); | |
105 | self.end(); | |
106 | } | |
107 | ||
108 | fn print_expr_struct( | |
109 | &mut self, | |
110 | qself: &Option<ast::QSelf>, | |
111 | path: &ast::Path, | |
112 | fields: &[ast::ExprField], | |
113 | rest: &ast::StructRest, | |
114 | ) { | |
115 | if let Some(qself) = qself { | |
116 | self.print_qpath(path, qself, true); | |
117 | } else { | |
118 | self.print_path(path, true, 0); | |
119 | } | |
120 | self.nbsp(); | |
121 | self.word("{"); | |
122 | let has_rest = match rest { | |
123 | ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true, | |
124 | ast::StructRest::None => false, | |
125 | }; | |
126 | if fields.is_empty() && !has_rest { | |
127 | self.word("}"); | |
128 | return; | |
129 | } | |
130 | self.cbox(0); | |
131 | for field in fields.iter().delimited() { | |
132 | self.maybe_print_comment(field.span.hi()); | |
133 | self.print_outer_attributes(&field.attrs); | |
134 | if field.is_first { | |
135 | self.space_if_not_bol(); | |
136 | } | |
137 | if !field.is_shorthand { | |
138 | self.print_ident(field.ident); | |
139 | self.word_nbsp(":"); | |
140 | } | |
141 | self.print_expr(&field.expr); | |
142 | if !field.is_last || has_rest { | |
143 | self.word_space(","); | |
144 | } else { | |
145 | self.trailing_comma_or_space(); | |
146 | } | |
147 | } | |
148 | if has_rest { | |
149 | if fields.is_empty() { | |
150 | self.space(); | |
151 | } | |
152 | self.word(".."); | |
153 | if let ast::StructRest::Base(expr) = rest { | |
154 | self.print_expr(expr); | |
155 | } | |
156 | self.space(); | |
157 | } | |
158 | self.offset(-INDENT_UNIT); | |
159 | self.end(); | |
160 | self.word("}"); | |
161 | } | |
162 | ||
163 | fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) { | |
164 | self.popen(); | |
165 | self.commasep_exprs(Inconsistent, exprs); | |
166 | if exprs.len() == 1 { | |
167 | self.word(","); | |
168 | } | |
169 | self.pclose() | |
170 | } | |
171 | ||
172 | fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>]) { | |
173 | let prec = match func.kind { | |
174 | ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN, | |
175 | _ => parser::PREC_POSTFIX, | |
176 | }; | |
177 | ||
178 | self.print_expr_maybe_paren(func, prec); | |
179 | self.print_call_post(args) | |
180 | } | |
181 | ||
182 | fn print_expr_method_call(&mut self, segment: &ast::PathSegment, args: &[P<ast::Expr>]) { | |
183 | let base_args = &args[1..]; | |
184 | self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX); | |
185 | self.word("."); | |
186 | self.print_ident(segment.ident); | |
187 | if let Some(ref args) = segment.args { | |
188 | self.print_generic_args(args, true); | |
189 | } | |
190 | self.print_call_post(base_args) | |
191 | } | |
192 | ||
193 | fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, rhs: &ast::Expr) { | |
194 | let assoc_op = AssocOp::from_ast_binop(op.node); | |
195 | let prec = assoc_op.precedence() as i8; | |
196 | let fixity = assoc_op.fixity(); | |
197 | ||
198 | let (left_prec, right_prec) = match fixity { | |
199 | Fixity::Left => (prec, prec + 1), | |
200 | Fixity::Right => (prec + 1, prec), | |
201 | Fixity::None => (prec + 1, prec + 1), | |
202 | }; | |
203 | ||
204 | let left_prec = match (&lhs.kind, op.node) { | |
205 | // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is | |
206 | // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead | |
207 | // of `(x as i32) < ...`. We need to convince it _not_ to do that. | |
208 | (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt | ast::BinOpKind::Shl) => { | |
209 | parser::PREC_FORCE_PAREN | |
210 | } | |
211 | // We are given `(let _ = a) OP b`. | |
212 | // | |
213 | // - When `OP <= LAnd` we should print `let _ = a OP b` to avoid redundant parens | |
214 | // as the parser will interpret this as `(let _ = a) OP b`. | |
215 | // | |
216 | // - Otherwise, e.g. when we have `(let a = b) < c` in AST, | |
217 | // parens are required since the parser would interpret `let a = b < c` as | |
218 | // `let a = (b < c)`. To achieve this, we force parens. | |
219 | (&ast::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(prec) => { | |
220 | parser::PREC_FORCE_PAREN | |
221 | } | |
222 | _ => left_prec, | |
223 | }; | |
224 | ||
225 | self.print_expr_maybe_paren(lhs, left_prec); | |
226 | self.space(); | |
227 | self.word_space(op.node.to_string()); | |
228 | self.print_expr_maybe_paren(rhs, right_prec) | |
229 | } | |
230 | ||
231 | fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) { | |
232 | self.word(ast::UnOp::to_string(op)); | |
233 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) | |
234 | } | |
235 | ||
236 | fn print_expr_addr_of( | |
237 | &mut self, | |
238 | kind: ast::BorrowKind, | |
239 | mutability: ast::Mutability, | |
240 | expr: &ast::Expr, | |
241 | ) { | |
242 | self.word("&"); | |
243 | match kind { | |
244 | ast::BorrowKind::Ref => self.print_mutability(mutability, false), | |
245 | ast::BorrowKind::Raw => { | |
246 | self.word_nbsp("raw"); | |
247 | self.print_mutability(mutability, true); | |
248 | } | |
249 | } | |
250 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) | |
251 | } | |
252 | ||
253 | pub fn print_expr(&mut self, expr: &ast::Expr) { | |
254 | self.print_expr_outer_attr_style(expr, true) | |
255 | } | |
256 | ||
257 | pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline: bool) { | |
258 | self.maybe_print_comment(expr.span.lo()); | |
259 | ||
260 | let attrs = &expr.attrs; | |
261 | if is_inline { | |
262 | self.print_outer_attributes_inline(attrs); | |
263 | } else { | |
264 | self.print_outer_attributes(attrs); | |
265 | } | |
266 | ||
267 | self.ibox(INDENT_UNIT); | |
268 | self.ann.pre(self, AnnNode::Expr(expr)); | |
269 | match expr.kind { | |
270 | ast::ExprKind::Box(ref expr) => { | |
271 | self.word_space("box"); | |
272 | self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); | |
273 | } | |
274 | ast::ExprKind::Array(ref exprs) => { | |
275 | self.print_expr_vec(exprs); | |
276 | } | |
277 | ast::ExprKind::ConstBlock(ref anon_const) => { | |
278 | self.print_expr_anon_const(anon_const); | |
279 | } | |
280 | ast::ExprKind::Repeat(ref element, ref count) => { | |
281 | self.print_expr_repeat(element, count); | |
282 | } | |
283 | ast::ExprKind::Struct(ref se) => { | |
284 | self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest); | |
285 | } | |
286 | ast::ExprKind::Tup(ref exprs) => { | |
287 | self.print_expr_tup(exprs); | |
288 | } | |
289 | ast::ExprKind::Call(ref func, ref args) => { | |
290 | self.print_expr_call(func, &args); | |
291 | } | |
292 | ast::ExprKind::MethodCall(ref segment, ref args, _) => { | |
293 | self.print_expr_method_call(segment, &args); | |
294 | } | |
295 | ast::ExprKind::Binary(op, ref lhs, ref rhs) => { | |
296 | self.print_expr_binary(op, lhs, rhs); | |
297 | } | |
298 | ast::ExprKind::Unary(op, ref expr) => { | |
299 | self.print_expr_unary(op, expr); | |
300 | } | |
301 | ast::ExprKind::AddrOf(k, m, ref expr) => { | |
302 | self.print_expr_addr_of(k, m, expr); | |
303 | } | |
304 | ast::ExprKind::Lit(ref lit) => { | |
305 | self.print_literal(lit); | |
306 | } | |
307 | ast::ExprKind::Cast(ref expr, ref ty) => { | |
308 | let prec = AssocOp::As.precedence() as i8; | |
309 | self.print_expr_maybe_paren(expr, prec); | |
310 | self.space(); | |
311 | self.word_space("as"); | |
312 | self.print_type(ty); | |
313 | } | |
314 | ast::ExprKind::Type(ref expr, ref ty) => { | |
315 | let prec = AssocOp::Colon.precedence() as i8; | |
316 | self.print_expr_maybe_paren(expr, prec); | |
317 | self.word_space(":"); | |
318 | self.print_type(ty); | |
319 | } | |
320 | ast::ExprKind::Let(ref pat, ref scrutinee, _) => { | |
321 | self.print_let(pat, scrutinee); | |
322 | } | |
323 | ast::ExprKind::If(ref test, ref blk, ref elseopt) => { | |
324 | self.print_if(test, blk, elseopt.as_deref()) | |
325 | } | |
326 | ast::ExprKind::While(ref test, ref blk, opt_label) => { | |
327 | if let Some(label) = opt_label { | |
328 | self.print_ident(label.ident); | |
329 | self.word_space(":"); | |
330 | } | |
331 | self.cbox(0); | |
332 | self.ibox(0); | |
333 | self.word_nbsp("while"); | |
334 | self.print_expr_as_cond(test); | |
335 | self.space(); | |
336 | self.print_block_with_attrs(blk, attrs); | |
337 | } | |
338 | ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => { | |
339 | if let Some(label) = opt_label { | |
340 | self.print_ident(label.ident); | |
341 | self.word_space(":"); | |
342 | } | |
343 | self.cbox(0); | |
344 | self.ibox(0); | |
345 | self.word_nbsp("for"); | |
346 | self.print_pat(pat); | |
347 | self.space(); | |
348 | self.word_space("in"); | |
349 | self.print_expr_as_cond(iter); | |
350 | self.space(); | |
351 | self.print_block_with_attrs(blk, attrs); | |
352 | } | |
353 | ast::ExprKind::Loop(ref blk, opt_label) => { | |
354 | if let Some(label) = opt_label { | |
355 | self.print_ident(label.ident); | |
356 | self.word_space(":"); | |
357 | } | |
358 | self.cbox(0); | |
359 | self.ibox(0); | |
360 | self.word_nbsp("loop"); | |
361 | self.print_block_with_attrs(blk, attrs); | |
362 | } | |
363 | ast::ExprKind::Match(ref expr, ref arms) => { | |
364 | self.cbox(0); | |
365 | self.ibox(0); | |
366 | self.word_nbsp("match"); | |
367 | self.print_expr_as_cond(expr); | |
368 | self.space(); | |
369 | self.bopen(); | |
370 | self.print_inner_attributes_no_trailing_hardbreak(attrs); | |
371 | for arm in arms { | |
372 | self.print_arm(arm); | |
373 | } | |
374 | let empty = attrs.is_empty() && arms.is_empty(); | |
375 | self.bclose(expr.span, empty); | |
376 | } | |
377 | ast::ExprKind::Closure( | |
378 | capture_clause, | |
379 | asyncness, | |
380 | movability, | |
381 | ref decl, | |
382 | ref body, | |
383 | _, | |
384 | ) => { | |
385 | self.print_movability(movability); | |
386 | self.print_asyncness(asyncness); | |
387 | self.print_capture_clause(capture_clause); | |
388 | ||
389 | self.print_fn_params_and_ret(decl, true); | |
390 | self.space(); | |
391 | self.print_expr(body); | |
392 | self.end(); // need to close a box | |
393 | ||
394 | // a box will be closed by print_expr, but we didn't want an overall | |
395 | // wrapper so we closed the corresponding opening. so create an | |
396 | // empty box to satisfy the close. | |
397 | self.ibox(0); | |
398 | } | |
399 | ast::ExprKind::Block(ref blk, opt_label) => { | |
400 | if let Some(label) = opt_label { | |
401 | self.print_ident(label.ident); | |
402 | self.word_space(":"); | |
403 | } | |
404 | // containing cbox, will be closed by print-block at } | |
405 | self.cbox(0); | |
406 | // head-box, will be closed by print-block after { | |
407 | self.ibox(0); | |
408 | self.print_block_with_attrs(blk, attrs); | |
409 | } | |
410 | ast::ExprKind::Async(capture_clause, _, ref blk) => { | |
411 | self.word_nbsp("async"); | |
412 | self.print_capture_clause(capture_clause); | |
413 | // cbox/ibox in analogy to the `ExprKind::Block` arm above | |
414 | self.cbox(0); | |
415 | self.ibox(0); | |
416 | self.print_block_with_attrs(blk, attrs); | |
417 | } | |
418 | ast::ExprKind::Await(ref expr) => { | |
419 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); | |
420 | self.word(".await"); | |
421 | } | |
422 | ast::ExprKind::Assign(ref lhs, ref rhs, _) => { | |
423 | let prec = AssocOp::Assign.precedence() as i8; | |
424 | self.print_expr_maybe_paren(lhs, prec + 1); | |
425 | self.space(); | |
426 | self.word_space("="); | |
427 | self.print_expr_maybe_paren(rhs, prec); | |
428 | } | |
429 | ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { | |
430 | let prec = AssocOp::Assign.precedence() as i8; | |
431 | self.print_expr_maybe_paren(lhs, prec + 1); | |
432 | self.space(); | |
433 | self.word(op.node.to_string()); | |
434 | self.word_space("="); | |
435 | self.print_expr_maybe_paren(rhs, prec); | |
436 | } | |
437 | ast::ExprKind::Field(ref expr, ident) => { | |
438 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); | |
439 | self.word("."); | |
440 | self.print_ident(ident); | |
441 | } | |
442 | ast::ExprKind::Index(ref expr, ref index) => { | |
443 | self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); | |
444 | self.word("["); | |
445 | self.print_expr(index); | |
446 | self.word("]"); | |
447 | } | |
448 | ast::ExprKind::Range(ref start, ref end, limits) => { | |
449 | // Special case for `Range`. `AssocOp` claims that `Range` has higher precedence | |
450 | // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. | |
451 | // Here we use a fake precedence value so that any child with lower precedence than | |
452 | // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) | |
453 | let fake_prec = AssocOp::LOr.precedence() as i8; | |
454 | if let Some(ref e) = *start { | |
455 | self.print_expr_maybe_paren(e, fake_prec); | |
456 | } | |
457 | if limits == ast::RangeLimits::HalfOpen { | |
458 | self.word(".."); | |
459 | } else { | |
460 | self.word("..="); | |
461 | } | |
462 | if let Some(ref e) = *end { | |
463 | self.print_expr_maybe_paren(e, fake_prec); | |
464 | } | |
465 | } | |
466 | ast::ExprKind::Underscore => self.word("_"), | |
467 | ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), | |
468 | ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), | |
469 | ast::ExprKind::Break(opt_label, ref opt_expr) => { | |
470 | self.word("break"); | |
471 | if let Some(label) = opt_label { | |
472 | self.space(); | |
473 | self.print_ident(label.ident); | |
474 | } | |
475 | if let Some(ref expr) = *opt_expr { | |
476 | self.space(); | |
477 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); | |
478 | } | |
479 | } | |
480 | ast::ExprKind::Continue(opt_label) => { | |
481 | self.word("continue"); | |
482 | if let Some(label) = opt_label { | |
483 | self.space(); | |
484 | self.print_ident(label.ident); | |
485 | } | |
486 | } | |
487 | ast::ExprKind::Ret(ref result) => { | |
488 | self.word("return"); | |
489 | if let Some(ref expr) = *result { | |
490 | self.word(" "); | |
491 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); | |
492 | } | |
493 | } | |
494 | ast::ExprKind::InlineAsm(ref a) => { | |
495 | self.word("asm!"); | |
496 | self.print_inline_asm(a); | |
497 | } | |
498 | ast::ExprKind::MacCall(ref m) => self.print_mac(m), | |
499 | ast::ExprKind::Paren(ref e) => { | |
500 | self.popen(); | |
501 | self.print_expr(e); | |
502 | self.pclose(); | |
503 | } | |
504 | ast::ExprKind::Yield(ref e) => { | |
505 | self.word("yield"); | |
506 | ||
507 | if let Some(ref expr) = *e { | |
508 | self.space(); | |
509 | self.print_expr_maybe_paren(expr, parser::PREC_JUMP); | |
510 | } | |
511 | } | |
512 | ast::ExprKind::Try(ref e) => { | |
513 | self.print_expr_maybe_paren(e, parser::PREC_POSTFIX); | |
514 | self.word("?") | |
515 | } | |
516 | ast::ExprKind::TryBlock(ref blk) => { | |
517 | self.cbox(0); | |
518 | self.ibox(0); | |
519 | self.word_nbsp("try"); | |
520 | self.print_block_with_attrs(blk, attrs) | |
521 | } | |
522 | ast::ExprKind::Err => { | |
523 | self.popen(); | |
524 | self.word("/*ERROR*/"); | |
525 | self.pclose() | |
526 | } | |
527 | } | |
528 | self.ann.post(self, AnnNode::Expr(expr)); | |
529 | self.end(); | |
530 | } | |
531 | ||
532 | fn print_arm(&mut self, arm: &ast::Arm) { | |
533 | // Note, I have no idea why this check is necessary, but here it is. | |
534 | if arm.attrs.is_empty() { | |
535 | self.space(); | |
536 | } | |
537 | self.cbox(INDENT_UNIT); | |
538 | self.ibox(0); | |
539 | self.maybe_print_comment(arm.pat.span.lo()); | |
540 | self.print_outer_attributes(&arm.attrs); | |
541 | self.print_pat(&arm.pat); | |
542 | self.space(); | |
543 | if let Some(ref e) = arm.guard { | |
544 | self.word_space("if"); | |
545 | self.print_expr(e); | |
546 | self.space(); | |
547 | } | |
548 | self.word_space("=>"); | |
549 | ||
550 | match arm.body.kind { | |
551 | ast::ExprKind::Block(ref blk, opt_label) => { | |
552 | if let Some(label) = opt_label { | |
553 | self.print_ident(label.ident); | |
554 | self.word_space(":"); | |
555 | } | |
556 | ||
557 | // The block will close the pattern's ibox. | |
558 | self.print_block_unclosed_indent(blk); | |
559 | ||
560 | // If it is a user-provided unsafe block, print a comma after it. | |
561 | if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules { | |
562 | self.word(","); | |
563 | } | |
564 | } | |
565 | _ => { | |
566 | self.end(); // Close the ibox for the pattern. | |
567 | self.print_expr(&arm.body); | |
568 | self.word(","); | |
569 | } | |
570 | } | |
571 | self.end(); // Close enclosing cbox. | |
572 | } | |
573 | ||
574 | fn print_movability(&mut self, movability: ast::Movability) { | |
575 | match movability { | |
576 | ast::Movability::Static => self.word_space("static"), | |
577 | ast::Movability::Movable => {} | |
578 | } | |
579 | } | |
580 | ||
581 | fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) { | |
582 | match capture_clause { | |
583 | ast::CaptureBy::Value => self.word_space("move"), | |
584 | ast::CaptureBy::Ref => {} | |
585 | } | |
586 | } | |
587 | } |