blob: 9b217203dbb9abe8564cc3888a5cb128c7b8ae4b [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayb79ee962016-09-04 09:39:20 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// Represents lifetimes and type parameters attached to a declaration
6 /// of a function, enum, trait, etc.
7 #[derive(Default)]
8 pub struct Generics {
David Tolnayf8db7ba2017-11-11 22:52:16 -08009 pub lt_token: Option<Token![<]>,
David Tolnayc2f1aba2017-11-12 20:29:22 -080010 pub params: Delimited<GenericParam, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080011 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070012 pub where_clause: WhereClause,
13 }
David Tolnayb79ee962016-09-04 09:39:20 -070014}
15
David Tolnayc2f1aba2017-11-12 20:29:22 -080016ast_enum_of_structs! {
17 pub enum GenericParam {
18 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
19 pub Lifetime(LifetimeDef {
20 pub attrs: Vec<Attribute>,
21 pub lifetime: Lifetime,
22 pub colon_token: Option<Token![:]>,
23 pub bounds: Delimited<Lifetime, Token![+]>,
24 }),
25 /// A generic type parameter, e.g. `T: Into<String>`.
26 pub Type(TypeParam {
27 pub attrs: Vec<Attribute>,
28 pub ident: Ident,
29 pub colon_token: Option<Token![:]>,
30 pub bounds: Delimited<TypeParamBound, Token![+]>,
31 pub eq_token: Option<Token![=]>,
32 pub default: Option<Type>,
33 }),
Nika Layzellf1fdc0b2017-12-04 19:58:32 -050034 /// A generic const parameter, e.g. `const LENGTH: usize`.
35 pub Const(ConstParam {
36 pub attrs: Vec<Attribute>,
37 pub const_token: Token![const],
38 pub ident: Ident,
39 pub colon_token: Token![:],
40 pub ty: Type,
41 pub eq_token: Option<Token![=]>,
42 pub default: Option<Expr>,
43 }),
David Tolnayc2f1aba2017-11-12 20:29:22 -080044 }
45}
46
David Tolnaye7678922016-10-13 20:44:03 -070047#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040048#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
49#[cfg_attr(feature = "clone-impls", derive(Clone))]
50/// Returned by `Generics::split_for_impl`.
51pub struct ImplGenerics<'a>(&'a Generics);
David Tolnaye7678922016-10-13 20:44:03 -070052
53#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040054#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
55#[cfg_attr(feature = "clone-impls", derive(Clone))]
56/// Returned by `Generics::split_for_impl`.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080057pub struct TypeGenerics<'a>(&'a Generics);
David Tolnaye7678922016-10-13 20:44:03 -070058
David Tolnayc879a502017-01-25 15:51:32 -080059#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040060#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
61#[cfg_attr(feature = "clone-impls", derive(Clone))]
David Tolnayfd6bf5c2017-11-12 09:41:14 -080062/// Returned by `TypeGenerics::as_turbofish`.
Nika Layzell6b38b132017-10-24 23:09:39 -040063pub struct Turbofish<'a>(&'a Generics);
David Tolnayc879a502017-01-25 15:51:32 -080064
David Tolnaye95cc9f2017-01-25 15:57:09 -080065#[cfg(feature = "printing")]
David Tolnayb153dbc2016-10-04 23:39:10 -070066impl Generics {
67 /// Split a type's generics into the pieces required for impl'ing a trait
68 /// for that type.
69 ///
70 /// ```
71 /// # extern crate syn;
72 /// # #[macro_use]
73 /// # extern crate quote;
74 /// # fn main() {
75 /// # let generics: syn::Generics = Default::default();
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 /// # let name = syn::Ident::from("MyType");
David Tolnayb153dbc2016-10-04 23:39:10 -070077 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
78 /// quote! {
79 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
80 /// // ...
81 /// }
82 /// }
83 /// # ;
84 /// # }
85 /// ```
David Tolnayfd6bf5c2017-11-12 09:41:14 -080086 pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, &WhereClause) {
87 (ImplGenerics(self), TypeGenerics(self), &self.where_clause)
David Tolnayb153dbc2016-10-04 23:39:10 -070088 }
89}
90
David Tolnaye95cc9f2017-01-25 15:57:09 -080091#[cfg(feature = "printing")]
David Tolnayfd6bf5c2017-11-12 09:41:14 -080092impl<'a> TypeGenerics<'a> {
David Tolnayc879a502017-01-25 15:51:32 -080093 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
94 pub fn as_turbofish(&self) -> Turbofish {
95 Turbofish(self.0)
96 }
97}
98
Alex Crichton62a0a592017-05-22 13:58:53 -070099ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700100 /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>`
101 #[derive(Default)]
102 pub struct BoundLifetimes {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800103 pub for_token: Token![for],
104 pub lt_token: Token![<],
105 pub lifetimes: Delimited<LifetimeDef, Token![,]>,
106 pub gt_token: Token![>],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700107 }
108}
109
David Tolnayf9505b52016-10-02 09:18:52 -0700110impl LifetimeDef {
David Tolnay63e3dee2017-06-03 20:13:17 -0700111 pub fn new(lifetime: Lifetime) -> Self {
David Tolnayf9505b52016-10-02 09:18:52 -0700112 LifetimeDef {
David Tolnaye7678922016-10-13 20:44:03 -0700113 attrs: Vec::new(),
David Tolnay63e3dee2017-06-03 20:13:17 -0700114 lifetime: lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700115 colon_token: None,
116 bounds: Delimited::new(),
David Tolnayf9505b52016-10-02 09:18:52 -0700117 }
118 }
119}
120
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800121impl From<Ident> for TypeParam {
Ted Driggs0547d0d2017-04-20 10:00:12 -0700122 fn from(ident: Ident) -> Self {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800123 TypeParam {
Ted Driggs0547d0d2017-04-20 10:00:12 -0700124 attrs: vec![],
125 ident: ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126 colon_token: None,
127 bounds: Delimited::new(),
128 eq_token: None,
Ted Driggs0547d0d2017-04-20 10:00:12 -0700129 default: None,
130 }
131 }
132}
133
Alex Crichton62a0a592017-05-22 13:58:53 -0700134ast_enum! {
135 /// The AST represents all type param bounds as types.
136 /// `typeck::collect::compute_bounds` matches these against
137 /// the "special" built-in traits (see `middle::lang_items`) and
138 /// detects Copy, Send and Sync.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800139 pub enum TypeParamBound {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 Trait(PolyTraitRef, TraitBoundModifier),
141 Region(Lifetime),
142 }
David Tolnay55337722016-09-11 12:58:56 -0700143}
144
Alex Crichton62a0a592017-05-22 13:58:53 -0700145ast_enum! {
146 /// A modifier on a bound, currently this is only used for `?Sized`, where the
147 /// modifier is `Maybe`. Negative bounds should also be handled here.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700148 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700149 pub enum TraitBoundModifier {
150 None,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800151 Maybe(Token![?]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700152 }
David Tolnay55337722016-09-11 12:58:56 -0700153}
154
Alex Crichton62a0a592017-05-22 13:58:53 -0700155ast_struct! {
156 /// A `where` clause in a definition
157 #[derive(Default)]
158 pub struct WhereClause {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800159 pub where_token: Option<Token![where]>,
160 pub predicates: Delimited<WherePredicate, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }
David Tolnayb79ee962016-09-04 09:39:20 -0700162}
163
David Tolnayb153dbc2016-10-04 23:39:10 -0700164impl WhereClause {
165 pub fn none() -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700166 WhereClause::default()
David Tolnayb153dbc2016-10-04 23:39:10 -0700167 }
168}
169
Alex Crichton62a0a592017-05-22 13:58:53 -0700170ast_enum_of_structs! {
171 /// A single predicate in a `where` clause
172 pub enum WherePredicate {
173 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
174 pub BoundPredicate(WhereBoundPredicate {
175 /// Any lifetimes from a `for` binding
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700176 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700177 /// The type being bounded
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800178 pub bounded_ty: Type,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800179 pub colon_token: Token![:],
Alex Crichton62a0a592017-05-22 13:58:53 -0700180 /// Trait and lifetime bounds (`Clone+Send+'static`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800181 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700183
Alex Crichton62a0a592017-05-22 13:58:53 -0700184 /// A lifetime predicate, e.g. `'a: 'b+'c`
185 pub RegionPredicate(WhereRegionPredicate {
186 pub lifetime: Lifetime,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800187 pub colon_token: Option<Token![:]>,
188 pub bounds: Delimited<Lifetime, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700189 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700190
Alex Crichton62a0a592017-05-22 13:58:53 -0700191 /// An equality predicate (unsupported)
192 pub EqPredicate(WhereEqPredicate {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800193 pub lhs_ty: Type,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800194 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800195 pub rhs_ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 }),
197 }
David Tolnayf8e08832017-01-23 00:04:32 -0800198}
199
David Tolnay86eca752016-09-04 11:26:41 -0700200#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700201pub mod parsing {
202 use super::*;
David Tolnay9d8f1972016-09-04 11:58:48 -0700203
David Tolnay63e3dee2017-06-03 20:13:17 -0700204 use synom::Synom;
David Tolnayc2f1aba2017-11-12 20:29:22 -0800205 use synom::delimited::Element;
Alex Crichton954046c2017-05-30 21:49:42 -0700206
207 impl Synom for Generics {
Michael Layzell92639a52017-06-01 00:07:44 -0400208 named!(parse -> Self, map!(
209 alt!(
210 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800211 lt: punct!(<) >>
David Tolnayc2f1aba2017-11-12 20:29:22 -0800212 lifetimes: call!(Delimited::<LifetimeDef, Token![,]>::parse_terminated) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400213 ty_params: cond!(
David Tolnayc2f1aba2017-11-12 20:29:22 -0800214 lifetimes.empty_or_trailing(),
215 call!(Delimited::<TypeParam, Token![,]>::parse_terminated)
Michael Layzell92639a52017-06-01 00:07:44 -0400216 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800217 gt: punct!(>) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400218 (lifetimes, ty_params, Some(lt), Some(gt))
219 )
220 |
221 epsilon!() => { |_| (Delimited::new(), None, None, None) }
222 ),
David Tolnaybc7d7d92017-06-03 20:54:05 -0700223 |(lifetimes, ty_params, lt, gt)| Generics {
Michael Layzell92639a52017-06-01 00:07:44 -0400224 lt_token: lt,
David Tolnayc2f1aba2017-11-12 20:29:22 -0800225 params: lifetimes.into_iter()
226 .map(Element::into_tuple)
227 .map(|(lifetime, comma)| (GenericParam::Lifetime(lifetime), comma))
228 .chain(ty_params.unwrap_or_default()
229 .into_iter()
230 .map(Element::into_tuple)
231 .map(|(ty_param, comma)| (GenericParam::Type(ty_param), comma)))
232 .collect::<Vec<_>>()
233 .into(),
234 gt_token: gt,
235 where_clause: WhereClause::default(),
Michael Layzell416724e2017-05-24 21:12:34 -0400236 }
Michael Layzell92639a52017-06-01 00:07:44 -0400237 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700238 }
239
Alex Crichton954046c2017-05-30 21:49:42 -0700240 impl Synom for LifetimeDef {
Michael Layzell92639a52017-06-01 00:07:44 -0400241 named!(parse -> Self, do_parse!(
242 attrs: many0!(call!(Attribute::parse_outer)) >>
243 life: syn!(Lifetime) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800244 colon: option!(punct!(:)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400245 bounds: cond!(
246 colon.is_some(),
247 call!(Delimited::parse_separated_nonempty)
248 ) >>
249 (LifetimeDef {
250 attrs: attrs,
251 lifetime: life,
252 bounds: bounds.unwrap_or_default(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800253 colon_token: colon.map(|_| <Token![:]>::default()),
Michael Layzell92639a52017-06-01 00:07:44 -0400254 })
255 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700256 }
257
258 impl Synom for BoundLifetimes {
Michael Layzell92639a52017-06-01 00:07:44 -0400259 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800260 for_: keyword!(for) >>
261 lt: punct!(<) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400262 lifetimes: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800263 gt: punct!(>) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400264 (BoundLifetimes {
265 for_token: for_,
266 lt_token: lt,
267 gt_token: gt,
268 lifetimes: lifetimes,
269 })
270 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700271 }
David Tolnay55337722016-09-11 12:58:56 -0700272
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800273 impl Synom for TypeParam {
Michael Layzell92639a52017-06-01 00:07:44 -0400274 named!(parse -> Self, do_parse!(
275 attrs: many0!(call!(Attribute::parse_outer)) >>
276 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800277 colon: option!(punct!(:)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400278 bounds: cond!(
279 colon.is_some(),
280 call!(Delimited::parse_separated_nonempty)
281 ) >>
282 default: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800283 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800284 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400285 (eq, ty)
286 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800287 (TypeParam {
Michael Layzell92639a52017-06-01 00:07:44 -0400288 attrs: attrs,
289 ident: id,
290 bounds: bounds.unwrap_or_default(),
291 colon_token: colon,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800292 eq_token: default.as_ref().map(|d| Token![=]((d.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -0400293 default: default.map(|d| d.1),
294 })
295 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700296 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700297
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800298 impl Synom for TypeParamBound {
Michael Layzell92639a52017-06-01 00:07:44 -0400299 named!(parse -> Self, alt!(
300 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800301 question: punct!(?) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400302 poly: syn!(PolyTraitRef) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800303 (TypeParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
Michael Layzell92639a52017-06-01 00:07:44 -0400304 )
305 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800306 syn!(Lifetime) => { TypeParamBound::Region }
Michael Layzell92639a52017-06-01 00:07:44 -0400307 |
308 syn!(PolyTraitRef) => {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800309 |poly| TypeParamBound::Trait(poly, TraitBoundModifier::None)
Alex Crichton954046c2017-05-30 21:49:42 -0700310 }
Michael Layzell92639a52017-06-01 00:07:44 -0400311 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700312
313 fn description() -> Option<&'static str> {
Nika Layzellc691cb42017-12-04 13:44:38 -0500314 Some("type parameter bound")
Alex Crichton954046c2017-05-30 21:49:42 -0700315 }
316 }
317
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500318 impl Synom for ConstParam {
319 named!(parse -> Self, do_parse!(
320 attrs: many0!(call!(Attribute::parse_outer)) >>
321 const_: keyword!(const) >>
322 ident: syn!(Ident) >>
323 colon: punct!(:) >>
324 ty: syn!(Type) >>
325 eq_def: option!(tuple!(punct!(=), syn!(Expr))) >>
David Tolnay78ee5202017-12-04 22:17:54 -0800326 ({
327 let (eq_token, default) = match eq_def {
328 Some((eq_token, default)) => (Some(eq_token), Some(default)),
329 None => (None, None),
330 };
331 ConstParam {
332 attrs: attrs,
333 const_token: const_,
334 ident: ident,
335 colon_token: colon,
336 ty: ty,
337 eq_token: eq_token,
338 default: default,
339 }
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500340 })
341 ));
342 }
343
Alex Crichton954046c2017-05-30 21:49:42 -0700344 impl Synom for WhereClause {
Michael Layzell92639a52017-06-01 00:07:44 -0400345 named!(parse -> Self, alt!(
346 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800347 where_: keyword!(where) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400348 predicates: call!(Delimited::parse_terminated) >>
349 (WhereClause {
350 predicates: predicates,
351 where_token: Some(where_),
352 })
353 )
354 |
355 epsilon!() => { |_| WhereClause::default() }
356 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700357
358 fn description() -> Option<&'static str> {
359 Some("where clause")
360 }
361 }
362
363 impl Synom for WherePredicate {
Michael Layzell92639a52017-06-01 00:07:44 -0400364 named!(parse -> Self, alt!(
365 do_parse!(
366 ident: syn!(Lifetime) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800367 colon: option!(punct!(:)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400368 bounds: cond!(
369 colon.is_some(),
370 call!(Delimited::parse_separated)
371 ) >>
372 (WherePredicate::RegionPredicate(WhereRegionPredicate {
373 lifetime: ident,
374 bounds: bounds.unwrap_or_default(),
375 colon_token: colon,
376 }))
377 )
378 |
379 do_parse!(
380 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800381 bounded_ty: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800382 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400383 bounds: call!(Delimited::parse_separated_nonempty) >>
384 (WherePredicate::BoundPredicate(WhereBoundPredicate {
385 bound_lifetimes: bound_lifetimes,
386 bounded_ty: bounded_ty,
387 bounds: bounds,
388 colon_token: colon,
389 }))
390 )
391 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700392 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700393}
David Tolnay87d0b442016-09-04 11:52:12 -0700394
395#[cfg(feature = "printing")]
396mod printing {
397 use super::*;
David Tolnaye7678922016-10-13 20:44:03 -0700398 use attr::FilterAttrs;
David Tolnay87d0b442016-09-04 11:52:12 -0700399 use quote::{Tokens, ToTokens};
400
Michael Layzell3936ceb2017-07-08 00:28:36 -0400401 /// Returns true if the generics object has no lifetimes or ty_params.
402 fn empty_normal_generics(generics: &Generics) -> bool {
David Tolnayc2f1aba2017-11-12 20:29:22 -0800403 generics.params.is_empty()
Michael Layzell3936ceb2017-07-08 00:28:36 -0400404 }
405
David Tolnay8ef93042016-09-04 14:08:40 -0700406 impl ToTokens for Generics {
407 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400408 if empty_normal_generics(self) {
409 return;
410 }
411
Alex Crichton259ee532017-07-14 06:51:02 -0700412 TokensOrDefault(&self.lt_token).to_tokens(tokens);
David Tolnayc2f1aba2017-11-12 20:29:22 -0800413 self.params.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700414 TokensOrDefault(&self.gt_token).to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700415 }
416 }
417
David Tolnaye7678922016-10-13 20:44:03 -0700418 impl<'a> ToTokens for ImplGenerics<'a> {
419 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400420 if empty_normal_generics(&self.0) {
421 return;
422 }
423
Alex Crichton259ee532017-07-14 06:51:02 -0700424 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
David Tolnayc2f1aba2017-11-12 20:29:22 -0800425 for param in self.0.params.iter() {
426 match **param.item() {
427 GenericParam::Lifetime(ref param) => {
428 param.to_tokens(tokens);
429 }
430 GenericParam::Type(ref param) => {
431 // Leave off the type parameter defaults
432 tokens.append_all(param.attrs.outer());
433 param.ident.to_tokens(tokens);
434 if !param.bounds.is_empty() {
435 TokensOrDefault(&param.colon_token).to_tokens(tokens);
436 param.bounds.to_tokens(tokens);
437 }
438 }
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500439 GenericParam::Const(ref param) => {
440 // Leave off the const parameter defaults
441 tokens.append_all(param.attrs.outer());
442 param.const_token.to_tokens(tokens);
443 param.ident.to_tokens(tokens);
444 param.colon_token.to_tokens(tokens);
445 param.ty.to_tokens(tokens);
446 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400447 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700448 param.delimiter().to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700449 }
Alex Crichton259ee532017-07-14 06:51:02 -0700450 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700451 }
452 }
453
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800454 impl<'a> ToTokens for TypeGenerics<'a> {
David Tolnaye7678922016-10-13 20:44:03 -0700455 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400456 if empty_normal_generics(&self.0) {
457 return;
458 }
459
Alex Crichton259ee532017-07-14 06:51:02 -0700460 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
David Tolnayc2f1aba2017-11-12 20:29:22 -0800461 for param in self.0.params.iter() {
462 match **param.item() {
463 GenericParam::Lifetime(ref param) => {
464 // Leave off the lifetime bounds and attributes
465 param.lifetime.to_tokens(tokens);
466 }
467 GenericParam::Type(ref param) => {
468 // Leave off the type parameter defaults
469 param.ident.to_tokens(tokens);
470 }
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500471 GenericParam::Const(ref param) => {
472 // Leave off the const parameter defaults
473 param.ident.to_tokens(tokens);
474 }
David Tolnayc2f1aba2017-11-12 20:29:22 -0800475 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700476 param.delimiter().to_tokens(tokens);
477 }
Alex Crichton259ee532017-07-14 06:51:02 -0700478 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700479 }
480 }
481
David Tolnayc879a502017-01-25 15:51:32 -0800482 impl<'a> ToTokens for Turbofish<'a> {
483 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400484 if !empty_normal_generics(&self.0) {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800485 <Token![::]>::default().to_tokens(tokens);
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800486 TypeGenerics(self.0).to_tokens(tokens);
David Tolnayc879a502017-01-25 15:51:32 -0800487 }
488 }
489 }
490
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700491 impl ToTokens for BoundLifetimes {
492 fn to_tokens(&self, tokens: &mut Tokens) {
493 self.for_token.to_tokens(tokens);
494 self.lt_token.to_tokens(tokens);
495 self.lifetimes.to_tokens(tokens);
496 self.gt_token.to_tokens(tokens);
497 }
498 }
499
David Tolnay87d0b442016-09-04 11:52:12 -0700500 impl ToTokens for LifetimeDef {
501 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700502 tokens.append_all(self.attrs.outer());
David Tolnay87d0b442016-09-04 11:52:12 -0700503 self.lifetime.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400504 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700505 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400506 self.bounds.to_tokens(tokens);
507 }
David Tolnay87d0b442016-09-04 11:52:12 -0700508 }
509 }
510
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800511 impl ToTokens for TypeParam {
David Tolnay8ef93042016-09-04 14:08:40 -0700512 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700513 tokens.append_all(self.attrs.outer());
David Tolnay8ef93042016-09-04 14:08:40 -0700514 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400515 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700516 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400517 self.bounds.to_tokens(tokens);
518 }
519 if self.default.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -0700520 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400521 self.default.to_tokens(tokens);
522 }
David Tolnay8ef93042016-09-04 14:08:40 -0700523 }
524 }
525
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800526 impl ToTokens for TypeParamBound {
David Tolnay87d0b442016-09-04 11:52:12 -0700527 fn to_tokens(&self, tokens: &mut Tokens) {
528 match *self {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800529 TypeParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
530 TypeParamBound::Trait(ref trait_ref, ref modifier) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 modifier.to_tokens(tokens);
David Tolnay55337722016-09-11 12:58:56 -0700532 trait_ref.to_tokens(tokens);
533 }
534 }
535 }
536 }
537
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 impl ToTokens for TraitBoundModifier {
539 fn to_tokens(&self, tokens: &mut Tokens) {
540 match *self {
541 TraitBoundModifier::None => {}
542 TraitBoundModifier::Maybe(ref t) => t.to_tokens(tokens),
543 }
544 }
545 }
546
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500547 impl ToTokens for ConstParam {
548 fn to_tokens(&self, tokens: &mut Tokens) {
549 tokens.append_all(self.attrs.outer());
550 self.const_token.to_tokens(tokens);
551 self.ident.to_tokens(tokens);
552 self.colon_token.to_tokens(tokens);
553 self.ty.to_tokens(tokens);
554 if self.default.is_some() {
David Tolnay78ee5202017-12-04 22:17:54 -0800555 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Nika Layzellf1fdc0b2017-12-04 19:58:32 -0500556 self.default.to_tokens(tokens);
557 }
558 }
559 }
560
David Tolnay55337722016-09-11 12:58:56 -0700561 impl ToTokens for WhereClause {
562 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400563 if !self.predicates.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700564 TokensOrDefault(&self.where_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400565 self.predicates.to_tokens(tokens);
566 }
David Tolnay87d0b442016-09-04 11:52:12 -0700567 }
568 }
David Tolnay8ef93042016-09-04 14:08:40 -0700569
David Tolnay8ef93042016-09-04 14:08:40 -0700570 impl ToTokens for WhereBoundPredicate {
571 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 self.bound_lifetimes.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700573 self.bounded_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700574 self.colon_token.to_tokens(tokens);
575 self.bounds.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700576 }
577 }
578
579 impl ToTokens for WhereRegionPredicate {
580 fn to_tokens(&self, tokens: &mut Tokens) {
581 self.lifetime.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400582 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700583 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400584 self.bounds.to_tokens(tokens);
585 }
David Tolnay8ef93042016-09-04 14:08:40 -0700586 }
587 }
David Tolnayf8e08832017-01-23 00:04:32 -0800588
589 impl ToTokens for WhereEqPredicate {
590 fn to_tokens(&self, tokens: &mut Tokens) {
591 self.lhs_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700592 self.eq_token.to_tokens(tokens);
David Tolnayf8e08832017-01-23 00:04:32 -0800593 self.rhs_ty.to_tokens(tokens);
594 }
595 }
David Tolnay87d0b442016-09-04 11:52:12 -0700596}