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