easy_ext/
ast.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3// Based on:
4// - https://github.com/dtolnay/syn/blob/1.0.70/src/item.rs
5// - https://github.com/dtolnay/syn/blob/1.0.70/src/generics.rs
6
7use std::fmt;
8
9use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
10
11#[derive(Clone)]
12pub(crate) struct Lifetime {
13    pub(crate) apostrophe: Span,
14    pub(crate) ident: Ident,
15}
16
17#[derive(Clone, Default)]
18pub(crate) struct Generics {
19    pub(crate) lt_token: Option<Punct>,
20    pub(crate) params: Vec<(GenericParam, Option<Punct>)>,
21    pub(crate) gt_token: Option<Punct>,
22    pub(crate) where_clause: Option<WhereClause>,
23}
24
25impl Generics {
26    pub(crate) fn make_where_clause(&mut self) -> &mut WhereClause {
27        self.where_clause.get_or_insert_with(|| WhereClause {
28            where_token: Ident::new("where", Span::call_site()),
29            predicates: vec![],
30        })
31    }
32
33    pub(crate) fn impl_generics(&self) -> ImplGenerics<'_> {
34        ImplGenerics(self)
35    }
36
37    pub(crate) fn ty_generics(&self) -> TypeGenerics<'_> {
38        TypeGenerics(self)
39    }
40}
41
42#[derive(Clone)]
43pub(crate) enum GenericParam {
44    /// A generic type parameter: `T: Into<String>`.
45    Type(TypeParam),
46    /// A lifetime definition: `'a: 'b + 'c + 'd`.
47    Lifetime(LifetimeDef),
48    /// A const generic parameter: `const LENGTH: usize`.
49    Const(ConstParam),
50}
51
52#[derive(Clone)]
53pub(crate) struct TypeParam {
54    pub(crate) attrs: Vec<Attribute>,
55    pub(crate) ident: Ident,
56    pub(crate) colon_token: Option<Punct>,
57    pub(crate) bounds: Vec<(TypeParamBound, Option<Punct>)>,
58    pub(crate) eq_token: Option<Punct>,
59    pub(crate) default: Option<TokenStream>,
60}
61
62#[derive(Clone)]
63pub(crate) struct TypeParamBound {
64    pub(crate) tokens: TokenStream,
65    pub(crate) is_maybe: bool,
66}
67
68impl TypeParamBound {
69    fn new(tokens: Vec<TokenTree>, is_maybe: bool) -> Self {
70        Self { tokens: tokens.into_iter().collect(), is_maybe }
71    }
72}
73
74#[derive(Clone)]
75pub(crate) struct LifetimeDef {
76    pub(crate) attrs: Vec<Attribute>,
77    pub(crate) lifetime: Lifetime,
78    pub(crate) colon_token: Option<Punct>,
79    pub(crate) bounds: TokenStream,
80}
81
82#[derive(Clone)]
83pub(crate) struct BoundLifetimes {
84    pub(crate) for_token: Ident,
85    pub(crate) lt_token: Punct,
86    pub(crate) lifetimes: Vec<(LifetimeDef, Option<Punct>)>,
87    pub(crate) gt_token: Punct,
88}
89
90#[derive(Clone)]
91pub(crate) struct ConstParam {
92    pub(crate) attrs: Vec<Attribute>,
93    pub(crate) const_token: Ident,
94    pub(crate) ident: Ident,
95    pub(crate) colon_token: Punct,
96    pub(crate) ty: TokenStream,
97    pub(crate) eq_token: Option<Punct>,
98    pub(crate) default: Option<TokenStream>,
99}
100
101pub(crate) struct ImplGenerics<'a>(&'a Generics);
102pub(crate) struct TypeGenerics<'a>(&'a Generics);
103
104#[derive(Clone)]
105pub(crate) struct WhereClause {
106    pub(crate) where_token: Ident,
107    pub(crate) predicates: Vec<(WherePredicate, Option<Punct>)>,
108}
109
110#[derive(Clone)]
111pub(crate) enum WherePredicate {
112    Type(PredicateType),
113    Lifetime(PredicateLifetime),
114}
115
116#[derive(Clone)]
117pub(crate) struct PredicateType {
118    pub(crate) lifetimes: Option<BoundLifetimes>,
119    pub(crate) bounded_ty: TokenStream,
120    pub(crate) colon_token: Punct,
121    pub(crate) bounds: Vec<(TypeParamBound, Option<Punct>)>,
122}
123
124#[derive(Clone)]
125pub(crate) struct PredicateLifetime {
126    pub(crate) lifetime: Lifetime,
127    pub(crate) colon_token: Punct,
128    pub(crate) bounds: Vec<(Lifetime, Option<Punct>)>,
129}
130
131// Outer attribute
132#[derive(Clone)]
133pub(crate) struct Attribute {
134    // `#`
135    pub(crate) pound_token: Punct,
136    // `[...]`
137    pub(crate) tokens: Group,
138    pub(crate) kind: AttributeKind,
139}
140
141#[derive(Clone, Copy, PartialEq)]
142pub(crate) enum AttributeKind {
143    // #[doc ...]
144    Doc,
145    // #[inline ...]
146    Inline,
147    Other,
148}
149
150impl Attribute {
151    pub(crate) fn new(tokens: Vec<TokenTree>) -> Self {
152        Self {
153            pound_token: Punct::new('#', Spacing::Alone),
154            tokens: Group::new(Delimiter::Bracket, tokens.into_iter().collect()),
155            kind: AttributeKind::Other,
156        }
157    }
158}
159
160#[derive(Clone)]
161pub(crate) enum Visibility {
162    // `pub`.
163    Public(Ident),
164    //`pub(self)`, `pub(super)`, `pub(crate)`, or `pub(in some::module)`
165    Restricted(Ident, Group),
166    Inherited,
167}
168
169impl Visibility {
170    pub(crate) fn is_inherited(&self) -> bool {
171        match self {
172            Visibility::Inherited => true,
173            _ => false,
174        }
175    }
176}
177
178impl PartialEq for Visibility {
179    fn eq(&self, other: &Self) -> bool {
180        match (self, other) {
181            (Visibility::Public(_), Visibility::Public(_))
182            | (Visibility::Inherited, Visibility::Inherited) => true,
183            (Visibility::Restricted(_, x), Visibility::Restricted(_, y)) => {
184                x.stream().to_string() == y.stream().to_string()
185            }
186            _ => false,
187        }
188    }
189}
190
191impl fmt::Display for Visibility {
192    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193        match self {
194            Visibility::Public(_) => f.write_str("pub"),
195            Visibility::Inherited => Ok(()),
196            Visibility::Restricted(_, g) => write!(f, "pub{}", g),
197        }
198    }
199}
200
201pub(crate) struct ItemImpl {
202    pub(crate) attrs: Vec<Attribute>,
203    pub(crate) vis: Visibility,
204    pub(crate) defaultness: Option<Ident>,
205    pub(crate) unsafety: Option<Ident>,
206    pub(crate) impl_token: Ident,
207    pub(crate) generics: Generics,
208    pub(crate) const_token: Option<Ident>,
209    pub(crate) trait_: Option<(Ident, TokenStream, Ident)>,
210    pub(crate) self_ty: Vec<TokenTree>,
211    pub(crate) brace_token: Span,
212    pub(crate) items: Vec<ImplItem>,
213}
214
215pub(crate) enum ImplItem {
216    Const(ImplItemConst),
217    Method(ImplItemMethod),
218    Type(ImplItemType),
219}
220
221pub(crate) struct ImplItemConst {
222    pub(crate) attrs: Vec<Attribute>,
223    pub(crate) vis: Visibility,
224    pub(crate) defaultness: Option<Ident>,
225    pub(crate) const_token: Ident,
226    pub(crate) ident: Ident,
227    pub(crate) colon_token: Punct,
228    pub(crate) ty: TokenStream,
229    pub(crate) eq_token: Punct,
230    pub(crate) expr: Vec<TokenTree>,
231    pub(crate) semi_token: Punct,
232}
233
234pub(crate) struct ImplItemMethod {
235    pub(crate) attrs: Vec<Attribute>,
236    pub(crate) vis: Visibility,
237    pub(crate) defaultness: Option<Ident>,
238    pub(crate) sig: Signature,
239    pub(crate) body: Group,
240}
241
242pub(crate) struct ImplItemType {
243    pub(crate) attrs: Vec<Attribute>,
244    pub(crate) vis: Visibility,
245    pub(crate) defaultness: Option<Ident>,
246    pub(crate) type_token: Ident,
247    pub(crate) ident: Ident,
248    pub(crate) generics: Generics,
249    pub(crate) eq_token: Punct,
250    pub(crate) ty: Vec<TokenTree>,
251    pub(crate) semi_token: Punct,
252}
253
254#[derive(Clone)]
255pub(crate) struct Signature {
256    // [const] [async] [unsafe] [extern [<abi>]] fn
257    pub(crate) before_ident: Vec<TokenTree>,
258    pub(crate) ident: Ident,
259    pub(crate) generics: Generics,
260    pub(crate) paren_token: Span,
261    pub(crate) inputs: Vec<FnArg>,
262    pub(crate) output: Option<TokenStream>,
263}
264
265#[derive(Clone)]
266pub(crate) enum FnArg {
267    Receiver(TokenStream, Option<TokenTree>),
268    Typed(TokenStream, Punct, TokenStream, Option<TokenTree>),
269}
270
271pub(crate) struct ItemTrait {
272    pub(crate) attrs: Vec<Attribute>,
273    pub(crate) vis: Visibility,
274    pub(crate) unsafety: Option<Ident>,
275    pub(crate) trait_token: Ident,
276    pub(crate) ident: Ident,
277    pub(crate) generics: Generics,
278    pub(crate) brace_token: Span,
279    pub(crate) items: Vec<TraitItem>,
280}
281
282pub(crate) enum TraitItem {
283    Const(TraitItemConst),
284    Method(TraitItemMethod),
285    Type(TraitItemType),
286}
287
288pub(crate) struct TraitItemConst {
289    pub(crate) attrs: Vec<Attribute>,
290    pub(crate) const_token: Ident,
291    pub(crate) ident: Ident,
292    pub(crate) colon_token: Punct,
293    pub(crate) ty: TokenStream,
294    pub(crate) semi_token: Punct,
295}
296
297pub(crate) struct TraitItemMethod {
298    pub(crate) attrs: Vec<Attribute>,
299    pub(crate) sig: Signature,
300    pub(crate) semi_token: Punct,
301}
302
303pub(crate) struct TraitItemType {
304    pub(crate) attrs: Vec<Attribute>,
305    pub(crate) type_token: Ident,
306    pub(crate) ident: Ident,
307    pub(crate) generics: Generics,
308    pub(crate) semi_token: Punct,
309}
310
311pub(crate) mod parsing {
312    use std::iter::FromIterator;
313
314    use proc_macro::{Delimiter, Punct, Spacing, TokenStream, TokenTree};
315
316    use super::{
317        Attribute, AttributeKind, BoundLifetimes, ConstParam, FnArg, GenericParam, Generics,
318        ImplItem, ImplItemConst, ImplItemMethod, ImplItemType, ItemImpl, Lifetime, LifetimeDef,
319        PredicateLifetime, PredicateType, Signature, TypeParam, TypeParamBound, Visibility,
320        WhereClause, WherePredicate,
321    };
322    use crate::{error::Result, iter::TokenIter, to_tokens::ToTokens};
323
324    fn parse_until_punct(input: &mut TokenIter, ch: char) -> Result<(Vec<TokenTree>, Punct)> {
325        let mut buf = vec![];
326        loop {
327            let tt = input.next();
328            match tt {
329                Some(TokenTree::Punct(ref p))
330                    if p.as_char() == ch && p.spacing() == Spacing::Alone =>
331                {
332                    if let Some(TokenTree::Punct(p)) = tt {
333                        return Ok((buf, p));
334                    }
335                    unreachable!();
336                }
337                None => {
338                    // TODO: pass scope span
339                    bail!(TokenStream::new(), "expected `{}`", ch);
340                }
341                Some(tt) => buf.push(tt),
342            }
343        }
344    }
345
346    fn append_tokens_until(
347        input: &mut TokenIter,
348        buf: &mut Vec<TokenTree>,
349        visit_first_angle_bracket: bool,
350        f: fn(Option<&TokenTree>) -> bool,
351    ) -> Result<()> {
352        let mut angle_bracket: i32 = 0 - i32::from(visit_first_angle_bracket);
353        loop {
354            let tt = input.peek();
355            match tt {
356                Some(TokenTree::Punct(p)) if p.as_char() == '<' => {
357                    angle_bracket += 1;
358                }
359                Some(TokenTree::Punct(p)) if p.as_char() == '>' => {
360                    match buf.last() {
361                        Some(TokenTree::Punct(p))
362                            if p.as_char() == '-' && p.spacing() == Spacing::Joint =>
363                        {
364                            // `->`
365                            // It's so confusing with `>`, so do not visit it.
366                            buf.push(input.next().unwrap());
367                            continue;
368                        }
369                        _ => {}
370                    }
371                    angle_bracket -= 1;
372                    if angle_bracket >= 0 {
373                        buf.push(input.next().unwrap());
374                        continue;
375                    }
376                }
377                Some(_) | None => {}
378            }
379            if angle_bracket <= 0 && f(tt) {
380                return Ok(());
381            }
382            buf.push(input.next().ok_or_else(|| {
383                // TODO: pass scope span
384                format_err!(TokenStream::new(), "unexpected end of input")
385            })?);
386        }
387    }
388
389    fn parse_attrs(input: &mut TokenIter) -> Result<Vec<Attribute>> {
390        let mut attrs = vec![];
391        while input.peek_t(&'#') {
392            let pound_token = input.parse_punct('#')?;
393            let tokens = input.parse_group(Delimiter::Bracket)?;
394            let mut kind = AttributeKind::Other;
395            let mut iter = TokenIter::new(tokens.stream());
396            if let Some(TokenTree::Ident(i)) = iter.next() {
397                match iter.next() {
398                    // ignore #[path ...]
399                    Some(TokenTree::Punct(ref p)) if p.as_char() == ':' => {}
400                    _ => match &*i.to_string() {
401                        "doc" => kind = AttributeKind::Doc,
402                        "inline" => kind = AttributeKind::Inline,
403                        _ => {}
404                    },
405                }
406            }
407
408            let attr = Attribute { pound_token, tokens, kind };
409            attrs.push(attr);
410        }
411        Ok(attrs)
412    }
413
414    fn parse_generics(input: &mut TokenIter) -> Result<Generics> {
415        if !input.peek_t(&'<') {
416            return Ok(Generics::default());
417        }
418
419        let lt_token = input.parse_punct('<')?;
420
421        let mut params = vec![];
422        loop {
423            if input.peek_t(&'>') {
424                break;
425            }
426
427            let attrs = parse_attrs(input)?;
428            let value = if input.peek_lifetime() {
429                GenericParam::Lifetime(LifetimeDef { attrs, ..parse_lifetime_def(input)? })
430            } else if input.peek_t(&"const") {
431                GenericParam::Const(ConstParam { attrs, ..parse_const_param(input)? })
432            } else if input.peek_t(&"_") {
433                GenericParam::Type(TypeParam {
434                    attrs,
435                    ident: input.parse_ident()?,
436                    colon_token: None,
437                    bounds: vec![],
438                    eq_token: None,
439                    default: None,
440                })
441            } else if input.peek_ident().is_some() {
442                GenericParam::Type(TypeParam { attrs, ..parse_type_param(input)? })
443            } else {
444                bail!(input.next(), "expected one of: lifetime, identifier, `const`, `_`");
445            };
446
447            if input.peek_t(&'>') {
448                params.push((value, None));
449                break;
450            }
451            let punct = input.parse_punct(',')?;
452            params.push((value, Some(punct)));
453        }
454
455        let gt_token = input.parse_punct('>')?;
456
457        Ok(Generics {
458            lt_token: Some(lt_token),
459            params,
460            gt_token: Some(gt_token),
461            where_clause: None,
462        })
463    }
464
465    fn parse_lifetime(input: &mut TokenIter) -> Result<Lifetime> {
466        let tt = input.next();
467        match &tt {
468            Some(TokenTree::Punct(p)) if p.as_char() == '\'' && p.spacing() == Spacing::Joint => {
469                match input.next() {
470                    Some(TokenTree::Ident(ident)) => Ok(Lifetime { apostrophe: p.span(), ident }),
471                    Some(tt2) => {
472                        bail!(TokenStream::from_iter(vec![tt.unwrap(), tt2]), "expected lifetime")
473                    }
474                    None => bail!(p, "expected lifetime"),
475                }
476            }
477            // TODO: pass scope span if tt is None
478            tt => bail!(tt, "expected lifetime"),
479        }
480    }
481
482    fn parse_lifetime_def(input: &mut TokenIter) -> Result<LifetimeDef> {
483        let attrs = parse_attrs(input)?;
484        let lifetime = parse_lifetime(input)?;
485        let colon_token = input.parse_punct_opt(':');
486
487        let mut bounds = TokenStream::new();
488        if colon_token.is_some() {
489            loop {
490                if input.peek_t(&',') || input.peek_t(&'>') {
491                    break;
492                }
493                let value = parse_lifetime(input)?;
494                value.to_tokens(&mut bounds);
495                if !input.peek_t(&'+') {
496                    break;
497                }
498                let punct = input.parse_punct('+')?;
499                punct.to_tokens(&mut bounds);
500            }
501        }
502
503        Ok(LifetimeDef { attrs, lifetime, colon_token, bounds })
504    }
505
506    fn parse_bound_lifetimes(input: &mut TokenIter) -> Result<BoundLifetimes> {
507        Ok(BoundLifetimes {
508            for_token: input.parse_kw("for")?,
509            lt_token: input.parse_punct('<')?,
510            lifetimes: {
511                let mut lifetimes = vec![];
512                while !input.peek_t(&'>') {
513                    let lifetime = parse_lifetime_def(input)?;
514                    if input.peek_t(&'>') {
515                        lifetimes.push((lifetime, None));
516                        break;
517                    }
518                    let punct = input.parse_punct(',')?;
519                    lifetimes.push((lifetime, Some(punct)));
520                }
521                lifetimes
522            },
523            gt_token: input.parse_punct('>')?,
524        })
525    }
526
527    fn parse_type_param(input: &mut TokenIter) -> Result<TypeParam> {
528        let attrs = parse_attrs(input)?;
529        let ident = input.parse_ident()?;
530        let colon_token = input.parse_punct_opt(':');
531
532        let mut bounds = vec![];
533        if colon_token.is_some() {
534            loop {
535                if input.peek_t(&',') || input.peek_t(&'>') || input.peek_t(&'=') {
536                    break;
537                }
538
539                let is_maybe = input.peek_t(&'?') && !input.peek2_t(&"const");
540                let mut value = vec![];
541                append_tokens_until(input, &mut value, false, |next| match next {
542                    Some(TokenTree::Punct(p))
543                        if p.as_char() == ','
544                            || p.as_char() == '>'
545                            || p.as_char() == '='
546                            || p.as_char() == '+' =>
547                    {
548                        true
549                    }
550                    None => true,
551                    _ => false,
552                })?;
553                if !input.peek_t(&'+') {
554                    bounds.push((TypeParamBound::new(value, is_maybe), None));
555                    break;
556                }
557                let punct = input.parse_punct('+')?;
558                bounds.push((TypeParamBound::new(value, is_maybe), Some(punct)));
559            }
560        }
561
562        let mut default = None;
563        let eq_token = input.parse_punct_opt('=');
564        if eq_token.is_some() {
565            default = Some({
566                let mut ty = vec![];
567                append_tokens_until(input, &mut ty, false, |next| match next {
568                    Some(TokenTree::Punct(p)) if p.as_char() == '>' || p.as_char() == ',' => true,
569                    None => true,
570                    _ => false,
571                })?;
572                ty.into_iter().collect()
573            });
574        }
575
576        Ok(TypeParam { attrs, ident, colon_token, bounds, eq_token, default })
577    }
578
579    fn const_argument(input: &mut TokenIter) -> Result<TokenTree> {
580        let tt = input.next();
581        match &tt {
582            Some(TokenTree::Literal(_)) | Some(TokenTree::Ident(_)) => Ok(tt.unwrap()),
583            Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => Ok(tt.unwrap()),
584            // TODO: pass scope span if tt is None
585            _ => bail!(tt, "expected one of: literal, ident, `{`"),
586        }
587    }
588
589    fn parse_const_param(input: &mut TokenIter) -> Result<ConstParam> {
590        let attrs = parse_attrs(input)?;
591        let const_token = input.parse_kw("const")?;
592        let ident = input.parse_ident()?;
593        let colon_token = input.parse_punct(':')?;
594
595        let mut ty = vec![];
596        append_tokens_until(input, &mut ty, false, |next| match next {
597            Some(TokenTree::Punct(p))
598                if p.as_char() == '>'
599                    || p.as_char() == '=' && p.spacing() == Spacing::Alone
600                    || p.as_char() == ',' && p.spacing() == Spacing::Alone =>
601            {
602                true
603            }
604            None => true,
605            _ => false,
606        })?;
607        let mut default = None;
608        let eq_token = if input.peek_t(&'=') {
609            let eq_token = input.parse_punct('=')?;
610            default = Some(std::iter::once(const_argument(input)?).collect());
611            Some(eq_token)
612        } else {
613            None
614        };
615
616        Ok(ConstParam {
617            attrs,
618            const_token,
619            ident,
620            colon_token,
621            ty: ty.into_iter().collect(),
622            eq_token,
623            default,
624        })
625    }
626
627    fn parse_where_clause(input: &mut TokenIter) -> Result<WhereClause> {
628        let where_token = input.parse_kw("where")?;
629        let mut predicates = vec![];
630        loop {
631            if input.is_empty()
632                || input.peek_t(&Delimiter::Brace)
633                || input.peek_t(&',')
634                || input.peek_t(&';')
635                || input.peek_t(&':') && !input.peek2_t(&':')
636                || input.peek_t(&'=')
637            {
638                break;
639            }
640            let value = parse_where_predicate(input)?;
641            if !input.peek_t(&',') {
642                predicates.push((value, None));
643                break;
644            }
645            let punct = input.parse_punct(',')?;
646            predicates.push((value, Some(punct)));
647        }
648        Ok(WhereClause { where_token, predicates })
649    }
650
651    fn parse_where_predicate(input: &mut TokenIter) -> Result<WherePredicate> {
652        if input.peek_lifetime() && input.peek3_t(&':') {
653            Ok(WherePredicate::Lifetime(PredicateLifetime {
654                lifetime: parse_lifetime(input)?,
655                colon_token: input.parse_punct(':')?,
656                bounds: {
657                    let mut bounds = vec![];
658                    loop {
659                        if input.is_empty()
660                            || input.peek_t(&Delimiter::Brace)
661                            || input.peek_t(&',')
662                            || input.peek_t(&';')
663                            || input.peek_t(&':')
664                            || input.peek_t(&'=')
665                        {
666                            break;
667                        }
668                        let value = parse_lifetime(input)?;
669                        if !input.peek_t(&'+') {
670                            bounds.push((value, None));
671                            break;
672                        }
673                        let punct = input.parse_punct('+')?;
674                        bounds.push((value, Some(punct)));
675                    }
676                    bounds
677                },
678            }))
679        } else {
680            Ok(WherePredicate::Type(PredicateType {
681                lifetimes: {
682                    if input.peek_t(&"for") {
683                        Some(parse_bound_lifetimes(input)?)
684                    } else {
685                        None
686                    }
687                },
688                bounded_ty: {
689                    let mut ty = vec![];
690                    append_tokens_until(input, &mut ty, false, |next| match next {
691                        Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => true,
692                        Some(TokenTree::Punct(p))
693                            if p.as_char() == ','
694                                || p.as_char() == '=' && p.spacing() == Spacing::Alone
695                                || p.as_char() == ':' && p.spacing() == Spacing::Alone =>
696                        {
697                            true
698                        }
699                        _ => false,
700                    })?;
701                    ty.into_iter().collect()
702                },
703                colon_token: input.parse_punct(':')?,
704                bounds: {
705                    let mut bounds = vec![];
706                    loop {
707                        if input.is_empty()
708                            || input.peek_t(&Delimiter::Brace)
709                            || input.peek_t(&',')
710                            || input.peek_t(&';')
711                            || input.peek_t(&':') && !input.peek2_t(&':')
712                            || input.peek_t(&'=')
713                        {
714                            break;
715                        }
716
717                        let is_maybe = input.peek_t(&'?') && !input.peek2_t(&"const");
718                        let mut value = vec![];
719                        append_tokens_until(input, &mut value, false, |next| match next {
720                            Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => true,
721                            Some(TokenTree::Punct(p))
722                                if p.as_char() == ','
723                                    || p.as_char() == '>'
724                                    || p.as_char() == '='
725                                    || p.as_char() == '+' =>
726                            {
727                                true
728                            }
729                            None => true,
730                            _ => false,
731                        })?;
732                        if !input.peek_t(&'+') {
733                            bounds.push((TypeParamBound::new(value, is_maybe), None));
734                            break;
735                        }
736                        let punct = input.parse_punct('+')?;
737                        bounds.push((TypeParamBound::new(value, is_maybe), Some(punct)));
738                    }
739                    bounds
740                },
741            }))
742        }
743    }
744
745    pub(crate) fn parse_visibility(input: &mut TokenIter) -> Result<Visibility> {
746        if input.peek_t(&"pub") {
747            let pub_token = input.parse_ident()?;
748            match input.peek() {
749                Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis {} => {
750                    let g = input.parse_group(Delimiter::Parenthesis)?;
751                    Ok(Visibility::Restricted(pub_token, g))
752                }
753                _ => Ok(Visibility::Public(pub_token)),
754            }
755        } else {
756            Ok(Visibility::Inherited)
757        }
758    }
759
760    pub(crate) fn parse_inputs(input: TokenStream) -> Result<Vec<FnArg>> {
761        let input = &mut TokenIter::new(input);
762        let mut inputs = vec![];
763
764        loop {
765            let mut pat = vec![];
766            append_tokens_until(input, &mut pat, false, |next| match next {
767                Some(TokenTree::Punct(p)) if p.as_char() == ',' || p.as_char() == ':' => true,
768                None => true,
769                _ => false,
770            })?;
771            if !input.peek_t(&':') {
772                if input.peek_t(&',') {
773                    inputs.push(FnArg::Receiver(
774                        pat.into_iter().collect(),
775                        Some(input.next().unwrap()),
776                    ));
777                    continue;
778                }
779                assert!(input.next().is_none());
780                inputs.push(FnArg::Receiver(pat.into_iter().collect(), None));
781                break;
782            }
783            let colon = input.parse_punct(':')?;
784            let mut ty = vec![];
785            append_tokens_until(input, &mut ty, false, |next| match next {
786                Some(TokenTree::Punct(p)) if p.as_char() == ',' => true,
787                None => true,
788                _ => false,
789            })?;
790            if input.peek_t(&',') {
791                inputs.push(FnArg::Typed(
792                    pat.into_iter().collect(),
793                    colon,
794                    ty.into_iter().collect(),
795                    Some(input.next().unwrap()),
796                ));
797                continue;
798            }
799            assert!(input.next().is_none());
800            inputs.push(FnArg::Typed(
801                pat.into_iter().collect(),
802                colon,
803                ty.into_iter().collect(),
804                None,
805            ));
806            break;
807        }
808
809        Ok(inputs)
810    }
811
812    pub(crate) fn parse_impl(input: &mut TokenIter) -> Result<ItemImpl> {
813        let attrs = parse_attrs(input)?;
814        let vis: Visibility = parse_visibility(input)?;
815        let defaultness = input.parse_kw_opt("default");
816        let unsafety = input.parse_kw_opt("unsafe");
817        let impl_token = input.parse_kw("impl")?;
818
819        let has_generics = input.peek_t(&'<')
820            && (input.peek2_t(&'>')
821                || input.peek2_t(&'#')
822                || input.peek2_ident().is_some()
823                    && (input.peek3_t(&':')
824                        || input.peek3_t(&',')
825                        || input.peek3_t(&'>')
826                        || input.peek3_t(&'='))
827                || input.peek2_lifetime()
828                    && (input.peek4_t(&':')
829                        || input.peek4_t(&',')
830                        || input.peek4_t(&'>')
831                        || input.peek4_t(&'='))
832                || input.peek2_t(&"const"));
833        let mut generics: Generics =
834            if has_generics { parse_generics(input)? } else { Generics::default() };
835
836        let const_token = input.parse_kw_opt("const");
837
838        let mut self_ty = vec![];
839        append_tokens_until(input, &mut self_ty, false, |next| match next {
840            Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => true,
841            Some(TokenTree::Ident(i)) if i.to_string() == "where" => true,
842            _ => false,
843        })?;
844
845        if input.peek_t(&"where") {
846            generics.where_clause = Some(parse_where_clause(input)?);
847        }
848
849        let g = input.parse_group(Delimiter::Brace)?;
850        let brace_token = g.span();
851        let content = &mut TokenIter::new(g.stream());
852
853        let mut items = vec![];
854        while !content.is_empty() {
855            items.push(parse_impl_item(content)?);
856        }
857
858        Ok(ItemImpl {
859            attrs,
860            vis,
861            defaultness,
862            unsafety,
863            impl_token,
864            generics,
865            const_token,
866            trait_: None,
867            self_ty,
868            brace_token,
869            items,
870        })
871    }
872
873    fn parse_impl_item(input: &mut TokenIter) -> Result<ImplItem> {
874        let attrs = parse_attrs(input)?;
875        let vis = parse_visibility(input)?;
876
877        let defaultness = if input.peek_t(&"default") && !input.peek2_t(&'!') {
878            Some(input.parse_kw("default")?)
879        } else {
880            None
881        };
882
883        if peek_signature(input) {
884            let sig = parse_signature(input)?;
885            let body = input.parse_group(Delimiter::Brace)?;
886            Ok(ImplItem::Method(ImplItemMethod { attrs, vis, defaultness, sig, body }))
887        } else if input.peek_t(&"const") {
888            let const_token = input.parse_kw("const")?;
889            let ident = input.parse_ident()?;
890            let colon_token = input.parse_punct(':')?;
891
892            let mut ty = vec![];
893            append_tokens_until(input, &mut ty, false, |next| match next {
894                Some(TokenTree::Punct(p))
895                    if p.as_char() == '=' && p.spacing() == Spacing::Alone
896                        || p.as_char() == ';' && p.spacing() == Spacing::Alone =>
897                {
898                    true
899                }
900                _ => false,
901            })?;
902            let eq_token = input.parse_punct('=')?;
903
904            let (expr, semi_token) = parse_until_punct(input, ';')?;
905
906            Ok(ImplItem::Const(ImplItemConst {
907                attrs,
908                vis,
909                defaultness,
910                const_token,
911                ident,
912                colon_token,
913                ty: ty.into_iter().collect(),
914                eq_token,
915                expr,
916                semi_token,
917            }))
918        } else if input.peek_t(&"type") {
919            let type_token = input.parse_kw("type")?;
920            let ident = input.parse_ident()?;
921            let mut generics = parse_generics(input)?;
922
923            if input.peek_t(&"where") {
924                generics.where_clause = Some(parse_where_clause(input)?);
925            }
926
927            let eq_token = input.parse_punct('=')?;
928
929            let (ty, semi_token) = parse_until_punct(input, ';')?;
930
931            Ok(ImplItem::Type(ImplItemType {
932                attrs,
933                vis,
934                defaultness,
935                type_token,
936                ident,
937                generics,
938                eq_token,
939                ty,
940                semi_token,
941            }))
942        } else {
943            bail!(input.next(), "expected one of: `default`, `fn`, `const`, `type`")
944        }
945    }
946
947    fn peek_signature(input: &TokenIter) -> bool {
948        let fork = &mut input.clone();
949        fork.parse_kw_opt("const");
950        fork.parse_kw_opt("async");
951        fork.parse_kw_opt("unsafe");
952        if fork.peek_t(&"extern") {
953            let _extern_token = fork.parse_kw("extern");
954            fork.parse_literal_opt();
955        }
956        fork.peek_t(&"fn")
957    }
958
959    fn parse_signature(input: &mut TokenIter) -> Result<Signature> {
960        let mut before_ident = vec![];
961        loop {
962            let tt = input.tt()?;
963            match &tt {
964                TokenTree::Ident(i) if i.to_string() == "fn" => {
965                    before_ident.push(tt);
966                    break;
967                }
968                TokenTree::Group(g) if g.delimiter() == Delimiter::None => {
969                    let mut iter = g.stream().into_iter();
970                    if let Some(TokenTree::Ident(i)) = iter.next() {
971                        if iter.next().is_none() && i.to_string() == "fn" {
972                            before_ident.push(tt);
973                            break;
974                        }
975                    }
976                    before_ident.push(tt);
977                }
978                _ => before_ident.push(tt),
979            }
980        }
981
982        let ident = input.parse_ident()?;
983        let mut generics = parse_generics(input)?;
984
985        let inputs = input.parse_group(Delimiter::Parenthesis)?;
986        let paren_token = inputs.span();
987        let inputs = parse_inputs(inputs.stream())?;
988
989        let output = if input.peek_punct('-').map_or(false, |p| p.spacing() == Spacing::Joint)
990            && input.peek2_t(&'>')
991        {
992            let arrow1 = input.tt()?;
993            let arrow2 = input.tt()?;
994            let mut tokens = vec![arrow1, arrow2];
995            append_tokens_until(input, &mut tokens, false, |next| match next {
996                Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => true,
997                Some(TokenTree::Ident(i)) if i.to_string() == "where" => true,
998                None => true,
999                _ => false,
1000            })?;
1001            Some(tokens.into_iter().collect())
1002        } else {
1003            None
1004        };
1005
1006        if input.peek_t(&"where") {
1007            generics.where_clause = Some(parse_where_clause(input)?);
1008        }
1009
1010        Ok(Signature { before_ident, ident, generics, paren_token, inputs, output })
1011    }
1012}
1013
1014pub(crate) mod printing {
1015    use proc_macro::{Delimiter, Group, Punct, Spacing, Span, TokenStream};
1016
1017    use super::{
1018        Attribute, BoundLifetimes, ConstParam, FnArg, GenericParam, Generics, ImplGenerics,
1019        ImplItem, ImplItemConst, ImplItemMethod, ImplItemType, ItemImpl, ItemTrait, Lifetime,
1020        LifetimeDef, PredicateLifetime, PredicateType, Signature, TraitItem, TraitItemConst,
1021        TraitItemMethod, TraitItemType, TypeGenerics, TypeParam, TypeParamBound, Visibility,
1022        WhereClause, WherePredicate,
1023    };
1024    use crate::to_tokens::ToTokens;
1025
1026    pub(crate) fn punct(ch: char, span: Span) -> Punct {
1027        let mut p = Punct::new(ch, Spacing::Alone);
1028        p.set_span(span);
1029        p
1030    }
1031
1032    fn tokens_or_default(p: &Option<Punct>, ch: char, tokens: &mut TokenStream) {
1033        match p {
1034            Some(p) => p.to_tokens(tokens),
1035            None => punct(ch, Span::call_site()).to_tokens(tokens),
1036        }
1037    }
1038
1039    impl ToTokens for Generics {
1040        fn to_tokens(&self, tokens: &mut TokenStream) {
1041            if self.params.is_empty() {
1042                return;
1043            }
1044
1045            tokens_or_default(&self.lt_token, '<', tokens);
1046
1047            // Print lifetimes before types and consts, regardless of their
1048            // order in self.params.
1049            //
1050            // TODO: ordering rules for const parameters vs type parameters have
1051            // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1052            let mut trailing_or_empty = true;
1053            for (param, p) in &self.params {
1054                if let GenericParam::Lifetime(_) = param {
1055                    param.to_tokens(tokens);
1056                    p.to_tokens(tokens);
1057                    trailing_or_empty = p.is_some();
1058                }
1059            }
1060            for (param, p) in &self.params {
1061                match param {
1062                    GenericParam::Type(_) | GenericParam::Const(_) => {
1063                        if !trailing_or_empty {
1064                            punct(',', Span::call_site()).to_tokens(tokens);
1065                            trailing_or_empty = true;
1066                        }
1067                        param.to_tokens(tokens);
1068                        p.to_tokens(tokens);
1069                    }
1070                    GenericParam::Lifetime(_) => {}
1071                }
1072            }
1073
1074            tokens_or_default(&self.gt_token, '>', tokens);
1075        }
1076    }
1077
1078    impl ToTokens for GenericParam {
1079        fn to_tokens(&self, tokens: &mut TokenStream) {
1080            match self {
1081                GenericParam::Const(p) => p.to_tokens(tokens),
1082                GenericParam::Lifetime(l) => l.to_tokens(tokens),
1083                GenericParam::Type(t) => t.to_tokens(tokens),
1084            }
1085        }
1086    }
1087
1088    impl ToTokens for BoundLifetimes {
1089        fn to_tokens(&self, tokens: &mut TokenStream) {
1090            self.for_token.to_tokens(tokens);
1091            self.lt_token.to_tokens(tokens);
1092            self.lifetimes.to_tokens(tokens);
1093            self.gt_token.to_tokens(tokens);
1094        }
1095    }
1096
1097    impl ToTokens for Lifetime {
1098        fn to_tokens(&self, tokens: &mut TokenStream) {
1099            let mut apostrophe = Punct::new('\'', Spacing::Joint);
1100            apostrophe.set_span(self.apostrophe);
1101            apostrophe.to_tokens(tokens);
1102            self.ident.to_tokens(tokens);
1103        }
1104    }
1105
1106    impl ToTokens for LifetimeDef {
1107        fn to_tokens(&self, tokens: &mut TokenStream) {
1108            self.attrs.to_tokens(tokens);
1109            self.lifetime.to_tokens(tokens);
1110            if !self.bounds.is_empty() {
1111                tokens_or_default(&self.colon_token, ':', tokens);
1112                self.bounds.to_tokens(tokens);
1113            }
1114        }
1115    }
1116
1117    impl ToTokens for TypeParam {
1118        fn to_tokens(&self, tokens: &mut TokenStream) {
1119            self.attrs.to_tokens(tokens);
1120            self.ident.to_tokens(tokens);
1121            if !self.bounds.is_empty() {
1122                tokens_or_default(&self.colon_token, ':', tokens);
1123                for (bound, punct) in &self.bounds {
1124                    bound.to_tokens(tokens);
1125                    punct.to_tokens(tokens);
1126                }
1127            }
1128            if let Some(default) = &self.default {
1129                tokens_or_default(&self.eq_token, '=', tokens);
1130                default.to_tokens(tokens);
1131            }
1132        }
1133    }
1134
1135    impl ToTokens for TypeParamBound {
1136        fn to_tokens(&self, tokens: &mut TokenStream) {
1137            self.tokens.to_tokens(tokens);
1138        }
1139    }
1140
1141    impl ToTokens for ConstParam {
1142        fn to_tokens(&self, tokens: &mut TokenStream) {
1143            self.attrs.to_tokens(tokens);
1144            self.const_token.to_tokens(tokens);
1145            self.ident.to_tokens(tokens);
1146            self.colon_token.to_tokens(tokens);
1147            self.ty.to_tokens(tokens);
1148            if let Some(default) = &self.default {
1149                tokens_or_default(&self.eq_token, '=', tokens);
1150                default.to_tokens(tokens);
1151            }
1152        }
1153    }
1154
1155    impl ToTokens for ImplGenerics<'_> {
1156        fn to_tokens(&self, tokens: &mut TokenStream) {
1157            if self.0.params.is_empty() {
1158                return;
1159            }
1160
1161            tokens_or_default(&self.0.lt_token, '<', tokens);
1162
1163            // Print lifetimes before types and consts, regardless of their
1164            // order in self.params.
1165            //
1166            // TODO: ordering rules for const parameters vs type parameters have
1167            // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1168            let mut trailing_or_empty = true;
1169            for (param, p) in &self.0.params {
1170                if let GenericParam::Lifetime(_) = param {
1171                    param.to_tokens(tokens);
1172                    p.to_tokens(tokens);
1173                    trailing_or_empty = p.is_some();
1174                }
1175            }
1176            for (param, p) in &self.0.params {
1177                if let GenericParam::Lifetime(_) = param {
1178                    continue;
1179                }
1180                if !trailing_or_empty {
1181                    punct(',', Span::call_site()).to_tokens(tokens);
1182                    trailing_or_empty = true;
1183                }
1184                match param {
1185                    GenericParam::Lifetime(_) => unreachable!(),
1186                    GenericParam::Type(param) => {
1187                        // Leave off the type parameter defaults
1188                        param.attrs.to_tokens(tokens);
1189                        param.ident.to_tokens(tokens);
1190                        if !param.bounds.is_empty() {
1191                            tokens_or_default(&param.colon_token, ':', tokens);
1192                            param.bounds.to_tokens(tokens);
1193                        }
1194                    }
1195                    GenericParam::Const(param) => {
1196                        // Leave off the const parameter defaults
1197                        param.attrs.to_tokens(tokens);
1198                        param.const_token.to_tokens(tokens);
1199                        param.ident.to_tokens(tokens);
1200                        param.colon_token.to_tokens(tokens);
1201                        param.ty.to_tokens(tokens);
1202                    }
1203                }
1204                p.to_tokens(tokens);
1205            }
1206
1207            tokens_or_default(&self.0.gt_token, '>', tokens);
1208        }
1209    }
1210
1211    impl ToTokens for TypeGenerics<'_> {
1212        fn to_tokens(&self, tokens: &mut TokenStream) {
1213            if self.0.params.is_empty() {
1214                return;
1215            }
1216
1217            tokens_or_default(&self.0.lt_token, '<', tokens);
1218
1219            // Print lifetimes before types and consts, regardless of their
1220            // order in self.params.
1221            //
1222            // TODO: ordering rules for const parameters vs type parameters have
1223            // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1224            let mut trailing_or_empty = true;
1225            for (param, p) in &self.0.params {
1226                if let GenericParam::Lifetime(def) = param {
1227                    // Leave off the lifetime bounds and attributes
1228                    def.lifetime.to_tokens(tokens);
1229                    p.to_tokens(tokens);
1230                    trailing_or_empty = p.is_some();
1231                }
1232            }
1233            for (param, p) in &self.0.params {
1234                if let GenericParam::Lifetime(_) = param {
1235                    continue;
1236                }
1237                if !trailing_or_empty {
1238                    punct(',', Span::call_site()).to_tokens(tokens);
1239                    trailing_or_empty = true;
1240                }
1241                match param {
1242                    GenericParam::Lifetime(_) => unreachable!(),
1243                    GenericParam::Type(param) => {
1244                        // Leave off the type parameter defaults
1245                        param.ident.to_tokens(tokens);
1246                    }
1247                    GenericParam::Const(param) => {
1248                        // Leave off the const parameter defaults
1249                        param.ident.to_tokens(tokens);
1250                    }
1251                }
1252                p.to_tokens(tokens);
1253            }
1254
1255            tokens_or_default(&self.0.gt_token, '>', tokens);
1256        }
1257    }
1258
1259    impl ToTokens for WhereClause {
1260        fn to_tokens(&self, tokens: &mut TokenStream) {
1261            if !self.predicates.is_empty() {
1262                self.where_token.to_tokens(tokens);
1263                self.predicates.to_tokens(tokens);
1264            }
1265        }
1266    }
1267
1268    impl ToTokens for WherePredicate {
1269        fn to_tokens(&self, tokens: &mut TokenStream) {
1270            match self {
1271                WherePredicate::Lifetime(l) => l.to_tokens(tokens),
1272                WherePredicate::Type(t) => t.to_tokens(tokens),
1273            }
1274        }
1275    }
1276
1277    impl ToTokens for PredicateType {
1278        fn to_tokens(&self, tokens: &mut TokenStream) {
1279            self.lifetimes.to_tokens(tokens);
1280            self.bounded_ty.to_tokens(tokens);
1281            self.colon_token.to_tokens(tokens);
1282            self.bounds.to_tokens(tokens);
1283        }
1284    }
1285
1286    impl ToTokens for PredicateLifetime {
1287        fn to_tokens(&self, tokens: &mut TokenStream) {
1288            self.lifetime.to_tokens(tokens);
1289            self.colon_token.to_tokens(tokens);
1290            self.bounds.to_tokens(tokens);
1291        }
1292    }
1293
1294    impl ToTokens for Visibility {
1295        fn to_tokens(&self, tokens: &mut TokenStream) {
1296            match self {
1297                Visibility::Public(i) => i.to_tokens(tokens),
1298                Visibility::Restricted(i, g) => {
1299                    i.to_tokens(tokens);
1300                    g.to_tokens(tokens);
1301                }
1302                Visibility::Inherited => {}
1303            }
1304        }
1305    }
1306
1307    impl ToTokens for Attribute {
1308        fn to_tokens(&self, tokens: &mut TokenStream) {
1309            self.pound_token.to_tokens(tokens);
1310            self.tokens.to_tokens(tokens);
1311        }
1312    }
1313
1314    fn group(
1315        span: Span,
1316        delimiter: Delimiter,
1317        tokens: &mut TokenStream,
1318        f: &dyn Fn(&mut TokenStream),
1319    ) {
1320        let mut inner = TokenStream::new();
1321        f(&mut inner);
1322        let mut g = Group::new(delimiter, inner);
1323        g.set_span(span);
1324        g.to_tokens(tokens);
1325    }
1326
1327    impl ToTokens for ItemTrait {
1328        fn to_tokens(&self, tokens: &mut TokenStream) {
1329            self.attrs.to_tokens(tokens);
1330            self.vis.to_tokens(tokens);
1331            self.unsafety.to_tokens(tokens);
1332            self.trait_token.to_tokens(tokens);
1333            self.ident.to_tokens(tokens);
1334            self.generics.to_tokens(tokens);
1335            self.generics.where_clause.to_tokens(tokens);
1336            group(self.brace_token, Delimiter::Brace, tokens, &|tokens| {
1337                self.items.to_tokens(tokens);
1338            });
1339        }
1340    }
1341
1342    impl ToTokens for ItemImpl {
1343        fn to_tokens(&self, tokens: &mut TokenStream) {
1344            self.attrs.to_tokens(tokens);
1345            self.defaultness.to_tokens(tokens);
1346            self.unsafety.to_tokens(tokens);
1347            self.impl_token.to_tokens(tokens);
1348            self.generics.impl_generics().to_tokens(tokens);
1349            self.const_token.to_tokens(tokens);
1350            if let Some((path, generics, for_)) = &self.trait_ {
1351                path.to_tokens(tokens);
1352                generics.to_tokens(tokens);
1353                for_.to_tokens(tokens);
1354            }
1355            self.self_ty.to_tokens(tokens);
1356            self.generics.where_clause.to_tokens(tokens);
1357            group(self.brace_token, Delimiter::Brace, tokens, &|tokens| {
1358                self.items.to_tokens(tokens);
1359            });
1360        }
1361    }
1362
1363    impl ToTokens for TraitItem {
1364        fn to_tokens(&self, tokens: &mut TokenStream) {
1365            match self {
1366                TraitItem::Const(i) => i.to_tokens(tokens),
1367                TraitItem::Method(i) => i.to_tokens(tokens),
1368                TraitItem::Type(i) => i.to_tokens(tokens),
1369            }
1370        }
1371    }
1372
1373    impl ToTokens for TraitItemConst {
1374        fn to_tokens(&self, tokens: &mut TokenStream) {
1375            self.attrs.to_tokens(tokens);
1376            self.const_token.to_tokens(tokens);
1377            self.ident.to_tokens(tokens);
1378            self.colon_token.to_tokens(tokens);
1379            self.ty.to_tokens(tokens);
1380            self.semi_token.to_tokens(tokens);
1381        }
1382    }
1383
1384    impl ToTokens for TraitItemMethod {
1385        fn to_tokens(&self, tokens: &mut TokenStream) {
1386            self.attrs.to_tokens(tokens);
1387            self.sig.to_tokens(tokens);
1388            self.semi_token.to_tokens(tokens);
1389        }
1390    }
1391
1392    impl ToTokens for TraitItemType {
1393        fn to_tokens(&self, tokens: &mut TokenStream) {
1394            self.attrs.to_tokens(tokens);
1395            self.type_token.to_tokens(tokens);
1396            self.ident.to_tokens(tokens);
1397            self.generics.to_tokens(tokens);
1398            self.generics.where_clause.to_tokens(tokens);
1399            self.semi_token.to_tokens(tokens);
1400        }
1401    }
1402
1403    impl ToTokens for ImplItem {
1404        fn to_tokens(&self, tokens: &mut TokenStream) {
1405            match self {
1406                ImplItem::Const(i) => i.to_tokens(tokens),
1407                ImplItem::Method(i) => i.to_tokens(tokens),
1408                ImplItem::Type(i) => i.to_tokens(tokens),
1409            }
1410        }
1411    }
1412
1413    impl ToTokens for ImplItemConst {
1414        fn to_tokens(&self, tokens: &mut TokenStream) {
1415            self.attrs.to_tokens(tokens);
1416            self.vis.to_tokens(tokens);
1417            self.defaultness.to_tokens(tokens);
1418            self.const_token.to_tokens(tokens);
1419            self.ident.to_tokens(tokens);
1420            self.colon_token.to_tokens(tokens);
1421            self.ty.to_tokens(tokens);
1422            self.eq_token.to_tokens(tokens);
1423            self.expr.to_tokens(tokens);
1424            self.semi_token.to_tokens(tokens);
1425        }
1426    }
1427
1428    impl ToTokens for ImplItemMethod {
1429        fn to_tokens(&self, tokens: &mut TokenStream) {
1430            self.attrs.to_tokens(tokens);
1431            self.vis.to_tokens(tokens);
1432            self.defaultness.to_tokens(tokens);
1433            self.sig.to_tokens(tokens);
1434            self.body.to_tokens(tokens);
1435        }
1436    }
1437
1438    impl ToTokens for ImplItemType {
1439        fn to_tokens(&self, tokens: &mut TokenStream) {
1440            self.attrs.to_tokens(tokens);
1441            self.vis.to_tokens(tokens);
1442            self.defaultness.to_tokens(tokens);
1443            self.type_token.to_tokens(tokens);
1444            self.ident.to_tokens(tokens);
1445            self.generics.to_tokens(tokens);
1446            self.generics.where_clause.to_tokens(tokens);
1447            self.eq_token.to_tokens(tokens);
1448            self.ty.to_tokens(tokens);
1449            self.semi_token.to_tokens(tokens);
1450        }
1451    }
1452
1453    impl ToTokens for Signature {
1454        fn to_tokens(&self, tokens: &mut TokenStream) {
1455            self.before_ident.to_tokens(tokens);
1456            self.ident.to_tokens(tokens);
1457            self.generics.to_tokens(tokens);
1458            group(self.paren_token, Delimiter::Parenthesis, tokens, &|tokens| {
1459                for arg in &self.inputs {
1460                    arg.to_tokens(tokens);
1461                }
1462            });
1463            self.output.to_tokens(tokens);
1464            self.generics.where_clause.to_tokens(tokens);
1465        }
1466    }
1467
1468    impl ToTokens for FnArg {
1469        fn to_tokens(&self, tokens: &mut TokenStream) {
1470            match self {
1471                FnArg::Receiver(pat, p) => {
1472                    pat.to_tokens(tokens);
1473                    p.to_tokens(tokens);
1474                }
1475                FnArg::Typed(pat, colon, ty, p) => {
1476                    pat.to_tokens(tokens);
1477                    colon.to_tokens(tokens);
1478                    ty.to_tokens(tokens);
1479                    p.to_tokens(tokens);
1480                }
1481            }
1482        }
1483    }
1484}