]> git.proxmox.com Git - rustc.git/blob - vendor/syn/src/generics.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / vendor / syn / src / generics.rs
1 use super::*;
2 use crate::punctuated::{Iter, IterMut, Punctuated};
3
4 ast_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
19 ast_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
46 ast_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
61 ast_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
74 ast_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
90 impl 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
173 pub struct TypeParams<'a>(Iter<'a, GenericParam>);
174
175 impl<'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
191 pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
192
193 impl<'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
209 pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
210
211 impl<'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
227 pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
228
229 impl<'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
245 pub struct ConstParams<'a>(Iter<'a, GenericParam>);
246
247 impl<'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
263 pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
264
265 impl<'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))]
288 pub 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))]
297 pub 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))]
306 pub struct Turbofish<'a>(&'a Generics);
307
308 #[cfg(feature = "printing")]
309 impl 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 /// #
317 /// # fn main() {
318 /// # let generics: syn::Generics = Default::default();
319 /// # let name = Ident::new("MyType", Span::call_site());
320 /// #
321 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
322 /// quote! {
323 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
324 /// // ...
325 /// }
326 /// }
327 /// # ;
328 /// # }
329 /// ```
330 ///
331 /// *This method is available if Syn is built with the `"derive"` or
332 /// `"full"` feature and the `"printing"` feature.*
333 pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
334 (
335 ImplGenerics(self),
336 TypeGenerics(self),
337 self.where_clause.as_ref(),
338 )
339 }
340 }
341
342 #[cfg(feature = "printing")]
343 impl<'a> TypeGenerics<'a> {
344 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
345 ///
346 /// *This method is available if Syn is built with the `"derive"` or
347 /// `"full"` feature and the `"printing"` feature.*
348 pub fn as_turbofish(&self) -> Turbofish {
349 Turbofish(self.0)
350 }
351 }
352
353 ast_struct! {
354 /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
355 ///
356 /// *This type is available if Syn is built with the `"derive"` or `"full"`
357 /// feature.*
358 #[derive(Default)]
359 pub struct BoundLifetimes {
360 pub for_token: Token![for],
361 pub lt_token: Token![<],
362 pub lifetimes: Punctuated<LifetimeDef, Token![,]>,
363 pub gt_token: Token![>],
364 }
365 }
366
367 impl LifetimeDef {
368 pub fn new(lifetime: Lifetime) -> Self {
369 LifetimeDef {
370 attrs: Vec::new(),
371 lifetime,
372 colon_token: None,
373 bounds: Punctuated::new(),
374 }
375 }
376 }
377
378 impl From<Ident> for TypeParam {
379 fn from(ident: Ident) -> Self {
380 TypeParam {
381 attrs: vec![],
382 ident,
383 colon_token: None,
384 bounds: Punctuated::new(),
385 eq_token: None,
386 default: None,
387 }
388 }
389 }
390
391 ast_enum_of_structs! {
392 /// A trait or lifetime used as a bound on a type parameter.
393 ///
394 /// *This type is available if Syn is built with the `"derive"` or `"full"`
395 /// feature.*
396 pub enum TypeParamBound {
397 Trait(TraitBound),
398 Lifetime(Lifetime),
399 }
400 }
401
402 ast_struct! {
403 /// A trait used as a bound on a type parameter.
404 ///
405 /// *This type is available if Syn is built with the `"derive"` or `"full"`
406 /// feature.*
407 pub struct TraitBound {
408 pub paren_token: Option<token::Paren>,
409 pub modifier: TraitBoundModifier,
410 /// The `for<'a>` in `for<'a> Foo<&'a T>`
411 pub lifetimes: Option<BoundLifetimes>,
412 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
413 pub path: Path,
414 }
415 }
416
417 ast_enum! {
418 /// A modifier on a trait bound, currently only used for the `?` in
419 /// `?Sized`.
420 ///
421 /// *This type is available if Syn is built with the `"derive"` or `"full"`
422 /// feature.*
423 #[cfg_attr(feature = "clone-impls", derive(Copy))]
424 pub enum TraitBoundModifier {
425 None,
426 Maybe(Token![?]),
427 }
428 }
429
430 ast_struct! {
431 /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
432 /// 'static`.
433 ///
434 /// *This type is available if Syn is built with the `"derive"` or `"full"`
435 /// feature.*
436 pub struct WhereClause {
437 pub where_token: Token![where],
438 pub predicates: Punctuated<WherePredicate, Token![,]>,
439 }
440 }
441
442 ast_enum_of_structs! {
443 /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
444 ///
445 /// *This type is available if Syn is built with the `"derive"` or `"full"`
446 /// feature.*
447 ///
448 /// # Syntax tree enum
449 ///
450 /// This type is a [syntax tree enum].
451 ///
452 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
453 //
454 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
455 // blocked on https://github.com/rust-lang/rust/issues/62833
456 pub enum WherePredicate {
457 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
458 Type(PredicateType),
459
460 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
461 Lifetime(PredicateLifetime),
462
463 /// An equality predicate in a `where` clause (unsupported).
464 Eq(PredicateEq),
465 }
466 }
467
468 ast_struct! {
469 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
470 ///
471 /// *This type is available if Syn is built with the `"derive"` or
472 /// `"full"` feature.*
473 pub struct PredicateType {
474 /// Any lifetimes from a `for` binding
475 pub lifetimes: Option<BoundLifetimes>,
476 /// The type being bounded
477 pub bounded_ty: Type,
478 pub colon_token: Token![:],
479 /// Trait and lifetime bounds (`Clone+Send+'static`)
480 pub bounds: Punctuated<TypeParamBound, Token![+]>,
481 }
482 }
483
484 ast_struct! {
485 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
486 ///
487 /// *This type is available if Syn is built with the `"derive"` or
488 /// `"full"` feature.*
489 pub struct PredicateLifetime {
490 pub lifetime: Lifetime,
491 pub colon_token: Token![:],
492 pub bounds: Punctuated<Lifetime, Token![+]>,
493 }
494 }
495
496 ast_struct! {
497 /// An equality predicate in a `where` clause (unsupported).
498 ///
499 /// *This type is available if Syn is built with the `"derive"` or
500 /// `"full"` feature.*
501 pub struct PredicateEq {
502 pub lhs_ty: Type,
503 pub eq_token: Token![=],
504 pub rhs_ty: Type,
505 }
506 }
507
508 #[cfg(feature = "parsing")]
509 pub mod parsing {
510 use super::*;
511
512 use crate::parse::{Parse, ParseStream, Result};
513
514 impl Parse for Generics {
515 fn parse(input: ParseStream) -> Result<Self> {
516 if !input.peek(Token![<]) {
517 return Ok(Generics::default());
518 }
519
520 let lt_token: Token![<] = input.parse()?;
521
522 let mut params = Punctuated::new();
523 let mut allow_lifetime_param = true;
524 let mut allow_type_param = true;
525 loop {
526 if input.peek(Token![>]) {
527 break;
528 }
529
530 let attrs = input.call(Attribute::parse_outer)?;
531 let lookahead = input.lookahead1();
532 if allow_lifetime_param && lookahead.peek(Lifetime) {
533 params.push_value(GenericParam::Lifetime(LifetimeDef {
534 attrs,
535 ..input.parse()?
536 }));
537 } else if allow_type_param && lookahead.peek(Ident) {
538 allow_lifetime_param = false;
539 params.push_value(GenericParam::Type(TypeParam {
540 attrs,
541 ..input.parse()?
542 }));
543 } else if lookahead.peek(Token![const]) {
544 allow_lifetime_param = false;
545 allow_type_param = false;
546 params.push_value(GenericParam::Const(ConstParam {
547 attrs,
548 ..input.parse()?
549 }));
550 } else {
551 return Err(lookahead.error());
552 }
553
554 if input.peek(Token![>]) {
555 break;
556 }
557 let punct = input.parse()?;
558 params.push_punct(punct);
559 }
560
561 let gt_token: Token![>] = input.parse()?;
562
563 Ok(Generics {
564 lt_token: Some(lt_token),
565 params,
566 gt_token: Some(gt_token),
567 where_clause: None,
568 })
569 }
570 }
571
572 impl Parse for GenericParam {
573 fn parse(input: ParseStream) -> Result<Self> {
574 let attrs = input.call(Attribute::parse_outer)?;
575
576 let lookahead = input.lookahead1();
577 if lookahead.peek(Ident) {
578 Ok(GenericParam::Type(TypeParam {
579 attrs,
580 ..input.parse()?
581 }))
582 } else if lookahead.peek(Lifetime) {
583 Ok(GenericParam::Lifetime(LifetimeDef {
584 attrs,
585 ..input.parse()?
586 }))
587 } else if lookahead.peek(Token![const]) {
588 Ok(GenericParam::Const(ConstParam {
589 attrs,
590 ..input.parse()?
591 }))
592 } else {
593 Err(lookahead.error())
594 }
595 }
596 }
597
598 impl Parse for LifetimeDef {
599 fn parse(input: ParseStream) -> Result<Self> {
600 let has_colon;
601 Ok(LifetimeDef {
602 attrs: input.call(Attribute::parse_outer)?,
603 lifetime: input.parse()?,
604 colon_token: {
605 if input.peek(Token![:]) {
606 has_colon = true;
607 Some(input.parse()?)
608 } else {
609 has_colon = false;
610 None
611 }
612 },
613 bounds: {
614 let mut bounds = Punctuated::new();
615 if has_colon {
616 loop {
617 if input.peek(Token![,]) || input.peek(Token![>]) {
618 break;
619 }
620 let value = input.parse()?;
621 bounds.push_value(value);
622 if !input.peek(Token![+]) {
623 break;
624 }
625 let punct = input.parse()?;
626 bounds.push_punct(punct);
627 }
628 }
629 bounds
630 },
631 })
632 }
633 }
634
635 impl Parse for BoundLifetimes {
636 fn parse(input: ParseStream) -> Result<Self> {
637 Ok(BoundLifetimes {
638 for_token: input.parse()?,
639 lt_token: input.parse()?,
640 lifetimes: {
641 let mut lifetimes = Punctuated::new();
642 while !input.peek(Token![>]) {
643 lifetimes.push_value(input.parse()?);
644 if input.peek(Token![>]) {
645 break;
646 }
647 lifetimes.push_punct(input.parse()?);
648 }
649 lifetimes
650 },
651 gt_token: input.parse()?,
652 })
653 }
654 }
655
656 impl Parse for Option<BoundLifetimes> {
657 fn parse(input: ParseStream) -> Result<Self> {
658 if input.peek(Token![for]) {
659 input.parse().map(Some)
660 } else {
661 Ok(None)
662 }
663 }
664 }
665
666 impl Parse for TypeParam {
667 fn parse(input: ParseStream) -> Result<Self> {
668 let has_colon;
669 let has_default;
670 Ok(TypeParam {
671 attrs: input.call(Attribute::parse_outer)?,
672 ident: input.parse()?,
673 colon_token: {
674 if input.peek(Token![:]) {
675 has_colon = true;
676 Some(input.parse()?)
677 } else {
678 has_colon = false;
679 None
680 }
681 },
682 bounds: {
683 let mut bounds = Punctuated::new();
684 if has_colon {
685 loop {
686 if input.peek(Token![,])
687 || input.peek(Token![>])
688 || input.peek(Token![=])
689 {
690 break;
691 }
692 let value = input.parse()?;
693 bounds.push_value(value);
694 if !input.peek(Token![+]) {
695 break;
696 }
697 let punct = input.parse()?;
698 bounds.push_punct(punct);
699 }
700 }
701 bounds
702 },
703 eq_token: {
704 if input.peek(Token![=]) {
705 has_default = true;
706 Some(input.parse()?)
707 } else {
708 has_default = false;
709 None
710 }
711 },
712 default: {
713 if has_default {
714 Some(input.parse()?)
715 } else {
716 None
717 }
718 },
719 })
720 }
721 }
722
723 impl Parse for TypeParamBound {
724 fn parse(input: ParseStream) -> Result<Self> {
725 if input.peek(Lifetime) {
726 return input.parse().map(TypeParamBound::Lifetime);
727 }
728
729 if input.peek(token::Paren) {
730 let content;
731 let paren_token = parenthesized!(content in input);
732 let mut bound: TraitBound = content.parse()?;
733 bound.paren_token = Some(paren_token);
734 return Ok(TypeParamBound::Trait(bound));
735 }
736
737 input.parse().map(TypeParamBound::Trait)
738 }
739 }
740
741 impl Parse for TraitBound {
742 fn parse(input: ParseStream) -> Result<Self> {
743 let modifier: TraitBoundModifier = input.parse()?;
744 let lifetimes: Option<BoundLifetimes> = input.parse()?;
745
746 let mut path: Path = input.parse()?;
747 if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) {
748 let parenthesized = PathArguments::Parenthesized(input.parse()?);
749 path.segments.last_mut().unwrap().arguments = parenthesized;
750 }
751
752 Ok(TraitBound {
753 paren_token: None,
754 modifier,
755 lifetimes,
756 path,
757 })
758 }
759 }
760
761 impl Parse for TraitBoundModifier {
762 fn parse(input: ParseStream) -> Result<Self> {
763 if input.peek(Token![?]) {
764 input.parse().map(TraitBoundModifier::Maybe)
765 } else {
766 Ok(TraitBoundModifier::None)
767 }
768 }
769 }
770
771 impl Parse for ConstParam {
772 fn parse(input: ParseStream) -> Result<Self> {
773 let mut default = None;
774 Ok(ConstParam {
775 attrs: input.call(Attribute::parse_outer)?,
776 const_token: input.parse()?,
777 ident: input.parse()?,
778 colon_token: input.parse()?,
779 ty: input.parse()?,
780 eq_token: {
781 if input.peek(Token![=]) {
782 let eq_token = input.parse()?;
783 default = Some(input.parse::<Expr>()?);
784 Some(eq_token)
785 } else {
786 None
787 }
788 },
789 default,
790 })
791 }
792 }
793
794 impl Parse for WhereClause {
795 fn parse(input: ParseStream) -> Result<Self> {
796 Ok(WhereClause {
797 where_token: input.parse()?,
798 predicates: {
799 let mut predicates = Punctuated::new();
800 loop {
801 if input.is_empty()
802 || input.peek(token::Brace)
803 || input.peek(Token![,])
804 || input.peek(Token![;])
805 || input.peek(Token![:]) && !input.peek(Token![::])
806 || input.peek(Token![=])
807 {
808 break;
809 }
810 let value = input.parse()?;
811 predicates.push_value(value);
812 if !input.peek(Token![,]) {
813 break;
814 }
815 let punct = input.parse()?;
816 predicates.push_punct(punct);
817 }
818 predicates
819 },
820 })
821 }
822 }
823
824 impl Parse for Option<WhereClause> {
825 fn parse(input: ParseStream) -> Result<Self> {
826 if input.peek(Token![where]) {
827 input.parse().map(Some)
828 } else {
829 Ok(None)
830 }
831 }
832 }
833
834 impl Parse for WherePredicate {
835 fn parse(input: ParseStream) -> Result<Self> {
836 if input.peek(Lifetime) && input.peek2(Token![:]) {
837 Ok(WherePredicate::Lifetime(PredicateLifetime {
838 lifetime: input.parse()?,
839 colon_token: input.parse()?,
840 bounds: {
841 let mut bounds = Punctuated::new();
842 loop {
843 if input.is_empty()
844 || input.peek(token::Brace)
845 || input.peek(Token![,])
846 || input.peek(Token![;])
847 || input.peek(Token![:])
848 || input.peek(Token![=])
849 {
850 break;
851 }
852 let value = input.parse()?;
853 bounds.push_value(value);
854 if !input.peek(Token![+]) {
855 break;
856 }
857 let punct = input.parse()?;
858 bounds.push_punct(punct);
859 }
860 bounds
861 },
862 }))
863 } else {
864 Ok(WherePredicate::Type(PredicateType {
865 lifetimes: input.parse()?,
866 bounded_ty: input.parse()?,
867 colon_token: input.parse()?,
868 bounds: {
869 let mut bounds = Punctuated::new();
870 loop {
871 if input.is_empty()
872 || input.peek(token::Brace)
873 || input.peek(Token![,])
874 || input.peek(Token![;])
875 || input.peek(Token![:]) && !input.peek(Token![::])
876 || input.peek(Token![=])
877 {
878 break;
879 }
880 let value = input.parse()?;
881 bounds.push_value(value);
882 if !input.peek(Token![+]) {
883 break;
884 }
885 let punct = input.parse()?;
886 bounds.push_punct(punct);
887 }
888 bounds
889 },
890 }))
891 }
892 }
893 }
894 }
895
896 #[cfg(feature = "printing")]
897 mod printing {
898 use super::*;
899
900 use proc_macro2::TokenStream;
901 use quote::{ToTokens, TokenStreamExt};
902
903 use crate::attr::FilterAttrs;
904 use crate::print::TokensOrDefault;
905
906 impl ToTokens for Generics {
907 fn to_tokens(&self, tokens: &mut TokenStream) {
908 if self.params.is_empty() {
909 return;
910 }
911
912 TokensOrDefault(&self.lt_token).to_tokens(tokens);
913
914 // Print lifetimes before types and consts, regardless of their
915 // order in self.params.
916 //
917 // TODO: ordering rules for const parameters vs type parameters have
918 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
919 let mut trailing_or_empty = true;
920 for param in self.params.pairs() {
921 if let GenericParam::Lifetime(_) = **param.value() {
922 param.to_tokens(tokens);
923 trailing_or_empty = param.punct().is_some();
924 }
925 }
926 for param in self.params.pairs() {
927 match **param.value() {
928 GenericParam::Type(_) | GenericParam::Const(_) => {
929 if !trailing_or_empty {
930 <Token![,]>::default().to_tokens(tokens);
931 trailing_or_empty = true;
932 }
933 param.to_tokens(tokens);
934 }
935 GenericParam::Lifetime(_) => {}
936 }
937 }
938
939 TokensOrDefault(&self.gt_token).to_tokens(tokens);
940 }
941 }
942
943 impl<'a> ToTokens for ImplGenerics<'a> {
944 fn to_tokens(&self, tokens: &mut TokenStream) {
945 if self.0.params.is_empty() {
946 return;
947 }
948
949 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
950
951 // Print lifetimes before types and consts, regardless of their
952 // order in self.params.
953 //
954 // TODO: ordering rules for const parameters vs type parameters have
955 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
956 let mut trailing_or_empty = true;
957 for param in self.0.params.pairs() {
958 if let GenericParam::Lifetime(_) = **param.value() {
959 param.to_tokens(tokens);
960 trailing_or_empty = param.punct().is_some();
961 }
962 }
963 for param in self.0.params.pairs() {
964 if let GenericParam::Lifetime(_) = **param.value() {
965 continue;
966 }
967 if !trailing_or_empty {
968 <Token![,]>::default().to_tokens(tokens);
969 trailing_or_empty = true;
970 }
971 match *param.value() {
972 GenericParam::Lifetime(_) => unreachable!(),
973 GenericParam::Type(param) => {
974 // Leave off the type parameter defaults
975 tokens.append_all(param.attrs.outer());
976 param.ident.to_tokens(tokens);
977 if !param.bounds.is_empty() {
978 TokensOrDefault(&param.colon_token).to_tokens(tokens);
979 param.bounds.to_tokens(tokens);
980 }
981 }
982 GenericParam::Const(param) => {
983 // Leave off the const parameter defaults
984 tokens.append_all(param.attrs.outer());
985 param.const_token.to_tokens(tokens);
986 param.ident.to_tokens(tokens);
987 param.colon_token.to_tokens(tokens);
988 param.ty.to_tokens(tokens);
989 }
990 }
991 param.punct().to_tokens(tokens);
992 }
993
994 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
995 }
996 }
997
998 impl<'a> ToTokens for TypeGenerics<'a> {
999 fn to_tokens(&self, tokens: &mut TokenStream) {
1000 if self.0.params.is_empty() {
1001 return;
1002 }
1003
1004 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1005
1006 // Print lifetimes before types and consts, regardless of their
1007 // order in self.params.
1008 //
1009 // TODO: ordering rules for const parameters vs type parameters have
1010 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1011 let mut trailing_or_empty = true;
1012 for param in self.0.params.pairs() {
1013 if let GenericParam::Lifetime(def) = *param.value() {
1014 // Leave off the lifetime bounds and attributes
1015 def.lifetime.to_tokens(tokens);
1016 param.punct().to_tokens(tokens);
1017 trailing_or_empty = param.punct().is_some();
1018 }
1019 }
1020 for param in self.0.params.pairs() {
1021 if let GenericParam::Lifetime(_) = **param.value() {
1022 continue;
1023 }
1024 if !trailing_or_empty {
1025 <Token![,]>::default().to_tokens(tokens);
1026 trailing_or_empty = true;
1027 }
1028 match *param.value() {
1029 GenericParam::Lifetime(_) => unreachable!(),
1030 GenericParam::Type(param) => {
1031 // Leave off the type parameter defaults
1032 param.ident.to_tokens(tokens);
1033 }
1034 GenericParam::Const(param) => {
1035 // Leave off the const parameter defaults
1036 param.ident.to_tokens(tokens);
1037 }
1038 }
1039 param.punct().to_tokens(tokens);
1040 }
1041
1042 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1043 }
1044 }
1045
1046 impl<'a> ToTokens for Turbofish<'a> {
1047 fn to_tokens(&self, tokens: &mut TokenStream) {
1048 if !self.0.params.is_empty() {
1049 <Token![::]>::default().to_tokens(tokens);
1050 TypeGenerics(self.0).to_tokens(tokens);
1051 }
1052 }
1053 }
1054
1055 impl ToTokens for BoundLifetimes {
1056 fn to_tokens(&self, tokens: &mut TokenStream) {
1057 self.for_token.to_tokens(tokens);
1058 self.lt_token.to_tokens(tokens);
1059 self.lifetimes.to_tokens(tokens);
1060 self.gt_token.to_tokens(tokens);
1061 }
1062 }
1063
1064 impl ToTokens for LifetimeDef {
1065 fn to_tokens(&self, tokens: &mut TokenStream) {
1066 tokens.append_all(self.attrs.outer());
1067 self.lifetime.to_tokens(tokens);
1068 if !self.bounds.is_empty() {
1069 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1070 self.bounds.to_tokens(tokens);
1071 }
1072 }
1073 }
1074
1075 impl ToTokens for TypeParam {
1076 fn to_tokens(&self, tokens: &mut TokenStream) {
1077 tokens.append_all(self.attrs.outer());
1078 self.ident.to_tokens(tokens);
1079 if !self.bounds.is_empty() {
1080 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1081 self.bounds.to_tokens(tokens);
1082 }
1083 if self.default.is_some() {
1084 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1085 self.default.to_tokens(tokens);
1086 }
1087 }
1088 }
1089
1090 impl ToTokens for TraitBound {
1091 fn to_tokens(&self, tokens: &mut TokenStream) {
1092 let to_tokens = |tokens: &mut TokenStream| {
1093 self.modifier.to_tokens(tokens);
1094 self.lifetimes.to_tokens(tokens);
1095 self.path.to_tokens(tokens);
1096 };
1097 match &self.paren_token {
1098 Some(paren) => paren.surround(tokens, to_tokens),
1099 None => to_tokens(tokens),
1100 }
1101 }
1102 }
1103
1104 impl ToTokens for TraitBoundModifier {
1105 fn to_tokens(&self, tokens: &mut TokenStream) {
1106 match self {
1107 TraitBoundModifier::None => {}
1108 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1109 }
1110 }
1111 }
1112
1113 impl ToTokens for ConstParam {
1114 fn to_tokens(&self, tokens: &mut TokenStream) {
1115 tokens.append_all(self.attrs.outer());
1116 self.const_token.to_tokens(tokens);
1117 self.ident.to_tokens(tokens);
1118 self.colon_token.to_tokens(tokens);
1119 self.ty.to_tokens(tokens);
1120 if self.default.is_some() {
1121 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1122 self.default.to_tokens(tokens);
1123 }
1124 }
1125 }
1126
1127 impl ToTokens for WhereClause {
1128 fn to_tokens(&self, tokens: &mut TokenStream) {
1129 if !self.predicates.is_empty() {
1130 self.where_token.to_tokens(tokens);
1131 self.predicates.to_tokens(tokens);
1132 }
1133 }
1134 }
1135
1136 impl ToTokens for PredicateType {
1137 fn to_tokens(&self, tokens: &mut TokenStream) {
1138 self.lifetimes.to_tokens(tokens);
1139 self.bounded_ty.to_tokens(tokens);
1140 self.colon_token.to_tokens(tokens);
1141 self.bounds.to_tokens(tokens);
1142 }
1143 }
1144
1145 impl ToTokens for PredicateLifetime {
1146 fn to_tokens(&self, tokens: &mut TokenStream) {
1147 self.lifetime.to_tokens(tokens);
1148 self.colon_token.to_tokens(tokens);
1149 self.bounds.to_tokens(tokens);
1150 }
1151 }
1152
1153 impl ToTokens for PredicateEq {
1154 fn to_tokens(&self, tokens: &mut TokenStream) {
1155 self.lhs_ty.to_tokens(tokens);
1156 self.eq_token.to_tokens(tokens);
1157 self.rhs_ty.to_tokens(tokens);
1158 }
1159 }
1160 }