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