1 use crate::pp
::Breaks
::Inconsistent
;
2 use crate::pprust
::state
::delimited
::IterDelimited
;
3 use crate::pprust
::state
::{AnnNode, PrintState, State, INDENT_UNIT}
;
7 use rustc_ast
::GenericBound
;
8 use rustc_ast
::ModKind
;
9 use rustc_span
::symbol
::Ident
;
11 fn visibility_qualified(vis
: &ast
::Visibility
, s
: &str) -> String
{
12 format
!("{}{}", State
::to_string(|s
| s
.print_visibility(vis
)), s
)
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
);
23 pub(crate) fn print_foreign_item(&mut self, item
: &ast
::ForeignItem
) {
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
);
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
);
33 ast
::ForeignItemKind
::Static(ty
, mutbl
, body
) => self.print_item_const(
36 &ast
::Generics
::default(),
40 ast
::Defaultness
::Final
,
42 ast
::ForeignItemKind
::TyAlias(box ast
::TyAlias
{
46 where_predicates_split
,
50 self.print_associated_type(
54 *where_predicates_split
,
61 ast
::ForeignItemKind
::MacCall(m
) => {
63 if m
.args
.need_semicolon() {
68 self.ann
.post(self, AnnNode
::SubItem(id
))
74 mutbl
: Option
<ast
::Mutability
>,
75 generics
: &ast
::Generics
,
77 body
: Option
<&ast
::Expr
>,
78 vis
: &ast
::Visibility
,
79 defaultness
: ast
::Defaultness
,
82 self.print_visibility(vis
);
83 self.print_defaultness(defaultness
);
84 let leading
= match mutbl
{
86 Some(ast
::Mutability
::Not
) => "static",
87 Some(ast
::Mutability
::Mut
) => "static mut",
89 self.word_space(leading
);
90 self.print_ident(ident
);
91 self.print_generic_params(&generics
.params
);
97 self.end(); // end the head-ibox
98 if let Some(body
) = body
{
100 self.print_expr(body
);
102 self.print_where_clause(&generics
.where_clause
);
104 self.end(); // end the outer cbox
107 fn print_associated_type(
110 generics
: &ast
::Generics
,
111 where_clauses
: (ast
::TyAliasWhereClause
, ast
::TyAliasWhereClause
),
112 where_predicates_split
: usize,
113 bounds
: &ast
::GenericBounds
,
114 ty
: Option
<&ast
::Ty
>,
115 vis
: &ast
::Visibility
,
116 defaultness
: ast
::Defaultness
,
118 let (before_predicates
, after_predicates
) =
119 generics
.where_clause
.predicates
.split_at(where_predicates_split
);
121 self.print_visibility(vis
);
122 self.print_defaultness(defaultness
);
123 self.word_space("type");
124 self.print_ident(ident
);
125 self.print_generic_params(&generics
.params
);
126 if !bounds
.is_empty() {
128 self.print_type_bounds(bounds
);
130 self.print_where_clause_parts(where_clauses
.0.0, before_predicates
);
131 if let Some(ty
) = ty
{
133 self.word_space("=");
136 self.print_where_clause_parts(where_clauses
.1.0, after_predicates
);
138 self.end(); // end inner head-block
139 self.end(); // end outer head-block
142 /// Pretty-prints an item.
143 pub(crate) fn print_item(&mut self, item
: &ast
::Item
) {
144 self.hardbreak_if_not_bol();
145 self.maybe_print_comment(item
.span
.lo());
146 self.print_outer_attributes(&item
.attrs
);
147 self.ann
.pre(self, AnnNode
::Item(item
));
149 ast
::ItemKind
::ExternCrate(orig_name
) => {
150 self.head(visibility_qualified(&item
.vis
, "extern crate"));
151 if let &Some(orig_name
) = orig_name
{
152 self.print_name(orig_name
);
157 self.print_ident(item
.ident
);
159 self.end(); // end inner head-block
160 self.end(); // end outer head-block
162 ast
::ItemKind
::Use(tree
) => {
163 self.print_visibility(&item
.vis
);
164 self.word_nbsp("use");
165 self.print_use_tree(tree
);
168 ast
::ItemKind
::Static(box StaticItem { ty, mutability: mutbl, expr: body }
) => {
169 self.print_item_const(
172 &ast
::Generics
::default(),
176 ast
::Defaultness
::Final
,
179 ast
::ItemKind
::Const(box ast
::ConstItem { defaultness, generics, ty, expr }
) => {
180 self.print_item_const(
190 ast
::ItemKind
::Fn(box ast
::Fn { defaultness, sig, generics, body }
) => {
201 ast
::ItemKind
::Mod(unsafety
, mod_kind
) => {
202 self.head(Self::to_string(|s
| {
203 s
.print_visibility(&item
.vis
);
204 s
.print_unsafety(*unsafety
);
207 self.print_ident(item
.ident
);
210 ModKind
::Loaded(items
, ..) => {
213 self.print_inner_attributes(&item
.attrs
);
215 self.print_item(item
);
217 let empty
= item
.attrs
.is_empty() && items
.is_empty();
218 self.bclose(item
.span
, empty
);
220 ModKind
::Unloaded
=> {
222 self.end(); // end inner head-block
223 self.end(); // end outer head-block
227 ast
::ItemKind
::ForeignMod(nmod
) => {
228 self.head(Self::to_string(|s
| {
229 s
.print_unsafety(nmod
.unsafety
);
232 if let Some(abi
) = nmod
.abi
{
233 self.print_token_literal(abi
.as_token_lit(), abi
.span
);
237 self.print_foreign_mod(nmod
, &item
.attrs
);
238 let empty
= item
.attrs
.is_empty() && nmod
.items
.is_empty();
239 self.bclose(item
.span
, empty
);
241 ast
::ItemKind
::GlobalAsm(asm
) => {
242 self.head(visibility_qualified(&item
.vis
, "global_asm!"));
243 self.print_inline_asm(asm
);
248 ast
::ItemKind
::TyAlias(box ast
::TyAlias
{
252 where_predicates_split
,
256 self.print_associated_type(
260 *where_predicates_split
,
267 ast
::ItemKind
::Enum(enum_definition
, params
) => {
268 self.print_enum_def(enum_definition
, params
, item
.ident
, item
.span
, &item
.vis
);
270 ast
::ItemKind
::Struct(struct_def
, generics
) => {
271 self.head(visibility_qualified(&item
.vis
, "struct"));
272 self.print_struct(struct_def
, generics
, item
.ident
, item
.span
, true);
274 ast
::ItemKind
::Union(struct_def
, generics
) => {
275 self.head(visibility_qualified(&item
.vis
, "union"));
276 self.print_struct(struct_def
, generics
, item
.ident
, item
.span
, true);
278 ast
::ItemKind
::Impl(box ast
::Impl
{
289 self.print_visibility(&item
.vis
);
290 self.print_defaultness(*defaultness
);
291 self.print_unsafety(*unsafety
);
294 if generics
.params
.is_empty() {
297 self.print_generic_params(&generics
.params
);
301 self.print_constness(*constness
);
303 if let ast
::ImplPolarity
::Negative(_
) = polarity
{
307 if let Some(t
) = of_trait
{
308 self.print_trait_ref(t
);
310 self.word_space("for");
313 self.print_type(self_ty
);
314 self.print_where_clause(&generics
.where_clause
);
318 self.print_inner_attributes(&item
.attrs
);
319 for impl_item
in items
{
320 self.print_assoc_item(impl_item
);
322 let empty
= item
.attrs
.is_empty() && items
.is_empty();
323 self.bclose(item
.span
, empty
);
325 ast
::ItemKind
::Trait(box ast
::Trait
{
334 self.print_visibility(&item
.vis
);
335 self.print_unsafety(*unsafety
);
336 self.print_is_auto(*is_auto
);
337 self.word_nbsp("trait");
338 self.print_ident(item
.ident
);
339 self.print_generic_params(&generics
.params
);
340 let mut real_bounds
= Vec
::with_capacity(bounds
.len());
341 for b
in bounds
.iter() {
342 if let GenericBound
::Trait(ptr
, ast
::TraitBoundModifier
::Maybe
) = b
{
344 self.word_space("for ?");
345 self.print_trait_ref(&ptr
.trait_ref
);
347 real_bounds
.push(b
.clone());
350 if !real_bounds
.is_empty() {
352 self.print_type_bounds(&real_bounds
);
354 self.print_where_clause(&generics
.where_clause
);
357 self.print_inner_attributes(&item
.attrs
);
358 for trait_item
in items
{
359 self.print_assoc_item(trait_item
);
361 let empty
= item
.attrs
.is_empty() && items
.is_empty();
362 self.bclose(item
.span
, empty
);
364 ast
::ItemKind
::TraitAlias(generics
, bounds
) => {
365 self.head(visibility_qualified(&item
.vis
, "trait"));
366 self.print_ident(item
.ident
);
367 self.print_generic_params(&generics
.params
);
369 if !bounds
.is_empty() {
371 self.print_type_bounds(&bounds
);
373 self.print_where_clause(&generics
.where_clause
);
375 self.end(); // end inner head-block
376 self.end(); // end outer head-block
378 ast
::ItemKind
::MacCall(mac
) => {
380 if mac
.args
.need_semicolon() {
384 ast
::ItemKind
::MacroDef(macro_def
) => {
385 self.print_mac_def(macro_def
, &item
.ident
, item
.span
, |state
| {
386 state
.print_visibility(&item
.vis
)
390 self.ann
.post(self, AnnNode
::Item(item
))
395 enum_definition
: &ast
::EnumDef
,
396 generics
: &ast
::Generics
,
398 span
: rustc_span
::Span
,
399 visibility
: &ast
::Visibility
,
401 self.head(visibility_qualified(visibility
, "enum"));
402 self.print_ident(ident
);
403 self.print_generic_params(&generics
.params
);
404 self.print_where_clause(&generics
.where_clause
);
406 self.print_variants(&enum_definition
.variants
, span
)
409 fn print_variants(&mut self, variants
: &[ast
::Variant
], span
: rustc_span
::Span
) {
412 self.space_if_not_bol();
413 self.maybe_print_comment(v
.span
.lo());
414 self.print_outer_attributes(&v
.attrs
);
416 self.print_variant(v
);
419 self.maybe_print_trailing_comment(v
.span
, None
);
421 let empty
= variants
.is_empty();
422 self.bclose(span
, empty
)
425 pub(crate) fn print_visibility(&mut self, vis
: &ast
::Visibility
) {
427 ast
::VisibilityKind
::Public
=> self.word_nbsp("pub"),
428 ast
::VisibilityKind
::Restricted { path, shorthand, .. }
=> {
429 let path
= Self::to_string(|s
| s
.print_path(path
, false, 0));
430 if *shorthand
&& (path
== "crate" || path
== "self" || path
== "super") {
431 self.word_nbsp(format
!("pub({path})"))
433 self.word_nbsp(format
!("pub(in {path})"))
436 ast
::VisibilityKind
::Inherited
=> {}
440 fn print_defaultness(&mut self, defaultness
: ast
::Defaultness
) {
441 if let ast
::Defaultness
::Default(_
) = defaultness
{
442 self.word_nbsp("default");
446 pub(crate) fn print_record_struct_body(
448 fields
: &[ast
::FieldDef
],
449 span
: rustc_span
::Span
,
454 let empty
= fields
.is_empty();
456 self.hardbreak_if_not_bol();
458 for field
in fields
{
459 self.hardbreak_if_not_bol();
460 self.maybe_print_comment(field
.span
.lo());
461 self.print_outer_attributes(&field
.attrs
);
462 self.print_visibility(&field
.vis
);
463 self.print_ident(field
.ident
.unwrap());
465 self.print_type(&field
.ty
);
470 self.bclose(span
, empty
);
475 struct_def
: &ast
::VariantData
,
476 generics
: &ast
::Generics
,
478 span
: rustc_span
::Span
,
479 print_finalizer
: bool
,
481 self.print_ident(ident
);
482 self.print_generic_params(&generics
.params
);
484 ast
::VariantData
::Tuple(..) | ast
::VariantData
::Unit(..) => {
485 if let ast
::VariantData
::Tuple(..) = struct_def
{
487 self.commasep(Inconsistent
, struct_def
.fields(), |s
, field
| {
488 s
.maybe_print_comment(field
.span
.lo());
489 s
.print_outer_attributes(&field
.attrs
);
490 s
.print_visibility(&field
.vis
);
491 s
.print_type(&field
.ty
)
495 self.print_where_clause(&generics
.where_clause
);
500 self.end(); // Close the outer-box.
502 ast
::VariantData
::Struct(fields
, ..) => {
503 self.print_where_clause(&generics
.where_clause
);
504 self.print_record_struct_body(fields
, span
);
509 pub(crate) fn print_variant(&mut self, v
: &ast
::Variant
) {
511 self.print_visibility(&v
.vis
);
512 let generics
= ast
::Generics
::default();
513 self.print_struct(&v
.data
, &generics
, v
.ident
, v
.span
, false);
514 if let Some(d
) = &v
.disr_expr
{
516 self.word_space("=");
517 self.print_expr(&d
.value
)
521 pub(crate) fn print_assoc_item(&mut self, item
: &ast
::AssocItem
) {
522 let ast
::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ }
= *item
;
523 self.ann
.pre(self, AnnNode
::SubItem(id
));
524 self.hardbreak_if_not_bol();
525 self.maybe_print_comment(span
.lo());
526 self.print_outer_attributes(attrs
);
528 ast
::AssocItemKind
::Fn(box ast
::Fn { defaultness, sig, generics, body }
) => {
529 self.print_fn_full(sig
, ident
, generics
, vis
, *defaultness
, body
.as_deref(), attrs
);
531 ast
::AssocItemKind
::Const(box ast
::ConstItem { defaultness, generics, ty, expr }
) => {
532 self.print_item_const(
542 ast
::AssocItemKind
::Type(box ast
::TyAlias
{
546 where_predicates_split
,
550 self.print_associated_type(
554 *where_predicates_split
,
561 ast
::AssocItemKind
::MacCall(m
) => {
563 if m
.args
.need_semicolon() {
568 self.ann
.post(self, AnnNode
::SubItem(id
))
575 generics
: &ast
::Generics
,
576 vis
: &ast
::Visibility
,
577 defaultness
: ast
::Defaultness
,
578 body
: Option
<&ast
::Block
>,
579 attrs
: &[ast
::Attribute
],
584 self.print_visibility(vis
);
585 self.print_defaultness(defaultness
);
586 self.print_fn(&sig
.decl
, sig
.header
, Some(name
), generics
);
587 if let Some(body
) = body
{
589 self.print_block_with_attrs(body
, attrs
);
595 pub(crate) fn print_fn(
598 header
: ast
::FnHeader
,
600 generics
: &ast
::Generics
,
602 self.print_fn_header_info(header
);
603 if let Some(name
) = name
{
605 self.print_ident(name
);
607 self.print_generic_params(&generics
.params
);
608 self.print_fn_params_and_ret(decl
, false);
609 self.print_where_clause(&generics
.where_clause
)
612 pub(crate) fn print_fn_params_and_ret(&mut self, decl
: &ast
::FnDecl
, is_closure
: bool
) {
613 let (open
, close
) = if is_closure { ("|", "|") }
else { ("(", ")") }
;
615 self.commasep(Inconsistent
, &decl
.inputs
, |s
, param
| s
.print_param(param
, is_closure
));
617 self.print_fn_ret_ty(&decl
.output
)
620 fn print_where_clause(&mut self, where_clause
: &ast
::WhereClause
) {
621 self.print_where_clause_parts(where_clause
.has_where_token
, &where_clause
.predicates
);
624 pub(crate) fn print_where_clause_parts(
626 has_where_token
: bool
,
627 predicates
: &[ast
::WherePredicate
],
629 if predicates
.is_empty() && !has_where_token
{
634 self.word_space("where");
636 for (i
, predicate
) in predicates
.iter().enumerate() {
638 self.word_space(",");
641 self.print_where_predicate(predicate
);
645 pub fn print_where_predicate(&mut self, predicate
: &ast
::WherePredicate
) {
647 ast
::WherePredicate
::BoundPredicate(where_bound_predicate
) => {
648 self.print_where_bound_predicate(where_bound_predicate
);
650 ast
::WherePredicate
::RegionPredicate(ast
::WhereRegionPredicate
{
655 self.print_lifetime(*lifetime
);
657 if !bounds
.is_empty() {
659 self.print_lifetime_bounds(bounds
);
662 ast
::WherePredicate
::EqPredicate(ast
::WhereEqPredicate { lhs_ty, rhs_ty, .. }
) => {
663 self.print_type(lhs_ty
);
665 self.word_space("=");
666 self.print_type(rhs_ty
);
671 pub fn print_where_bound_predicate(
673 where_bound_predicate
: &ast
::WhereBoundPredicate
,
675 self.print_formal_generic_params(&where_bound_predicate
.bound_generic_params
);
676 self.print_type(&where_bound_predicate
.bounded_ty
);
678 if !where_bound_predicate
.bounds
.is_empty() {
680 self.print_type_bounds(&where_bound_predicate
.bounds
);
684 fn print_use_tree(&mut self, tree
: &ast
::UseTree
) {
686 ast
::UseTreeKind
::Simple(rename
) => {
687 self.print_path(&tree
.prefix
, false, 0);
688 if let &Some(rename
) = rename
{
690 self.word_nbsp("as");
691 self.print_ident(rename
);
694 ast
::UseTreeKind
::Glob
=> {
695 if !tree
.prefix
.segments
.is_empty() {
696 self.print_path(&tree
.prefix
, false, 0);
701 ast
::UseTreeKind
::Nested(items
) => {
702 if !tree
.prefix
.segments
.is_empty() {
703 self.print_path(&tree
.prefix
, false, 0);
706 if items
.is_empty() {
708 } else if items
.len() == 1 {
709 self.print_use_tree(&items
[0].0);
711 self.cbox(INDENT_UNIT
);
715 for use_tree
in items
.iter().delimited() {
716 self.print_use_tree(&use_tree
.0);
717 if !use_tree
.is_last
{
719 if let ast
::UseTreeKind
::Nested(_
) = use_tree
.0.kind
{
727 self.trailing_comma();
728 self.offset(-INDENT_UNIT
);