1 use super::*;
2 
3 /// The different kinds of types recognized by the compiler
4 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
5 pub enum Ty {
6     /// A variable-length array (`[T]`)
7     Slice(Box<Ty>),
8     /// A fixed length array (`[T; n]`)
9     Array(Box<Ty>, ConstExpr),
10     /// A raw pointer (`*const T` or `*mut T`)
11     Ptr(Box<MutTy>),
12     /// A reference (`&'a T` or `&'a mut T`)
13     Rptr(Option<Lifetime>, Box<MutTy>),
14     /// A bare function (e.g. `fn(usize) -> bool`)
15     BareFn(Box<BareFnTy>),
16     /// The never type (`!`)
17     Never,
18     /// A tuple (`(A, B, C, D, ...)`)
19     Tup(Vec<Ty>),
20     /// A path (`module::module::...::Type`), optionally
21     /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
22     ///
23     /// Type parameters are stored in the Path itself
24     Path(Option<QSelf>, Path),
25     /// A trait object type `Bound1 + Bound2 + Bound3`
26     /// where `Bound` is a trait or a lifetime.
27     TraitObject(Vec<TyParamBound>),
28     /// An `impl Bound1 + Bound2 + Bound3` type
29     /// where `Bound` is a trait or a lifetime.
30     ImplTrait(Vec<TyParamBound>),
31     /// No-op; kept solely so that we can pretty-print faithfully
32     Paren(Box<Ty>),
33     /// TyKind::Infer means the type should be inferred instead of it having been
34     /// specified. This can appear anywhere in a type.
35     Infer,
36     /// A macro in the type position.
37     Mac(Mac),
38 }
39 
40 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
41 pub struct MutTy {
42     pub ty: Ty,
43     pub mutability: Mutability,
44 }
45 
46 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
47 pub enum Mutability {
48     Mutable,
49     Immutable,
50 }
51 
52 /// A "Path" is essentially Rust's notion of a name.
53 ///
54 /// It's represented as a sequence of identifiers,
55 /// along with a bunch of supporting information.
56 ///
57 /// E.g. `std::cmp::PartialEq`
58 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
59 pub struct Path {
60     /// A `::foo` path, is relative to the crate root rather than current
61     /// module (like paths in an import).
62     pub global: bool,
63     /// The segments in the path: the things separated by `::`.
64     pub segments: Vec<PathSegment>,
65 }
66 
67 impl<T> From<T> for Path
68     where T: Into<PathSegment>
69 {
from(segment: T) -> Self70     fn from(segment: T) -> Self {
71         Path {
72             global: false,
73             segments: vec![segment.into()],
74         }
75     }
76 }
77 
78 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
79 ///
80 /// E.g. `std`, `String` or `Box<T>`
81 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
82 pub struct PathSegment {
83     /// The identifier portion of this path segment.
84     pub ident: Ident,
85     /// Type/lifetime parameters attached to this path. They come in
86     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
87     /// this is more than just simple syntactic sugar; the use of
88     /// parens affects the region binding rules, so we preserve the
89     /// distinction.
90     pub parameters: PathParameters,
91 }
92 
93 impl<T> From<T> for PathSegment
94     where T: Into<Ident>
95 {
from(ident: T) -> Self96     fn from(ident: T) -> Self {
97         PathSegment {
98             ident: ident.into(),
99             parameters: PathParameters::none(),
100         }
101     }
102 }
103 
104 /// Parameters of a path segment.
105 ///
106 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
107 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
108 pub enum PathParameters {
109     /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
110     AngleBracketed(AngleBracketedParameterData),
111     /// The `(A, B)` and `C` in `Foo(A, B) -> C`
112     Parenthesized(ParenthesizedParameterData),
113 }
114 
115 impl PathParameters {
none() -> Self116     pub fn none() -> Self {
117         PathParameters::AngleBracketed(AngleBracketedParameterData::default())
118     }
119 
is_empty(&self) -> bool120     pub fn is_empty(&self) -> bool {
121         match *self {
122             PathParameters::AngleBracketed(ref bracketed) => {
123                 bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
124                 bracketed.bindings.is_empty()
125             }
126             PathParameters::Parenthesized(_) => false,
127         }
128     }
129 }
130 
131 /// A path like `Foo<'a, T>`
132 #[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
133 pub struct AngleBracketedParameterData {
134     /// The lifetime parameters for this path segment.
135     pub lifetimes: Vec<Lifetime>,
136     /// The type parameters for this path segment, if present.
137     pub types: Vec<Ty>,
138     /// Bindings (equality constraints) on associated types, if present.
139     ///
140     /// E.g., `Foo<A=Bar>`.
141     pub bindings: Vec<TypeBinding>,
142 }
143 
144 /// Bind a type to an associated type: `A=Foo`.
145 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
146 pub struct TypeBinding {
147     pub ident: Ident,
148     pub ty: Ty,
149 }
150 
151 /// A path like `Foo(A,B) -> C`
152 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
153 pub struct ParenthesizedParameterData {
154     /// `(A, B)`
155     pub inputs: Vec<Ty>,
156     /// `C`
157     pub output: Option<Ty>,
158 }
159 
160 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
161 pub struct PolyTraitRef {
162     /// The `'a` in `<'a> Foo<&'a T>`
163     pub bound_lifetimes: Vec<LifetimeDef>,
164     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
165     pub trait_ref: Path,
166 }
167 
168 /// The explicit Self type in a "qualified path". The actual
169 /// path, including the trait and the associated item, is stored
170 /// separately. `position` represents the index of the associated
171 /// item qualified with this Self type.
172 ///
173 /// ```rust,ignore
174 /// <Vec<T> as a::b::Trait>::AssociatedItem
175 ///  ^~~~~     ~~~~~~~~~~~~~~^
176 ///  ty        position = 3
177 ///
178 /// <Vec<T>>::AssociatedItem
179 ///  ^~~~~    ^
180 ///  ty       position = 0
181 /// ```
182 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
183 pub struct QSelf {
184     pub ty: Box<Ty>,
185     pub position: usize,
186 }
187 
188 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
189 pub struct BareFnTy {
190     pub unsafety: Unsafety,
191     pub abi: Option<Abi>,
192     pub lifetimes: Vec<LifetimeDef>,
193     pub inputs: Vec<BareFnArg>,
194     pub output: FunctionRetTy,
195     pub variadic: bool,
196 }
197 
198 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
199 pub enum Unsafety {
200     Unsafe,
201     Normal,
202 }
203 
204 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
205 pub enum Abi {
206     Named(String),
207     Rust,
208 }
209 
210 /// An argument in a function type.
211 ///
212 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
213 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
214 pub struct BareFnArg {
215     pub name: Option<Ident>,
216     pub ty: Ty,
217 }
218 
219 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
220 pub enum FunctionRetTy {
221     /// Return type is not specified.
222     ///
223     /// Functions default to `()` and
224     /// closures default to inference. Span points to where return
225     /// type would be inserted.
226     Default,
227     /// Everything else
228     Ty(Ty),
229 }
230 
231 #[cfg(feature = "parsing")]
232 pub mod parsing {
233     use super::*;
234     use {TyParamBound, TraitBoundModifier};
235     #[cfg(feature = "full")]
236     use ConstExpr;
237     #[cfg(feature = "full")]
238     use constant::parsing::const_expr;
239     #[cfg(feature = "full")]
240     use expr::parsing::expr;
241     use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes};
242     use ident::parsing::ident;
243     use lit::parsing::quoted_string;
244     use mac::parsing::mac;
245     use std::str;
246 
247     named!(pub ty -> Ty, alt!(
248         ty_paren // must be before ty_tup
249         |
250         ty_mac // must be before ty_path
251         |
252         ty_path // must be before ty_poly_trait_ref
253         |
254         ty_vec
255         |
256         ty_array
257         |
258         ty_ptr
259         |
260         ty_rptr
261         |
262         ty_bare_fn
263         |
264         ty_never
265         |
266         ty_tup
267         |
268         ty_poly_trait_ref
269         |
270         ty_impl_trait
271     ));
272 
273     named!(ty_mac -> Ty, map!(mac, Ty::Mac));
274 
275     named!(ty_vec -> Ty, do_parse!(
276         punct!("[") >>
277         elem: ty >>
278         punct!("]") >>
279         (Ty::Slice(Box::new(elem)))
280     ));
281 
282     named!(ty_array -> Ty, do_parse!(
283         punct!("[") >>
284         elem: ty >>
285         punct!(";") >>
286         len: array_len >>
287         punct!("]") >>
288         (Ty::Array(Box::new(elem), len))
289     ));
290 
291     #[cfg(not(feature = "full"))]
292     use constant::parsing::const_expr as array_len;
293 
294     #[cfg(feature = "full")]
295     named!(array_len -> ConstExpr, alt!(
296         terminated!(const_expr, after_array_len)
297         |
298         terminated!(expr, after_array_len) => { ConstExpr::Other }
299     ));
300 
301     #[cfg(feature = "full")]
302     named!(after_array_len -> &str, peek!(punct!("]")));
303 
304     named!(ty_ptr -> Ty, do_parse!(
305         punct!("*") >>
306         mutability: alt!(
307             keyword!("const") => { |_| Mutability::Immutable }
308             |
309             keyword!("mut") => { |_| Mutability::Mutable }
310         ) >>
311         target: ty >>
312         (Ty::Ptr(Box::new(MutTy {
313             ty: target,
314             mutability: mutability,
315         })))
316     ));
317 
318     named!(ty_rptr -> Ty, do_parse!(
319         punct!("&") >>
320         life: option!(lifetime) >>
321         mutability: mutability >>
322         target: ty >>
323         (Ty::Rptr(life, Box::new(MutTy {
324             ty: target,
325             mutability: mutability,
326         })))
327     ));
328 
329     named!(ty_bare_fn -> Ty, do_parse!(
330         lifetimes: opt_vec!(do_parse!(
331             keyword!("for") >>
332             punct!("<") >>
333             lifetimes: terminated_list!(punct!(","), lifetime_def) >>
334             punct!(">") >>
335             (lifetimes)
336         )) >>
337         unsafety: unsafety >>
338         abi: option!(abi) >>
339         keyword!("fn") >>
340         punct!("(") >>
341         inputs: separated_list!(punct!(","), fn_arg) >>
342         trailing_comma: option!(punct!(",")) >>
343         variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
344         punct!(")") >>
345         output: option!(preceded!(
346             punct!("->"),
347             ty
348         )) >>
349         (Ty::BareFn(Box::new(BareFnTy {
350             unsafety: unsafety,
351             abi: abi,
352             lifetimes: lifetimes,
353             inputs: inputs,
354             output: match output {
355                 Some(ty) => FunctionRetTy::Ty(ty),
356                 None => FunctionRetTy::Default,
357             },
358             variadic: variadic.is_some(),
359         })))
360     ));
361 
362     named!(ty_never -> Ty, map!(punct!("!"), |_| Ty::Never));
363 
364     named!(ty_tup -> Ty, do_parse!(
365         punct!("(") >>
366         elems: terminated_list!(punct!(","), ty) >>
367         punct!(")") >>
368         (Ty::Tup(elems))
369     ));
370 
371     named!(ty_path -> Ty, do_parse!(
372         qpath: qpath >>
373         parenthesized: cond!(
374             qpath.1.segments.last().unwrap().parameters == PathParameters::none(),
375             option!(parenthesized_parameter_data)
376         ) >>
377         bounds: many0!(preceded!(punct!("+"), ty_param_bound)) >>
378         ({
379             let (qself, mut path) = qpath;
380             if let Some(Some(parenthesized)) = parenthesized {
381                 path.segments.last_mut().unwrap().parameters = parenthesized;
382             }
383             if bounds.is_empty() {
384                 Ty::Path(qself, path)
385             } else {
386                 let path = TyParamBound::Trait(
387                     PolyTraitRef {
388                         bound_lifetimes: Vec::new(),
389                         trait_ref: path,
390                     },
391                     TraitBoundModifier::None,
392                 );
393                 let bounds = Some(path).into_iter().chain(bounds).collect();
394                 Ty::TraitObject(bounds)
395             }
396         })
397     ));
398 
399     named!(parenthesized_parameter_data -> PathParameters, do_parse!(
400         punct!("(") >>
401         inputs: terminated_list!(punct!(","), ty) >>
402         punct!(")") >>
403         output: option!(preceded!(
404             punct!("->"),
405             ty
406         )) >>
407         (PathParameters::Parenthesized(
408             ParenthesizedParameterData {
409                 inputs: inputs,
410                 output: output,
411             },
412         ))
413     ));
414 
415     named!(pub qpath -> (Option<QSelf>, Path), alt!(
416         map!(path, |p| (None, p))
417         |
418         do_parse!(
419             punct!("<") >>
420             this: map!(ty, Box::new) >>
421             path: option!(preceded!(
422                 keyword!("as"),
423                 path
424             )) >>
425             punct!(">") >>
426             punct!("::") >>
427             rest: separated_nonempty_list!(punct!("::"), path_segment) >>
428             ({
429                 match path {
430                     Some(mut path) => {
431                         let pos = path.segments.len();
432                         path.segments.extend(rest);
433                         (Some(QSelf { ty: this, position: pos }), path)
434                     }
435                     None => {
436                         (Some(QSelf { ty: this, position: 0 }), Path {
437                             global: false,
438                             segments: rest,
439                         })
440                     }
441                 }
442             })
443         )
444         |
445         map!(keyword!("self"), |_| (None, "self".into()))
446     ));
447 
448     named!(ty_poly_trait_ref -> Ty, map!(
449         separated_nonempty_list!(punct!("+"), ty_param_bound),
450         Ty::TraitObject
451     ));
452 
453     named!(ty_impl_trait -> Ty, do_parse!(
454         keyword!("impl") >>
455         elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
456         (Ty::ImplTrait(elem))
457     ));
458 
459     named!(ty_paren -> Ty, do_parse!(
460         punct!("(") >>
461         elem: ty >>
462         punct!(")") >>
463         (Ty::Paren(Box::new(elem)))
464     ));
465 
466     named!(pub mutability -> Mutability, alt!(
467         keyword!("mut") => { |_| Mutability::Mutable }
468         |
469         epsilon!() => { |_| Mutability::Immutable }
470     ));
471 
472     named!(pub path -> Path, do_parse!(
473         global: option!(punct!("::")) >>
474         segments: separated_nonempty_list!(punct!("::"), path_segment) >>
475         (Path {
476             global: global.is_some(),
477             segments: segments,
478         })
479     ));
480 
481     named!(path_segment -> PathSegment, alt!(
482         do_parse!(
483             id: option!(ident) >>
484             punct!("<") >>
485             lifetimes: separated_list!(punct!(","), lifetime) >>
486             types: opt_vec!(preceded!(
487                 cond!(!lifetimes.is_empty(), punct!(",")),
488                 separated_nonempty_list!(
489                     punct!(","),
490                     terminated!(ty, not!(punct!("=")))
491                 )
492             )) >>
493             bindings: opt_vec!(preceded!(
494                 cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")),
495                 separated_nonempty_list!(punct!(","), type_binding)
496             )) >>
497             cond!(!lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty(), option!(punct!(","))) >>
498             punct!(">") >>
499             (PathSegment {
500                 ident: id.unwrap_or_else(|| "".into()),
501                 parameters: PathParameters::AngleBracketed(
502                     AngleBracketedParameterData {
503                         lifetimes: lifetimes,
504                         types: types,
505                         bindings: bindings,
506                     }
507                 ),
508             })
509         )
510         |
511         map!(ident, Into::into)
512         |
513         map!(alt!(
514             keyword!("super")
515             |
516             keyword!("self")
517             |
518             keyword!("Self")
519         ), Into::into)
520     ));
521 
522     named!(type_binding -> TypeBinding, do_parse!(
523         id: ident >>
524         punct!("=") >>
525         ty: ty >>
526         (TypeBinding {
527             ident: id,
528             ty: ty,
529         })
530     ));
531 
532     named!(pub poly_trait_ref -> PolyTraitRef, do_parse!(
533         bound_lifetimes: bound_lifetimes >>
534         trait_ref: path >>
535         parenthesized: option!(cond_reduce!(
536             trait_ref.segments.last().unwrap().parameters == PathParameters::none(),
537             parenthesized_parameter_data
538         )) >>
539         ({
540             let mut trait_ref = trait_ref;
541             if let Some(parenthesized) = parenthesized {
542                 trait_ref.segments.last_mut().unwrap().parameters = parenthesized;
543             }
544             PolyTraitRef {
545                 bound_lifetimes: bound_lifetimes,
546                 trait_ref: trait_ref,
547             }
548         })
549     ));
550 
551     named!(pub fn_arg -> BareFnArg, do_parse!(
552         name: option!(do_parse!(
553             name: ident >>
554             punct!(":") >>
555             not!(tag!(":")) >> // not ::
556             (name)
557         )) >>
558         ty: ty >>
559         (BareFnArg {
560             name: name,
561             ty: ty,
562         })
563     ));
564 
565     named!(pub unsafety -> Unsafety, alt!(
566         keyword!("unsafe") => { |_| Unsafety::Unsafe }
567         |
568         epsilon!() => { |_| Unsafety::Normal }
569     ));
570 
571     named!(pub abi -> Abi, do_parse!(
572         keyword!("extern") >>
573         name: option!(quoted_string) >>
574         (match name {
575             Some(name) => Abi::Named(name),
576             None => Abi::Rust,
577         })
578     ));
579 }
580 
581 #[cfg(feature = "printing")]
582 mod printing {
583     use super::*;
584     use quote::{Tokens, ToTokens};
585 
586     impl ToTokens for Ty {
to_tokens(&self, tokens: &mut Tokens)587         fn to_tokens(&self, tokens: &mut Tokens) {
588             match *self {
589                 Ty::Slice(ref inner) => {
590                     tokens.append("[");
591                     inner.to_tokens(tokens);
592                     tokens.append("]");
593                 }
594                 Ty::Array(ref inner, ref len) => {
595                     tokens.append("[");
596                     inner.to_tokens(tokens);
597                     tokens.append(";");
598                     len.to_tokens(tokens);
599                     tokens.append("]");
600                 }
601                 Ty::Ptr(ref target) => {
602                     tokens.append("*");
603                     match target.mutability {
604                         Mutability::Mutable => tokens.append("mut"),
605                         Mutability::Immutable => tokens.append("const"),
606                     }
607                     target.ty.to_tokens(tokens);
608                 }
609                 Ty::Rptr(ref lifetime, ref target) => {
610                     tokens.append("&");
611                     lifetime.to_tokens(tokens);
612                     target.mutability.to_tokens(tokens);
613                     target.ty.to_tokens(tokens);
614                 }
615                 Ty::BareFn(ref func) => {
616                     func.to_tokens(tokens);
617                 }
618                 Ty::Never => {
619                     tokens.append("!");
620                 }
621                 Ty::Tup(ref elems) => {
622                     tokens.append("(");
623                     tokens.append_separated(elems, ",");
624                     if elems.len() == 1 {
625                         tokens.append(",");
626                     }
627                     tokens.append(")");
628                 }
629                 Ty::Path(None, ref path) => {
630                     path.to_tokens(tokens);
631                 }
632                 Ty::Path(Some(ref qself), ref path) => {
633                     tokens.append("<");
634                     qself.ty.to_tokens(tokens);
635                     if qself.position > 0 {
636                         tokens.append("as");
637                         for (i, segment) in path.segments
638                                 .iter()
639                                 .take(qself.position)
640                                 .enumerate() {
641                             if i > 0 || path.global {
642                                 tokens.append("::");
643                             }
644                             segment.to_tokens(tokens);
645                         }
646                     }
647                     tokens.append(">");
648                     for segment in path.segments.iter().skip(qself.position) {
649                         tokens.append("::");
650                         segment.to_tokens(tokens);
651                     }
652                 }
653                 Ty::TraitObject(ref bounds) => {
654                     tokens.append_separated(bounds, "+");
655                 }
656                 Ty::ImplTrait(ref bounds) => {
657                     tokens.append("impl");
658                     tokens.append_separated(bounds, "+");
659                 }
660                 Ty::Paren(ref inner) => {
661                     tokens.append("(");
662                     inner.to_tokens(tokens);
663                     tokens.append(")");
664                 }
665                 Ty::Infer => {
666                     tokens.append("_");
667                 }
668                 Ty::Mac(ref mac) => mac.to_tokens(tokens),
669             }
670         }
671     }
672 
673     impl ToTokens for Mutability {
to_tokens(&self, tokens: &mut Tokens)674         fn to_tokens(&self, tokens: &mut Tokens) {
675             if let Mutability::Mutable = *self {
676                 tokens.append("mut");
677             }
678         }
679     }
680 
681     impl ToTokens for Path {
to_tokens(&self, tokens: &mut Tokens)682         fn to_tokens(&self, tokens: &mut Tokens) {
683             for (i, segment) in self.segments.iter().enumerate() {
684                 if i > 0 || self.global {
685                     tokens.append("::");
686                 }
687                 segment.to_tokens(tokens);
688             }
689         }
690     }
691 
692     impl ToTokens for PathSegment {
to_tokens(&self, tokens: &mut Tokens)693         fn to_tokens(&self, tokens: &mut Tokens) {
694             self.ident.to_tokens(tokens);
695             if self.ident.as_ref().is_empty() && self.parameters.is_empty() {
696                 tokens.append("<");
697                 tokens.append(">");
698             } else {
699                 self.parameters.to_tokens(tokens);
700             }
701         }
702     }
703 
704     impl ToTokens for PathParameters {
to_tokens(&self, tokens: &mut Tokens)705         fn to_tokens(&self, tokens: &mut Tokens) {
706             match *self {
707                 PathParameters::AngleBracketed(ref parameters) => {
708                     parameters.to_tokens(tokens);
709                 }
710                 PathParameters::Parenthesized(ref parameters) => {
711                     parameters.to_tokens(tokens);
712                 }
713             }
714         }
715     }
716 
717     impl ToTokens for AngleBracketedParameterData {
to_tokens(&self, tokens: &mut Tokens)718         fn to_tokens(&self, tokens: &mut Tokens) {
719             let has_lifetimes = !self.lifetimes.is_empty();
720             let has_types = !self.types.is_empty();
721             let has_bindings = !self.bindings.is_empty();
722             if !has_lifetimes && !has_types && !has_bindings {
723                 return;
724             }
725 
726             tokens.append("<");
727 
728             let mut first = true;
729             for lifetime in &self.lifetimes {
730                 if !first {
731                     tokens.append(",");
732                 }
733                 lifetime.to_tokens(tokens);
734                 first = false;
735             }
736             for ty in &self.types {
737                 if !first {
738                     tokens.append(",");
739                 }
740                 ty.to_tokens(tokens);
741                 first = false;
742             }
743             for binding in &self.bindings {
744                 if !first {
745                     tokens.append(",");
746                 }
747                 binding.to_tokens(tokens);
748                 first = false;
749             }
750 
751             tokens.append(">");
752         }
753     }
754 
755     impl ToTokens for TypeBinding {
to_tokens(&self, tokens: &mut Tokens)756         fn to_tokens(&self, tokens: &mut Tokens) {
757             self.ident.to_tokens(tokens);
758             tokens.append("=");
759             self.ty.to_tokens(tokens);
760         }
761     }
762 
763     impl ToTokens for ParenthesizedParameterData {
to_tokens(&self, tokens: &mut Tokens)764         fn to_tokens(&self, tokens: &mut Tokens) {
765             tokens.append("(");
766             tokens.append_separated(&self.inputs, ",");
767             tokens.append(")");
768             if let Some(ref output) = self.output {
769                 tokens.append("->");
770                 output.to_tokens(tokens);
771             }
772         }
773     }
774 
775     impl ToTokens for PolyTraitRef {
to_tokens(&self, tokens: &mut Tokens)776         fn to_tokens(&self, tokens: &mut Tokens) {
777             if !self.bound_lifetimes.is_empty() {
778                 tokens.append("for");
779                 tokens.append("<");
780                 tokens.append_separated(&self.bound_lifetimes, ",");
781                 tokens.append(">");
782             }
783             self.trait_ref.to_tokens(tokens);
784         }
785     }
786 
787     impl ToTokens for BareFnTy {
to_tokens(&self, tokens: &mut Tokens)788         fn to_tokens(&self, tokens: &mut Tokens) {
789             if !self.lifetimes.is_empty() {
790                 tokens.append("for");
791                 tokens.append("<");
792                 tokens.append_separated(&self.lifetimes, ",");
793                 tokens.append(">");
794             }
795             self.unsafety.to_tokens(tokens);
796             self.abi.to_tokens(tokens);
797             tokens.append("fn");
798             tokens.append("(");
799             tokens.append_separated(&self.inputs, ",");
800             if self.variadic {
801                 if !self.inputs.is_empty() {
802                     tokens.append(",");
803                 }
804                 tokens.append("...");
805             }
806             tokens.append(")");
807             if let FunctionRetTy::Ty(ref ty) = self.output {
808                 tokens.append("->");
809                 ty.to_tokens(tokens);
810             }
811         }
812     }
813 
814     impl ToTokens for BareFnArg {
to_tokens(&self, tokens: &mut Tokens)815         fn to_tokens(&self, tokens: &mut Tokens) {
816             if let Some(ref name) = self.name {
817                 name.to_tokens(tokens);
818                 tokens.append(":");
819             }
820             self.ty.to_tokens(tokens);
821         }
822     }
823 
824     impl ToTokens for Unsafety {
to_tokens(&self, tokens: &mut Tokens)825         fn to_tokens(&self, tokens: &mut Tokens) {
826             match *self {
827                 Unsafety::Unsafe => tokens.append("unsafe"),
828                 Unsafety::Normal => {
829                     // nothing
830                 }
831             }
832         }
833     }
834 
835     impl ToTokens for Abi {
to_tokens(&self, tokens: &mut Tokens)836         fn to_tokens(&self, tokens: &mut Tokens) {
837             tokens.append("extern");
838             match *self {
839                 Abi::Named(ref named) => named.to_tokens(tokens),
840                 Abi::Rust => {}
841             }
842         }
843     }
844 }
845