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