1use ast::StaticItem;
2use itertools::{Itertools, Position};
3use rustc_ast::{self as ast, EiiImpl, ModKind, Safety, TraitAlias};
4use rustc_span::Ident;
5
6use crate::pp::BoxMarker;
7use crate::pp::Breaks::Inconsistent;
8use crate::pprust::state::fixup::FixupContext;
9use crate::pprust::state::{AnnNode, INDENT_UNIT, PrintState, State};
10
11enum DelegationKind<'a> {
12 Single,
13 List(&'a [(Ident, Option<Ident>)]),
14 Glob,
15}
16
17fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
18 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}",
State::to_string(|s| s.print_visibility(vis)), s))
})format!("{}{}", State::to_string(|s| s.print_visibility(vis)), s)
19}
20
21impl<'a> State<'a> {
22 fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) {
23 self.print_inner_attributes(attrs);
24 for item in &nmod.items {
25 self.print_foreign_item(item);
26 }
27 }
28
29 pub(crate) fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
30 let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
31 self.ann.pre(self, AnnNode::SubItem(id));
32 self.hardbreak_if_not_bol();
33 self.maybe_print_comment(span.lo());
34 self.print_outer_attributes(attrs);
35 match kind {
36 ast::ForeignItemKind::Fn(func) => {
37 self.print_fn_full(vis, attrs, &*func);
38 }
39 ast::ForeignItemKind::Static(box ast::StaticItem {
40 ident,
41 ty,
42 mutability,
43 expr,
44 safety,
45 define_opaque,
46 }) => self.print_item_const(
47 *ident,
48 Some(*mutability),
49 &ast::Generics::default(),
50 ty,
51 expr.as_deref(),
52 vis,
53 *safety,
54 ast::Defaultness::Final,
55 define_opaque.as_deref(),
56 ),
57 ast::ForeignItemKind::TyAlias(box ast::TyAlias {
58 defaultness,
59 ident,
60 generics,
61 after_where_clause,
62 bounds,
63 ty,
64 }) => {
65 self.print_associated_type(
66 *ident,
67 generics,
68 after_where_clause,
69 bounds,
70 ty.as_deref(),
71 vis,
72 *defaultness,
73 );
74 }
75 ast::ForeignItemKind::MacCall(m) => {
76 self.print_mac(m);
77 if m.args.need_semicolon() {
78 self.word(";");
79 }
80 }
81 }
82 self.ann.post(self, AnnNode::SubItem(id))
83 }
84
85 fn print_item_const(
86 &mut self,
87 ident: Ident,
88 mutbl: Option<ast::Mutability>,
89 generics: &ast::Generics,
90 ty: &ast::Ty,
91 body: Option<&ast::Expr>,
92 vis: &ast::Visibility,
93 safety: ast::Safety,
94 defaultness: ast::Defaultness,
95 define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
96 ) {
97 self.print_define_opaques(define_opaque);
98 let (cb, ib) = self.head("");
99 self.print_visibility(vis);
100 self.print_safety(safety);
101 self.print_defaultness(defaultness);
102 let leading = match mutbl {
103 None => "const",
104 Some(ast::Mutability::Not) => "static",
105 Some(ast::Mutability::Mut) => "static mut",
106 };
107 self.word_space(leading);
108 self.print_ident(ident);
109 self.print_generic_params(&generics.params);
110 self.word_space(":");
111 self.print_type(ty);
112 if body.is_some() {
113 self.space();
114 }
115 self.end(ib);
116 if let Some(body) = body {
117 self.word_space("=");
118 self.print_expr(body, FixupContext::default());
119 }
120 self.print_where_clause(&generics.where_clause);
121 self.word(";");
122 self.end(cb);
123 }
124
125 fn print_associated_type(
126 &mut self,
127 ident: Ident,
128 generics: &ast::Generics,
129 after_where_clause: &ast::WhereClause,
130 bounds: &ast::GenericBounds,
131 ty: Option<&ast::Ty>,
132 vis: &ast::Visibility,
133 defaultness: ast::Defaultness,
134 ) {
135 let (cb, ib) = self.head("");
136 self.print_visibility(vis);
137 self.print_defaultness(defaultness);
138 self.word_space("type");
139 self.print_ident(ident);
140 self.print_generic_params(&generics.params);
141 if !bounds.is_empty() {
142 self.word_nbsp(":");
143 self.print_type_bounds(bounds);
144 }
145 self.print_where_clause(&generics.where_clause);
146 if let Some(ty) = ty {
147 self.space();
148 self.word_space("=");
149 self.print_type(ty);
150 }
151 self.print_where_clause(&after_where_clause);
152 self.word(";");
153 self.end(ib);
154 self.end(cb);
155 }
156
157 pub(crate) fn print_item(&mut self, item: &ast::Item) {
159 if self.is_sdylib_interface && item.span.is_dummy() {
160 return;
162 }
163 self.hardbreak_if_not_bol();
164 self.maybe_print_comment(item.span.lo());
165 self.print_outer_attributes(&item.attrs);
166 self.ann.pre(self, AnnNode::Item(item));
167 match &item.kind {
168 ast::ItemKind::ExternCrate(orig_name, ident) => {
169 let (cb, ib) = self.head(visibility_qualified(&item.vis, "extern crate"));
170 if let &Some(orig_name) = orig_name {
171 self.print_name(orig_name);
172 self.space();
173 self.word("as");
174 self.space();
175 }
176 self.print_ident(*ident);
177 self.word(";");
178 self.end(ib);
179 self.end(cb);
180 }
181 ast::ItemKind::Use(tree) => {
182 self.print_visibility(&item.vis);
183 self.word_nbsp("use");
184 self.print_use_tree(tree);
185 self.word(";");
186 }
187 ast::ItemKind::Static(box StaticItem {
188 ident,
189 ty,
190 safety,
191 mutability: mutbl,
192 expr: body,
193 define_opaque,
194 }) => {
195 self.print_safety(*safety);
196 self.print_item_const(
197 *ident,
198 Some(*mutbl),
199 &ast::Generics::default(),
200 ty,
201 body.as_deref(),
202 &item.vis,
203 ast::Safety::Default,
204 ast::Defaultness::Final,
205 define_opaque.as_deref(),
206 );
207 }
208 ast::ItemKind::ConstBlock(ast::ConstBlockItem { id: _, span: _, block }) => {
209 let ib = self.ibox(INDENT_UNIT);
210 self.word("const");
211 self.nbsp();
212 {
213 let cb = self.cbox(0);
214 let ib = self.ibox(0);
215 self.print_block_with_attrs(block, &[], cb, ib);
216 }
217 self.end(ib);
218 }
219 ast::ItemKind::Const(box ast::ConstItem {
220 defaultness,
221 ident,
222 generics,
223 ty,
224 rhs,
225 define_opaque,
226 }) => {
227 self.print_item_const(
228 *ident,
229 None,
230 generics,
231 ty,
232 rhs.as_ref().map(|ct| ct.expr()),
233 &item.vis,
234 ast::Safety::Default,
235 *defaultness,
236 define_opaque.as_deref(),
237 );
238 }
239 ast::ItemKind::Fn(func) => {
240 self.print_fn_full(&item.vis, &item.attrs, &*func);
241 }
242 ast::ItemKind::Mod(safety, ident, mod_kind) => {
243 let (cb, ib) = self.head(Self::to_string(|s| {
244 s.print_visibility(&item.vis);
245 s.print_safety(*safety);
246 s.word("mod");
247 }));
248 self.print_ident(*ident);
249
250 match mod_kind {
251 ModKind::Loaded(items, ..) => {
252 self.nbsp();
253 self.bopen(ib);
254 self.print_inner_attributes(&item.attrs);
255 for item in items {
256 self.print_item(item);
257 }
258 let empty = item.attrs.is_empty() && items.is_empty();
259 self.bclose(item.span, empty, cb);
260 }
261 ModKind::Unloaded => {
262 self.word(";");
263 self.end(ib);
264 self.end(cb);
265 }
266 }
267 }
268 ast::ItemKind::ForeignMod(nmod) => {
269 let (cb, ib) = self.head(Self::to_string(|s| {
270 s.print_safety(nmod.safety);
271 s.word("extern");
272 }));
273 if let Some(abi) = nmod.abi {
274 self.print_token_literal(abi.as_token_lit(), abi.span);
275 self.nbsp();
276 }
277 self.bopen(ib);
278 self.print_foreign_mod(nmod, &item.attrs);
279 let empty = item.attrs.is_empty() && nmod.items.is_empty();
280 self.bclose(item.span, empty, cb);
281 }
282 ast::ItemKind::GlobalAsm(asm) => {
283 let (cb, ib) = self.head(visibility_qualified(&item.vis, "global_asm!"));
285 self.print_inline_asm(asm);
286 self.word(";");
287 self.end(ib);
288 self.end(cb);
289 }
290 ast::ItemKind::TyAlias(box ast::TyAlias {
291 defaultness,
292 ident,
293 generics,
294 after_where_clause,
295 bounds,
296 ty,
297 }) => {
298 self.print_associated_type(
299 *ident,
300 generics,
301 after_where_clause,
302 bounds,
303 ty.as_deref(),
304 &item.vis,
305 *defaultness,
306 );
307 }
308 ast::ItemKind::Enum(ident, generics, enum_definition) => {
309 self.print_enum_def(enum_definition, generics, *ident, item.span, &item.vis);
310 }
311 ast::ItemKind::Struct(ident, generics, struct_def) => {
312 let (cb, ib) = self.head(visibility_qualified(&item.vis, "struct"));
313 self.print_struct(struct_def, generics, *ident, item.span, true, cb, ib);
314 }
315 ast::ItemKind::Union(ident, generics, struct_def) => {
316 let (cb, ib) = self.head(visibility_qualified(&item.vis, "union"));
317 self.print_struct(struct_def, generics, *ident, item.span, true, cb, ib);
318 }
319 ast::ItemKind::Impl(ast::Impl { generics, of_trait, self_ty, items, constness }) => {
320 let (cb, ib) = self.head("");
321 self.print_visibility(&item.vis);
322
323 let impl_generics = |this: &mut Self| {
324 this.word("impl");
325
326 if generics.params.is_empty() {
327 this.nbsp();
328 } else {
329 this.print_generic_params(&generics.params);
330 this.space();
331 }
332 };
333
334 if let Some(box of_trait) = of_trait {
335 let ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } =
336 *of_trait;
337 self.print_defaultness(defaultness);
338 self.print_safety(safety);
339 impl_generics(self);
340 self.print_constness(*constness);
341 if let ast::ImplPolarity::Negative(_) = polarity {
342 self.word("!");
343 }
344 self.print_trait_ref(trait_ref);
345 self.space();
346 self.word_space("for");
347 } else {
348 self.print_constness(*constness);
349 impl_generics(self);
350 }
351
352 self.print_type(self_ty);
353 self.print_where_clause(&generics.where_clause);
354
355 self.space();
356 self.bopen(ib);
357 self.print_inner_attributes(&item.attrs);
358 for impl_item in items {
359 self.print_assoc_item(impl_item);
360 }
361 let empty = item.attrs.is_empty() && items.is_empty();
362 self.bclose(item.span, empty, cb);
363 }
364 ast::ItemKind::Trait(box ast::Trait {
365 constness,
366 safety,
367 is_auto,
368 ident,
369 generics,
370 bounds,
371 items,
372 }) => {
373 let (cb, ib) = self.head("");
374 self.print_visibility(&item.vis);
375 self.print_constness(*constness);
376 self.print_safety(*safety);
377 self.print_is_auto(*is_auto);
378 self.word_nbsp("trait");
379 self.print_ident(*ident);
380 self.print_generic_params(&generics.params);
381 if !bounds.is_empty() {
382 self.word_nbsp(":");
383 self.print_type_bounds(bounds);
384 }
385 self.print_where_clause(&generics.where_clause);
386 self.word(" ");
387 self.bopen(ib);
388 self.print_inner_attributes(&item.attrs);
389 for trait_item in items {
390 self.print_assoc_item(trait_item);
391 }
392 let empty = item.attrs.is_empty() && items.is_empty();
393 self.bclose(item.span, empty, cb);
394 }
395 ast::ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
396 let (cb, ib) = self.head("");
397 self.print_visibility(&item.vis);
398 self.print_constness(*constness);
399 self.word_nbsp("trait");
400 self.print_ident(*ident);
401 self.print_generic_params(&generics.params);
402 self.nbsp();
403 if !bounds.is_empty() {
404 self.word_nbsp("=");
405 self.print_type_bounds(bounds);
406 }
407 self.print_where_clause(&generics.where_clause);
408 self.word(";");
409 self.end(ib);
410 self.end(cb);
411 }
412 ast::ItemKind::MacCall(mac) => {
413 self.print_mac(mac);
414 if mac.args.need_semicolon() {
415 self.word(";");
416 }
417 }
418 ast::ItemKind::MacroDef(ident, macro_def) => {
419 self.print_mac_def(macro_def, &ident, item.span, |state| {
420 state.print_visibility(&item.vis)
421 });
422 }
423 ast::ItemKind::Delegation(deleg) => self.print_delegation(
424 &item.attrs,
425 &item.vis,
426 &deleg.qself,
427 &deleg.path,
428 DelegationKind::Single,
429 &deleg.body,
430 ),
431 ast::ItemKind::DelegationMac(deleg) => self.print_delegation(
432 &item.attrs,
433 &item.vis,
434 &deleg.qself,
435 &deleg.prefix,
436 deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
437 &deleg.body,
438 ),
439 }
440 self.ann.post(self, AnnNode::Item(item))
441 }
442
443 fn print_enum_def(
444 &mut self,
445 enum_definition: &ast::EnumDef,
446 generics: &ast::Generics,
447 ident: Ident,
448 span: rustc_span::Span,
449 visibility: &ast::Visibility,
450 ) {
451 let (cb, ib) = self.head(visibility_qualified(visibility, "enum"));
452 self.print_ident(ident);
453 self.print_generic_params(&generics.params);
454 self.print_where_clause(&generics.where_clause);
455 self.space();
456 self.bopen(ib);
457 for v in enum_definition.variants.iter() {
458 self.space_if_not_bol();
459 self.maybe_print_comment(v.span.lo());
460 self.print_outer_attributes(&v.attrs);
461 let ib = self.ibox(0);
462 self.print_variant(v);
463 self.word(",");
464 self.end(ib);
465 self.maybe_print_trailing_comment(v.span, None);
466 }
467 let empty = enum_definition.variants.is_empty();
468 self.bclose(span, empty, cb)
469 }
470
471 pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) {
472 match &vis.kind {
473 ast::VisibilityKind::Public => self.word_nbsp("pub"),
474 ast::VisibilityKind::Restricted { path, shorthand, .. } => {
475 let path = Self::to_string(|s| s.print_path(path, false, 0));
476 if *shorthand && (path == "crate" || path == "self" || path == "super") {
477 self.word_nbsp(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("pub({0})", path))
})format!("pub({path})"))
478 } else {
479 self.word_nbsp(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("pub(in {0})", path))
})format!("pub(in {path})"))
480 }
481 }
482 ast::VisibilityKind::Inherited => {}
483 }
484 }
485
486 fn print_defaultness(&mut self, defaultness: ast::Defaultness) {
487 if let ast::Defaultness::Default(_) = defaultness {
488 self.word_nbsp("default");
489 }
490 }
491
492 fn print_struct(
493 &mut self,
494 struct_def: &ast::VariantData,
495 generics: &ast::Generics,
496 ident: Ident,
497 span: rustc_span::Span,
498 print_finalizer: bool,
499 cb: BoxMarker,
500 ib: BoxMarker,
501 ) {
502 self.print_ident(ident);
503 self.print_generic_params(&generics.params);
504 match &struct_def {
505 ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
506 if let ast::VariantData::Tuple(..) = struct_def {
507 self.popen();
508 self.commasep(Inconsistent, struct_def.fields(), |s, field| {
509 s.maybe_print_comment(field.span.lo());
510 s.print_outer_attributes(&field.attrs);
511 s.print_visibility(&field.vis);
512 s.print_type(&field.ty)
513 });
514 self.pclose();
515 }
516 self.print_where_clause(&generics.where_clause);
517 if print_finalizer {
518 self.word(";");
519 }
520 self.end(ib);
521 self.end(cb);
522 }
523 ast::VariantData::Struct { fields, .. } => {
524 self.print_where_clause(&generics.where_clause);
525 self.nbsp();
526 self.bopen(ib);
527
528 let empty = fields.is_empty();
529 if !empty {
530 self.hardbreak_if_not_bol();
531
532 for field in fields {
533 self.hardbreak_if_not_bol();
534 self.maybe_print_comment(field.span.lo());
535 self.print_outer_attributes(&field.attrs);
536 self.print_visibility(&field.vis);
537 self.print_ident(field.ident.unwrap());
538 self.word_nbsp(":");
539 self.print_type(&field.ty);
540 self.word(",");
541 }
542 }
543
544 self.bclose(span, empty, cb);
545 }
546 }
547 }
548
549 pub(crate) fn print_variant(&mut self, v: &ast::Variant) {
550 let (cb, ib) = self.head("");
551 self.print_visibility(&v.vis);
552 let generics = ast::Generics::default();
553 self.print_struct(&v.data, &generics, v.ident, v.span, false, cb, ib);
554 if let Some(d) = &v.disr_expr {
555 self.space();
556 self.word_space("=");
557 self.print_expr(&d.value, FixupContext::default())
558 }
559 }
560
561 pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) {
562 let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
563 self.ann.pre(self, AnnNode::SubItem(id));
564 self.hardbreak_if_not_bol();
565 self.maybe_print_comment(span.lo());
566 self.print_outer_attributes(attrs);
567 match kind {
568 ast::AssocItemKind::Fn(func) => {
569 self.print_fn_full(vis, attrs, &*func);
570 }
571 ast::AssocItemKind::Const(box ast::ConstItem {
572 defaultness,
573 ident,
574 generics,
575 ty,
576 rhs,
577 define_opaque,
578 }) => {
579 self.print_item_const(
580 *ident,
581 None,
582 generics,
583 ty,
584 rhs.as_ref().map(|ct| ct.expr()),
585 vis,
586 ast::Safety::Default,
587 *defaultness,
588 define_opaque.as_deref(),
589 );
590 }
591 ast::AssocItemKind::Type(box ast::TyAlias {
592 defaultness,
593 ident,
594 generics,
595 after_where_clause,
596 bounds,
597 ty,
598 }) => {
599 self.print_associated_type(
600 *ident,
601 generics,
602 after_where_clause,
603 bounds,
604 ty.as_deref(),
605 vis,
606 *defaultness,
607 );
608 }
609 ast::AssocItemKind::MacCall(m) => {
610 self.print_mac(m);
611 if m.args.need_semicolon() {
612 self.word(";");
613 }
614 }
615 ast::AssocItemKind::Delegation(deleg) => self.print_delegation(
616 &item.attrs,
617 vis,
618 &deleg.qself,
619 &deleg.path,
620 DelegationKind::Single,
621 &deleg.body,
622 ),
623 ast::AssocItemKind::DelegationMac(deleg) => self.print_delegation(
624 &item.attrs,
625 vis,
626 &deleg.qself,
627 &deleg.prefix,
628 deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
629 &deleg.body,
630 ),
631 }
632 self.ann.post(self, AnnNode::SubItem(id))
633 }
634
635 fn print_delegation(
636 &mut self,
637 attrs: &[ast::Attribute],
638 vis: &ast::Visibility,
639 qself: &Option<Box<ast::QSelf>>,
640 path: &ast::Path,
641 kind: DelegationKind<'_>,
642 body: &Option<Box<ast::Block>>,
643 ) {
644 let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
645 self.print_visibility(vis);
646 self.word_nbsp("reuse");
647
648 if let Some(qself) = qself {
649 self.print_qpath(path, qself, false);
650 } else {
651 self.print_path(path, false, 0);
652 }
653 match kind {
654 DelegationKind::Single => {}
655 DelegationKind::List(suffixes) => {
656 self.word("::");
657 self.word("{");
658 for (i, (ident, rename)) in suffixes.iter().enumerate() {
659 self.print_ident(*ident);
660 if let Some(rename) = rename {
661 self.nbsp();
662 self.word_nbsp("as");
663 self.print_ident(*rename);
664 }
665 if i != suffixes.len() - 1 {
666 self.word_space(",");
667 }
668 }
669 self.word("}");
670 }
671 DelegationKind::Glob => {
672 self.word("::");
673 self.word("*");
674 }
675 }
676 if let Some((body, (cb, ib))) = body_cb_ib {
677 self.nbsp();
678 self.print_block_with_attrs(body, attrs, cb, ib);
679 } else {
680 self.word(";");
681 }
682 }
683
684 fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
685 let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impls } =
686 func;
687
688 self.print_define_opaques(define_opaque.as_deref());
689
690 for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls {
691 self.word("#[");
692 if let Safety::Unsafe(..) = impl_safety {
693 self.word("unsafe");
694 self.popen();
695 }
696 self.print_path(eii_macro_path, false, 0);
697 if let Safety::Unsafe(..) = impl_safety {
698 self.pclose();
699 }
700 self.word("]");
701 self.hardbreak();
702 }
703
704 let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
705
706 self.print_visibility(vis);
707 self.print_defaultness(*defaultness);
708 self.print_fn(&sig.decl, sig.header, Some(*ident), generics);
709 if let Some(contract) = &contract {
710 self.nbsp();
711 self.print_contract(contract);
712 }
713 if let Some((body, (cb, ib))) = body_cb_ib {
714 if self.is_sdylib_interface {
715 self.word(";");
716 self.end(ib); self.end(cb); return;
719 }
720
721 self.nbsp();
722 self.print_block_with_attrs(body, attrs, cb, ib);
723 } else {
724 self.word(";");
725 }
726 }
727
728 fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
729 if let Some(define_opaque) = define_opaque {
730 self.word("#[define_opaque(");
731 for (i, (_, path)) in define_opaque.iter().enumerate() {
732 if i != 0 {
733 self.word_space(",");
734 }
735
736 self.print_path(path, false, 0);
737 }
738 self.word(")]");
739 }
740 self.hardbreak_if_not_bol();
741 }
742
743 fn print_contract(&mut self, contract: &ast::FnContract) {
744 if let Some(pred) = &contract.requires {
745 self.word("rustc_requires");
746 self.popen();
747 self.print_expr(pred, FixupContext::default());
748 self.pclose();
749 }
750 if let Some(pred) = &contract.ensures {
751 self.word("rustc_ensures");
752 self.popen();
753 self.print_expr(pred, FixupContext::default());
754 self.pclose();
755 }
756 }
757
758 pub(crate) fn print_fn(
759 &mut self,
760 decl: &ast::FnDecl,
761 header: ast::FnHeader,
762 ident: Option<Ident>,
763 generics: &ast::Generics,
764 ) {
765 self.print_fn_header_info(header);
766 if let Some(ident) = ident {
767 self.nbsp();
768 self.print_ident(ident);
769 }
770 self.print_generic_params(&generics.params);
771 self.print_fn_params_and_ret(decl, false);
772 self.print_where_clause(&generics.where_clause);
773 }
774
775 pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {
776 let (open, close) = if is_closure { ("|", "|") } else { ("(", ")") };
777 self.word(open);
778 self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, is_closure));
779 self.word(close);
780 self.print_fn_ret_ty(&decl.output)
781 }
782
783 fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
784 let ast::WhereClause { has_where_token, ref predicates, span: _ } = *where_clause;
785 if predicates.is_empty() && !has_where_token {
786 return;
787 }
788
789 self.space();
790 self.word_space("where");
791
792 for (i, predicate) in predicates.iter().enumerate() {
793 if i != 0 {
794 self.word_space(",");
795 }
796
797 self.print_where_predicate(predicate);
798 }
799 }
800
801 pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
802 let ast::WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
803 self.print_outer_attributes(attrs);
804 match kind {
805 ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
806 self.print_where_bound_predicate(where_bound_predicate);
807 }
808 ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
809 lifetime,
810 bounds,
811 ..
812 }) => {
813 self.print_lifetime(*lifetime);
814 self.word(":");
815 if !bounds.is_empty() {
816 self.nbsp();
817 self.print_lifetime_bounds(bounds);
818 }
819 }
820 ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate {
821 lhs_ty, rhs_ty, ..
822 }) => {
823 self.print_type(lhs_ty);
824 self.space();
825 self.word_space("=");
826 self.print_type(rhs_ty);
827 }
828 }
829 }
830
831 pub(crate) fn print_where_bound_predicate(
832 &mut self,
833 where_bound_predicate: &ast::WhereBoundPredicate,
834 ) {
835 self.print_formal_generic_params(&where_bound_predicate.bound_generic_params);
836 self.print_type(&where_bound_predicate.bounded_ty);
837 self.word(":");
838 if !where_bound_predicate.bounds.is_empty() {
839 self.nbsp();
840 self.print_type_bounds(&where_bound_predicate.bounds);
841 }
842 }
843
844 fn print_use_tree(&mut self, tree: &ast::UseTree) {
845 match &tree.kind {
846 ast::UseTreeKind::Simple(rename) => {
847 self.print_path(&tree.prefix, false, 0);
848 if let &Some(rename) = rename {
849 self.nbsp();
850 self.word_nbsp("as");
851 self.print_ident(rename);
852 }
853 }
854 ast::UseTreeKind::Glob => {
855 if !tree.prefix.segments.is_empty() {
856 self.print_path(&tree.prefix, false, 0);
857 self.word("::");
858 }
859 self.word("*");
860 }
861 ast::UseTreeKind::Nested { items, .. } => {
862 if !tree.prefix.segments.is_empty() {
863 self.print_path(&tree.prefix, false, 0);
864 self.word("::");
865 }
866 if items.is_empty() {
867 self.word("{}");
868 } else if let [(item, _)] = items.as_slice() {
869 self.print_use_tree(item);
870 } else {
871 let cb = self.cbox(INDENT_UNIT);
872 self.word("{");
873 self.zerobreak();
874 let ib = self.ibox(0);
875 for (pos, use_tree) in items.iter().with_position() {
876 let is_last = #[allow(non_exhaustive_omitted_patterns)] match pos {
Position::Last | Position::Only => true,
_ => false,
}matches!(pos, Position::Last | Position::Only);
877 self.print_use_tree(&use_tree.0);
878 if !is_last {
879 self.word(",");
880 if let ast::UseTreeKind::Nested { .. } = use_tree.0.kind {
881 self.hardbreak();
882 } else {
883 self.space();
884 }
885 }
886 }
887 self.end(ib);
888 self.trailing_comma();
889 self.offset(-INDENT_UNIT);
890 self.word("}");
891 self.end(cb);
892 }
893 }
894 }
895 }
896}