blob: f9897955d162b7e21311bee647f3665358284846 [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 {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07009 pub lt_token: Option<tokens::Lt>,
10 pub gt_token: Option<tokens::Gt>,
11 pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
12 pub ty_params: Delimited<TyParam, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -070013 pub where_clause: WhereClause,
14 }
David Tolnayb79ee962016-09-04 09:39:20 -070015}
16
David Tolnaye7678922016-10-13 20:44:03 -070017#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040018#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
19#[cfg_attr(feature = "clone-impls", derive(Clone))]
20/// Returned by `Generics::split_for_impl`.
21pub struct ImplGenerics<'a>(&'a Generics);
David Tolnaye7678922016-10-13 20:44:03 -070022
23#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040024#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
25#[cfg_attr(feature = "clone-impls", derive(Clone))]
26/// Returned by `Generics::split_for_impl`.
27pub struct TyGenerics<'a>(&'a Generics);
David Tolnaye7678922016-10-13 20:44:03 -070028
David Tolnayc879a502017-01-25 15:51:32 -080029#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -040030#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
31#[cfg_attr(feature = "clone-impls", derive(Clone))]
32/// Returned by `TyGenerics::as_turbofish`.
33pub struct Turbofish<'a>(&'a Generics);
David Tolnayc879a502017-01-25 15:51:32 -080034
David Tolnaye95cc9f2017-01-25 15:57:09 -080035#[cfg(feature = "printing")]
David Tolnayb153dbc2016-10-04 23:39:10 -070036impl Generics {
37 /// Split a type's generics into the pieces required for impl'ing a trait
38 /// for that type.
39 ///
40 /// ```
41 /// # extern crate syn;
42 /// # #[macro_use]
43 /// # extern crate quote;
44 /// # fn main() {
45 /// # let generics: syn::Generics = Default::default();
Alex Crichtonccbb45d2017-05-23 10:58:24 -070046 /// # let name = syn::Ident::from("MyType");
David Tolnayb153dbc2016-10-04 23:39:10 -070047 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
48 /// quote! {
49 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
50 /// // ...
51 /// }
52 /// }
53 /// # ;
54 /// # }
55 /// ```
David Tolnaye7678922016-10-13 20:44:03 -070056 pub fn split_for_impl(&self) -> (ImplGenerics, TyGenerics, &WhereClause) {
57 (ImplGenerics(self), TyGenerics(self), &self.where_clause)
David Tolnayb153dbc2016-10-04 23:39:10 -070058 }
59}
60
David Tolnaye95cc9f2017-01-25 15:57:09 -080061#[cfg(feature = "printing")]
David Tolnayc879a502017-01-25 15:51:32 -080062impl<'a> TyGenerics<'a> {
David Tolnayc879a502017-01-25 15:51:32 -080063 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
64 pub fn as_turbofish(&self) -> Turbofish {
65 Turbofish(self.0)
66 }
67}
68
Alex Crichton62a0a592017-05-22 13:58:53 -070069ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070070 /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>`
71 #[derive(Default)]
72 pub struct BoundLifetimes {
73 pub for_token: tokens::For,
74 pub lt_token: tokens::Lt,
75 pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
76 pub gt_token: tokens::Gt,
77 }
78}
79
80ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -070081 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
82 pub struct LifetimeDef {
83 pub attrs: Vec<Attribute>,
84 pub lifetime: Lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070085 pub colon_token: Option<tokens::Colon>,
86 pub bounds: Delimited<Lifetime, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -070087 }
David Tolnayb79ee962016-09-04 09:39:20 -070088}
89
David Tolnayf9505b52016-10-02 09:18:52 -070090impl LifetimeDef {
David Tolnay63e3dee2017-06-03 20:13:17 -070091 pub fn new(lifetime: Lifetime) -> Self {
David Tolnayf9505b52016-10-02 09:18:52 -070092 LifetimeDef {
David Tolnaye7678922016-10-13 20:44:03 -070093 attrs: Vec::new(),
David Tolnay63e3dee2017-06-03 20:13:17 -070094 lifetime: lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070095 colon_token: None,
96 bounds: Delimited::new(),
David Tolnayf9505b52016-10-02 09:18:52 -070097 }
98 }
99}
100
Alex Crichton62a0a592017-05-22 13:58:53 -0700101ast_struct! {
102 /// A generic type parameter, e.g. `T: Into<String>`.
103 pub struct TyParam {
104 pub attrs: Vec<Attribute>,
105 pub ident: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700106 pub colon_token: Option<tokens::Colon>,
107 pub bounds: Delimited<TyParamBound, tokens::Add>,
108 pub eq_token: Option<tokens::Eq>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 pub default: Option<Ty>,
110 }
David Tolnayb79ee962016-09-04 09:39:20 -0700111}
112
Ted Driggs0547d0d2017-04-20 10:00:12 -0700113impl From<Ident> for TyParam {
114 fn from(ident: Ident) -> Self {
115 TyParam {
116 attrs: vec![],
117 ident: ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700118 colon_token: None,
119 bounds: Delimited::new(),
120 eq_token: None,
Ted Driggs0547d0d2017-04-20 10:00:12 -0700121 default: None,
122 }
123 }
124}
125
Alex Crichton62a0a592017-05-22 13:58:53 -0700126ast_enum! {
127 /// The AST represents all type param bounds as types.
128 /// `typeck::collect::compute_bounds` matches these against
129 /// the "special" built-in traits (see `middle::lang_items`) and
130 /// detects Copy, Send and Sync.
131 pub enum TyParamBound {
132 Trait(PolyTraitRef, TraitBoundModifier),
133 Region(Lifetime),
134 }
David Tolnay55337722016-09-11 12:58:56 -0700135}
136
Alex Crichton62a0a592017-05-22 13:58:53 -0700137ast_enum! {
138 /// A modifier on a bound, currently this is only used for `?Sized`, where the
139 /// modifier is `Maybe`. Negative bounds should also be handled here.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700140 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700141 pub enum TraitBoundModifier {
142 None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 Maybe(tokens::Question),
Alex Crichton62a0a592017-05-22 13:58:53 -0700144 }
David Tolnay55337722016-09-11 12:58:56 -0700145}
146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147ast_struct! {
148 /// A `where` clause in a definition
149 #[derive(Default)]
150 pub struct WhereClause {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700151 pub where_token: Option<tokens::Where>,
152 pub predicates: Delimited<WherePredicate, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 }
David Tolnayb79ee962016-09-04 09:39:20 -0700154}
155
David Tolnayb153dbc2016-10-04 23:39:10 -0700156impl WhereClause {
157 pub fn none() -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700158 WhereClause::default()
David Tolnayb153dbc2016-10-04 23:39:10 -0700159 }
160}
161
Alex Crichton62a0a592017-05-22 13:58:53 -0700162ast_enum_of_structs! {
163 /// A single predicate in a `where` clause
164 pub enum WherePredicate {
165 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
166 pub BoundPredicate(WhereBoundPredicate {
167 /// Any lifetimes from a `for` binding
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700168 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 /// The type being bounded
170 pub bounded_ty: Ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700171 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700172 /// Trait and lifetime bounds (`Clone+Send+'static`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700173 pub bounds: Delimited<TyParamBound, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700174 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700175
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 /// A lifetime predicate, e.g. `'a: 'b+'c`
177 pub RegionPredicate(WhereRegionPredicate {
178 pub lifetime: Lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700179 pub colon_token: Option<tokens::Colon>,
180 pub bounds: Delimited<Lifetime, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700181 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700182
Alex Crichton62a0a592017-05-22 13:58:53 -0700183 /// An equality predicate (unsupported)
184 pub EqPredicate(WhereEqPredicate {
185 pub lhs_ty: Ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700186 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700187 pub rhs_ty: Ty,
188 }),
189 }
David Tolnayf8e08832017-01-23 00:04:32 -0800190}
191
David Tolnay86eca752016-09-04 11:26:41 -0700192#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700193pub mod parsing {
194 use super::*;
David Tolnay9d8f1972016-09-04 11:58:48 -0700195
David Tolnay63e3dee2017-06-03 20:13:17 -0700196 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700197 use synom::tokens::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700198
199 impl Synom for Generics {
Michael Layzell92639a52017-06-01 00:07:44 -0400200 named!(parse -> Self, map!(
201 alt!(
202 do_parse!(
203 lt: syn!(Lt) >>
204 lifetimes: call!(Delimited::parse_terminated) >>
205 ty_params: cond!(
206 lifetimes.is_empty() || lifetimes.trailing_delim(),
207 call!(Delimited::parse_terminated)
208 ) >>
209 gt: syn!(Gt) >>
210 (lifetimes, ty_params, Some(lt), Some(gt))
211 )
212 |
213 epsilon!() => { |_| (Delimited::new(), None, None, None) }
214 ),
David Tolnaybc7d7d92017-06-03 20:54:05 -0700215 |(lifetimes, ty_params, lt, gt)| Generics {
Michael Layzell92639a52017-06-01 00:07:44 -0400216 lifetimes: lifetimes,
217 ty_params: ty_params.unwrap_or_default(),
218 where_clause: WhereClause::default(),
219 gt_token: gt,
220 lt_token: lt,
Michael Layzell416724e2017-05-24 21:12:34 -0400221 }
Michael Layzell92639a52017-06-01 00:07:44 -0400222 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700223 }
224
Alex Crichton954046c2017-05-30 21:49:42 -0700225 impl Synom for LifetimeDef {
Michael Layzell92639a52017-06-01 00:07:44 -0400226 named!(parse -> Self, do_parse!(
227 attrs: many0!(call!(Attribute::parse_outer)) >>
228 life: syn!(Lifetime) >>
229 colon: option!(syn!(Colon)) >>
230 bounds: cond!(
231 colon.is_some(),
232 call!(Delimited::parse_separated_nonempty)
233 ) >>
234 (LifetimeDef {
235 attrs: attrs,
236 lifetime: life,
237 bounds: bounds.unwrap_or_default(),
238 colon_token: colon.map(|_| tokens::Colon::default()),
239 })
240 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700241 }
242
243 impl Synom for BoundLifetimes {
Michael Layzell92639a52017-06-01 00:07:44 -0400244 named!(parse -> Self, do_parse!(
245 for_: syn!(For) >>
246 lt: syn!(Lt) >>
247 lifetimes: call!(Delimited::parse_terminated) >>
248 gt: syn!(Gt) >>
249 (BoundLifetimes {
250 for_token: for_,
251 lt_token: lt,
252 gt_token: gt,
253 lifetimes: lifetimes,
254 })
255 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700256 }
David Tolnay55337722016-09-11 12:58:56 -0700257
Alex Crichton954046c2017-05-30 21:49:42 -0700258 impl Synom for TyParam {
Michael Layzell92639a52017-06-01 00:07:44 -0400259 named!(parse -> Self, do_parse!(
260 attrs: many0!(call!(Attribute::parse_outer)) >>
261 id: syn!(Ident) >>
262 colon: option!(syn!(Colon)) >>
263 bounds: cond!(
264 colon.is_some(),
265 call!(Delimited::parse_separated_nonempty)
266 ) >>
267 default: option!(do_parse!(
268 eq: syn!(Eq) >>
269 ty: syn!(Ty) >>
270 (eq, ty)
271 )) >>
272 (TyParam {
273 attrs: attrs,
274 ident: id,
275 bounds: bounds.unwrap_or_default(),
276 colon_token: colon,
277 eq_token: default.as_ref().map(|d| tokens::Eq((d.0).0)),
278 default: default.map(|d| d.1),
279 })
280 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700281 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700282
Alex Crichton954046c2017-05-30 21:49:42 -0700283 impl Synom for TyParamBound {
Michael Layzell92639a52017-06-01 00:07:44 -0400284 named!(parse -> Self, alt!(
285 do_parse!(
286 question: syn!(Question) >>
287 poly: syn!(PolyTraitRef) >>
288 (TyParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
289 )
290 |
291 syn!(Lifetime) => { TyParamBound::Region }
292 |
293 syn!(PolyTraitRef) => {
294 |poly| TyParamBound::Trait(poly, TraitBoundModifier::None)
Alex Crichton954046c2017-05-30 21:49:42 -0700295 }
Michael Layzell92639a52017-06-01 00:07:44 -0400296 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700297
298 fn description() -> Option<&'static str> {
299 Some("type parameter buond")
300 }
301 }
302
303 impl Synom for WhereClause {
Michael Layzell92639a52017-06-01 00:07:44 -0400304 named!(parse -> Self, alt!(
305 do_parse!(
306 where_: syn!(Where) >>
307 predicates: call!(Delimited::parse_terminated) >>
308 (WhereClause {
309 predicates: predicates,
310 where_token: Some(where_),
311 })
312 )
313 |
314 epsilon!() => { |_| WhereClause::default() }
315 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700316
317 fn description() -> Option<&'static str> {
318 Some("where clause")
319 }
320 }
321
322 impl Synom for WherePredicate {
Michael Layzell92639a52017-06-01 00:07:44 -0400323 named!(parse -> Self, alt!(
324 do_parse!(
325 ident: syn!(Lifetime) >>
326 colon: option!(syn!(Colon)) >>
327 bounds: cond!(
328 colon.is_some(),
329 call!(Delimited::parse_separated)
330 ) >>
331 (WherePredicate::RegionPredicate(WhereRegionPredicate {
332 lifetime: ident,
333 bounds: bounds.unwrap_or_default(),
334 colon_token: colon,
335 }))
336 )
337 |
338 do_parse!(
339 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
340 bounded_ty: syn!(Ty) >>
341 colon: syn!(Colon) >>
342 bounds: call!(Delimited::parse_separated_nonempty) >>
343 (WherePredicate::BoundPredicate(WhereBoundPredicate {
344 bound_lifetimes: bound_lifetimes,
345 bounded_ty: bounded_ty,
346 bounds: bounds,
347 colon_token: colon,
348 }))
349 )
350 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700351 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700352}
David Tolnay87d0b442016-09-04 11:52:12 -0700353
354#[cfg(feature = "printing")]
355mod printing {
356 use super::*;
David Tolnaye7678922016-10-13 20:44:03 -0700357 use attr::FilterAttrs;
David Tolnay87d0b442016-09-04 11:52:12 -0700358 use quote::{Tokens, ToTokens};
359
Michael Layzell3936ceb2017-07-08 00:28:36 -0400360 /// Returns true if the generics object has no lifetimes or ty_params.
361 fn empty_normal_generics(generics: &Generics) -> bool {
362 generics.lifetimes.is_empty() && generics.ty_params.is_empty()
363 }
364
365 /// We need a comma between the lifetimes list and the ty_params list if
366 /// there are more than 0 lifetimes, the lifetimes list didn't have a
367 /// trailing delimiter, and there are more than 0 type parameters. This is a
368 /// helper method for adding that comma.
369 fn maybe_add_lifetime_params_comma(tokens: &mut Tokens, generics: &Generics) {
370 // We may need to require a trailing comma if we have any ty_params.
371 if !generics.lifetimes.empty_or_trailing() && !generics.ty_params.is_empty() {
372 tokens::Comma::default().to_tokens(tokens);
373 }
374 }
375
David Tolnay8ef93042016-09-04 14:08:40 -0700376 impl ToTokens for Generics {
377 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400378 if empty_normal_generics(self) {
379 return;
380 }
381
Alex Crichton259ee532017-07-14 06:51:02 -0700382 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700383 self.lifetimes.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400384 maybe_add_lifetime_params_comma(tokens, self);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700385 self.ty_params.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700386 TokensOrDefault(&self.gt_token).to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700387 }
388 }
389
David Tolnaye7678922016-10-13 20:44:03 -0700390 impl<'a> ToTokens for ImplGenerics<'a> {
391 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400392 if empty_normal_generics(&self.0) {
393 return;
394 }
395
Alex Crichton259ee532017-07-14 06:51:02 -0700396 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700397 self.0.lifetimes.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400398 maybe_add_lifetime_params_comma(tokens, &self.0);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700399 for param in self.0.ty_params.iter() {
400 // Leave off the type parameter defaults
401 let item = param.item();
402 tokens.append_all(item.attrs.outer());
403 item.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400404 if !item.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700405 TokensOrDefault(&item.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400406 item.bounds.to_tokens(tokens);
407 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700408 param.delimiter().to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700409 }
Alex Crichton259ee532017-07-14 06:51:02 -0700410 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700411 }
412 }
413
414 impl<'a> ToTokens for TyGenerics<'a> {
415 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400416 if empty_normal_generics(&self.0) {
417 return;
418 }
419
Alex Crichton259ee532017-07-14 06:51:02 -0700420 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700421 // Leave off the lifetime bounds and attributes
422 for param in self.0.lifetimes.iter() {
423 param.item().lifetime.to_tokens(tokens);
424 param.delimiter().to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700425 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400426 maybe_add_lifetime_params_comma(tokens, &self.0);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700427 // Leave off the type parameter defaults
428 for param in self.0.ty_params.iter() {
429 param.item().ident.to_tokens(tokens);
430 param.delimiter().to_tokens(tokens);
431 }
Alex Crichton259ee532017-07-14 06:51:02 -0700432 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700433 }
434 }
435
David Tolnayc879a502017-01-25 15:51:32 -0800436 impl<'a> ToTokens for Turbofish<'a> {
437 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400438 if !empty_normal_generics(&self.0) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700439 tokens::Colon2::default().to_tokens(tokens);
David Tolnayc879a502017-01-25 15:51:32 -0800440 TyGenerics(self.0).to_tokens(tokens);
441 }
442 }
443 }
444
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700445 impl ToTokens for BoundLifetimes {
446 fn to_tokens(&self, tokens: &mut Tokens) {
447 self.for_token.to_tokens(tokens);
448 self.lt_token.to_tokens(tokens);
449 self.lifetimes.to_tokens(tokens);
450 self.gt_token.to_tokens(tokens);
451 }
452 }
453
David Tolnay87d0b442016-09-04 11:52:12 -0700454 impl ToTokens for LifetimeDef {
455 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700456 tokens.append_all(self.attrs.outer());
David Tolnay87d0b442016-09-04 11:52:12 -0700457 self.lifetime.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400458 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700459 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400460 self.bounds.to_tokens(tokens);
461 }
David Tolnay87d0b442016-09-04 11:52:12 -0700462 }
463 }
464
David Tolnay8ef93042016-09-04 14:08:40 -0700465 impl ToTokens for TyParam {
466 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700467 tokens.append_all(self.attrs.outer());
David Tolnay8ef93042016-09-04 14:08:40 -0700468 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400469 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700470 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400471 self.bounds.to_tokens(tokens);
472 }
473 if self.default.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -0700474 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400475 self.default.to_tokens(tokens);
476 }
David Tolnay8ef93042016-09-04 14:08:40 -0700477 }
478 }
479
David Tolnay87d0b442016-09-04 11:52:12 -0700480 impl ToTokens for TyParamBound {
481 fn to_tokens(&self, tokens: &mut Tokens) {
482 match *self {
David Tolnay87d0b442016-09-04 11:52:12 -0700483 TyParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700484 TyParamBound::Trait(ref trait_ref, ref modifier) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 modifier.to_tokens(tokens);
David Tolnay55337722016-09-11 12:58:56 -0700486 trait_ref.to_tokens(tokens);
487 }
488 }
489 }
490 }
491
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700492 impl ToTokens for TraitBoundModifier {
493 fn to_tokens(&self, tokens: &mut Tokens) {
494 match *self {
495 TraitBoundModifier::None => {}
496 TraitBoundModifier::Maybe(ref t) => t.to_tokens(tokens),
497 }
498 }
499 }
500
David Tolnay55337722016-09-11 12:58:56 -0700501 impl ToTokens for WhereClause {
502 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400503 if !self.predicates.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700504 TokensOrDefault(&self.where_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400505 self.predicates.to_tokens(tokens);
506 }
David Tolnay87d0b442016-09-04 11:52:12 -0700507 }
508 }
David Tolnay8ef93042016-09-04 14:08:40 -0700509
David Tolnay8ef93042016-09-04 14:08:40 -0700510 impl ToTokens for WhereBoundPredicate {
511 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700512 self.bound_lifetimes.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700513 self.bounded_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700514 self.colon_token.to_tokens(tokens);
515 self.bounds.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700516 }
517 }
518
519 impl ToTokens for WhereRegionPredicate {
520 fn to_tokens(&self, tokens: &mut Tokens) {
521 self.lifetime.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400522 if !self.bounds.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -0700523 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400524 self.bounds.to_tokens(tokens);
525 }
David Tolnay8ef93042016-09-04 14:08:40 -0700526 }
527 }
David Tolnayf8e08832017-01-23 00:04:32 -0800528
529 impl ToTokens for WhereEqPredicate {
530 fn to_tokens(&self, tokens: &mut Tokens) {
531 self.lhs_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700532 self.eq_token.to_tokens(tokens);
David Tolnayf8e08832017-01-23 00:04:32 -0800533 self.rhs_ty.to_tokens(tokens);
534 }
535 }
David Tolnay87d0b442016-09-04 11:52:12 -0700536}