blob: 2ab61bfe1d9f620a177719f452b51f2c5a6bf425 [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")]
Alex Crichton2e0229c2017-05-23 09:34:50 -070018ast_struct! {
19 /// Returned by `Generics::split_for_impl`.
20 pub struct ImplGenerics<'a>(&'a Generics);
21}
David Tolnaye7678922016-10-13 20:44:03 -070022
23#[cfg(feature = "printing")]
Alex Crichton2e0229c2017-05-23 09:34:50 -070024ast_struct! {
25 /// Returned by `Generics::split_for_impl`.
26 pub struct TyGenerics<'a>(&'a Generics);
27}
David Tolnaye7678922016-10-13 20:44:03 -070028
David Tolnayc879a502017-01-25 15:51:32 -080029#[cfg(feature = "printing")]
Alex Crichton2e0229c2017-05-23 09:34:50 -070030ast_struct! {
31 /// Returned by `TyGenerics::as_turbofish`.
32 pub struct Turbofish<'a>(&'a Generics);
33}
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! {
70 pub struct Lifetime {
71 pub ident: Ident,
72 }
David Tolnayb79ee962016-09-04 09:39:20 -070073}
74
David Tolnay01405f02016-10-02 09:05:02 -070075impl Lifetime {
76 pub fn new<T: Into<Ident>>(t: T) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070077 let id = t.into();
David Tolnayff3b8ae2016-10-08 11:54:18 -070078 if !id.as_ref().starts_with('\'') {
79 panic!("lifetime name must start with apostrophe as in \"'a\", \
David Tolnay3bcfb722016-10-08 11:58:36 -070080 got {:?}",
81 id.as_ref());
David Tolnayff3b8ae2016-10-08 11:54:18 -070082 }
83 Lifetime { ident: id }
David Tolnay01405f02016-10-02 09:05:02 -070084 }
85}
86
Alex Crichton62a0a592017-05-22 13:58:53 -070087ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070088 /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>`
89 #[derive(Default)]
90 pub struct BoundLifetimes {
91 pub for_token: tokens::For,
92 pub lt_token: tokens::Lt,
93 pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
94 pub gt_token: tokens::Gt,
95 }
96}
97
98ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -070099 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
100 pub struct LifetimeDef {
101 pub attrs: Vec<Attribute>,
102 pub lifetime: Lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700103 pub colon_token: Option<tokens::Colon>,
104 pub bounds: Delimited<Lifetime, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 }
David Tolnayb79ee962016-09-04 09:39:20 -0700106}
107
David Tolnayf9505b52016-10-02 09:18:52 -0700108impl LifetimeDef {
109 pub fn new<T: Into<Ident>>(t: T) -> Self {
110 LifetimeDef {
David Tolnaye7678922016-10-13 20:44:03 -0700111 attrs: Vec::new(),
David Tolnayf9505b52016-10-02 09:18:52 -0700112 lifetime: Lifetime::new(t),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700113 colon_token: None,
114 bounds: Delimited::new(),
David Tolnayf9505b52016-10-02 09:18:52 -0700115 }
116 }
117}
118
Alex Crichton62a0a592017-05-22 13:58:53 -0700119ast_struct! {
120 /// A generic type parameter, e.g. `T: Into<String>`.
121 pub struct TyParam {
122 pub attrs: Vec<Attribute>,
123 pub ident: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700124 pub colon_token: Option<tokens::Colon>,
125 pub bounds: Delimited<TyParamBound, tokens::Add>,
126 pub eq_token: Option<tokens::Eq>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700127 pub default: Option<Ty>,
128 }
David Tolnayb79ee962016-09-04 09:39:20 -0700129}
130
Ted Driggs0547d0d2017-04-20 10:00:12 -0700131impl From<Ident> for TyParam {
132 fn from(ident: Ident) -> Self {
133 TyParam {
134 attrs: vec![],
135 ident: ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700136 colon_token: None,
137 bounds: Delimited::new(),
138 eq_token: None,
Ted Driggs0547d0d2017-04-20 10:00:12 -0700139 default: None,
140 }
141 }
142}
143
Alex Crichton62a0a592017-05-22 13:58:53 -0700144ast_enum! {
145 /// The AST represents all type param bounds as types.
146 /// `typeck::collect::compute_bounds` matches these against
147 /// the "special" built-in traits (see `middle::lang_items`) and
148 /// detects Copy, Send and Sync.
149 pub enum TyParamBound {
150 Trait(PolyTraitRef, TraitBoundModifier),
151 Region(Lifetime),
152 }
David Tolnay55337722016-09-11 12:58:56 -0700153}
154
Alex Crichton62a0a592017-05-22 13:58:53 -0700155ast_enum! {
156 /// A modifier on a bound, currently this is only used for `?Sized`, where the
157 /// modifier is `Maybe`. Negative bounds should also be handled here.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700158 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700159 pub enum TraitBoundModifier {
160 None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700161 Maybe(tokens::Question),
Alex Crichton62a0a592017-05-22 13:58:53 -0700162 }
David Tolnay55337722016-09-11 12:58:56 -0700163}
164
Alex Crichton62a0a592017-05-22 13:58:53 -0700165ast_struct! {
166 /// A `where` clause in a definition
167 #[derive(Default)]
168 pub struct WhereClause {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700169 pub where_token: Option<tokens::Where>,
170 pub predicates: Delimited<WherePredicate, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700171 }
David Tolnayb79ee962016-09-04 09:39:20 -0700172}
173
David Tolnayb153dbc2016-10-04 23:39:10 -0700174impl WhereClause {
175 pub fn none() -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700176 WhereClause::default()
David Tolnayb153dbc2016-10-04 23:39:10 -0700177 }
178}
179
Alex Crichton62a0a592017-05-22 13:58:53 -0700180ast_enum_of_structs! {
181 /// A single predicate in a `where` clause
182 pub enum WherePredicate {
183 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
184 pub BoundPredicate(WhereBoundPredicate {
185 /// Any lifetimes from a `for` binding
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700186 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700187 /// The type being bounded
188 pub bounded_ty: Ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700189 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 /// Trait and lifetime bounds (`Clone+Send+'static`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700191 pub bounds: Delimited<TyParamBound, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700193
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 /// A lifetime predicate, e.g. `'a: 'b+'c`
195 pub RegionPredicate(WhereRegionPredicate {
196 pub lifetime: Lifetime,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700197 pub colon_token: Option<tokens::Colon>,
198 pub bounds: Delimited<Lifetime, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700199 }),
David Tolnayb79ee962016-09-04 09:39:20 -0700200
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 /// An equality predicate (unsupported)
202 pub EqPredicate(WhereEqPredicate {
203 pub lhs_ty: Ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700204 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 pub rhs_ty: Ty,
206 }),
207 }
David Tolnayf8e08832017-01-23 00:04:32 -0800208}
209
David Tolnay86eca752016-09-04 11:26:41 -0700210#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700211pub mod parsing {
212 use super::*;
David Tolnay9d8f1972016-09-04 11:58:48 -0700213
Michael Layzell92639a52017-06-01 00:07:44 -0400214 use synom::{PResult, Cursor, Synom, parse_error};
Alex Crichton954046c2017-05-30 21:49:42 -0700215 use synom::tokens::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400216 use proc_macro2::TokenKind;
Alex Crichton954046c2017-05-30 21:49:42 -0700217
218 impl Synom for Generics {
Michael Layzell92639a52017-06-01 00:07:44 -0400219 named!(parse -> Self, map!(
220 alt!(
221 do_parse!(
222 lt: syn!(Lt) >>
223 lifetimes: call!(Delimited::parse_terminated) >>
224 ty_params: cond!(
225 lifetimes.is_empty() || lifetimes.trailing_delim(),
226 call!(Delimited::parse_terminated)
227 ) >>
228 gt: syn!(Gt) >>
229 (lifetimes, ty_params, Some(lt), Some(gt))
230 )
231 |
232 epsilon!() => { |_| (Delimited::new(), None, None, None) }
233 ),
234 |(lifetimes, ty_params, lt, gt): (_, Option<_>, _, _)| Generics {
235 lifetimes: lifetimes,
236 ty_params: ty_params.unwrap_or_default(),
237 where_clause: WhereClause::default(),
238 gt_token: gt,
239 lt_token: lt,
Michael Layzell416724e2017-05-24 21:12:34 -0400240 }
Michael Layzell92639a52017-06-01 00:07:44 -0400241 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700242 }
243
244 impl Synom for Lifetime {
Michael Layzell92639a52017-06-01 00:07:44 -0400245 fn parse(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700246 let mut tokens = input.iter();
247 let token = match tokens.next() {
248 Some(token) => token,
Michael Layzell92639a52017-06-01 00:07:44 -0400249 None => return parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700250 };
251 if let TokenKind::Word(s) = token.kind {
252 if s.as_str().starts_with('\'') {
Michael Layzell92639a52017-06-01 00:07:44 -0400253 return Ok((tokens.as_slice(), Lifetime {
Alex Crichton954046c2017-05-30 21:49:42 -0700254 ident: Ident {
255 span: Span(token.span),
256 sym: s,
257 },
Michael Layzell92639a52017-06-01 00:07:44 -0400258 }))
Alex Crichton954046c2017-05-30 21:49:42 -0700259 }
260 }
Michael Layzell92639a52017-06-01 00:07:44 -0400261 parse_error()
Michael Layzell416724e2017-05-24 21:12:34 -0400262 }
263 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700264
Alex Crichton954046c2017-05-30 21:49:42 -0700265 impl Synom for LifetimeDef {
Michael Layzell92639a52017-06-01 00:07:44 -0400266 named!(parse -> Self, do_parse!(
267 attrs: many0!(call!(Attribute::parse_outer)) >>
268 life: syn!(Lifetime) >>
269 colon: option!(syn!(Colon)) >>
270 bounds: cond!(
271 colon.is_some(),
272 call!(Delimited::parse_separated_nonempty)
273 ) >>
274 (LifetimeDef {
275 attrs: attrs,
276 lifetime: life,
277 bounds: bounds.unwrap_or_default(),
278 colon_token: colon.map(|_| tokens::Colon::default()),
279 })
280 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700281 }
282
283 impl Synom for BoundLifetimes {
Michael Layzell92639a52017-06-01 00:07:44 -0400284 named!(parse -> Self, do_parse!(
285 for_: syn!(For) >>
286 lt: syn!(Lt) >>
287 lifetimes: call!(Delimited::parse_terminated) >>
288 gt: syn!(Gt) >>
289 (BoundLifetimes {
290 for_token: for_,
291 lt_token: lt,
292 gt_token: gt,
293 lifetimes: lifetimes,
294 })
295 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700296 }
David Tolnay55337722016-09-11 12:58:56 -0700297
Alex Crichton954046c2017-05-30 21:49:42 -0700298 impl Synom for TyParam {
Michael Layzell92639a52017-06-01 00:07:44 -0400299 named!(parse -> Self, do_parse!(
300 attrs: many0!(call!(Attribute::parse_outer)) >>
301 id: syn!(Ident) >>
302 colon: option!(syn!(Colon)) >>
303 bounds: cond!(
304 colon.is_some(),
305 call!(Delimited::parse_separated_nonempty)
306 ) >>
307 default: option!(do_parse!(
308 eq: syn!(Eq) >>
309 ty: syn!(Ty) >>
310 (eq, ty)
311 )) >>
312 (TyParam {
313 attrs: attrs,
314 ident: id,
315 bounds: bounds.unwrap_or_default(),
316 colon_token: colon,
317 eq_token: default.as_ref().map(|d| tokens::Eq((d.0).0)),
318 default: default.map(|d| d.1),
319 })
320 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700321 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700322
Alex Crichton954046c2017-05-30 21:49:42 -0700323 impl Synom for TyParamBound {
Michael Layzell92639a52017-06-01 00:07:44 -0400324 named!(parse -> Self, alt!(
325 do_parse!(
326 question: syn!(Question) >>
327 poly: syn!(PolyTraitRef) >>
328 (TyParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
329 )
330 |
331 syn!(Lifetime) => { TyParamBound::Region }
332 |
333 syn!(PolyTraitRef) => {
334 |poly| TyParamBound::Trait(poly, TraitBoundModifier::None)
Alex Crichton954046c2017-05-30 21:49:42 -0700335 }
Michael Layzell92639a52017-06-01 00:07:44 -0400336 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700337
338 fn description() -> Option<&'static str> {
339 Some("type parameter buond")
340 }
341 }
342
343 impl Synom for WhereClause {
Michael Layzell92639a52017-06-01 00:07:44 -0400344 named!(parse -> Self, alt!(
345 do_parse!(
346 where_: syn!(Where) >>
347 predicates: call!(Delimited::parse_terminated) >>
348 (WhereClause {
349 predicates: predicates,
350 where_token: Some(where_),
351 })
352 )
353 |
354 epsilon!() => { |_| WhereClause::default() }
355 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700356
357 fn description() -> Option<&'static str> {
358 Some("where clause")
359 }
360 }
361
362 impl Synom for WherePredicate {
Michael Layzell92639a52017-06-01 00:07:44 -0400363 named!(parse -> Self, alt!(
364 do_parse!(
365 ident: syn!(Lifetime) >>
366 colon: option!(syn!(Colon)) >>
367 bounds: cond!(
368 colon.is_some(),
369 call!(Delimited::parse_separated)
370 ) >>
371 (WherePredicate::RegionPredicate(WhereRegionPredicate {
372 lifetime: ident,
373 bounds: bounds.unwrap_or_default(),
374 colon_token: colon,
375 }))
376 )
377 |
378 do_parse!(
379 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
380 bounded_ty: syn!(Ty) >>
381 colon: syn!(Colon) >>
382 bounds: call!(Delimited::parse_separated_nonempty) >>
383 (WherePredicate::BoundPredicate(WhereBoundPredicate {
384 bound_lifetimes: bound_lifetimes,
385 bounded_ty: bounded_ty,
386 bounds: bounds,
387 colon_token: colon,
388 }))
389 )
390 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700391 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700392}
David Tolnay87d0b442016-09-04 11:52:12 -0700393
394#[cfg(feature = "printing")]
395mod printing {
396 use super::*;
David Tolnaye7678922016-10-13 20:44:03 -0700397 use attr::FilterAttrs;
David Tolnay87d0b442016-09-04 11:52:12 -0700398 use quote::{Tokens, ToTokens};
399
David Tolnay8ef93042016-09-04 14:08:40 -0700400 impl ToTokens for Generics {
401 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700402 self.lt_token.to_tokens(tokens);
403 self.lifetimes.to_tokens(tokens);
404 self.ty_params.to_tokens(tokens);
405 self.gt_token.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700406 }
407 }
408
David Tolnaye7678922016-10-13 20:44:03 -0700409 impl<'a> ToTokens for ImplGenerics<'a> {
410 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700411 self.0.lt_token.to_tokens(tokens);
412 self.0.lifetimes.to_tokens(tokens);
413 for param in self.0.ty_params.iter() {
414 // Leave off the type parameter defaults
415 let item = param.item();
416 tokens.append_all(item.attrs.outer());
417 item.ident.to_tokens(tokens);
418 item.colon_token.to_tokens(tokens);
419 item.bounds.to_tokens(tokens);
420 param.delimiter().to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700421 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700422 self.0.gt_token.to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700423 }
424 }
425
426 impl<'a> ToTokens for TyGenerics<'a> {
427 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700428 self.0.lt_token.to_tokens(tokens);
429 // Leave off the lifetime bounds and attributes
430 for param in self.0.lifetimes.iter() {
431 param.item().lifetime.to_tokens(tokens);
432 param.delimiter().to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700433 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700434 // Leave off the type parameter defaults
435 for param in self.0.ty_params.iter() {
436 param.item().ident.to_tokens(tokens);
437 param.delimiter().to_tokens(tokens);
438 }
439 self.0.gt_token.to_tokens(tokens);
David Tolnaye7678922016-10-13 20:44:03 -0700440 }
441 }
442
David Tolnayc879a502017-01-25 15:51:32 -0800443 impl<'a> ToTokens for Turbofish<'a> {
444 fn to_tokens(&self, tokens: &mut Tokens) {
445 let has_lifetimes = !self.0.lifetimes.is_empty();
446 let has_ty_params = !self.0.ty_params.is_empty();
447 if has_lifetimes || has_ty_params {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700448 tokens::Colon2::default().to_tokens(tokens);
David Tolnayc879a502017-01-25 15:51:32 -0800449 TyGenerics(self.0).to_tokens(tokens);
450 }
451 }
452 }
453
David Tolnay87d0b442016-09-04 11:52:12 -0700454 impl ToTokens for Lifetime {
455 fn to_tokens(&self, tokens: &mut Tokens) {
456 self.ident.to_tokens(tokens);
457 }
458 }
459
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700460 impl ToTokens for BoundLifetimes {
461 fn to_tokens(&self, tokens: &mut Tokens) {
462 self.for_token.to_tokens(tokens);
463 self.lt_token.to_tokens(tokens);
464 self.lifetimes.to_tokens(tokens);
465 self.gt_token.to_tokens(tokens);
466 }
467 }
468
David Tolnay87d0b442016-09-04 11:52:12 -0700469 impl ToTokens for LifetimeDef {
470 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700471 tokens.append_all(self.attrs.outer());
David Tolnay87d0b442016-09-04 11:52:12 -0700472 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700473 self.colon_token.to_tokens(tokens);
474 self.bounds.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700475 }
476 }
477
David Tolnay8ef93042016-09-04 14:08:40 -0700478 impl ToTokens for TyParam {
479 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye7678922016-10-13 20:44:03 -0700480 tokens.append_all(self.attrs.outer());
David Tolnay8ef93042016-09-04 14:08:40 -0700481 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700482 self.colon_token.to_tokens(tokens);
483 self.bounds.to_tokens(tokens);
484 self.eq_token.to_tokens(tokens);
485 self.default.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700486 }
487 }
488
David Tolnay87d0b442016-09-04 11:52:12 -0700489 impl ToTokens for TyParamBound {
490 fn to_tokens(&self, tokens: &mut Tokens) {
491 match *self {
David Tolnay87d0b442016-09-04 11:52:12 -0700492 TyParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700493 TyParamBound::Trait(ref trait_ref, ref modifier) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 modifier.to_tokens(tokens);
David Tolnay55337722016-09-11 12:58:56 -0700495 trait_ref.to_tokens(tokens);
496 }
497 }
498 }
499 }
500
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700501 impl ToTokens for TraitBoundModifier {
502 fn to_tokens(&self, tokens: &mut Tokens) {
503 match *self {
504 TraitBoundModifier::None => {}
505 TraitBoundModifier::Maybe(ref t) => t.to_tokens(tokens),
506 }
507 }
508 }
509
David Tolnay55337722016-09-11 12:58:56 -0700510 impl ToTokens for WhereClause {
511 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700512 self.where_token.to_tokens(tokens);
513 self.predicates.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700514 }
515 }
David Tolnay8ef93042016-09-04 14:08:40 -0700516
David Tolnay8ef93042016-09-04 14:08:40 -0700517 impl ToTokens for WhereBoundPredicate {
518 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700519 self.bound_lifetimes.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700520 self.bounded_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 self.colon_token.to_tokens(tokens);
522 self.bounds.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700523 }
524 }
525
526 impl ToTokens for WhereRegionPredicate {
527 fn to_tokens(&self, tokens: &mut Tokens) {
528 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700529 self.colon_token.to_tokens(tokens);
530 self.bounds.to_tokens(tokens);
David Tolnay8ef93042016-09-04 14:08:40 -0700531 }
532 }
David Tolnayf8e08832017-01-23 00:04:32 -0800533
534 impl ToTokens for WhereEqPredicate {
535 fn to_tokens(&self, tokens: &mut Tokens) {
536 self.lhs_ty.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700537 self.eq_token.to_tokens(tokens);
David Tolnayf8e08832017-01-23 00:04:32 -0800538 self.rhs_ty.to_tokens(tokens);
539 }
540 }
David Tolnay87d0b442016-09-04 11:52:12 -0700541}