]> git.proxmox.com Git - rustc.git/blame - vendor/syn/src/generics.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / vendor / syn / src / generics.rs
CommitLineData
e74abb32
XL
1use super::*;
2use crate::punctuated::{Iter, IterMut, Punctuated};
3
4ast_struct! {
5 /// Lifetimes and type parameters attached to a declaration of a function,
6 /// enum, trait, etc.
7 ///
8 /// *This type is available if Syn is built with the `"derive"` or `"full"`
9 /// feature.*
10 #[derive(Default)]
11 pub struct Generics {
12 pub lt_token: Option<Token![<]>,
13 pub params: Punctuated<GenericParam, Token![,]>,
14 pub gt_token: Option<Token![>]>,
15 pub where_clause: Option<WhereClause>,
16 }
17}
18
19ast_enum_of_structs! {
20 /// A generic type parameter, lifetime, or const generic: `T: Into<String>`,
21 /// `'a: 'b`, `const LEN: usize`.
22 ///
23 /// *This type is available if Syn is built with the `"derive"` or `"full"`
24 /// feature.*
25 ///
26 /// # Syntax tree enum
27 ///
28 /// This type is a [syntax tree enum].
29 ///
30 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
31 //
32 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
33 // blocked on https://github.com/rust-lang/rust/issues/62833
34 pub enum GenericParam {
35 /// A generic type parameter: `T: Into<String>`.
36 Type(TypeParam),
37
38 /// A lifetime definition: `'a: 'b + 'c + 'd`.
39 Lifetime(LifetimeDef),
40
41 /// A const generic parameter: `const LENGTH: usize`.
42 Const(ConstParam),
43 }
44}
45
46ast_struct! {
47 /// A generic type parameter: `T: Into<String>`.
48 ///
49 /// *This type is available if Syn is built with the `"derive"` or
50 /// `"full"` feature.*
51 pub struct TypeParam {
52 pub attrs: Vec<Attribute>,
53 pub ident: Ident,
54 pub colon_token: Option<Token![:]>,
55 pub bounds: Punctuated<TypeParamBound, Token![+]>,
56 pub eq_token: Option<Token![=]>,
57 pub default: Option<Type>,
58 }
59}
60
61ast_struct! {
62 /// A lifetime definition: `'a: 'b + 'c + 'd`.
63 ///
64 /// *This type is available if Syn is built with the `"derive"` or
65 /// `"full"` feature.*
66 pub struct LifetimeDef {
67 pub attrs: Vec<Attribute>,
68 pub lifetime: Lifetime,
69 pub colon_token: Option<Token![:]>,
70 pub bounds: Punctuated<Lifetime, Token![+]>,
71 }
72}
73
74ast_struct! {
75 /// A const generic parameter: `const LENGTH: usize`.
76 ///
77 /// *This type is available if Syn is built with the `"derive"` or
78 /// `"full"` feature.*
79 pub struct ConstParam {
80 pub attrs: Vec<Attribute>,
81 pub const_token: Token![const],
82 pub ident: Ident,
83 pub colon_token: Token![:],
84 pub ty: Type,
85 pub eq_token: Option<Token![=]>,
86 pub default: Option<Expr>,
87 }
88}
89
90impl Generics {
91 /// Returns an
92 /// <code
93 /// style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
94 /// href="struct.TypeParam.html"><code
95 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
96 /// style="padding-left:0;">&gt;</code>
97 /// over the type parameters in `self.params`.
98 pub fn type_params(&self) -> TypeParams {
99 TypeParams(self.params.iter())
100 }
101
102 /// Returns an
103 /// <code
104 /// style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
105 /// href="struct.TypeParam.html"><code
106 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
107 /// style="padding-left:0;">&gt;</code>
108 /// over the type parameters in `self.params`.
109 pub fn type_params_mut(&mut self) -> TypeParamsMut {
110 TypeParamsMut(self.params.iter_mut())
111 }
112
113 /// Returns an
114 /// <code
115 /// style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
116 /// href="struct.LifetimeDef.html"><code
117 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
118 /// style="padding-left:0;">&gt;</code>
119 /// over the lifetime parameters in `self.params`.
120 pub fn lifetimes(&self) -> Lifetimes {
121 Lifetimes(self.params.iter())
122 }
123
124 /// Returns an
125 /// <code
126 /// style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
127 /// href="struct.LifetimeDef.html"><code
128 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
129 /// style="padding-left:0;">&gt;</code>
130 /// over the lifetime parameters in `self.params`.
131 pub fn lifetimes_mut(&mut self) -> LifetimesMut {
132 LifetimesMut(self.params.iter_mut())
133 }
134
135 /// Returns an
136 /// <code
137 /// style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
138 /// href="struct.ConstParam.html"><code
139 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
140 /// style="padding-left:0;">&gt;</code>
141 /// over the constant parameters in `self.params`.
142 pub fn const_params(&self) -> ConstParams {
143 ConstParams(self.params.iter())
144 }
145
146 /// Returns an
147 /// <code
148 /// style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
149 /// href="struct.ConstParam.html"><code
150 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
151 /// style="padding-left:0;">&gt;</code>
152 /// over the constant parameters in `self.params`.
153 pub fn const_params_mut(&mut self) -> ConstParamsMut {
154 ConstParamsMut(self.params.iter_mut())
155 }
156
157 /// Initializes an empty `where`-clause if there is not one present already.
158 pub fn make_where_clause(&mut self) -> &mut WhereClause {
159 // This is Option::get_or_insert_with in Rust 1.20.
160 if self.where_clause.is_none() {
161 self.where_clause = Some(WhereClause {
162 where_token: <Token![where]>::default(),
163 predicates: Punctuated::new(),
164 });
165 }
166 match &mut self.where_clause {
167 Some(where_clause) => where_clause,
168 None => unreachable!(),
169 }
170 }
171}
172
173pub struct TypeParams<'a>(Iter<'a, GenericParam>);
174
175impl<'a> Iterator for TypeParams<'a> {
176 type Item = &'a TypeParam;
177
178 fn next(&mut self) -> Option<Self::Item> {
179 let next = match self.0.next() {
180 Some(item) => item,
181 None => return None,
182 };
183 if let GenericParam::Type(type_param) = next {
184 Some(type_param)
185 } else {
186 self.next()
187 }
188 }
189}
190
191pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
192
193impl<'a> Iterator for TypeParamsMut<'a> {
194 type Item = &'a mut TypeParam;
195
196 fn next(&mut self) -> Option<Self::Item> {
197 let next = match self.0.next() {
198 Some(item) => item,
199 None => return None,
200 };
201 if let GenericParam::Type(type_param) = next {
202 Some(type_param)
203 } else {
204 self.next()
205 }
206 }
207}
208
209pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
210
211impl<'a> Iterator for Lifetimes<'a> {
212 type Item = &'a LifetimeDef;
213
214 fn next(&mut self) -> Option<Self::Item> {
215 let next = match self.0.next() {
216 Some(item) => item,
217 None => return None,
218 };
219 if let GenericParam::Lifetime(lifetime) = next {
220 Some(lifetime)
221 } else {
222 self.next()
223 }
224 }
225}
226
227pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
228
229impl<'a> Iterator for LifetimesMut<'a> {
230 type Item = &'a mut LifetimeDef;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 let next = match self.0.next() {
234 Some(item) => item,
235 None => return None,
236 };
237 if let GenericParam::Lifetime(lifetime) = next {
238 Some(lifetime)
239 } else {
240 self.next()
241 }
242 }
243}
244
245pub struct ConstParams<'a>(Iter<'a, GenericParam>);
246
247impl<'a> Iterator for ConstParams<'a> {
248 type Item = &'a ConstParam;
249
250 fn next(&mut self) -> Option<Self::Item> {
251 let next = match self.0.next() {
252 Some(item) => item,
253 None => return None,
254 };
255 if let GenericParam::Const(const_param) = next {
256 Some(const_param)
257 } else {
258 self.next()
259 }
260 }
261}
262
263pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
264
265impl<'a> Iterator for ConstParamsMut<'a> {
266 type Item = &'a mut ConstParam;
267
268 fn next(&mut self) -> Option<Self::Item> {
269 let next = match self.0.next() {
270 Some(item) => item,
271 None => return None,
272 };
273 if let GenericParam::Const(const_param) = next {
274 Some(const_param)
275 } else {
276 self.next()
277 }
278 }
279}
280
281/// Returned by `Generics::split_for_impl`.
282///
283/// *This type is available if Syn is built with the `"derive"` or `"full"`
284/// feature and the `"printing"` feature.*
285#[cfg(feature = "printing")]
286#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
287#[cfg_attr(feature = "clone-impls", derive(Clone))]
288pub struct ImplGenerics<'a>(&'a Generics);
289
290/// Returned by `Generics::split_for_impl`.
291///
292/// *This type is available if Syn is built with the `"derive"` or `"full"`
293/// feature and the `"printing"` feature.*
294#[cfg(feature = "printing")]
295#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
296#[cfg_attr(feature = "clone-impls", derive(Clone))]
297pub struct TypeGenerics<'a>(&'a Generics);
298
299/// Returned by `TypeGenerics::as_turbofish`.
300///
301/// *This type is available if Syn is built with the `"derive"` or `"full"`
302/// feature and the `"printing"` feature.*
303#[cfg(feature = "printing")]
304#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
305#[cfg_attr(feature = "clone-impls", derive(Clone))]
306pub struct Turbofish<'a>(&'a Generics);
307
308#[cfg(feature = "printing")]
309impl Generics {
310 /// Split a type's generics into the pieces required for impl'ing a trait
311 /// for that type.
312 ///
313 /// ```
314 /// # use proc_macro2::{Span, Ident};
315 /// # use quote::quote;
316 /// #
60c5eb7d
XL
317 /// # let generics: syn::Generics = Default::default();
318 /// # let name = Ident::new("MyType", Span::call_site());
e74abb32
XL
319 /// #
320 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
321 /// quote! {
322 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
323 /// // ...
324 /// }
325 /// }
60c5eb7d 326 /// # ;
e74abb32
XL
327 /// ```
328 ///
329 /// *This method is available if Syn is built with the `"derive"` or
330 /// `"full"` feature and the `"printing"` feature.*
331 pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
332 (
333 ImplGenerics(self),
334 TypeGenerics(self),
335 self.where_clause.as_ref(),
336 )
337 }
338}
339
340#[cfg(feature = "printing")]
341impl<'a> TypeGenerics<'a> {
342 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
343 ///
344 /// *This method is available if Syn is built with the `"derive"` or
345 /// `"full"` feature and the `"printing"` feature.*
346 pub fn as_turbofish(&self) -> Turbofish {
347 Turbofish(self.0)
348 }
349}
350
351ast_struct! {
352 /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
353 ///
354 /// *This type is available if Syn is built with the `"derive"` or `"full"`
355 /// feature.*
356 #[derive(Default)]
357 pub struct BoundLifetimes {
358 pub for_token: Token![for],
359 pub lt_token: Token![<],
360 pub lifetimes: Punctuated<LifetimeDef, Token![,]>,
361 pub gt_token: Token![>],
362 }
363}
364
365impl LifetimeDef {
366 pub fn new(lifetime: Lifetime) -> Self {
367 LifetimeDef {
368 attrs: Vec::new(),
369 lifetime,
370 colon_token: None,
371 bounds: Punctuated::new(),
372 }
373 }
374}
375
376impl From<Ident> for TypeParam {
377 fn from(ident: Ident) -> Self {
378 TypeParam {
379 attrs: vec![],
380 ident,
381 colon_token: None,
382 bounds: Punctuated::new(),
383 eq_token: None,
384 default: None,
385 }
386 }
387}
388
389ast_enum_of_structs! {
390 /// A trait or lifetime used as a bound on a type parameter.
391 ///
392 /// *This type is available if Syn is built with the `"derive"` or `"full"`
393 /// feature.*
394 pub enum TypeParamBound {
395 Trait(TraitBound),
396 Lifetime(Lifetime),
397 }
398}
399
400ast_struct! {
401 /// A trait used as a bound on a type parameter.
402 ///
403 /// *This type is available if Syn is built with the `"derive"` or `"full"`
404 /// feature.*
405 pub struct TraitBound {
406 pub paren_token: Option<token::Paren>,
407 pub modifier: TraitBoundModifier,
408 /// The `for<'a>` in `for<'a> Foo<&'a T>`
409 pub lifetimes: Option<BoundLifetimes>,
410 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
411 pub path: Path,
412 }
413}
414
415ast_enum! {
416 /// A modifier on a trait bound, currently only used for the `?` in
417 /// `?Sized`.
418 ///
419 /// *This type is available if Syn is built with the `"derive"` or `"full"`
420 /// feature.*
421 #[cfg_attr(feature = "clone-impls", derive(Copy))]
422 pub enum TraitBoundModifier {
423 None,
424 Maybe(Token![?]),
425 }
426}
427
428ast_struct! {
429 /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
430 /// 'static`.
431 ///
432 /// *This type is available if Syn is built with the `"derive"` or `"full"`
433 /// feature.*
434 pub struct WhereClause {
435 pub where_token: Token![where],
436 pub predicates: Punctuated<WherePredicate, Token![,]>,
437 }
438}
439
440ast_enum_of_structs! {
441 /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
442 ///
443 /// *This type is available if Syn is built with the `"derive"` or `"full"`
444 /// feature.*
445 ///
446 /// # Syntax tree enum
447 ///
448 /// This type is a [syntax tree enum].
449 ///
450 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
451 //
452 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
453 // blocked on https://github.com/rust-lang/rust/issues/62833
454 pub enum WherePredicate {
455 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
456 Type(PredicateType),
457
458 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
459 Lifetime(PredicateLifetime),
460
461 /// An equality predicate in a `where` clause (unsupported).
462 Eq(PredicateEq),
463 }
464}
465
466ast_struct! {
467 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
468 ///
469 /// *This type is available if Syn is built with the `"derive"` or
470 /// `"full"` feature.*
471 pub struct PredicateType {
472 /// Any lifetimes from a `for` binding
473 pub lifetimes: Option<BoundLifetimes>,
474 /// The type being bounded
475 pub bounded_ty: Type,
476 pub colon_token: Token![:],
477 /// Trait and lifetime bounds (`Clone+Send+'static`)
478 pub bounds: Punctuated<TypeParamBound, Token![+]>,
479 }
480}
481
482ast_struct! {
483 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
484 ///
485 /// *This type is available if Syn is built with the `"derive"` or
486 /// `"full"` feature.*
487 pub struct PredicateLifetime {
488 pub lifetime: Lifetime,
489 pub colon_token: Token![:],
490 pub bounds: Punctuated<Lifetime, Token![+]>,
491 }
492}
493
494ast_struct! {
495 /// An equality predicate in a `where` clause (unsupported).
496 ///
497 /// *This type is available if Syn is built with the `"derive"` or
498 /// `"full"` feature.*
499 pub struct PredicateEq {
500 pub lhs_ty: Type,
501 pub eq_token: Token![=],
502 pub rhs_ty: Type,
503 }
504}
505
506#[cfg(feature = "parsing")]
507pub mod parsing {
508 use super::*;
509
510 use crate::parse::{Parse, ParseStream, Result};
511
512 impl Parse for Generics {
513 fn parse(input: ParseStream) -> Result<Self> {
514 if !input.peek(Token![<]) {
515 return Ok(Generics::default());
516 }
517
518 let lt_token: Token![<] = input.parse()?;
519
520 let mut params = Punctuated::new();
521 let mut allow_lifetime_param = true;
522 let mut allow_type_param = true;
523 loop {
524 if input.peek(Token![>]) {
525 break;
526 }
527
528 let attrs = input.call(Attribute::parse_outer)?;
529 let lookahead = input.lookahead1();
530 if allow_lifetime_param && lookahead.peek(Lifetime) {
531 params.push_value(GenericParam::Lifetime(LifetimeDef {
532 attrs,
533 ..input.parse()?
534 }));
535 } else if allow_type_param && lookahead.peek(Ident) {
536 allow_lifetime_param = false;
537 params.push_value(GenericParam::Type(TypeParam {
538 attrs,
539 ..input.parse()?
540 }));
541 } else if lookahead.peek(Token![const]) {
542 allow_lifetime_param = false;
543 allow_type_param = false;
544 params.push_value(GenericParam::Const(ConstParam {
545 attrs,
546 ..input.parse()?
547 }));
548 } else {
549 return Err(lookahead.error());
550 }
551
552 if input.peek(Token![>]) {
553 break;
554 }
555 let punct = input.parse()?;
556 params.push_punct(punct);
557 }
558
559 let gt_token: Token![>] = input.parse()?;
560
561 Ok(Generics {
562 lt_token: Some(lt_token),
563 params,
564 gt_token: Some(gt_token),
565 where_clause: None,
566 })
567 }
568 }
569
570 impl Parse for GenericParam {
571 fn parse(input: ParseStream) -> Result<Self> {
572 let attrs = input.call(Attribute::parse_outer)?;
573
574 let lookahead = input.lookahead1();
575 if lookahead.peek(Ident) {
576 Ok(GenericParam::Type(TypeParam {
577 attrs,
578 ..input.parse()?
579 }))
580 } else if lookahead.peek(Lifetime) {
581 Ok(GenericParam::Lifetime(LifetimeDef {
582 attrs,
583 ..input.parse()?
584 }))
585 } else if lookahead.peek(Token![const]) {
586 Ok(GenericParam::Const(ConstParam {
587 attrs,
588 ..input.parse()?
589 }))
590 } else {
591 Err(lookahead.error())
592 }
593 }
594 }
595
596 impl Parse for LifetimeDef {
597 fn parse(input: ParseStream) -> Result<Self> {
598 let has_colon;
599 Ok(LifetimeDef {
600 attrs: input.call(Attribute::parse_outer)?,
601 lifetime: input.parse()?,
602 colon_token: {
603 if input.peek(Token![:]) {
604 has_colon = true;
605 Some(input.parse()?)
606 } else {
607 has_colon = false;
608 None
609 }
610 },
611 bounds: {
612 let mut bounds = Punctuated::new();
613 if has_colon {
614 loop {
615 if input.peek(Token![,]) || input.peek(Token![>]) {
616 break;
617 }
618 let value = input.parse()?;
619 bounds.push_value(value);
620 if !input.peek(Token![+]) {
621 break;
622 }
623 let punct = input.parse()?;
624 bounds.push_punct(punct);
625 }
626 }
627 bounds
628 },
629 })
630 }
631 }
632
633 impl Parse for BoundLifetimes {
634 fn parse(input: ParseStream) -> Result<Self> {
635 Ok(BoundLifetimes {
636 for_token: input.parse()?,
637 lt_token: input.parse()?,
638 lifetimes: {
639 let mut lifetimes = Punctuated::new();
640 while !input.peek(Token![>]) {
641 lifetimes.push_value(input.parse()?);
642 if input.peek(Token![>]) {
643 break;
644 }
645 lifetimes.push_punct(input.parse()?);
646 }
647 lifetimes
648 },
649 gt_token: input.parse()?,
650 })
651 }
652 }
653
654 impl Parse for Option<BoundLifetimes> {
655 fn parse(input: ParseStream) -> Result<Self> {
656 if input.peek(Token![for]) {
657 input.parse().map(Some)
658 } else {
659 Ok(None)
660 }
661 }
662 }
663
664 impl Parse for TypeParam {
665 fn parse(input: ParseStream) -> Result<Self> {
666 let has_colon;
667 let has_default;
668 Ok(TypeParam {
669 attrs: input.call(Attribute::parse_outer)?,
670 ident: input.parse()?,
671 colon_token: {
672 if input.peek(Token![:]) {
673 has_colon = true;
674 Some(input.parse()?)
675 } else {
676 has_colon = false;
677 None
678 }
679 },
680 bounds: {
681 let mut bounds = Punctuated::new();
682 if has_colon {
683 loop {
684 if input.peek(Token![,])
685 || input.peek(Token![>])
686 || input.peek(Token![=])
687 {
688 break;
689 }
690 let value = input.parse()?;
691 bounds.push_value(value);
692 if !input.peek(Token![+]) {
693 break;
694 }
695 let punct = input.parse()?;
696 bounds.push_punct(punct);
697 }
698 }
699 bounds
700 },
701 eq_token: {
702 if input.peek(Token![=]) {
703 has_default = true;
704 Some(input.parse()?)
705 } else {
706 has_default = false;
707 None
708 }
709 },
710 default: {
711 if has_default {
712 Some(input.parse()?)
713 } else {
714 None
715 }
716 },
717 })
718 }
719 }
720
721 impl Parse for TypeParamBound {
722 fn parse(input: ParseStream) -> Result<Self> {
723 if input.peek(Lifetime) {
724 return input.parse().map(TypeParamBound::Lifetime);
725 }
726
727 if input.peek(token::Paren) {
728 let content;
729 let paren_token = parenthesized!(content in input);
730 let mut bound: TraitBound = content.parse()?;
731 bound.paren_token = Some(paren_token);
732 return Ok(TypeParamBound::Trait(bound));
733 }
734
735 input.parse().map(TypeParamBound::Trait)
736 }
737 }
738
739 impl Parse for TraitBound {
740 fn parse(input: ParseStream) -> Result<Self> {
741 let modifier: TraitBoundModifier = input.parse()?;
742 let lifetimes: Option<BoundLifetimes> = input.parse()?;
743
744 let mut path: Path = input.parse()?;
745 if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) {
746 let parenthesized = PathArguments::Parenthesized(input.parse()?);
747 path.segments.last_mut().unwrap().arguments = parenthesized;
748 }
749
750 Ok(TraitBound {
751 paren_token: None,
752 modifier,
753 lifetimes,
754 path,
755 })
756 }
757 }
758
759 impl Parse for TraitBoundModifier {
760 fn parse(input: ParseStream) -> Result<Self> {
761 if input.peek(Token![?]) {
762 input.parse().map(TraitBoundModifier::Maybe)
763 } else {
764 Ok(TraitBoundModifier::None)
765 }
766 }
767 }
768
769 impl Parse for ConstParam {
770 fn parse(input: ParseStream) -> Result<Self> {
771 let mut default = None;
772 Ok(ConstParam {
773 attrs: input.call(Attribute::parse_outer)?,
774 const_token: input.parse()?,
775 ident: input.parse()?,
776 colon_token: input.parse()?,
777 ty: input.parse()?,
778 eq_token: {
779 if input.peek(Token![=]) {
780 let eq_token = input.parse()?;
781 default = Some(input.parse::<Expr>()?);
782 Some(eq_token)
783 } else {
784 None
785 }
786 },
787 default,
788 })
789 }
790 }
791
792 impl Parse for WhereClause {
793 fn parse(input: ParseStream) -> Result<Self> {
794 Ok(WhereClause {
795 where_token: input.parse()?,
796 predicates: {
797 let mut predicates = Punctuated::new();
798 loop {
799 if input.is_empty()
800 || input.peek(token::Brace)
801 || input.peek(Token![,])
802 || input.peek(Token![;])
803 || input.peek(Token![:]) && !input.peek(Token![::])
804 || input.peek(Token![=])
805 {
806 break;
807 }
808 let value = input.parse()?;
809 predicates.push_value(value);
810 if !input.peek(Token![,]) {
811 break;
812 }
813 let punct = input.parse()?;
814 predicates.push_punct(punct);
815 }
816 predicates
817 },
818 })
819 }
820 }
821
822 impl Parse for Option<WhereClause> {
823 fn parse(input: ParseStream) -> Result<Self> {
824 if input.peek(Token![where]) {
825 input.parse().map(Some)
826 } else {
827 Ok(None)
828 }
829 }
830 }
831
832 impl Parse for WherePredicate {
833 fn parse(input: ParseStream) -> Result<Self> {
834 if input.peek(Lifetime) && input.peek2(Token![:]) {
835 Ok(WherePredicate::Lifetime(PredicateLifetime {
836 lifetime: input.parse()?,
837 colon_token: input.parse()?,
838 bounds: {
839 let mut bounds = Punctuated::new();
840 loop {
841 if input.is_empty()
842 || input.peek(token::Brace)
843 || input.peek(Token![,])
844 || input.peek(Token![;])
845 || input.peek(Token![:])
846 || input.peek(Token![=])
847 {
848 break;
849 }
850 let value = input.parse()?;
851 bounds.push_value(value);
852 if !input.peek(Token![+]) {
853 break;
854 }
855 let punct = input.parse()?;
856 bounds.push_punct(punct);
857 }
858 bounds
859 },
860 }))
861 } else {
862 Ok(WherePredicate::Type(PredicateType {
863 lifetimes: input.parse()?,
864 bounded_ty: input.parse()?,
865 colon_token: input.parse()?,
866 bounds: {
867 let mut bounds = Punctuated::new();
868 loop {
869 if input.is_empty()
870 || input.peek(token::Brace)
871 || input.peek(Token![,])
872 || input.peek(Token![;])
873 || input.peek(Token![:]) && !input.peek(Token![::])
874 || input.peek(Token![=])
875 {
876 break;
877 }
878 let value = input.parse()?;
879 bounds.push_value(value);
880 if !input.peek(Token![+]) {
881 break;
882 }
883 let punct = input.parse()?;
884 bounds.push_punct(punct);
885 }
886 bounds
887 },
888 }))
889 }
890 }
891 }
892}
893
894#[cfg(feature = "printing")]
895mod printing {
896 use super::*;
897
898 use proc_macro2::TokenStream;
899 use quote::{ToTokens, TokenStreamExt};
900
901 use crate::attr::FilterAttrs;
902 use crate::print::TokensOrDefault;
903
904 impl ToTokens for Generics {
905 fn to_tokens(&self, tokens: &mut TokenStream) {
906 if self.params.is_empty() {
907 return;
908 }
909
910 TokensOrDefault(&self.lt_token).to_tokens(tokens);
911
912 // Print lifetimes before types and consts, regardless of their
913 // order in self.params.
914 //
915 // TODO: ordering rules for const parameters vs type parameters have
916 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
917 let mut trailing_or_empty = true;
918 for param in self.params.pairs() {
919 if let GenericParam::Lifetime(_) = **param.value() {
920 param.to_tokens(tokens);
921 trailing_or_empty = param.punct().is_some();
922 }
923 }
924 for param in self.params.pairs() {
925 match **param.value() {
926 GenericParam::Type(_) | GenericParam::Const(_) => {
927 if !trailing_or_empty {
928 <Token![,]>::default().to_tokens(tokens);
929 trailing_or_empty = true;
930 }
931 param.to_tokens(tokens);
932 }
933 GenericParam::Lifetime(_) => {}
934 }
935 }
936
937 TokensOrDefault(&self.gt_token).to_tokens(tokens);
938 }
939 }
940
941 impl<'a> ToTokens for ImplGenerics<'a> {
942 fn to_tokens(&self, tokens: &mut TokenStream) {
943 if self.0.params.is_empty() {
944 return;
945 }
946
947 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
948
949 // Print lifetimes before types and consts, regardless of their
950 // order in self.params.
951 //
952 // TODO: ordering rules for const parameters vs type parameters have
953 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
954 let mut trailing_or_empty = true;
955 for param in self.0.params.pairs() {
956 if let GenericParam::Lifetime(_) = **param.value() {
957 param.to_tokens(tokens);
958 trailing_or_empty = param.punct().is_some();
959 }
960 }
961 for param in self.0.params.pairs() {
962 if let GenericParam::Lifetime(_) = **param.value() {
963 continue;
964 }
965 if !trailing_or_empty {
966 <Token![,]>::default().to_tokens(tokens);
967 trailing_or_empty = true;
968 }
969 match *param.value() {
970 GenericParam::Lifetime(_) => unreachable!(),
971 GenericParam::Type(param) => {
972 // Leave off the type parameter defaults
973 tokens.append_all(param.attrs.outer());
974 param.ident.to_tokens(tokens);
975 if !param.bounds.is_empty() {
976 TokensOrDefault(&param.colon_token).to_tokens(tokens);
977 param.bounds.to_tokens(tokens);
978 }
979 }
980 GenericParam::Const(param) => {
981 // Leave off the const parameter defaults
982 tokens.append_all(param.attrs.outer());
983 param.const_token.to_tokens(tokens);
984 param.ident.to_tokens(tokens);
985 param.colon_token.to_tokens(tokens);
986 param.ty.to_tokens(tokens);
987 }
988 }
989 param.punct().to_tokens(tokens);
990 }
991
992 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
993 }
994 }
995
996 impl<'a> ToTokens for TypeGenerics<'a> {
997 fn to_tokens(&self, tokens: &mut TokenStream) {
998 if self.0.params.is_empty() {
999 return;
1000 }
1001
1002 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1003
1004 // Print lifetimes before types and consts, regardless of their
1005 // order in self.params.
1006 //
1007 // TODO: ordering rules for const parameters vs type parameters have
1008 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1009 let mut trailing_or_empty = true;
1010 for param in self.0.params.pairs() {
1011 if let GenericParam::Lifetime(def) = *param.value() {
1012 // Leave off the lifetime bounds and attributes
1013 def.lifetime.to_tokens(tokens);
1014 param.punct().to_tokens(tokens);
1015 trailing_or_empty = param.punct().is_some();
1016 }
1017 }
1018 for param in self.0.params.pairs() {
1019 if let GenericParam::Lifetime(_) = **param.value() {
1020 continue;
1021 }
1022 if !trailing_or_empty {
1023 <Token![,]>::default().to_tokens(tokens);
1024 trailing_or_empty = true;
1025 }
1026 match *param.value() {
1027 GenericParam::Lifetime(_) => unreachable!(),
1028 GenericParam::Type(param) => {
1029 // Leave off the type parameter defaults
1030 param.ident.to_tokens(tokens);
1031 }
1032 GenericParam::Const(param) => {
1033 // Leave off the const parameter defaults
1034 param.ident.to_tokens(tokens);
1035 }
1036 }
1037 param.punct().to_tokens(tokens);
1038 }
1039
1040 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1041 }
1042 }
1043
1044 impl<'a> ToTokens for Turbofish<'a> {
1045 fn to_tokens(&self, tokens: &mut TokenStream) {
1046 if !self.0.params.is_empty() {
1047 <Token![::]>::default().to_tokens(tokens);
1048 TypeGenerics(self.0).to_tokens(tokens);
1049 }
1050 }
1051 }
1052
1053 impl ToTokens for BoundLifetimes {
1054 fn to_tokens(&self, tokens: &mut TokenStream) {
1055 self.for_token.to_tokens(tokens);
1056 self.lt_token.to_tokens(tokens);
1057 self.lifetimes.to_tokens(tokens);
1058 self.gt_token.to_tokens(tokens);
1059 }
1060 }
1061
1062 impl ToTokens for LifetimeDef {
1063 fn to_tokens(&self, tokens: &mut TokenStream) {
1064 tokens.append_all(self.attrs.outer());
1065 self.lifetime.to_tokens(tokens);
1066 if !self.bounds.is_empty() {
1067 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1068 self.bounds.to_tokens(tokens);
1069 }
1070 }
1071 }
1072
1073 impl ToTokens for TypeParam {
1074 fn to_tokens(&self, tokens: &mut TokenStream) {
1075 tokens.append_all(self.attrs.outer());
1076 self.ident.to_tokens(tokens);
1077 if !self.bounds.is_empty() {
1078 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1079 self.bounds.to_tokens(tokens);
1080 }
1081 if self.default.is_some() {
1082 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1083 self.default.to_tokens(tokens);
1084 }
1085 }
1086 }
1087
1088 impl ToTokens for TraitBound {
1089 fn to_tokens(&self, tokens: &mut TokenStream) {
1090 let to_tokens = |tokens: &mut TokenStream| {
1091 self.modifier.to_tokens(tokens);
1092 self.lifetimes.to_tokens(tokens);
1093 self.path.to_tokens(tokens);
1094 };
1095 match &self.paren_token {
1096 Some(paren) => paren.surround(tokens, to_tokens),
1097 None => to_tokens(tokens),
1098 }
1099 }
1100 }
1101
1102 impl ToTokens for TraitBoundModifier {
1103 fn to_tokens(&self, tokens: &mut TokenStream) {
1104 match self {
1105 TraitBoundModifier::None => {}
1106 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1107 }
1108 }
1109 }
1110
1111 impl ToTokens for ConstParam {
1112 fn to_tokens(&self, tokens: &mut TokenStream) {
1113 tokens.append_all(self.attrs.outer());
1114 self.const_token.to_tokens(tokens);
1115 self.ident.to_tokens(tokens);
1116 self.colon_token.to_tokens(tokens);
1117 self.ty.to_tokens(tokens);
1118 if self.default.is_some() {
1119 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1120 self.default.to_tokens(tokens);
1121 }
1122 }
1123 }
1124
1125 impl ToTokens for WhereClause {
1126 fn to_tokens(&self, tokens: &mut TokenStream) {
1127 if !self.predicates.is_empty() {
1128 self.where_token.to_tokens(tokens);
1129 self.predicates.to_tokens(tokens);
1130 }
1131 }
1132 }
1133
1134 impl ToTokens for PredicateType {
1135 fn to_tokens(&self, tokens: &mut TokenStream) {
1136 self.lifetimes.to_tokens(tokens);
1137 self.bounded_ty.to_tokens(tokens);
1138 self.colon_token.to_tokens(tokens);
1139 self.bounds.to_tokens(tokens);
1140 }
1141 }
1142
1143 impl ToTokens for PredicateLifetime {
1144 fn to_tokens(&self, tokens: &mut TokenStream) {
1145 self.lifetime.to_tokens(tokens);
1146 self.colon_token.to_tokens(tokens);
1147 self.bounds.to_tokens(tokens);
1148 }
1149 }
1150
1151 impl ToTokens for PredicateEq {
1152 fn to_tokens(&self, tokens: &mut TokenStream) {
1153 self.lhs_ty.to_tokens(tokens);
1154 self.eq_token.to_tokens(tokens);
1155 self.rhs_ty.to_tokens(tokens);
1156 }
1157 }
1158}