]>
Commit | Line | Data |
---|---|---|
5099ac24 FG |
1 | use crate::pp::Breaks::Inconsistent; |
2 | use crate::pprust::state::delimited::IterDelimited; | |
3 | use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; | |
4 | ||
5 | use rustc_ast as ast; | |
6 | use rustc_ast::GenericBound; | |
7 | use rustc_ast::ModKind; | |
8 | use rustc_span::symbol::Ident; | |
9 | ||
10 | fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String { | |
11 | format!("{}{}", State::to_string(|s| s.print_visibility(vis)), s) | |
12 | } | |
13 | ||
14 | impl<'a> State<'a> { | |
15 | fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) { | |
16 | self.print_inner_attributes(attrs); | |
17 | for item in &nmod.items { | |
18 | self.print_foreign_item(item); | |
19 | } | |
20 | } | |
21 | ||
923072b8 | 22 | pub(crate) fn print_foreign_item(&mut self, item: &ast::ForeignItem) { |
5099ac24 FG |
23 | let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; |
24 | self.ann.pre(self, AnnNode::SubItem(id)); | |
25 | self.hardbreak_if_not_bol(); | |
26 | self.maybe_print_comment(span.lo()); | |
27 | self.print_outer_attributes(attrs); | |
28 | match kind { | |
29 | ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { | |
30 | self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); | |
31 | } | |
32 | ast::ForeignItemKind::Static(ty, mutbl, body) => { | |
33 | let def = ast::Defaultness::Final; | |
34 | self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def); | |
35 | } | |
36 | ast::ForeignItemKind::TyAlias(box ast::TyAlias { | |
37 | defaultness, | |
38 | generics, | |
5e7ed085 FG |
39 | where_clauses, |
40 | where_predicates_split, | |
5099ac24 FG |
41 | bounds, |
42 | ty, | |
43 | }) => { | |
44 | self.print_associated_type( | |
45 | ident, | |
46 | generics, | |
5e7ed085 FG |
47 | *where_clauses, |
48 | *where_predicates_split, | |
5099ac24 FG |
49 | bounds, |
50 | ty.as_deref(), | |
51 | vis, | |
52 | *defaultness, | |
53 | ); | |
54 | } | |
55 | ast::ForeignItemKind::MacCall(m) => { | |
56 | self.print_mac(m); | |
57 | if m.args.need_semicolon() { | |
58 | self.word(";"); | |
59 | } | |
60 | } | |
61 | } | |
62 | self.ann.post(self, AnnNode::SubItem(id)) | |
63 | } | |
64 | ||
65 | fn print_item_const( | |
66 | &mut self, | |
67 | ident: Ident, | |
68 | mutbl: Option<ast::Mutability>, | |
69 | ty: &ast::Ty, | |
70 | body: Option<&ast::Expr>, | |
71 | vis: &ast::Visibility, | |
72 | defaultness: ast::Defaultness, | |
73 | ) { | |
74 | self.head(""); | |
75 | self.print_visibility(vis); | |
76 | self.print_defaultness(defaultness); | |
77 | let leading = match mutbl { | |
78 | None => "const", | |
79 | Some(ast::Mutability::Not) => "static", | |
80 | Some(ast::Mutability::Mut) => "static mut", | |
81 | }; | |
82 | self.word_space(leading); | |
83 | self.print_ident(ident); | |
84 | self.word_space(":"); | |
85 | self.print_type(ty); | |
86 | if body.is_some() { | |
87 | self.space(); | |
88 | } | |
89 | self.end(); // end the head-ibox | |
90 | if let Some(body) = body { | |
91 | self.word_space("="); | |
92 | self.print_expr(body); | |
93 | } | |
94 | self.word(";"); | |
95 | self.end(); // end the outer cbox | |
96 | } | |
97 | ||
98 | fn print_associated_type( | |
99 | &mut self, | |
100 | ident: Ident, | |
101 | generics: &ast::Generics, | |
5e7ed085 FG |
102 | where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause), |
103 | where_predicates_split: usize, | |
5099ac24 FG |
104 | bounds: &ast::GenericBounds, |
105 | ty: Option<&ast::Ty>, | |
106 | vis: &ast::Visibility, | |
107 | defaultness: ast::Defaultness, | |
108 | ) { | |
5e7ed085 FG |
109 | let (before_predicates, after_predicates) = |
110 | generics.where_clause.predicates.split_at(where_predicates_split); | |
5099ac24 FG |
111 | self.head(""); |
112 | self.print_visibility(vis); | |
113 | self.print_defaultness(defaultness); | |
114 | self.word_space("type"); | |
115 | self.print_ident(ident); | |
116 | self.print_generic_params(&generics.params); | |
923072b8 FG |
117 | if !bounds.is_empty() { |
118 | self.word_nbsp(":"); | |
119 | self.print_type_bounds(bounds); | |
120 | } | |
5e7ed085 | 121 | self.print_where_clause_parts(where_clauses.0.0, before_predicates); |
5099ac24 FG |
122 | if let Some(ty) = ty { |
123 | self.space(); | |
124 | self.word_space("="); | |
125 | self.print_type(ty); | |
126 | } | |
5e7ed085 | 127 | self.print_where_clause_parts(where_clauses.1.0, after_predicates); |
5099ac24 FG |
128 | self.word(";"); |
129 | self.end(); // end inner head-block | |
130 | self.end(); // end outer head-block | |
131 | } | |
132 | ||
133 | /// Pretty-prints an item. | |
923072b8 | 134 | pub(crate) fn print_item(&mut self, item: &ast::Item) { |
5099ac24 FG |
135 | self.hardbreak_if_not_bol(); |
136 | self.maybe_print_comment(item.span.lo()); | |
137 | self.print_outer_attributes(&item.attrs); | |
138 | self.ann.pre(self, AnnNode::Item(item)); | |
487cf647 | 139 | match &item.kind { |
5099ac24 FG |
140 | ast::ItemKind::ExternCrate(orig_name) => { |
141 | self.head(visibility_qualified(&item.vis, "extern crate")); | |
487cf647 | 142 | if let &Some(orig_name) = orig_name { |
5099ac24 FG |
143 | self.print_name(orig_name); |
144 | self.space(); | |
145 | self.word("as"); | |
146 | self.space(); | |
147 | } | |
148 | self.print_ident(item.ident); | |
149 | self.word(";"); | |
150 | self.end(); // end inner head-block | |
151 | self.end(); // end outer head-block | |
152 | } | |
487cf647 | 153 | ast::ItemKind::Use(tree) => { |
5099ac24 FG |
154 | self.print_visibility(&item.vis); |
155 | self.word_nbsp("use"); | |
156 | self.print_use_tree(tree); | |
157 | self.word(";"); | |
158 | } | |
487cf647 | 159 | ast::ItemKind::Static(ty, mutbl, body) => { |
5099ac24 | 160 | let def = ast::Defaultness::Final; |
487cf647 FG |
161 | self.print_item_const( |
162 | item.ident, | |
163 | Some(*mutbl), | |
164 | ty, | |
165 | body.as_deref(), | |
166 | &item.vis, | |
167 | def, | |
168 | ); | |
5099ac24 | 169 | } |
487cf647 FG |
170 | ast::ItemKind::Const(def, ty, body) => { |
171 | self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def); | |
5099ac24 | 172 | } |
487cf647 | 173 | ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { |
5099ac24 FG |
174 | self.print_fn_full( |
175 | sig, | |
176 | item.ident, | |
177 | generics, | |
178 | &item.vis, | |
487cf647 FG |
179 | *defaultness, |
180 | body.as_deref(), | |
5099ac24 FG |
181 | &item.attrs, |
182 | ); | |
183 | } | |
487cf647 | 184 | ast::ItemKind::Mod(unsafety, mod_kind) => { |
5099ac24 FG |
185 | self.head(Self::to_string(|s| { |
186 | s.print_visibility(&item.vis); | |
487cf647 | 187 | s.print_unsafety(*unsafety); |
5099ac24 FG |
188 | s.word("mod"); |
189 | })); | |
190 | self.print_ident(item.ident); | |
191 | ||
192 | match mod_kind { | |
193 | ModKind::Loaded(items, ..) => { | |
194 | self.nbsp(); | |
195 | self.bopen(); | |
196 | self.print_inner_attributes(&item.attrs); | |
197 | for item in items { | |
198 | self.print_item(item); | |
199 | } | |
200 | let empty = item.attrs.is_empty() && items.is_empty(); | |
201 | self.bclose(item.span, empty); | |
202 | } | |
203 | ModKind::Unloaded => { | |
204 | self.word(";"); | |
205 | self.end(); // end inner head-block | |
206 | self.end(); // end outer head-block | |
207 | } | |
208 | } | |
209 | } | |
487cf647 | 210 | ast::ItemKind::ForeignMod(nmod) => { |
5099ac24 FG |
211 | self.head(Self::to_string(|s| { |
212 | s.print_unsafety(nmod.unsafety); | |
213 | s.word("extern"); | |
214 | })); | |
215 | if let Some(abi) = nmod.abi { | |
487cf647 | 216 | self.print_token_literal(abi.as_token_lit(), abi.span); |
5099ac24 FG |
217 | self.nbsp(); |
218 | } | |
219 | self.bopen(); | |
220 | self.print_foreign_mod(nmod, &item.attrs); | |
221 | let empty = item.attrs.is_empty() && nmod.items.is_empty(); | |
222 | self.bclose(item.span, empty); | |
223 | } | |
487cf647 | 224 | ast::ItemKind::GlobalAsm(asm) => { |
5099ac24 FG |
225 | self.head(visibility_qualified(&item.vis, "global_asm!")); |
226 | self.print_inline_asm(asm); | |
f2b60f7d FG |
227 | self.word(";"); |
228 | self.end(); | |
5099ac24 FG |
229 | self.end(); |
230 | } | |
231 | ast::ItemKind::TyAlias(box ast::TyAlias { | |
232 | defaultness, | |
487cf647 | 233 | generics, |
5e7ed085 FG |
234 | where_clauses, |
235 | where_predicates_split, | |
487cf647 FG |
236 | bounds, |
237 | ty, | |
5099ac24 | 238 | }) => { |
5099ac24 FG |
239 | self.print_associated_type( |
240 | item.ident, | |
241 | generics, | |
487cf647 FG |
242 | *where_clauses, |
243 | *where_predicates_split, | |
5099ac24 | 244 | bounds, |
487cf647 | 245 | ty.as_deref(), |
5099ac24 | 246 | &item.vis, |
487cf647 | 247 | *defaultness, |
5099ac24 FG |
248 | ); |
249 | } | |
487cf647 | 250 | ast::ItemKind::Enum(enum_definition, params) => { |
5099ac24 FG |
251 | self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); |
252 | } | |
487cf647 | 253 | ast::ItemKind::Struct(struct_def, generics) => { |
5099ac24 FG |
254 | self.head(visibility_qualified(&item.vis, "struct")); |
255 | self.print_struct(struct_def, generics, item.ident, item.span, true); | |
256 | } | |
487cf647 | 257 | ast::ItemKind::Union(struct_def, generics) => { |
5099ac24 FG |
258 | self.head(visibility_qualified(&item.vis, "union")); |
259 | self.print_struct(struct_def, generics, item.ident, item.span, true); | |
260 | } | |
261 | ast::ItemKind::Impl(box ast::Impl { | |
262 | unsafety, | |
263 | polarity, | |
264 | defaultness, | |
265 | constness, | |
487cf647 FG |
266 | generics, |
267 | of_trait, | |
268 | self_ty, | |
269 | items, | |
5099ac24 FG |
270 | }) => { |
271 | self.head(""); | |
272 | self.print_visibility(&item.vis); | |
487cf647 FG |
273 | self.print_defaultness(*defaultness); |
274 | self.print_unsafety(*unsafety); | |
5099ac24 FG |
275 | self.word("impl"); |
276 | ||
277 | if generics.params.is_empty() { | |
278 | self.nbsp(); | |
279 | } else { | |
280 | self.print_generic_params(&generics.params); | |
281 | self.space(); | |
282 | } | |
283 | ||
487cf647 | 284 | self.print_constness(*constness); |
5099ac24 FG |
285 | |
286 | if let ast::ImplPolarity::Negative(_) = polarity { | |
287 | self.word("!"); | |
288 | } | |
289 | ||
487cf647 | 290 | if let Some(t) = of_trait { |
5099ac24 FG |
291 | self.print_trait_ref(t); |
292 | self.space(); | |
293 | self.word_space("for"); | |
294 | } | |
295 | ||
296 | self.print_type(self_ty); | |
297 | self.print_where_clause(&generics.where_clause); | |
298 | ||
299 | self.space(); | |
300 | self.bopen(); | |
301 | self.print_inner_attributes(&item.attrs); | |
302 | for impl_item in items { | |
303 | self.print_assoc_item(impl_item); | |
304 | } | |
305 | let empty = item.attrs.is_empty() && items.is_empty(); | |
306 | self.bclose(item.span, empty); | |
307 | } | |
308 | ast::ItemKind::Trait(box ast::Trait { | |
309 | is_auto, | |
310 | unsafety, | |
487cf647 FG |
311 | generics, |
312 | bounds, | |
313 | items, | |
5099ac24 FG |
314 | .. |
315 | }) => { | |
316 | self.head(""); | |
317 | self.print_visibility(&item.vis); | |
487cf647 FG |
318 | self.print_unsafety(*unsafety); |
319 | self.print_is_auto(*is_auto); | |
5099ac24 FG |
320 | self.word_nbsp("trait"); |
321 | self.print_ident(item.ident); | |
322 | self.print_generic_params(&generics.params); | |
323 | let mut real_bounds = Vec::with_capacity(bounds.len()); | |
324 | for b in bounds.iter() { | |
487cf647 | 325 | if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { |
5099ac24 FG |
326 | self.space(); |
327 | self.word_space("for ?"); | |
328 | self.print_trait_ref(&ptr.trait_ref); | |
329 | } else { | |
330 | real_bounds.push(b.clone()); | |
331 | } | |
332 | } | |
923072b8 FG |
333 | if !real_bounds.is_empty() { |
334 | self.word_nbsp(":"); | |
335 | self.print_type_bounds(&real_bounds); | |
336 | } | |
5099ac24 FG |
337 | self.print_where_clause(&generics.where_clause); |
338 | self.word(" "); | |
339 | self.bopen(); | |
340 | self.print_inner_attributes(&item.attrs); | |
341 | for trait_item in items { | |
342 | self.print_assoc_item(trait_item); | |
343 | } | |
344 | let empty = item.attrs.is_empty() && items.is_empty(); | |
345 | self.bclose(item.span, empty); | |
346 | } | |
487cf647 | 347 | ast::ItemKind::TraitAlias(generics, bounds) => { |
5099ac24 FG |
348 | self.head(visibility_qualified(&item.vis, "trait")); |
349 | self.print_ident(item.ident); | |
350 | self.print_generic_params(&generics.params); | |
5099ac24 | 351 | self.nbsp(); |
487cf647 | 352 | if !bounds.is_empty() { |
923072b8 | 353 | self.word_nbsp("="); |
487cf647 | 354 | self.print_type_bounds(&bounds); |
923072b8 | 355 | } |
5099ac24 FG |
356 | self.print_where_clause(&generics.where_clause); |
357 | self.word(";"); | |
358 | self.end(); // end inner head-block | |
359 | self.end(); // end outer head-block | |
360 | } | |
487cf647 | 361 | ast::ItemKind::MacCall(mac) => { |
5099ac24 FG |
362 | self.print_mac(mac); |
363 | if mac.args.need_semicolon() { | |
364 | self.word(";"); | |
365 | } | |
366 | } | |
487cf647 | 367 | ast::ItemKind::MacroDef(macro_def) => { |
5099ac24 FG |
368 | self.print_mac_def(macro_def, &item.ident, item.span, |state| { |
369 | state.print_visibility(&item.vis) | |
370 | }); | |
371 | } | |
372 | } | |
373 | self.ann.post(self, AnnNode::Item(item)) | |
374 | } | |
375 | ||
376 | fn print_enum_def( | |
377 | &mut self, | |
378 | enum_definition: &ast::EnumDef, | |
379 | generics: &ast::Generics, | |
380 | ident: Ident, | |
381 | span: rustc_span::Span, | |
382 | visibility: &ast::Visibility, | |
383 | ) { | |
384 | self.head(visibility_qualified(visibility, "enum")); | |
385 | self.print_ident(ident); | |
386 | self.print_generic_params(&generics.params); | |
387 | self.print_where_clause(&generics.where_clause); | |
388 | self.space(); | |
389 | self.print_variants(&enum_definition.variants, span) | |
390 | } | |
391 | ||
392 | fn print_variants(&mut self, variants: &[ast::Variant], span: rustc_span::Span) { | |
393 | self.bopen(); | |
394 | for v in variants { | |
395 | self.space_if_not_bol(); | |
396 | self.maybe_print_comment(v.span.lo()); | |
397 | self.print_outer_attributes(&v.attrs); | |
398 | self.ibox(0); | |
399 | self.print_variant(v); | |
400 | self.word(","); | |
401 | self.end(); | |
402 | self.maybe_print_trailing_comment(v.span, None); | |
403 | } | |
404 | let empty = variants.is_empty(); | |
405 | self.bclose(span, empty) | |
406 | } | |
407 | ||
923072b8 | 408 | pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { |
487cf647 | 409 | match &vis.kind { |
5099ac24 | 410 | ast::VisibilityKind::Public => self.word_nbsp("pub"), |
487cf647 | 411 | ast::VisibilityKind::Restricted { path, shorthand, .. } => { |
5099ac24 | 412 | let path = Self::to_string(|s| s.print_path(path, false, 0)); |
487cf647 | 413 | if *shorthand && (path == "crate" || path == "self" || path == "super") { |
5099ac24 FG |
414 | self.word_nbsp(format!("pub({})", path)) |
415 | } else { | |
416 | self.word_nbsp(format!("pub(in {})", path)) | |
417 | } | |
418 | } | |
419 | ast::VisibilityKind::Inherited => {} | |
420 | } | |
421 | } | |
422 | ||
423 | fn print_defaultness(&mut self, defaultness: ast::Defaultness) { | |
424 | if let ast::Defaultness::Default(_) = defaultness { | |
425 | self.word_nbsp("default"); | |
426 | } | |
427 | } | |
428 | ||
429 | fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) { | |
430 | self.nbsp(); | |
431 | self.bopen(); | |
432 | ||
433 | let empty = fields.is_empty(); | |
434 | if !empty { | |
435 | self.hardbreak_if_not_bol(); | |
436 | ||
437 | for field in fields { | |
438 | self.hardbreak_if_not_bol(); | |
439 | self.maybe_print_comment(field.span.lo()); | |
440 | self.print_outer_attributes(&field.attrs); | |
441 | self.print_visibility(&field.vis); | |
442 | self.print_ident(field.ident.unwrap()); | |
443 | self.word_nbsp(":"); | |
444 | self.print_type(&field.ty); | |
445 | self.word(","); | |
446 | } | |
447 | } | |
448 | ||
449 | self.bclose(span, empty); | |
450 | } | |
451 | ||
452 | fn print_struct( | |
453 | &mut self, | |
454 | struct_def: &ast::VariantData, | |
455 | generics: &ast::Generics, | |
456 | ident: Ident, | |
457 | span: rustc_span::Span, | |
458 | print_finalizer: bool, | |
459 | ) { | |
460 | self.print_ident(ident); | |
461 | self.print_generic_params(&generics.params); | |
487cf647 | 462 | match &struct_def { |
5099ac24 FG |
463 | ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { |
464 | if let ast::VariantData::Tuple(..) = struct_def { | |
465 | self.popen(); | |
466 | self.commasep(Inconsistent, struct_def.fields(), |s, field| { | |
467 | s.maybe_print_comment(field.span.lo()); | |
468 | s.print_outer_attributes(&field.attrs); | |
469 | s.print_visibility(&field.vis); | |
470 | s.print_type(&field.ty) | |
471 | }); | |
472 | self.pclose(); | |
473 | } | |
474 | self.print_where_clause(&generics.where_clause); | |
475 | if print_finalizer { | |
476 | self.word(";"); | |
477 | } | |
478 | self.end(); | |
479 | self.end(); // Close the outer-box. | |
480 | } | |
487cf647 | 481 | ast::VariantData::Struct(fields, ..) => { |
5099ac24 FG |
482 | self.print_where_clause(&generics.where_clause); |
483 | self.print_record_struct_body(fields, span); | |
484 | } | |
485 | } | |
486 | } | |
487 | ||
923072b8 | 488 | pub(crate) fn print_variant(&mut self, v: &ast::Variant) { |
5099ac24 FG |
489 | self.head(""); |
490 | self.print_visibility(&v.vis); | |
491 | let generics = ast::Generics::default(); | |
492 | self.print_struct(&v.data, &generics, v.ident, v.span, false); | |
487cf647 | 493 | if let Some(d) = &v.disr_expr { |
5099ac24 FG |
494 | self.space(); |
495 | self.word_space("="); | |
496 | self.print_expr(&d.value) | |
497 | } | |
498 | } | |
499 | ||
923072b8 | 500 | pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) { |
5099ac24 FG |
501 | let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; |
502 | self.ann.pre(self, AnnNode::SubItem(id)); | |
503 | self.hardbreak_if_not_bol(); | |
504 | self.maybe_print_comment(span.lo()); | |
505 | self.print_outer_attributes(attrs); | |
506 | match kind { | |
507 | ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { | |
508 | self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); | |
509 | } | |
510 | ast::AssocItemKind::Const(def, ty, body) => { | |
511 | self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); | |
512 | } | |
2b03887a | 513 | ast::AssocItemKind::Type(box ast::TyAlias { |
5e7ed085 FG |
514 | defaultness, |
515 | generics, | |
516 | where_clauses, | |
517 | where_predicates_split, | |
518 | bounds, | |
519 | ty, | |
520 | }) => { | |
5099ac24 FG |
521 | self.print_associated_type( |
522 | ident, | |
523 | generics, | |
5e7ed085 FG |
524 | *where_clauses, |
525 | *where_predicates_split, | |
5099ac24 FG |
526 | bounds, |
527 | ty.as_deref(), | |
528 | vis, | |
529 | *defaultness, | |
530 | ); | |
531 | } | |
532 | ast::AssocItemKind::MacCall(m) => { | |
533 | self.print_mac(m); | |
534 | if m.args.need_semicolon() { | |
535 | self.word(";"); | |
536 | } | |
537 | } | |
538 | } | |
539 | self.ann.post(self, AnnNode::SubItem(id)) | |
540 | } | |
541 | ||
542 | fn print_fn_full( | |
543 | &mut self, | |
544 | sig: &ast::FnSig, | |
545 | name: Ident, | |
546 | generics: &ast::Generics, | |
547 | vis: &ast::Visibility, | |
548 | defaultness: ast::Defaultness, | |
549 | body: Option<&ast::Block>, | |
550 | attrs: &[ast::Attribute], | |
551 | ) { | |
552 | if body.is_some() { | |
553 | self.head(""); | |
554 | } | |
555 | self.print_visibility(vis); | |
556 | self.print_defaultness(defaultness); | |
557 | self.print_fn(&sig.decl, sig.header, Some(name), generics); | |
558 | if let Some(body) = body { | |
559 | self.nbsp(); | |
560 | self.print_block_with_attrs(body, attrs); | |
561 | } else { | |
562 | self.word(";"); | |
563 | } | |
564 | } | |
565 | ||
923072b8 | 566 | pub(crate) fn print_fn( |
5099ac24 FG |
567 | &mut self, |
568 | decl: &ast::FnDecl, | |
569 | header: ast::FnHeader, | |
570 | name: Option<Ident>, | |
571 | generics: &ast::Generics, | |
572 | ) { | |
573 | self.print_fn_header_info(header); | |
574 | if let Some(name) = name { | |
575 | self.nbsp(); | |
576 | self.print_ident(name); | |
577 | } | |
578 | self.print_generic_params(&generics.params); | |
579 | self.print_fn_params_and_ret(decl, false); | |
580 | self.print_where_clause(&generics.where_clause) | |
581 | } | |
582 | ||
923072b8 | 583 | pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) { |
5099ac24 FG |
584 | let (open, close) = if is_closure { ("|", "|") } else { ("(", ")") }; |
585 | self.word(open); | |
586 | self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, is_closure)); | |
587 | self.word(close); | |
588 | self.print_fn_ret_ty(&decl.output) | |
589 | } | |
590 | ||
591 | fn print_where_clause(&mut self, where_clause: &ast::WhereClause) { | |
5e7ed085 FG |
592 | self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates); |
593 | } | |
594 | ||
923072b8 | 595 | pub(crate) fn print_where_clause_parts( |
5e7ed085 FG |
596 | &mut self, |
597 | has_where_token: bool, | |
598 | predicates: &[ast::WherePredicate], | |
599 | ) { | |
600 | if predicates.is_empty() && !has_where_token { | |
5099ac24 FG |
601 | return; |
602 | } | |
603 | ||
604 | self.space(); | |
605 | self.word_space("where"); | |
606 | ||
5e7ed085 | 607 | for (i, predicate) in predicates.iter().enumerate() { |
5099ac24 FG |
608 | if i != 0 { |
609 | self.word_space(","); | |
610 | } | |
611 | ||
612 | self.print_where_predicate(predicate); | |
613 | } | |
614 | } | |
615 | ||
616 | pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) { | |
617 | match predicate { | |
618 | ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { | |
619 | bound_generic_params, | |
620 | bounded_ty, | |
621 | bounds, | |
622 | .. | |
623 | }) => { | |
624 | self.print_formal_generic_params(bound_generic_params); | |
625 | self.print_type(bounded_ty); | |
923072b8 FG |
626 | self.word(":"); |
627 | if !bounds.is_empty() { | |
628 | self.nbsp(); | |
629 | self.print_type_bounds(bounds); | |
630 | } | |
5099ac24 FG |
631 | } |
632 | ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { | |
633 | lifetime, | |
634 | bounds, | |
635 | .. | |
636 | }) => { | |
923072b8 FG |
637 | self.print_lifetime(*lifetime); |
638 | self.word(":"); | |
639 | if !bounds.is_empty() { | |
640 | self.nbsp(); | |
641 | self.print_lifetime_bounds(bounds); | |
642 | } | |
5099ac24 FG |
643 | } |
644 | ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { | |
645 | self.print_type(lhs_ty); | |
646 | self.space(); | |
647 | self.word_space("="); | |
648 | self.print_type(rhs_ty); | |
649 | } | |
650 | } | |
651 | } | |
652 | ||
653 | fn print_use_tree(&mut self, tree: &ast::UseTree) { | |
487cf647 FG |
654 | match &tree.kind { |
655 | ast::UseTreeKind::Simple(rename) => { | |
5099ac24 | 656 | self.print_path(&tree.prefix, false, 0); |
487cf647 | 657 | if let &Some(rename) = rename { |
5099ac24 FG |
658 | self.nbsp(); |
659 | self.word_nbsp("as"); | |
660 | self.print_ident(rename); | |
661 | } | |
662 | } | |
663 | ast::UseTreeKind::Glob => { | |
664 | if !tree.prefix.segments.is_empty() { | |
665 | self.print_path(&tree.prefix, false, 0); | |
666 | self.word("::"); | |
667 | } | |
668 | self.word("*"); | |
669 | } | |
487cf647 | 670 | ast::UseTreeKind::Nested(items) => { |
5099ac24 FG |
671 | if !tree.prefix.segments.is_empty() { |
672 | self.print_path(&tree.prefix, false, 0); | |
673 | self.word("::"); | |
674 | } | |
675 | if items.is_empty() { | |
676 | self.word("{}"); | |
677 | } else if items.len() == 1 { | |
678 | self.print_use_tree(&items[0].0); | |
679 | } else { | |
680 | self.cbox(INDENT_UNIT); | |
681 | self.word("{"); | |
682 | self.zerobreak(); | |
683 | self.ibox(0); | |
684 | for use_tree in items.iter().delimited() { | |
685 | self.print_use_tree(&use_tree.0); | |
686 | if !use_tree.is_last { | |
687 | self.word(","); | |
688 | if let ast::UseTreeKind::Nested(_) = use_tree.0.kind { | |
689 | self.hardbreak(); | |
690 | } else { | |
691 | self.space(); | |
692 | } | |
693 | } | |
694 | } | |
695 | self.end(); | |
696 | self.trailing_comma(); | |
697 | self.offset(-INDENT_UNIT); | |
698 | self.word("}"); | |
699 | self.end(); | |
700 | } | |
701 | } | |
702 | } | |
703 | } | |
704 | } |