]> git.proxmox.com Git - rustc.git/blob - vendor/syn-0.11.11/src/ty.rs
New upstream version 1.33.0+dfsg1
[rustc.git] / vendor / syn-0.11.11 / src / ty.rs
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 {
70 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 {
96 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 {
116 pub fn none() -> Self {
117 PathParameters::AngleBracketed(AngleBracketedParameterData::default())
118 }
119
120 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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 }