prettyplease/
item.rs

1use crate::algorithm::Printer;
2use crate::fixup::FixupContext;
3use crate::iter::IterDelimited;
4use crate::path::PathKind;
5use crate::INDENT;
6use proc_macro2::TokenStream;
7use syn::{
8    Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic,
9    ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, Item,
10    ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod,
11    ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver,
12    Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro,
13    TraitItemType, Type, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,
14};
15
16impl Printer {
17    pub fn item(&mut self, item: &Item) {
18        match item {
19            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
20            Item::Const(item) => self.item_const(item),
21            Item::Enum(item) => self.item_enum(item),
22            Item::ExternCrate(item) => self.item_extern_crate(item),
23            Item::Fn(item) => self.item_fn(item),
24            Item::ForeignMod(item) => self.item_foreign_mod(item),
25            Item::Impl(item) => self.item_impl(item),
26            Item::Macro(item) => self.item_macro(item),
27            Item::Mod(item) => self.item_mod(item),
28            Item::Static(item) => self.item_static(item),
29            Item::Struct(item) => self.item_struct(item),
30            Item::Trait(item) => self.item_trait(item),
31            Item::TraitAlias(item) => self.item_trait_alias(item),
32            Item::Type(item) => self.item_type(item),
33            Item::Union(item) => self.item_union(item),
34            Item::Use(item) => self.item_use(item),
35            Item::Verbatim(item) => self.item_verbatim(item),
36            _ => unimplemented!("unknown Item"),
37        }
38    }
39
40    fn item_const(&mut self, item: &ItemConst) {
41        self.outer_attrs(&item.attrs);
42        self.cbox(0);
43        self.visibility(&item.vis);
44        self.word("const ");
45        self.ident(&item.ident);
46        self.generics(&item.generics);
47        self.word(": ");
48        self.ty(&item.ty);
49        self.word(" = ");
50        self.neverbreak();
51        self.expr(&item.expr, FixupContext::NONE);
52        self.word(";");
53        self.end();
54        self.hardbreak();
55    }
56
57    fn item_enum(&mut self, item: &ItemEnum) {
58        self.outer_attrs(&item.attrs);
59        self.cbox(INDENT);
60        self.visibility(&item.vis);
61        self.word("enum ");
62        self.ident(&item.ident);
63        self.generics(&item.generics);
64        self.where_clause_for_body(&item.generics.where_clause);
65        self.word("{");
66        self.hardbreak_if_nonempty();
67        for variant in &item.variants {
68            self.variant(variant);
69            self.word(",");
70            self.hardbreak();
71        }
72        self.offset(-INDENT);
73        self.end();
74        self.word("}");
75        self.hardbreak();
76    }
77
78    fn item_extern_crate(&mut self, item: &ItemExternCrate) {
79        self.outer_attrs(&item.attrs);
80        self.visibility(&item.vis);
81        self.word("extern crate ");
82        self.ident(&item.ident);
83        if let Some((_as_token, rename)) = &item.rename {
84            self.word(" as ");
85            self.ident(rename);
86        }
87        self.word(";");
88        self.hardbreak();
89    }
90
91    fn item_fn(&mut self, item: &ItemFn) {
92        self.outer_attrs(&item.attrs);
93        self.cbox(INDENT);
94        self.visibility(&item.vis);
95        self.signature(
96            &item.sig,
97            #[cfg(feature = "verbatim")]
98            &verbatim::Safety::Disallowed,
99        );
100        self.where_clause_for_body(&item.sig.generics.where_clause);
101        self.word("{");
102        self.hardbreak_if_nonempty();
103        self.inner_attrs(&item.attrs);
104        for stmt in &item.block.stmts {
105            self.stmt(stmt);
106        }
107        self.offset(-INDENT);
108        self.end();
109        self.word("}");
110        self.hardbreak();
111    }
112
113    fn item_foreign_mod(&mut self, item: &ItemForeignMod) {
114        self.outer_attrs(&item.attrs);
115        self.cbox(INDENT);
116        if item.unsafety.is_some() {
117            self.word("unsafe ");
118        }
119        self.abi(&item.abi);
120        self.word("{");
121        self.hardbreak_if_nonempty();
122        self.inner_attrs(&item.attrs);
123        for foreign_item in &item.items {
124            self.foreign_item(foreign_item);
125        }
126        self.offset(-INDENT);
127        self.end();
128        self.word("}");
129        self.hardbreak();
130    }
131
132    fn item_impl(&mut self, item: &ItemImpl) {
133        self.outer_attrs(&item.attrs);
134        self.cbox(INDENT);
135        self.ibox(-INDENT);
136        self.cbox(INDENT);
137        if item.defaultness.is_some() {
138            self.word("default ");
139        }
140        if item.unsafety.is_some() {
141            self.word("unsafe ");
142        }
143        self.word("impl");
144        self.generics(&item.generics);
145        self.end();
146        self.nbsp();
147        if let Some((negative_polarity, path, _for_token)) = &item.trait_ {
148            if negative_polarity.is_some() {
149                self.word("!");
150            }
151            self.path(path, PathKind::Type);
152            self.space();
153            self.word("for ");
154        }
155        self.ty(&item.self_ty);
156        self.end();
157        self.where_clause_for_body(&item.generics.where_clause);
158        self.word("{");
159        self.hardbreak_if_nonempty();
160        self.inner_attrs(&item.attrs);
161        for impl_item in &item.items {
162            self.impl_item(impl_item);
163        }
164        self.offset(-INDENT);
165        self.end();
166        self.word("}");
167        self.hardbreak();
168    }
169
170    fn item_macro(&mut self, item: &ItemMacro) {
171        self.outer_attrs(&item.attrs);
172        let semicolon = true;
173        self.mac(&item.mac, item.ident.as_ref(), semicolon);
174        self.hardbreak();
175    }
176
177    fn item_mod(&mut self, item: &ItemMod) {
178        self.outer_attrs(&item.attrs);
179        self.cbox(INDENT);
180        self.visibility(&item.vis);
181        if item.unsafety.is_some() {
182            self.word("unsafe ");
183        }
184        self.word("mod ");
185        self.ident(&item.ident);
186        if let Some((_brace, items)) = &item.content {
187            self.word(" {");
188            self.hardbreak_if_nonempty();
189            self.inner_attrs(&item.attrs);
190            for item in items {
191                self.item(item);
192            }
193            self.offset(-INDENT);
194            self.end();
195            self.word("}");
196        } else {
197            self.word(";");
198            self.end();
199        }
200        self.hardbreak();
201    }
202
203    fn item_static(&mut self, item: &ItemStatic) {
204        self.outer_attrs(&item.attrs);
205        self.cbox(0);
206        self.visibility(&item.vis);
207        self.word("static ");
208        self.static_mutability(&item.mutability);
209        self.ident(&item.ident);
210        self.word(": ");
211        self.ty(&item.ty);
212        self.word(" = ");
213        self.neverbreak();
214        self.expr(&item.expr, FixupContext::NONE);
215        self.word(";");
216        self.end();
217        self.hardbreak();
218    }
219
220    fn item_struct(&mut self, item: &ItemStruct) {
221        self.outer_attrs(&item.attrs);
222        self.cbox(INDENT);
223        self.visibility(&item.vis);
224        self.word("struct ");
225        self.ident(&item.ident);
226        self.generics(&item.generics);
227        match &item.fields {
228            Fields::Named(fields) => {
229                self.where_clause_for_body(&item.generics.where_clause);
230                self.word("{");
231                self.hardbreak_if_nonempty();
232                for field in &fields.named {
233                    self.field(field);
234                    self.word(",");
235                    self.hardbreak();
236                }
237                self.offset(-INDENT);
238                self.end();
239                self.word("}");
240            }
241            Fields::Unnamed(fields) => {
242                self.fields_unnamed(fields);
243                self.where_clause_semi(&item.generics.where_clause);
244                self.end();
245            }
246            Fields::Unit => {
247                self.where_clause_semi(&item.generics.where_clause);
248                self.end();
249            }
250        }
251        self.hardbreak();
252    }
253
254    fn item_trait(&mut self, item: &ItemTrait) {
255        self.outer_attrs(&item.attrs);
256        self.cbox(INDENT);
257        self.visibility(&item.vis);
258        if item.unsafety.is_some() {
259            self.word("unsafe ");
260        }
261        if item.auto_token.is_some() {
262            self.word("auto ");
263        }
264        self.word("trait ");
265        self.ident(&item.ident);
266        self.generics(&item.generics);
267        for supertrait in item.supertraits.iter().delimited() {
268            if supertrait.is_first {
269                self.word(": ");
270            } else {
271                self.word(" + ");
272            }
273            self.type_param_bound(&supertrait);
274        }
275        self.where_clause_for_body(&item.generics.where_clause);
276        self.word("{");
277        self.hardbreak_if_nonempty();
278        self.inner_attrs(&item.attrs);
279        for trait_item in &item.items {
280            self.trait_item(trait_item);
281        }
282        self.offset(-INDENT);
283        self.end();
284        self.word("}");
285        self.hardbreak();
286    }
287
288    fn item_trait_alias(&mut self, item: &ItemTraitAlias) {
289        self.outer_attrs(&item.attrs);
290        self.cbox(INDENT);
291        self.visibility(&item.vis);
292        self.word("trait ");
293        self.ident(&item.ident);
294        self.generics(&item.generics);
295        self.word(" = ");
296        self.neverbreak();
297        for bound in item.bounds.iter().delimited() {
298            if !bound.is_first {
299                self.space();
300                self.word("+ ");
301            }
302            self.type_param_bound(&bound);
303        }
304        self.where_clause_semi(&item.generics.where_clause);
305        self.end();
306        self.hardbreak();
307    }
308
309    fn item_type(&mut self, item: &ItemType) {
310        self.outer_attrs(&item.attrs);
311        self.cbox(INDENT);
312        self.visibility(&item.vis);
313        self.word("type ");
314        self.ident(&item.ident);
315        self.generics(&item.generics);
316        self.where_clause_oneline(&item.generics.where_clause);
317        self.word("= ");
318        self.neverbreak();
319        self.ibox(-INDENT);
320        self.ty(&item.ty);
321        self.end();
322        self.word(";");
323        self.end();
324        self.hardbreak();
325    }
326
327    fn item_union(&mut self, item: &ItemUnion) {
328        self.outer_attrs(&item.attrs);
329        self.cbox(INDENT);
330        self.visibility(&item.vis);
331        self.word("union ");
332        self.ident(&item.ident);
333        self.generics(&item.generics);
334        self.where_clause_for_body(&item.generics.where_clause);
335        self.word("{");
336        self.hardbreak_if_nonempty();
337        for field in &item.fields.named {
338            self.field(field);
339            self.word(",");
340            self.hardbreak();
341        }
342        self.offset(-INDENT);
343        self.end();
344        self.word("}");
345        self.hardbreak();
346    }
347
348    fn item_use(&mut self, item: &ItemUse) {
349        self.outer_attrs(&item.attrs);
350        self.visibility(&item.vis);
351        self.word("use ");
352        if item.leading_colon.is_some() {
353            self.word("::");
354        }
355        self.use_tree(&item.tree);
356        self.word(";");
357        self.hardbreak();
358    }
359
360    #[cfg(not(feature = "verbatim"))]
361    fn item_verbatim(&mut self, item: &TokenStream) {
362        if !item.is_empty() {
363            unimplemented!("Item::Verbatim `{}`", item);
364        }
365        self.hardbreak();
366    }
367
368    #[cfg(feature = "verbatim")]
369    fn item_verbatim(&mut self, tokens: &TokenStream) {
370        use syn::parse::{Parse, ParseStream, Result};
371        use syn::punctuated::Punctuated;
372        use syn::{
373            braced, parenthesized, token, Attribute, Generics, Ident, Lifetime, Token, Visibility,
374        };
375        use verbatim::{
376            FlexibleItemConst, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType,
377            WhereClauseLocation,
378        };
379
380        enum ItemVerbatim {
381            Empty,
382            Ellipsis,
383            ConstFlexible(FlexibleItemConst),
384            FnFlexible(FlexibleItemFn),
385            ImplFlexible(ImplFlexible),
386            Macro2(Macro2),
387            StaticFlexible(FlexibleItemStatic),
388            TypeFlexible(FlexibleItemType),
389            UseBrace(UseBrace),
390        }
391
392        struct ImplFlexible {
393            attrs: Vec<Attribute>,
394            vis: Visibility,
395            defaultness: bool,
396            unsafety: bool,
397            generics: Generics,
398            constness: ImplConstness,
399            negative_impl: bool,
400            trait_: Option<Type>,
401            self_ty: Type,
402            items: Vec<ImplItem>,
403        }
404
405        enum ImplConstness {
406            None,
407            MaybeConst,
408            Const,
409        }
410
411        struct Macro2 {
412            attrs: Vec<Attribute>,
413            vis: Visibility,
414            ident: Ident,
415            args: Option<TokenStream>,
416            body: TokenStream,
417        }
418
419        struct UseBrace {
420            attrs: Vec<Attribute>,
421            vis: Visibility,
422            trees: Punctuated<RootUseTree, Token![,]>,
423        }
424
425        struct RootUseTree {
426            leading_colon: Option<Token![::]>,
427            inner: UseTree,
428        }
429
430        impl Parse for ImplConstness {
431            fn parse(input: ParseStream) -> Result<Self> {
432                if input.parse::<Option<Token![?]>>()?.is_some() {
433                    input.parse::<Token![const]>()?;
434                    Ok(ImplConstness::MaybeConst)
435                } else if input.parse::<Option<Token![const]>>()?.is_some() {
436                    Ok(ImplConstness::Const)
437                } else {
438                    Ok(ImplConstness::None)
439                }
440            }
441        }
442
443        impl Parse for RootUseTree {
444            fn parse(input: ParseStream) -> Result<Self> {
445                Ok(RootUseTree {
446                    leading_colon: input.parse()?,
447                    inner: input.parse()?,
448                })
449            }
450        }
451
452        impl Parse for ItemVerbatim {
453            fn parse(input: ParseStream) -> Result<Self> {
454                if input.is_empty() {
455                    return Ok(ItemVerbatim::Empty);
456                } else if input.peek(Token![...]) {
457                    input.parse::<Token![...]>()?;
458                    return Ok(ItemVerbatim::Ellipsis);
459                }
460
461                let mut attrs = input.call(Attribute::parse_outer)?;
462                let vis: Visibility = input.parse()?;
463
464                let lookahead = input.lookahead1();
465                if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
466                    let defaultness = false;
467                    let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
468                    Ok(ItemVerbatim::ConstFlexible(flexible_item))
469                } else if input.peek(Token![const])
470                    || lookahead.peek(Token![async])
471                    || lookahead.peek(Token![unsafe]) && !input.peek2(Token![impl])
472                    || lookahead.peek(Token![extern])
473                    || lookahead.peek(Token![fn])
474                {
475                    let defaultness = false;
476                    let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
477                    Ok(ItemVerbatim::FnFlexible(flexible_item))
478                } else if lookahead.peek(Token![default])
479                    || input.peek(Token![unsafe])
480                    || lookahead.peek(Token![impl])
481                {
482                    let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
483                    let unsafety = input.parse::<Option<Token![unsafe]>>()?.is_some();
484                    input.parse::<Token![impl]>()?;
485                    let has_generics = input.peek(Token![<])
486                        && (input.peek2(Token![>])
487                            || input.peek2(Token![#])
488                            || (input.peek2(Ident) || input.peek2(Lifetime))
489                                && (input.peek3(Token![:])
490                                    || input.peek3(Token![,])
491                                    || input.peek3(Token![>])
492                                    || input.peek3(Token![=]))
493                            || input.peek2(Token![const]));
494                    let mut generics: Generics = if has_generics {
495                        input.parse()?
496                    } else {
497                        Generics::default()
498                    };
499                    let constness: ImplConstness = input.parse()?;
500                    let negative_impl =
501                        !input.peek2(token::Brace) && input.parse::<Option<Token![!]>>()?.is_some();
502                    let first_ty: Type = input.parse()?;
503                    let (trait_, self_ty) = if input.parse::<Option<Token![for]>>()?.is_some() {
504                        (Some(first_ty), input.parse()?)
505                    } else {
506                        (None, first_ty)
507                    };
508                    generics.where_clause = input.parse()?;
509                    let content;
510                    braced!(content in input);
511                    let inner_attrs = content.call(Attribute::parse_inner)?;
512                    attrs.extend(inner_attrs);
513                    let mut items = Vec::new();
514                    while !content.is_empty() {
515                        items.push(content.parse()?);
516                    }
517                    Ok(ItemVerbatim::ImplFlexible(ImplFlexible {
518                        attrs,
519                        vis,
520                        defaultness,
521                        unsafety,
522                        generics,
523                        constness,
524                        negative_impl,
525                        trait_,
526                        self_ty,
527                        items,
528                    }))
529                } else if lookahead.peek(Token![macro]) {
530                    input.parse::<Token![macro]>()?;
531                    let ident: Ident = input.parse()?;
532                    let args = if input.peek(token::Paren) {
533                        let paren_content;
534                        parenthesized!(paren_content in input);
535                        Some(paren_content.parse::<TokenStream>()?)
536                    } else {
537                        None
538                    };
539                    let brace_content;
540                    braced!(brace_content in input);
541                    let body: TokenStream = brace_content.parse()?;
542                    Ok(ItemVerbatim::Macro2(Macro2 {
543                        attrs,
544                        vis,
545                        ident,
546                        args,
547                        body,
548                    }))
549                } else if lookahead.peek(Token![static]) {
550                    let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?;
551                    Ok(ItemVerbatim::StaticFlexible(flexible_item))
552                } else if lookahead.peek(Token![type]) {
553                    let defaultness = false;
554                    let flexible_item = FlexibleItemType::parse(
555                        attrs,
556                        vis,
557                        defaultness,
558                        input,
559                        WhereClauseLocation::BeforeEq,
560                    )?;
561                    Ok(ItemVerbatim::TypeFlexible(flexible_item))
562                } else if lookahead.peek(Token![use]) {
563                    input.parse::<Token![use]>()?;
564                    let content;
565                    braced!(content in input);
566                    let trees = content.parse_terminated(RootUseTree::parse, Token![,])?;
567                    input.parse::<Token![;]>()?;
568                    Ok(ItemVerbatim::UseBrace(UseBrace { attrs, vis, trees }))
569                } else {
570                    Err(lookahead.error())
571                }
572            }
573        }
574
575        let item: ItemVerbatim = match syn::parse2(tokens.clone()) {
576            Ok(item) => item,
577            Err(_) => unimplemented!("Item::Verbatim `{}`", tokens),
578        };
579
580        match item {
581            ItemVerbatim::Empty => {
582                self.hardbreak();
583            }
584            ItemVerbatim::Ellipsis => {
585                self.word("...");
586                self.hardbreak();
587            }
588            ItemVerbatim::ConstFlexible(item) => {
589                self.flexible_item_const(&item);
590            }
591            ItemVerbatim::FnFlexible(item) => {
592                self.flexible_item_fn(&item);
593            }
594            ItemVerbatim::ImplFlexible(item) => {
595                self.outer_attrs(&item.attrs);
596                self.cbox(INDENT);
597                self.ibox(-INDENT);
598                self.cbox(INDENT);
599                self.visibility(&item.vis);
600                if item.defaultness {
601                    self.word("default ");
602                }
603                if item.unsafety {
604                    self.word("unsafe ");
605                }
606                self.word("impl");
607                self.generics(&item.generics);
608                self.end();
609                self.nbsp();
610                match item.constness {
611                    ImplConstness::None => {}
612                    ImplConstness::MaybeConst => self.word("?const "),
613                    ImplConstness::Const => self.word("const "),
614                }
615                if item.negative_impl {
616                    self.word("!");
617                }
618                if let Some(trait_) = &item.trait_ {
619                    self.ty(trait_);
620                    self.space();
621                    self.word("for ");
622                }
623                self.ty(&item.self_ty);
624                self.end();
625                self.where_clause_for_body(&item.generics.where_clause);
626                self.word("{");
627                self.hardbreak_if_nonempty();
628                self.inner_attrs(&item.attrs);
629                for impl_item in &item.items {
630                    self.impl_item(impl_item);
631                }
632                self.offset(-INDENT);
633                self.end();
634                self.word("}");
635                self.hardbreak();
636            }
637            ItemVerbatim::Macro2(item) => {
638                self.outer_attrs(&item.attrs);
639                self.visibility(&item.vis);
640                self.word("macro ");
641                self.ident(&item.ident);
642                if let Some(args) = &item.args {
643                    self.word("(");
644                    self.cbox(INDENT);
645                    self.zerobreak();
646                    self.ibox(0);
647                    self.macro_rules_tokens(args.clone(), true);
648                    self.end();
649                    self.zerobreak();
650                    self.offset(-INDENT);
651                    self.end();
652                    self.word(")");
653                }
654                self.word(" {");
655                if !item.body.is_empty() {
656                    self.neverbreak();
657                    self.cbox(INDENT);
658                    self.hardbreak();
659                    self.ibox(0);
660                    self.macro_rules_tokens(item.body.clone(), false);
661                    self.end();
662                    self.hardbreak();
663                    self.offset(-INDENT);
664                    self.end();
665                }
666                self.word("}");
667                self.hardbreak();
668            }
669            ItemVerbatim::StaticFlexible(item) => {
670                self.flexible_item_static(&item);
671            }
672            ItemVerbatim::TypeFlexible(item) => {
673                self.flexible_item_type(&item);
674            }
675            ItemVerbatim::UseBrace(item) => {
676                self.outer_attrs(&item.attrs);
677                self.visibility(&item.vis);
678                self.word("use ");
679                if item.trees.len() == 1 {
680                    self.word("::");
681                    self.use_tree(&item.trees[0].inner);
682                } else {
683                    self.cbox(INDENT);
684                    self.word("{");
685                    self.zerobreak();
686                    self.ibox(0);
687                    for use_tree in item.trees.iter().delimited() {
688                        if use_tree.leading_colon.is_some() {
689                            self.word("::");
690                        }
691                        self.use_tree(&use_tree.inner);
692                        if !use_tree.is_last {
693                            self.word(",");
694                            let mut use_tree = &use_tree.inner;
695                            while let UseTree::Path(use_path) = use_tree {
696                                use_tree = &use_path.tree;
697                            }
698                            if let UseTree::Group(_) = use_tree {
699                                self.hardbreak();
700                            } else {
701                                self.space();
702                            }
703                        }
704                    }
705                    self.end();
706                    self.trailing_comma(true);
707                    self.offset(-INDENT);
708                    self.word("}");
709                    self.end();
710                }
711                self.word(";");
712                self.hardbreak();
713            }
714        }
715    }
716
717    fn use_tree(&mut self, use_tree: &UseTree) {
718        match use_tree {
719            UseTree::Path(use_path) => self.use_path(use_path),
720            UseTree::Name(use_name) => self.use_name(use_name),
721            UseTree::Rename(use_rename) => self.use_rename(use_rename),
722            UseTree::Glob(use_glob) => self.use_glob(use_glob),
723            UseTree::Group(use_group) => self.use_group(use_group),
724        }
725    }
726
727    fn use_path(&mut self, use_path: &UsePath) {
728        self.ident(&use_path.ident);
729        self.word("::");
730        self.use_tree(&use_path.tree);
731    }
732
733    fn use_name(&mut self, use_name: &UseName) {
734        self.ident(&use_name.ident);
735    }
736
737    fn use_rename(&mut self, use_rename: &UseRename) {
738        self.ident(&use_rename.ident);
739        self.word(" as ");
740        self.ident(&use_rename.rename);
741    }
742
743    fn use_glob(&mut self, use_glob: &UseGlob) {
744        let _ = use_glob;
745        self.word("*");
746    }
747
748    fn use_group(&mut self, use_group: &UseGroup) {
749        if use_group.items.is_empty() {
750            self.word("{}");
751        } else if use_group.items.len() == 1
752            && match &use_group.items[0] {
753                UseTree::Rename(use_rename) => use_rename.ident != "self",
754                _ => true,
755            }
756        {
757            self.use_tree(&use_group.items[0]);
758        } else {
759            self.cbox(INDENT);
760            self.word("{");
761            self.zerobreak();
762            self.ibox(0);
763            for use_tree in use_group.items.iter().delimited() {
764                self.use_tree(&use_tree);
765                if !use_tree.is_last {
766                    self.word(",");
767                    let mut use_tree = *use_tree;
768                    while let UseTree::Path(use_path) = use_tree {
769                        use_tree = &use_path.tree;
770                    }
771                    if let UseTree::Group(_) = use_tree {
772                        self.hardbreak();
773                    } else {
774                        self.space();
775                    }
776                }
777            }
778            self.end();
779            self.trailing_comma(true);
780            self.offset(-INDENT);
781            self.word("}");
782            self.end();
783        }
784    }
785
786    fn foreign_item(&mut self, foreign_item: &ForeignItem) {
787        match foreign_item {
788            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
789            ForeignItem::Fn(item) => self.foreign_item_fn(item),
790            ForeignItem::Static(item) => self.foreign_item_static(item),
791            ForeignItem::Type(item) => self.foreign_item_type(item),
792            ForeignItem::Macro(item) => self.foreign_item_macro(item),
793            ForeignItem::Verbatim(item) => self.foreign_item_verbatim(item),
794            _ => unimplemented!("unknown ForeignItem"),
795        }
796    }
797
798    fn foreign_item_fn(&mut self, foreign_item: &ForeignItemFn) {
799        self.outer_attrs(&foreign_item.attrs);
800        self.cbox(INDENT);
801        self.visibility(&foreign_item.vis);
802        self.signature(
803            &foreign_item.sig,
804            #[cfg(feature = "verbatim")]
805            &verbatim::Safety::Disallowed,
806        );
807        self.where_clause_semi(&foreign_item.sig.generics.where_clause);
808        self.end();
809        self.hardbreak();
810    }
811
812    fn foreign_item_static(&mut self, foreign_item: &ForeignItemStatic) {
813        self.outer_attrs(&foreign_item.attrs);
814        self.cbox(0);
815        self.visibility(&foreign_item.vis);
816        self.word("static ");
817        self.static_mutability(&foreign_item.mutability);
818        self.ident(&foreign_item.ident);
819        self.word(": ");
820        self.ty(&foreign_item.ty);
821        self.word(";");
822        self.end();
823        self.hardbreak();
824    }
825
826    fn foreign_item_type(&mut self, foreign_item: &ForeignItemType) {
827        self.outer_attrs(&foreign_item.attrs);
828        self.cbox(0);
829        self.visibility(&foreign_item.vis);
830        self.word("type ");
831        self.ident(&foreign_item.ident);
832        self.generics(&foreign_item.generics);
833        self.word(";");
834        self.end();
835        self.hardbreak();
836    }
837
838    fn foreign_item_macro(&mut self, foreign_item: &ForeignItemMacro) {
839        self.outer_attrs(&foreign_item.attrs);
840        let semicolon = true;
841        self.mac(&foreign_item.mac, None, semicolon);
842        self.hardbreak();
843    }
844
845    #[cfg(not(feature = "verbatim"))]
846    fn foreign_item_verbatim(&mut self, foreign_item: &TokenStream) {
847        if !foreign_item.is_empty() {
848            unimplemented!("ForeignItem::Verbatim `{}`", foreign_item);
849        }
850        self.hardbreak();
851    }
852
853    #[cfg(feature = "verbatim")]
854    fn foreign_item_verbatim(&mut self, tokens: &TokenStream) {
855        use syn::parse::{Parse, ParseStream, Result};
856        use syn::{Abi, Attribute, Token, Visibility};
857        use verbatim::{
858            kw, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, WhereClauseLocation,
859        };
860
861        enum ForeignItemVerbatim {
862            Empty,
863            Ellipsis,
864            FnFlexible(FlexibleItemFn),
865            StaticFlexible(FlexibleItemStatic),
866            TypeFlexible(FlexibleItemType),
867        }
868
869        fn peek_signature(input: ParseStream) -> bool {
870            let fork = input.fork();
871            fork.parse::<Option<Token![const]>>().is_ok()
872                && fork.parse::<Option<Token![async]>>().is_ok()
873                && ((fork.peek(kw::safe) && fork.parse::<kw::safe>().is_ok())
874                    || fork.parse::<Option<Token![unsafe]>>().is_ok())
875                && fork.parse::<Option<Abi>>().is_ok()
876                && fork.peek(Token![fn])
877        }
878
879        impl Parse for ForeignItemVerbatim {
880            fn parse(input: ParseStream) -> Result<Self> {
881                if input.is_empty() {
882                    return Ok(ForeignItemVerbatim::Empty);
883                } else if input.peek(Token![...]) {
884                    input.parse::<Token![...]>()?;
885                    return Ok(ForeignItemVerbatim::Ellipsis);
886                }
887
888                let attrs = input.call(Attribute::parse_outer)?;
889                let vis: Visibility = input.parse()?;
890                let defaultness = false;
891
892                let lookahead = input.lookahead1();
893                if lookahead.peek(Token![fn]) || peek_signature(input) {
894                    let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
895                    Ok(ForeignItemVerbatim::FnFlexible(flexible_item))
896                } else if lookahead.peek(Token![static])
897                    || ((input.peek(Token![unsafe]) || input.peek(kw::safe))
898                        && input.peek2(Token![static]))
899                {
900                    let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?;
901                    Ok(ForeignItemVerbatim::StaticFlexible(flexible_item))
902                } else if lookahead.peek(Token![type]) {
903                    let flexible_item = FlexibleItemType::parse(
904                        attrs,
905                        vis,
906                        defaultness,
907                        input,
908                        WhereClauseLocation::Both,
909                    )?;
910                    Ok(ForeignItemVerbatim::TypeFlexible(flexible_item))
911                } else {
912                    Err(lookahead.error())
913                }
914            }
915        }
916
917        let foreign_item: ForeignItemVerbatim = match syn::parse2(tokens.clone()) {
918            Ok(foreign_item) => foreign_item,
919            Err(_) => unimplemented!("ForeignItem::Verbatim `{}`", tokens),
920        };
921
922        match foreign_item {
923            ForeignItemVerbatim::Empty => {
924                self.hardbreak();
925            }
926            ForeignItemVerbatim::Ellipsis => {
927                self.word("...");
928                self.hardbreak();
929            }
930            ForeignItemVerbatim::FnFlexible(foreign_item) => {
931                self.flexible_item_fn(&foreign_item);
932            }
933            ForeignItemVerbatim::StaticFlexible(foreign_item) => {
934                self.flexible_item_static(&foreign_item);
935            }
936            ForeignItemVerbatim::TypeFlexible(foreign_item) => {
937                self.flexible_item_type(&foreign_item);
938            }
939        }
940    }
941
942    fn trait_item(&mut self, trait_item: &TraitItem) {
943        match trait_item {
944            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
945            TraitItem::Const(item) => self.trait_item_const(item),
946            TraitItem::Fn(item) => self.trait_item_fn(item),
947            TraitItem::Type(item) => self.trait_item_type(item),
948            TraitItem::Macro(item) => self.trait_item_macro(item),
949            TraitItem::Verbatim(item) => self.trait_item_verbatim(item),
950            _ => unimplemented!("unknown TraitItem"),
951        }
952    }
953
954    fn trait_item_const(&mut self, trait_item: &TraitItemConst) {
955        self.outer_attrs(&trait_item.attrs);
956        self.cbox(0);
957        self.word("const ");
958        self.ident(&trait_item.ident);
959        self.generics(&trait_item.generics);
960        self.word(": ");
961        self.ty(&trait_item.ty);
962        if let Some((_eq_token, default)) = &trait_item.default {
963            self.word(" = ");
964            self.neverbreak();
965            self.expr(default, FixupContext::NONE);
966        }
967        self.word(";");
968        self.end();
969        self.hardbreak();
970    }
971
972    fn trait_item_fn(&mut self, trait_item: &TraitItemFn) {
973        self.outer_attrs(&trait_item.attrs);
974        self.cbox(INDENT);
975        self.signature(
976            &trait_item.sig,
977            #[cfg(feature = "verbatim")]
978            &verbatim::Safety::Disallowed,
979        );
980        if let Some(block) = &trait_item.default {
981            self.where_clause_for_body(&trait_item.sig.generics.where_clause);
982            self.word("{");
983            self.hardbreak_if_nonempty();
984            self.inner_attrs(&trait_item.attrs);
985            for stmt in &block.stmts {
986                self.stmt(stmt);
987            }
988            self.offset(-INDENT);
989            self.end();
990            self.word("}");
991        } else {
992            self.where_clause_semi(&trait_item.sig.generics.where_clause);
993            self.end();
994        }
995        self.hardbreak();
996    }
997
998    fn trait_item_type(&mut self, trait_item: &TraitItemType) {
999        self.outer_attrs(&trait_item.attrs);
1000        self.cbox(INDENT);
1001        self.word("type ");
1002        self.ident(&trait_item.ident);
1003        self.generics(&trait_item.generics);
1004        for bound in trait_item.bounds.iter().delimited() {
1005            if bound.is_first {
1006                self.word(": ");
1007            } else {
1008                self.space();
1009                self.word("+ ");
1010            }
1011            self.type_param_bound(&bound);
1012        }
1013        if let Some((_eq_token, default)) = &trait_item.default {
1014            self.word(" = ");
1015            self.neverbreak();
1016            self.ibox(-INDENT);
1017            self.ty(default);
1018            self.end();
1019        }
1020        self.where_clause_oneline_semi(&trait_item.generics.where_clause);
1021        self.end();
1022        self.hardbreak();
1023    }
1024
1025    fn trait_item_macro(&mut self, trait_item: &TraitItemMacro) {
1026        self.outer_attrs(&trait_item.attrs);
1027        let semicolon = true;
1028        self.mac(&trait_item.mac, None, semicolon);
1029        self.hardbreak();
1030    }
1031
1032    #[cfg(not(feature = "verbatim"))]
1033    fn trait_item_verbatim(&mut self, trait_item: &TokenStream) {
1034        if !trait_item.is_empty() {
1035            unimplemented!("TraitItem::Verbatim `{}`", trait_item);
1036        }
1037        self.hardbreak();
1038    }
1039
1040    #[cfg(feature = "verbatim")]
1041    fn trait_item_verbatim(&mut self, tokens: &TokenStream) {
1042        use syn::parse::{Parse, ParseStream, Result};
1043        use syn::{Attribute, Ident, Token, Visibility};
1044        use verbatim::{FlexibleItemConst, FlexibleItemType, WhereClauseLocation};
1045
1046        enum TraitItemVerbatim {
1047            Empty,
1048            Ellipsis,
1049            ConstFlexible(FlexibleItemConst),
1050            TypeFlexible(FlexibleItemType),
1051            PubOrDefault(PubOrDefaultTraitItem),
1052        }
1053
1054        struct PubOrDefaultTraitItem {
1055            attrs: Vec<Attribute>,
1056            vis: Visibility,
1057            defaultness: bool,
1058            trait_item: TraitItem,
1059        }
1060
1061        impl Parse for TraitItemVerbatim {
1062            fn parse(input: ParseStream) -> Result<Self> {
1063                if input.is_empty() {
1064                    return Ok(TraitItemVerbatim::Empty);
1065                } else if input.peek(Token![...]) {
1066                    input.parse::<Token![...]>()?;
1067                    return Ok(TraitItemVerbatim::Ellipsis);
1068                }
1069
1070                let attrs = input.call(Attribute::parse_outer)?;
1071                let vis: Visibility = input.parse()?;
1072                let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
1073
1074                let lookahead = input.lookahead1();
1075                if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
1076                    let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
1077                    Ok(TraitItemVerbatim::ConstFlexible(flexible_item))
1078                } else if lookahead.peek(Token![type]) {
1079                    let flexible_item = FlexibleItemType::parse(
1080                        attrs,
1081                        vis,
1082                        defaultness,
1083                        input,
1084                        WhereClauseLocation::AfterEq,
1085                    )?;
1086                    Ok(TraitItemVerbatim::TypeFlexible(flexible_item))
1087                } else if (input.peek(Token![const])
1088                    || lookahead.peek(Token![async])
1089                    || lookahead.peek(Token![unsafe])
1090                    || lookahead.peek(Token![extern])
1091                    || lookahead.peek(Token![fn]))
1092                    && (!matches!(vis, Visibility::Inherited) || defaultness)
1093                {
1094                    Ok(TraitItemVerbatim::PubOrDefault(PubOrDefaultTraitItem {
1095                        attrs,
1096                        vis,
1097                        defaultness,
1098                        trait_item: input.parse()?,
1099                    }))
1100                } else {
1101                    Err(lookahead.error())
1102                }
1103            }
1104        }
1105
1106        let impl_item: TraitItemVerbatim = match syn::parse2(tokens.clone()) {
1107            Ok(impl_item) => impl_item,
1108            Err(_) => unimplemented!("TraitItem::Verbatim `{}`", tokens),
1109        };
1110
1111        match impl_item {
1112            TraitItemVerbatim::Empty => {
1113                self.hardbreak();
1114            }
1115            TraitItemVerbatim::Ellipsis => {
1116                self.word("...");
1117                self.hardbreak();
1118            }
1119            TraitItemVerbatim::ConstFlexible(trait_item) => {
1120                self.flexible_item_const(&trait_item);
1121            }
1122            TraitItemVerbatim::TypeFlexible(trait_item) => {
1123                self.flexible_item_type(&trait_item);
1124            }
1125            TraitItemVerbatim::PubOrDefault(trait_item) => {
1126                self.outer_attrs(&trait_item.attrs);
1127                self.visibility(&trait_item.vis);
1128                if trait_item.defaultness {
1129                    self.word("default ");
1130                }
1131                self.trait_item(&trait_item.trait_item);
1132            }
1133        }
1134    }
1135
1136    fn impl_item(&mut self, impl_item: &ImplItem) {
1137        match impl_item {
1138            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1139            ImplItem::Const(item) => self.impl_item_const(item),
1140            ImplItem::Fn(item) => self.impl_item_fn(item),
1141            ImplItem::Type(item) => self.impl_item_type(item),
1142            ImplItem::Macro(item) => self.impl_item_macro(item),
1143            ImplItem::Verbatim(item) => self.impl_item_verbatim(item),
1144            _ => unimplemented!("unknown ImplItem"),
1145        }
1146    }
1147
1148    fn impl_item_const(&mut self, impl_item: &ImplItemConst) {
1149        self.outer_attrs(&impl_item.attrs);
1150        self.cbox(0);
1151        self.visibility(&impl_item.vis);
1152        if impl_item.defaultness.is_some() {
1153            self.word("default ");
1154        }
1155        self.word("const ");
1156        self.ident(&impl_item.ident);
1157        self.generics(&impl_item.generics);
1158        self.word(": ");
1159        self.ty(&impl_item.ty);
1160        self.word(" = ");
1161        self.neverbreak();
1162        self.expr(&impl_item.expr, FixupContext::NONE);
1163        self.word(";");
1164        self.end();
1165        self.hardbreak();
1166    }
1167
1168    fn impl_item_fn(&mut self, impl_item: &ImplItemFn) {
1169        self.outer_attrs(&impl_item.attrs);
1170        self.cbox(INDENT);
1171        self.visibility(&impl_item.vis);
1172        if impl_item.defaultness.is_some() {
1173            self.word("default ");
1174        }
1175        self.signature(
1176            &impl_item.sig,
1177            #[cfg(feature = "verbatim")]
1178            &verbatim::Safety::Disallowed,
1179        );
1180        self.where_clause_for_body(&impl_item.sig.generics.where_clause);
1181        self.word("{");
1182        self.hardbreak_if_nonempty();
1183        self.inner_attrs(&impl_item.attrs);
1184        for stmt in &impl_item.block.stmts {
1185            self.stmt(stmt);
1186        }
1187        self.offset(-INDENT);
1188        self.end();
1189        self.word("}");
1190        self.hardbreak();
1191    }
1192
1193    fn impl_item_type(&mut self, impl_item: &ImplItemType) {
1194        self.outer_attrs(&impl_item.attrs);
1195        self.cbox(INDENT);
1196        self.visibility(&impl_item.vis);
1197        if impl_item.defaultness.is_some() {
1198            self.word("default ");
1199        }
1200        self.word("type ");
1201        self.ident(&impl_item.ident);
1202        self.generics(&impl_item.generics);
1203        self.word(" = ");
1204        self.neverbreak();
1205        self.ibox(-INDENT);
1206        self.ty(&impl_item.ty);
1207        self.end();
1208        self.where_clause_oneline_semi(&impl_item.generics.where_clause);
1209        self.end();
1210        self.hardbreak();
1211    }
1212
1213    fn impl_item_macro(&mut self, impl_item: &ImplItemMacro) {
1214        self.outer_attrs(&impl_item.attrs);
1215        let semicolon = true;
1216        self.mac(&impl_item.mac, None, semicolon);
1217        self.hardbreak();
1218    }
1219
1220    #[cfg(not(feature = "verbatim"))]
1221    fn impl_item_verbatim(&mut self, impl_item: &TokenStream) {
1222        if !impl_item.is_empty() {
1223            unimplemented!("ImplItem::Verbatim `{}`", impl_item);
1224        }
1225        self.hardbreak();
1226    }
1227
1228    #[cfg(feature = "verbatim")]
1229    fn impl_item_verbatim(&mut self, tokens: &TokenStream) {
1230        use syn::parse::{Parse, ParseStream, Result};
1231        use syn::{Attribute, Ident, Token, Visibility};
1232        use verbatim::{FlexibleItemConst, FlexibleItemFn, FlexibleItemType, WhereClauseLocation};
1233
1234        enum ImplItemVerbatim {
1235            Empty,
1236            Ellipsis,
1237            ConstFlexible(FlexibleItemConst),
1238            FnFlexible(FlexibleItemFn),
1239            TypeFlexible(FlexibleItemType),
1240        }
1241
1242        impl Parse for ImplItemVerbatim {
1243            fn parse(input: ParseStream) -> Result<Self> {
1244                if input.is_empty() {
1245                    return Ok(ImplItemVerbatim::Empty);
1246                } else if input.peek(Token![...]) {
1247                    input.parse::<Token![...]>()?;
1248                    return Ok(ImplItemVerbatim::Ellipsis);
1249                }
1250
1251                let attrs = input.call(Attribute::parse_outer)?;
1252                let vis: Visibility = input.parse()?;
1253                let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
1254
1255                let lookahead = input.lookahead1();
1256                if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
1257                    let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
1258                    Ok(ImplItemVerbatim::ConstFlexible(flexible_item))
1259                } else if input.peek(Token![const])
1260                    || lookahead.peek(Token![async])
1261                    || lookahead.peek(Token![unsafe])
1262                    || lookahead.peek(Token![extern])
1263                    || lookahead.peek(Token![fn])
1264                {
1265                    let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
1266                    Ok(ImplItemVerbatim::FnFlexible(flexible_item))
1267                } else if lookahead.peek(Token![type]) {
1268                    let flexible_item = FlexibleItemType::parse(
1269                        attrs,
1270                        vis,
1271                        defaultness,
1272                        input,
1273                        WhereClauseLocation::AfterEq,
1274                    )?;
1275                    Ok(ImplItemVerbatim::TypeFlexible(flexible_item))
1276                } else {
1277                    Err(lookahead.error())
1278                }
1279            }
1280        }
1281
1282        let impl_item: ImplItemVerbatim = match syn::parse2(tokens.clone()) {
1283            Ok(impl_item) => impl_item,
1284            Err(_) => unimplemented!("ImplItem::Verbatim `{}`", tokens),
1285        };
1286
1287        match impl_item {
1288            ImplItemVerbatim::Empty => {
1289                self.hardbreak();
1290            }
1291            ImplItemVerbatim::Ellipsis => {
1292                self.word("...");
1293                self.hardbreak();
1294            }
1295            ImplItemVerbatim::ConstFlexible(impl_item) => {
1296                self.flexible_item_const(&impl_item);
1297            }
1298            ImplItemVerbatim::FnFlexible(impl_item) => {
1299                self.flexible_item_fn(&impl_item);
1300            }
1301            ImplItemVerbatim::TypeFlexible(impl_item) => {
1302                self.flexible_item_type(&impl_item);
1303            }
1304        }
1305    }
1306
1307    fn signature(
1308        &mut self,
1309        signature: &Signature,
1310        #[cfg(feature = "verbatim")] safety: &verbatim::Safety,
1311    ) {
1312        if signature.constness.is_some() {
1313            self.word("const ");
1314        }
1315        if signature.asyncness.is_some() {
1316            self.word("async ");
1317        }
1318        #[cfg(feature = "verbatim")]
1319        {
1320            if let verbatim::Safety::Disallowed = safety {
1321                if signature.unsafety.is_some() {
1322                    self.word("unsafe ");
1323                }
1324            } else {
1325                self.safety(safety);
1326            }
1327        }
1328        #[cfg(not(feature = "verbatim"))]
1329        {
1330            if signature.unsafety.is_some() {
1331                self.word("unsafe ");
1332            }
1333        }
1334        if let Some(abi) = &signature.abi {
1335            self.abi(abi);
1336        }
1337        self.word("fn ");
1338        self.ident(&signature.ident);
1339        self.generics(&signature.generics);
1340        self.word("(");
1341        self.neverbreak();
1342        self.cbox(0);
1343        self.zerobreak();
1344        for input in signature.inputs.iter().delimited() {
1345            self.fn_arg(&input);
1346            let is_last = input.is_last && signature.variadic.is_none();
1347            self.trailing_comma(is_last);
1348        }
1349        if let Some(variadic) = &signature.variadic {
1350            self.variadic(variadic);
1351            self.zerobreak();
1352        }
1353        self.offset(-INDENT);
1354        self.end();
1355        self.word(")");
1356        self.cbox(-INDENT);
1357        self.return_type(&signature.output);
1358        self.end();
1359    }
1360
1361    fn fn_arg(&mut self, fn_arg: &FnArg) {
1362        match fn_arg {
1363            FnArg::Receiver(receiver) => self.receiver(receiver),
1364            FnArg::Typed(pat_type) => self.pat_type(pat_type),
1365        }
1366    }
1367
1368    fn receiver(&mut self, receiver: &Receiver) {
1369        self.outer_attrs(&receiver.attrs);
1370        if let Some((_ampersand, lifetime)) = &receiver.reference {
1371            self.word("&");
1372            if let Some(lifetime) = lifetime {
1373                self.lifetime(lifetime);
1374                self.nbsp();
1375            }
1376        }
1377        if receiver.mutability.is_some() {
1378            self.word("mut ");
1379        }
1380        self.word("self");
1381        if receiver.colon_token.is_some() {
1382            self.word(": ");
1383            self.ty(&receiver.ty);
1384        } else {
1385            let consistent = match (&receiver.reference, &receiver.mutability, &*receiver.ty) {
1386                (Some(_), mutability, Type::Reference(ty)) => {
1387                    mutability.is_some() == ty.mutability.is_some()
1388                        && match &*ty.elem {
1389                            Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self"),
1390                            _ => false,
1391                        }
1392                }
1393                (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"),
1394                _ => false,
1395            };
1396            if !consistent {
1397                self.word(": ");
1398                self.ty(&receiver.ty);
1399            }
1400        }
1401    }
1402
1403    fn variadic(&mut self, variadic: &Variadic) {
1404        self.outer_attrs(&variadic.attrs);
1405        if let Some((pat, _colon)) = &variadic.pat {
1406            self.pat(pat);
1407            self.word(": ");
1408        }
1409        self.word("...");
1410    }
1411
1412    fn static_mutability(&mut self, mutability: &StaticMutability) {
1413        match mutability {
1414            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1415            StaticMutability::Mut(_) => self.word("mut "),
1416            StaticMutability::None => {}
1417            _ => unimplemented!("unknown StaticMutability"),
1418        }
1419    }
1420}
1421
1422#[cfg(feature = "verbatim")]
1423mod verbatim {
1424    use crate::algorithm::Printer;
1425    use crate::fixup::FixupContext;
1426    use crate::iter::IterDelimited;
1427    use crate::INDENT;
1428    use syn::ext::IdentExt;
1429    use syn::parse::{Parse, ParseStream, Result};
1430    use syn::{
1431        braced, token, Attribute, Block, Expr, Generics, Ident, Signature, StaticMutability, Stmt,
1432        Token, Type, TypeParamBound, Visibility, WhereClause,
1433    };
1434
1435    pub mod kw {
1436        syn::custom_keyword!(safe);
1437    }
1438
1439    pub struct FlexibleItemConst {
1440        pub attrs: Vec<Attribute>,
1441        pub vis: Visibility,
1442        pub defaultness: bool,
1443        pub ident: Ident,
1444        pub generics: Generics,
1445        pub ty: Type,
1446        pub value: Option<Expr>,
1447    }
1448
1449    pub struct FlexibleItemFn {
1450        pub attrs: Vec<Attribute>,
1451        pub vis: Visibility,
1452        pub defaultness: bool,
1453        pub safety: Safety,
1454        pub sig: Signature,
1455        pub body: Option<Vec<Stmt>>,
1456    }
1457
1458    pub struct FlexibleItemStatic {
1459        pub attrs: Vec<Attribute>,
1460        pub vis: Visibility,
1461        pub safety: Safety,
1462        pub mutability: StaticMutability,
1463        pub ident: Ident,
1464        pub ty: Option<Type>,
1465        pub expr: Option<Expr>,
1466    }
1467
1468    pub struct FlexibleItemType {
1469        pub attrs: Vec<Attribute>,
1470        pub vis: Visibility,
1471        pub defaultness: bool,
1472        pub ident: Ident,
1473        pub generics: Generics,
1474        pub bounds: Vec<TypeParamBound>,
1475        pub definition: Option<Type>,
1476        pub where_clause_after_eq: Option<WhereClause>,
1477    }
1478
1479    pub enum Safety {
1480        Unsafe,
1481        Safe,
1482        Default,
1483        Disallowed,
1484    }
1485
1486    pub enum WhereClauseLocation {
1487        // type Ty<T> where T: 'static = T;
1488        BeforeEq,
1489        // type Ty<T> = T where T: 'static;
1490        AfterEq,
1491        // TODO: goes away once the migration period on rust-lang/rust#89122 is over
1492        Both,
1493    }
1494
1495    impl FlexibleItemConst {
1496        pub fn parse(
1497            attrs: Vec<Attribute>,
1498            vis: Visibility,
1499            defaultness: bool,
1500            input: ParseStream,
1501        ) -> Result<Self> {
1502            input.parse::<Token![const]>()?;
1503            let ident = input.call(Ident::parse_any)?;
1504            let mut generics: Generics = input.parse()?;
1505            input.parse::<Token![:]>()?;
1506            let ty: Type = input.parse()?;
1507            let value = if input.parse::<Option<Token![=]>>()?.is_some() {
1508                let expr: Expr = input.parse()?;
1509                Some(expr)
1510            } else {
1511                None
1512            };
1513            generics.where_clause = input.parse()?;
1514            input.parse::<Token![;]>()?;
1515
1516            Ok(FlexibleItemConst {
1517                attrs,
1518                vis,
1519                defaultness,
1520                ident,
1521                generics,
1522                ty,
1523                value,
1524            })
1525        }
1526    }
1527
1528    impl FlexibleItemFn {
1529        pub fn parse(
1530            mut attrs: Vec<Attribute>,
1531            vis: Visibility,
1532            defaultness: bool,
1533            input: ParseStream,
1534        ) -> Result<Self> {
1535            let constness: Option<Token![const]> = input.parse()?;
1536            let asyncness: Option<Token![async]> = input.parse()?;
1537            let safety: Safety = input.parse()?;
1538
1539            let lookahead = input.lookahead1();
1540            let sig: Signature = if lookahead.peek(Token![extern]) || lookahead.peek(Token![fn]) {
1541                input.parse()?
1542            } else {
1543                return Err(lookahead.error());
1544            };
1545
1546            let lookahead = input.lookahead1();
1547            let body = if lookahead.peek(Token![;]) {
1548                input.parse::<Token![;]>()?;
1549                None
1550            } else if lookahead.peek(token::Brace) {
1551                let content;
1552                braced!(content in input);
1553                attrs.extend(content.call(Attribute::parse_inner)?);
1554                Some(content.call(Block::parse_within)?)
1555            } else {
1556                return Err(lookahead.error());
1557            };
1558
1559            Ok(FlexibleItemFn {
1560                attrs,
1561                vis,
1562                defaultness,
1563                safety,
1564                sig: Signature {
1565                    constness,
1566                    asyncness,
1567                    unsafety: None,
1568                    ..sig
1569                },
1570                body,
1571            })
1572        }
1573    }
1574
1575    impl FlexibleItemStatic {
1576        pub fn parse(attrs: Vec<Attribute>, vis: Visibility, input: ParseStream) -> Result<Self> {
1577            let safety: Safety = input.parse()?;
1578            input.parse::<Token![static]>()?;
1579            let mutability: StaticMutability = input.parse()?;
1580            let ident = input.parse()?;
1581
1582            let lookahead = input.lookahead1();
1583            let has_type = lookahead.peek(Token![:]);
1584            let has_expr = lookahead.peek(Token![=]);
1585            if !has_type && !has_expr {
1586                return Err(lookahead.error());
1587            }
1588
1589            let ty: Option<Type> = if has_type {
1590                input.parse::<Token![:]>()?;
1591                input.parse().map(Some)?
1592            } else {
1593                None
1594            };
1595
1596            let expr: Option<Expr> = if input.parse::<Option<Token![=]>>()?.is_some() {
1597                input.parse().map(Some)?
1598            } else {
1599                None
1600            };
1601
1602            input.parse::<Token![;]>()?;
1603
1604            Ok(FlexibleItemStatic {
1605                attrs,
1606                vis,
1607                safety,
1608                mutability,
1609                ident,
1610                ty,
1611                expr,
1612            })
1613        }
1614    }
1615
1616    impl FlexibleItemType {
1617        pub fn parse(
1618            attrs: Vec<Attribute>,
1619            vis: Visibility,
1620            defaultness: bool,
1621            input: ParseStream,
1622            where_clause_location: WhereClauseLocation,
1623        ) -> Result<Self> {
1624            input.parse::<Token![type]>()?;
1625            let ident: Ident = input.parse()?;
1626            let mut generics: Generics = input.parse()?;
1627
1628            let mut bounds = Vec::new();
1629            if input.parse::<Option<Token![:]>>()?.is_some() {
1630                loop {
1631                    if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1632                        break;
1633                    }
1634                    bounds.push(input.parse::<TypeParamBound>()?);
1635                    if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1636                        break;
1637                    }
1638                    input.parse::<Token![+]>()?;
1639                }
1640            }
1641
1642            match where_clause_location {
1643                WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => {
1644                    generics.where_clause = input.parse()?;
1645                }
1646                WhereClauseLocation::AfterEq => {}
1647            }
1648
1649            let definition = if input.parse::<Option<Token![=]>>()?.is_some() {
1650                Some(input.parse()?)
1651            } else {
1652                None
1653            };
1654
1655            let where_clause_after_eq = match where_clause_location {
1656                WhereClauseLocation::AfterEq | WhereClauseLocation::Both
1657                    if generics.where_clause.is_none() =>
1658                {
1659                    input.parse()?
1660                }
1661                _ => None,
1662            };
1663
1664            input.parse::<Token![;]>()?;
1665
1666            Ok(FlexibleItemType {
1667                attrs,
1668                vis,
1669                defaultness,
1670                ident,
1671                generics,
1672                bounds,
1673                definition,
1674                where_clause_after_eq,
1675            })
1676        }
1677    }
1678
1679    impl Parse for Safety {
1680        fn parse(input: ParseStream) -> Result<Self> {
1681            if input.peek(Token![unsafe]) {
1682                input.parse::<Token![unsafe]>()?;
1683                Ok(Safety::Unsafe)
1684            } else if input.peek(kw::safe) {
1685                input.parse::<kw::safe>()?;
1686                Ok(Safety::Safe)
1687            } else {
1688                Ok(Safety::Default)
1689            }
1690        }
1691    }
1692
1693    impl Printer {
1694        pub fn flexible_item_const(&mut self, item: &FlexibleItemConst) {
1695            self.outer_attrs(&item.attrs);
1696            self.cbox(INDENT);
1697            self.visibility(&item.vis);
1698            if item.defaultness {
1699                self.word("default ");
1700            }
1701            self.word("const ");
1702            self.ident(&item.ident);
1703            self.generics(&item.generics);
1704            self.word(": ");
1705            self.cbox(-INDENT);
1706            self.ty(&item.ty);
1707            self.end();
1708            if let Some(value) = &item.value {
1709                self.word(" = ");
1710                self.neverbreak();
1711                self.ibox(-INDENT);
1712                self.expr(value, FixupContext::NONE);
1713                self.end();
1714            }
1715            self.where_clause_oneline_semi(&item.generics.where_clause);
1716            self.end();
1717            self.hardbreak();
1718        }
1719
1720        pub fn flexible_item_fn(&mut self, item: &FlexibleItemFn) {
1721            self.outer_attrs(&item.attrs);
1722            self.cbox(INDENT);
1723            self.visibility(&item.vis);
1724            if item.defaultness {
1725                self.word("default ");
1726            }
1727            self.signature(&item.sig, &item.safety);
1728            if let Some(body) = &item.body {
1729                self.where_clause_for_body(&item.sig.generics.where_clause);
1730                self.word("{");
1731                self.hardbreak_if_nonempty();
1732                self.inner_attrs(&item.attrs);
1733                for stmt in body {
1734                    self.stmt(stmt);
1735                }
1736                self.offset(-INDENT);
1737                self.end();
1738                self.word("}");
1739            } else {
1740                self.where_clause_semi(&item.sig.generics.where_clause);
1741                self.end();
1742            }
1743            self.hardbreak();
1744        }
1745
1746        pub fn flexible_item_static(&mut self, item: &FlexibleItemStatic) {
1747            self.outer_attrs(&item.attrs);
1748            self.cbox(0);
1749            self.visibility(&item.vis);
1750            self.safety(&item.safety);
1751            self.word("static ");
1752            self.static_mutability(&item.mutability);
1753            self.ident(&item.ident);
1754            if let Some(ty) = &item.ty {
1755                self.word(": ");
1756                self.ty(ty);
1757            }
1758            if let Some(expr) = &item.expr {
1759                self.word(" = ");
1760                self.neverbreak();
1761                self.expr(expr, FixupContext::NONE);
1762            }
1763            self.word(";");
1764            self.end();
1765            self.hardbreak();
1766        }
1767
1768        pub fn flexible_item_type(&mut self, item: &FlexibleItemType) {
1769            self.outer_attrs(&item.attrs);
1770            self.cbox(INDENT);
1771            self.visibility(&item.vis);
1772            if item.defaultness {
1773                self.word("default ");
1774            }
1775            self.word("type ");
1776            self.ident(&item.ident);
1777            self.generics(&item.generics);
1778            for bound in item.bounds.iter().delimited() {
1779                if bound.is_first {
1780                    self.word(": ");
1781                } else {
1782                    self.space();
1783                    self.word("+ ");
1784                }
1785                self.type_param_bound(&bound);
1786            }
1787            if let Some(definition) = &item.definition {
1788                self.where_clause_oneline(&item.generics.where_clause);
1789                self.word("= ");
1790                self.neverbreak();
1791                self.ibox(-INDENT);
1792                self.ty(definition);
1793                self.end();
1794                self.where_clause_oneline_semi(&item.where_clause_after_eq);
1795            } else {
1796                self.where_clause_oneline_semi(&item.generics.where_clause);
1797            }
1798            self.end();
1799            self.hardbreak();
1800        }
1801
1802        pub fn safety(&mut self, safety: &Safety) {
1803            match safety {
1804                Safety::Unsafe => self.word("unsafe "),
1805                Safety::Safe => self.word("safe "),
1806                Safety::Default => {}
1807                Safety::Disallowed => unreachable!(),
1808            }
1809        }
1810    }
1811}