1use 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 Type(TypeParam),
46 Lifetime(LifetimeDef),
48 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#[derive(Clone)]
133pub(crate) struct Attribute {
134 pub(crate) pound_token: Punct,
136 pub(crate) tokens: Group,
138 pub(crate) kind: AttributeKind,
139}
140
141#[derive(Clone, Copy, PartialEq)]
142pub(crate) enum AttributeKind {
143 Doc,
145 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 Public(Ident),
164 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 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 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 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 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 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 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 _ => 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 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 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 param.attrs.to_tokens(tokens);
1189 param.ident.to_tokens(tokens);
1190 if !param.bounds.is_empty() {
1191 tokens_or_default(¶m.colon_token, ':', tokens);
1192 param.bounds.to_tokens(tokens);
1193 }
1194 }
1195 GenericParam::Const(param) => {
1196 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 let mut trailing_or_empty = true;
1225 for (param, p) in &self.0.params {
1226 if let GenericParam::Lifetime(def) = param {
1227 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 param.ident.to_tokens(tokens);
1246 }
1247 GenericParam::Const(param) => {
1248 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}