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