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