• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ast::StaticItem;
6 use rustc_ast as ast;
7 use rustc_ast::GenericBound;
8 use rustc_ast::ModKind;
9 use rustc_span::symbol::Ident;
10 
visibility_qualified(vis: &ast::Visibility, s: &str) -> String11 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> {
print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute])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 
print_foreign_item(&mut self, item: &ast::ForeignItem)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);
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,
40                 where_clauses,
41                 where_predicates_split,
42                 bounds,
43                 ty,
44             }) => {
45                 self.print_associated_type(
46                     ident,
47                     generics,
48                     *where_clauses,
49                     *where_predicates_split,
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 
print_item_const( &mut self, ident: Ident, mutbl: Option<ast::Mutability>, ty: &ast::Ty, body: Option<&ast::Expr>, vis: &ast::Visibility, defaultness: ast::Defaultness, )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 
print_associated_type( &mut self, ident: Ident, generics: &ast::Generics, where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause), where_predicates_split: usize, bounds: &ast::GenericBounds, ty: Option<&ast::Ty>, vis: &ast::Visibility, defaultness: ast::Defaultness, )99     fn print_associated_type(
100         &mut self,
101         ident: Ident,
102         generics: &ast::Generics,
103         where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
104         where_predicates_split: usize,
105         bounds: &ast::GenericBounds,
106         ty: Option<&ast::Ty>,
107         vis: &ast::Visibility,
108         defaultness: ast::Defaultness,
109     ) {
110         let (before_predicates, after_predicates) =
111             generics.where_clause.predicates.split_at(where_predicates_split);
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);
118         if !bounds.is_empty() {
119             self.word_nbsp(":");
120             self.print_type_bounds(bounds);
121         }
122         self.print_where_clause_parts(where_clauses.0.0, before_predicates);
123         if let Some(ty) = ty {
124             self.space();
125             self.word_space("=");
126             self.print_type(ty);
127         }
128         self.print_where_clause_parts(where_clauses.1.0, after_predicates);
129         self.word(";");
130         self.end(); // end inner head-block
131         self.end(); // end outer head-block
132     }
133 
134     /// Pretty-prints an item.
print_item(&mut self, item: &ast::Item)135     pub(crate) fn print_item(&mut self, item: &ast::Item) {
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));
140         match &item.kind {
141             ast::ItemKind::ExternCrate(orig_name) => {
142                 self.head(visibility_qualified(&item.vis, "extern crate"));
143                 if let &Some(orig_name) = orig_name {
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             }
154             ast::ItemKind::Use(tree) => {
155                 self.print_visibility(&item.vis);
156                 self.word_nbsp("use");
157                 self.print_use_tree(tree);
158                 self.word(";");
159             }
160             ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => {
161                 let def = ast::Defaultness::Final;
162                 self.print_item_const(
163                     item.ident,
164                     Some(*mutbl),
165                     ty,
166                     body.as_deref(),
167                     &item.vis,
168                     def,
169                 );
170             }
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                 );
180             }
181             ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
182                 self.print_fn_full(
183                     sig,
184                     item.ident,
185                     generics,
186                     &item.vis,
187                     *defaultness,
188                     body.as_deref(),
189                     &item.attrs,
190                 );
191             }
192             ast::ItemKind::Mod(unsafety, mod_kind) => {
193                 self.head(Self::to_string(|s| {
194                     s.print_visibility(&item.vis);
195                     s.print_unsafety(*unsafety);
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             }
218             ast::ItemKind::ForeignMod(nmod) => {
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 {
224                     self.print_token_literal(abi.as_token_lit(), abi.span);
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             }
232             ast::ItemKind::GlobalAsm(asm) => {
233                 self.head(visibility_qualified(&item.vis, "global_asm!"));
234                 self.print_inline_asm(asm);
235                 self.word(";");
236                 self.end();
237                 self.end();
238             }
239             ast::ItemKind::TyAlias(box ast::TyAlias {
240                 defaultness,
241                 generics,
242                 where_clauses,
243                 where_predicates_split,
244                 bounds,
245                 ty,
246             }) => {
247                 self.print_associated_type(
248                     item.ident,
249                     generics,
250                     *where_clauses,
251                     *where_predicates_split,
252                     bounds,
253                     ty.as_deref(),
254                     &item.vis,
255                     *defaultness,
256                 );
257             }
258             ast::ItemKind::Enum(enum_definition, params) => {
259                 self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
260             }
261             ast::ItemKind::Struct(struct_def, generics) => {
262                 self.head(visibility_qualified(&item.vis, "struct"));
263                 self.print_struct(struct_def, generics, item.ident, item.span, true);
264             }
265             ast::ItemKind::Union(struct_def, generics) => {
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,
274                 generics,
275                 of_trait,
276                 self_ty,
277                 items,
278             }) => {
279                 self.head("");
280                 self.print_visibility(&item.vis);
281                 self.print_defaultness(*defaultness);
282                 self.print_unsafety(*unsafety);
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 
292                 self.print_constness(*constness);
293 
294                 if let ast::ImplPolarity::Negative(_) = polarity {
295                     self.word("!");
296                 }
297 
298                 if let Some(t) = of_trait {
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,
319                 generics,
320                 bounds,
321                 items,
322                 ..
323             }) => {
324                 self.head("");
325                 self.print_visibility(&item.vis);
326                 self.print_unsafety(*unsafety);
327                 self.print_is_auto(*is_auto);
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() {
333                     if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b {
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                 }
341                 if !real_bounds.is_empty() {
342                     self.word_nbsp(":");
343                     self.print_type_bounds(&real_bounds);
344                 }
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             }
355             ast::ItemKind::TraitAlias(generics, bounds) => {
356                 self.head(visibility_qualified(&item.vis, "trait"));
357                 self.print_ident(item.ident);
358                 self.print_generic_params(&generics.params);
359                 self.nbsp();
360                 if !bounds.is_empty() {
361                     self.word_nbsp("=");
362                     self.print_type_bounds(&bounds);
363                 }
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             }
369             ast::ItemKind::MacCall(mac) => {
370                 self.print_mac(mac);
371                 if mac.args.need_semicolon() {
372                     self.word(";");
373                 }
374             }
375             ast::ItemKind::MacroDef(macro_def) => {
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 
print_enum_def( &mut self, enum_definition: &ast::EnumDef, generics: &ast::Generics, ident: Ident, span: rustc_span::Span, visibility: &ast::Visibility, )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 
print_variants(&mut self, variants: &[ast::Variant], span: rustc_span::Span)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 
print_visibility(&mut self, vis: &ast::Visibility)416     pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) {
417         match &vis.kind {
418             ast::VisibilityKind::Public => self.word_nbsp("pub"),
419             ast::VisibilityKind::Restricted { path, shorthand, .. } => {
420                 let path = Self::to_string(|s| s.print_path(path, false, 0));
421                 if *shorthand && (path == "crate" || path == "self" || path == "super") {
422                     self.word_nbsp(format!("pub({path})"))
423                 } else {
424                     self.word_nbsp(format!("pub(in {path})"))
425                 }
426             }
427             ast::VisibilityKind::Inherited => {}
428         }
429     }
430 
print_defaultness(&mut self, defaultness: ast::Defaultness)431     fn print_defaultness(&mut self, defaultness: ast::Defaultness) {
432         if let ast::Defaultness::Default(_) = defaultness {
433             self.word_nbsp("default");
434         }
435     }
436 
print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span)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 
print_struct( &mut self, struct_def: &ast::VariantData, generics: &ast::Generics, ident: Ident, span: rustc_span::Span, print_finalizer: bool, )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);
470         match &struct_def {
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             }
489             ast::VariantData::Struct(fields, ..) => {
490                 self.print_where_clause(&generics.where_clause);
491                 self.print_record_struct_body(fields, span);
492             }
493         }
494     }
495 
print_variant(&mut self, v: &ast::Variant)496     pub(crate) fn print_variant(&mut self, v: &ast::Variant) {
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);
501         if let Some(d) = &v.disr_expr {
502             self.space();
503             self.word_space("=");
504             self.print_expr(&d.value)
505         }
506     }
507 
print_assoc_item(&mut self, item: &ast::AssocItem)508     pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) {
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             }
518             ast::AssocItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => {
519                 self.print_item_const(ident, None, ty, expr.as_deref(), vis, *defaultness);
520             }
521             ast::AssocItemKind::Type(box ast::TyAlias {
522                 defaultness,
523                 generics,
524                 where_clauses,
525                 where_predicates_split,
526                 bounds,
527                 ty,
528             }) => {
529                 self.print_associated_type(
530                     ident,
531                     generics,
532                     *where_clauses,
533                     *where_predicates_split,
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 
print_fn_full( &mut self, sig: &ast::FnSig, name: Ident, generics: &ast::Generics, vis: &ast::Visibility, defaultness: ast::Defaultness, body: Option<&ast::Block>, attrs: &[ast::Attribute], )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 
print_fn( &mut self, decl: &ast::FnDecl, header: ast::FnHeader, name: Option<Ident>, generics: &ast::Generics, )574     pub(crate) fn print_fn(
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 
print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool)591     pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {
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 
print_where_clause(&mut self, where_clause: &ast::WhereClause)599     fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
600         self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates);
601     }
602 
print_where_clause_parts( &mut self, has_where_token: bool, predicates: &[ast::WherePredicate], )603     pub(crate) fn print_where_clause_parts(
604         &mut self,
605         has_where_token: bool,
606         predicates: &[ast::WherePredicate],
607     ) {
608         if predicates.is_empty() && !has_where_token {
609             return;
610         }
611 
612         self.space();
613         self.word_space("where");
614 
615         for (i, predicate) in predicates.iter().enumerate() {
616             if i != 0 {
617                 self.word_space(",");
618             }
619 
620             self.print_where_predicate(predicate);
621         }
622     }
623 
print_where_predicate(&mut self, predicate: &ast::WherePredicate)624     pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
625         match predicate {
626             ast::WherePredicate::BoundPredicate(where_bound_predicate) => {
627                 self.print_where_bound_predicate(where_bound_predicate);
628             }
629             ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
630                 lifetime,
631                 bounds,
632                 ..
633             }) => {
634                 self.print_lifetime(*lifetime);
635                 self.word(":");
636                 if !bounds.is_empty() {
637                     self.nbsp();
638                     self.print_lifetime_bounds(bounds);
639                 }
640             }
641             ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
642                 self.print_type(lhs_ty);
643                 self.space();
644                 self.word_space("=");
645                 self.print_type(rhs_ty);
646             }
647         }
648     }
649 
print_where_bound_predicate( &mut self, where_bound_predicate: &ast::WhereBoundPredicate, )650     pub fn print_where_bound_predicate(
651         &mut self,
652         where_bound_predicate: &ast::WhereBoundPredicate,
653     ) {
654         self.print_formal_generic_params(&where_bound_predicate.bound_generic_params);
655         self.print_type(&where_bound_predicate.bounded_ty);
656         self.word(":");
657         if !where_bound_predicate.bounds.is_empty() {
658             self.nbsp();
659             self.print_type_bounds(&where_bound_predicate.bounds);
660         }
661     }
662 
print_use_tree(&mut self, tree: &ast::UseTree)663     fn print_use_tree(&mut self, tree: &ast::UseTree) {
664         match &tree.kind {
665             ast::UseTreeKind::Simple(rename) => {
666                 self.print_path(&tree.prefix, false, 0);
667                 if let &Some(rename) = rename {
668                     self.nbsp();
669                     self.word_nbsp("as");
670                     self.print_ident(rename);
671                 }
672             }
673             ast::UseTreeKind::Glob => {
674                 if !tree.prefix.segments.is_empty() {
675                     self.print_path(&tree.prefix, false, 0);
676                     self.word("::");
677                 }
678                 self.word("*");
679             }
680             ast::UseTreeKind::Nested(items) => {
681                 if !tree.prefix.segments.is_empty() {
682                     self.print_path(&tree.prefix, false, 0);
683                     self.word("::");
684                 }
685                 if items.is_empty() {
686                     self.word("{}");
687                 } else if items.len() == 1 {
688                     self.print_use_tree(&items[0].0);
689                 } else {
690                     self.cbox(INDENT_UNIT);
691                     self.word("{");
692                     self.zerobreak();
693                     self.ibox(0);
694                     for use_tree in items.iter().delimited() {
695                         self.print_use_tree(&use_tree.0);
696                         if !use_tree.is_last {
697                             self.word(",");
698                             if let ast::UseTreeKind::Nested(_) = use_tree.0.kind {
699                                 self.hardbreak();
700                             } else {
701                                 self.space();
702                             }
703                         }
704                     }
705                     self.end();
706                     self.trailing_comma();
707                     self.offset(-INDENT_UNIT);
708                     self.word("}");
709                     self.end();
710                 }
711             }
712         }
713     }
714 }
715