blob: b8aee5a532600351e7ab56af9a832ce39d66e907 [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnay771ecf42016-09-23 19:26:37 -07003/// The different kinds of types recognized by the compiler
David Tolnayb79ee962016-09-04 09:39:20 -07004#[derive(Debug, Clone, Eq, PartialEq)]
5pub enum Ty {
6 /// A variable-length array (`[T]`)
David Tolnay16709ba2016-10-05 23:11:32 -07007 Slice(Box<Ty>),
David Tolnayb79ee962016-09-04 09:39:20 -07008 /// A fixed length array (`[T; n]`)
David Tolnayfa94b6f2016-10-05 23:26:11 -07009 Array(Box<Ty>, ArrayLen),
David Tolnayb79ee962016-09-04 09:39:20 -070010 /// 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 /// Something like `A+B`. Note that `B` must always be a path.
26 ObjectSum(Box<Ty>, Vec<TyParamBound>),
27 /// A type like `for<'a> Foo<&'a Bar>`
28 PolyTraitRef(Vec<TyParamBound>),
29 /// An `impl TraitA+TraitB` type.
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}
37
38#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayfa94b6f2016-10-05 23:26:11 -070039pub enum ArrayLen {
40 /// As in `[T; 0]`.
41 Usize(usize),
42 /// As in `[T; LEN]` or `[T; helper::LEN as usize]`. The boolean indicates
43 /// whether the path is followed by `as usize`.
44 Path(Path, bool),
45}
46
47#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayb79ee962016-09-04 09:39:20 -070048pub struct MutTy {
49 pub ty: Ty,
50 pub mutability: Mutability,
51}
52
David Tolnayf4bbbd92016-09-23 14:41:55 -070053#[derive(Debug, Copy, Clone, Eq, PartialEq)]
David Tolnayb79ee962016-09-04 09:39:20 -070054pub enum Mutability {
55 Mutable,
56 Immutable,
57}
58
David Tolnay771ecf42016-09-23 19:26:37 -070059/// A "Path" is essentially Rust's notion of a name.
60///
61/// It's represented as a sequence of identifiers,
62/// along with a bunch of supporting information.
63///
64/// E.g. `std::cmp::PartialEq`
David Tolnayb79ee962016-09-04 09:39:20 -070065#[derive(Debug, Clone, Eq, PartialEq)]
66pub struct Path {
67 pub global: bool,
68 pub segments: Vec<PathSegment>,
69}
70
David Tolnaydaaf7742016-10-03 11:11:43 -070071impl<T> From<T> for Path
72 where T: Into<PathSegment>
73{
David Tolnay84aa0752016-10-02 23:01:13 -070074 fn from(segment: T) -> Self {
75 Path {
76 global: false,
77 segments: vec![segment.into()],
78 }
79 }
80}
81
David Tolnayb79ee962016-09-04 09:39:20 -070082/// A segment of a path: an identifier, an optional lifetime, and a set of types.
83///
84/// E.g. `std`, `String` or `Box<T>`
85#[derive(Debug, Clone, Eq, PartialEq)]
86pub struct PathSegment {
87 pub ident: Ident,
88 pub parameters: PathParameters,
89}
90
David Tolnaydaaf7742016-10-03 11:11:43 -070091impl<T> From<T> for PathSegment
92 where T: Into<Ident>
93{
David Tolnay84aa0752016-10-02 23:01:13 -070094 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -070095 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -070096 ident: ident.into(),
David Tolnayb79ee962016-09-04 09:39:20 -070097 parameters: PathParameters::none(),
98 }
99 }
100}
101
102/// Parameters of a path segment.
103///
104/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
105#[derive(Debug, Clone, Eq, PartialEq)]
106pub enum PathParameters {
107 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
108 AngleBracketed(AngleBracketedParameterData),
109 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
110 Parenthesized(ParenthesizedParameterData),
111}
112
113impl PathParameters {
114 pub fn none() -> Self {
115 PathParameters::AngleBracketed(AngleBracketedParameterData::default())
116 }
117}
118
119/// A path like `Foo<'a, T>`
120#[derive(Debug, Clone, Eq, PartialEq, Default)]
121pub struct AngleBracketedParameterData {
122 /// The lifetime parameters for this path segment.
123 pub lifetimes: Vec<Lifetime>,
124 /// The type parameters for this path segment, if present.
125 pub types: Vec<Ty>,
126 /// Bindings (equality constraints) on associated types, if present.
127 ///
128 /// E.g., `Foo<A=Bar>`.
129 pub bindings: Vec<TypeBinding>,
130}
131
132/// Bind a type to an associated type: `A=Foo`.
133#[derive(Debug, Clone, Eq, PartialEq)]
134pub struct TypeBinding {
135 pub ident: Ident,
136 pub ty: Ty,
137}
138
139/// A path like `Foo(A,B) -> C`
140#[derive(Debug, Clone, Eq, PartialEq)]
141pub struct ParenthesizedParameterData {
142 /// `(A, B)`
143 pub inputs: Vec<Ty>,
144 /// `C`
145 pub output: Option<Ty>,
146}
147
148#[derive(Debug, Clone, Eq, PartialEq)]
149pub struct PolyTraitRef {
150 /// The `'a` in `<'a> Foo<&'a T>`
151 pub bound_lifetimes: Vec<LifetimeDef>,
152 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
153 pub trait_ref: Path,
154}
155
156/// The explicit Self type in a "qualified path". The actual
157/// path, including the trait and the associated item, is stored
158/// separately. `position` represents the index of the associated
159/// item qualified with this Self type.
160///
161/// ```rust,ignore
162/// <Vec<T> as a::b::Trait>::AssociatedItem
163/// ^~~~~ ~~~~~~~~~~~~~~^
164/// ty position = 3
165///
166/// <Vec<T>>::AssociatedItem
167/// ^~~~~ ^
168/// ty position = 0
169/// ```
170#[derive(Debug, Clone, Eq, PartialEq)]
171pub struct QSelf {
172 pub ty: Box<Ty>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700173 pub position: usize,
David Tolnayb79ee962016-09-04 09:39:20 -0700174}
175
176#[derive(Debug, Clone, Eq, PartialEq)]
177pub struct BareFnTy {
178 pub lifetimes: Vec<LifetimeDef>,
David Tolnay62f374c2016-10-02 13:37:00 -0700179 pub inputs: Vec<BareFnArg>,
David Tolnayb79ee962016-09-04 09:39:20 -0700180 pub output: FunctionRetTy,
181}
182
David Tolnay62f374c2016-10-02 13:37:00 -0700183/// An argument in a function type.
David Tolnayb79ee962016-09-04 09:39:20 -0700184///
185/// E.g. `bar: usize` as in `fn foo(bar: usize)`
186#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnay62f374c2016-10-02 13:37:00 -0700187pub struct BareFnArg {
188 pub name: Option<Ident>,
David Tolnayb79ee962016-09-04 09:39:20 -0700189 pub ty: Ty,
190}
191
192#[derive(Debug, Clone, Eq, PartialEq)]
193pub enum FunctionRetTy {
194 /// Return type is not specified.
195 ///
196 /// Functions default to `()` and
197 /// closures default to inference. Span points to where return
198 /// type would be inserted.
199 Default,
200 /// Everything else
201 Ty(Ty),
202}
203
David Tolnay86eca752016-09-04 11:26:41 -0700204#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700205pub mod parsing {
206 use super::*;
David Tolnay9d8f1972016-09-04 11:58:48 -0700207 use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes};
David Tolnay55337722016-09-11 12:58:56 -0700208 use ident::parsing::ident;
David Tolnayde206222016-09-30 11:47:01 -0700209 use lit::parsing::int;
David Tolnay9d8f1972016-09-04 11:58:48 -0700210 use std::str;
David Tolnayda4049b2016-09-04 10:59:23 -0700211
David Tolnayb5a7b142016-09-13 22:46:39 -0700212 named!(pub ty -> Ty, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700213 ty_vec
David Tolnayda4049b2016-09-04 10:59:23 -0700214 |
David Tolnayfa94b6f2016-10-05 23:26:11 -0700215 ty_array
David Tolnayb79ee962016-09-04 09:39:20 -0700216 |
David Tolnay9d8f1972016-09-04 11:58:48 -0700217 ty_ptr
218 |
219 ty_rptr
220 |
221 ty_bare_fn
222 |
223 ty_never
224 |
225 ty_tup
226 |
227 ty_path
228 |
David Tolnay9d8f1972016-09-04 11:58:48 -0700229 ty_impl_trait
230 |
231 ty_paren
232 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700233
David Tolnayb5a7b142016-09-13 22:46:39 -0700234 named!(ty_vec -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700235 punct!("[") >>
236 elem: ty >>
237 punct!("]") >>
David Tolnay16709ba2016-10-05 23:11:32 -0700238 (Ty::Slice(Box::new(elem)))
David Tolnay9d8f1972016-09-04 11:58:48 -0700239 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700240
David Tolnayfa94b6f2016-10-05 23:26:11 -0700241 named!(ty_array -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700242 punct!("[") >>
243 elem: ty >>
244 punct!(";") >>
David Tolnayfa94b6f2016-10-05 23:26:11 -0700245 len: array_len >>
David Tolnayc94c38a2016-09-05 17:02:03 -0700246 punct!("]") >>
David Tolnayfa94b6f2016-10-05 23:26:11 -0700247 (Ty::Array(Box::new(elem), len))
248 ));
249
250 named!(array_len -> ArrayLen, alt!(
251 map!(int, |(i, _)| ArrayLen::Usize(i as usize))
252 |
253 do_parse!(
254 path: path >>
255 as_usize: option!(tuple!(keyword!("as"), keyword!("usize"))) >>
256 (ArrayLen::Path(path, as_usize.is_some()))
257 )
David Tolnay9d8f1972016-09-04 11:58:48 -0700258 ));
259
David Tolnayb5a7b142016-09-13 22:46:39 -0700260 named!(ty_ptr -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700261 punct!("*") >>
David Tolnayb5a7b142016-09-13 22:46:39 -0700262 mutability: alt!(
David Tolnay10413f02016-09-30 09:12:02 -0700263 keyword!("const") => { |_| Mutability::Immutable }
David Tolnay9d8f1972016-09-04 11:58:48 -0700264 |
David Tolnay10413f02016-09-30 09:12:02 -0700265 keyword!("mut") => { |_| Mutability::Mutable }
David Tolnay9d8f1972016-09-04 11:58:48 -0700266 ) >>
267 target: ty >>
268 (Ty::Ptr(Box::new(MutTy {
269 ty: target,
270 mutability: mutability,
271 })))
272 ));
273
David Tolnayb5a7b142016-09-13 22:46:39 -0700274 named!(ty_rptr -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700275 punct!("&") >>
David Tolnayf6ccb832016-09-04 15:00:56 -0700276 life: option!(lifetime) >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700277 mutability: mutability >>
278 target: ty >>
279 (Ty::Rptr(life, Box::new(MutTy {
280 ty: target,
281 mutability: mutability,
282 })))
283 ));
284
David Tolnayb5a7b142016-09-13 22:46:39 -0700285 named!(ty_bare_fn -> Ty, do_parse!(
David Tolnay10413f02016-09-30 09:12:02 -0700286 keyword!("fn") >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700287 lifetimes: opt_vec!(delimited!(
288 punct!("<"),
289 separated_list!(punct!(","), lifetime_def),
290 punct!(">")
David Tolnay6b7aaf02016-09-04 10:39:25 -0700291 )) >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700292 punct!("(") >>
293 inputs: separated_list!(punct!(","), fn_arg) >>
294 punct!(")") >>
David Tolnayf6ccb832016-09-04 15:00:56 -0700295 output: option!(preceded!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700296 punct!("->"),
297 ty
298 )) >>
299 (Ty::BareFn(Box::new(BareFnTy {
300 lifetimes: lifetimes,
David Tolnay62f374c2016-10-02 13:37:00 -0700301 inputs: inputs,
302 output: match output {
303 Some(ty) => FunctionRetTy::Ty(ty),
304 None => FunctionRetTy::Default,
David Tolnay9d8f1972016-09-04 11:58:48 -0700305 },
306 })))
307 ));
308
David Tolnayb5a7b142016-09-13 22:46:39 -0700309 named!(ty_never -> Ty, map!(punct!("!"), |_| Ty::Never));
David Tolnay9d8f1972016-09-04 11:58:48 -0700310
David Tolnayb5a7b142016-09-13 22:46:39 -0700311 named!(ty_tup -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700312 punct!("(") >>
313 elems: separated_list!(punct!(","), ty) >>
314 punct!(")") >>
315 (Ty::Tup(elems))
316 ));
317
David Tolnay9636c052016-10-02 17:11:17 -0700318 named!(ty_path -> Ty, map!(qpath, |(qself, p)| Ty::Path(qself, p)));
David Tolnay9d8f1972016-09-04 11:58:48 -0700319
David Tolnay9636c052016-10-02 17:11:17 -0700320 named!(pub qpath -> (Option<QSelf>, Path), alt!(
321 map!(path, |p| (None, p))
322 |
323 do_parse!(
324 punct!("<") >>
325 this: map!(ty, Box::new) >>
326 path: option!(preceded!(
327 keyword!("as"),
328 path
329 )) >>
330 punct!(">") >>
331 punct!("::") >>
332 rest: separated_nonempty_list!(punct!("::"), path_segment) >>
333 ({
334 match path {
335 Some(mut path) => {
336 let pos = path.segments.len();
337 path.segments.extend(rest);
338 (Some(QSelf { ty: this, position: pos }), path)
339 }
340 None => {
341 (Some(QSelf { ty: this, position: 0 }), Path {
342 global: false,
343 segments: rest,
344 })
345 }
David Tolnayb79ee962016-09-04 09:39:20 -0700346 }
David Tolnay9636c052016-10-02 17:11:17 -0700347 })
348 )
David Tolnay9d8f1972016-09-04 11:58:48 -0700349 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700350
David Tolnayb5a7b142016-09-13 22:46:39 -0700351 named!(ty_impl_trait -> Ty, do_parse!(
David Tolnay10413f02016-09-30 09:12:02 -0700352 keyword!("impl") >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700353 elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
354 (Ty::ImplTrait(elem))
355 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700356
David Tolnayb5a7b142016-09-13 22:46:39 -0700357 named!(ty_paren -> Ty, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700358 punct!("(") >>
359 elem: ty >>
360 punct!(")") >>
361 (Ty::Paren(Box::new(elem)))
362 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700363
David Tolnay47a877c2016-10-01 16:50:55 -0700364 named!(pub mutability -> Mutability, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700365 keyword!("mut") => { |_| Mutability::Mutable }
David Tolnayf6ccb832016-09-04 15:00:56 -0700366 |
367 epsilon!() => { |_| Mutability::Immutable }
David Tolnay9d8f1972016-09-04 11:58:48 -0700368 ));
369
David Tolnayb5a7b142016-09-13 22:46:39 -0700370 named!(pub path -> Path, do_parse!(
David Tolnayf6ccb832016-09-04 15:00:56 -0700371 global: option!(punct!("::")) >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700372 segments: separated_nonempty_list!(punct!("::"), path_segment) >>
373 (Path {
374 global: global.is_some(),
375 segments: segments,
376 })
377 ));
378
David Tolnay9636c052016-10-02 17:11:17 -0700379 named!(path_segment -> PathSegment, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700380 do_parse!(
David Tolnay9636c052016-10-02 17:11:17 -0700381 id: option!(ident) >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700382 punct!("<") >>
383 lifetimes: separated_list!(punct!(","), lifetime) >>
384 types: opt_vec!(preceded!(
385 cond!(!lifetimes.is_empty(), punct!(",")),
386 separated_nonempty_list!(
387 punct!(","),
388 terminated!(ty, not!(peek!(punct!("="))))
389 )
390 )) >>
391 bindings: opt_vec!(preceded!(
392 cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")),
393 separated_nonempty_list!(punct!(","), type_binding)
394 )) >>
395 punct!(">") >>
396 (PathSegment {
David Tolnay9636c052016-10-02 17:11:17 -0700397 ident: id.unwrap_or_else(|| "".into()),
David Tolnay9d8f1972016-09-04 11:58:48 -0700398 parameters: PathParameters::AngleBracketed(
399 AngleBracketedParameterData {
400 lifetimes: lifetimes,
401 types: types,
402 bindings: bindings,
403 }
404 ),
405 })
406 )
407 |
David Tolnay84aa0752016-10-02 23:01:13 -0700408 map!(ident, Into::into)
David Tolnay9d8f1972016-09-04 11:58:48 -0700409 ));
410
David Tolnayb5a7b142016-09-13 22:46:39 -0700411 named!(type_binding -> TypeBinding, do_parse!(
David Tolnay55337722016-09-11 12:58:56 -0700412 id: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700413 punct!("=") >>
414 ty: ty >>
415 (TypeBinding {
David Tolnay55337722016-09-11 12:58:56 -0700416 ident: id,
David Tolnay9d8f1972016-09-04 11:58:48 -0700417 ty: ty,
418 })
419 ));
420
David Tolnayb5a7b142016-09-13 22:46:39 -0700421 named!(pub poly_trait_ref -> PolyTraitRef, do_parse!(
David Tolnay9d8f1972016-09-04 11:58:48 -0700422 bound_lifetimes: bound_lifetimes >>
423 trait_ref: path >>
424 (PolyTraitRef {
425 bound_lifetimes: bound_lifetimes,
426 trait_ref: trait_ref,
427 })
428 ));
429
David Tolnay62f374c2016-10-02 13:37:00 -0700430 named!(pub fn_arg -> BareFnArg, do_parse!(
431 name: option!(terminated!(ident, punct!(":"))) >>
David Tolnay9d8f1972016-09-04 11:58:48 -0700432 ty: ty >>
David Tolnay62f374c2016-10-02 13:37:00 -0700433 (BareFnArg {
434 name: name,
David Tolnay9d8f1972016-09-04 11:58:48 -0700435 ty: ty,
436 })
437 ));
438}
David Tolnay87d0b442016-09-04 11:52:12 -0700439
440#[cfg(feature = "printing")]
441mod printing {
442 use super::*;
443 use quote::{Tokens, ToTokens};
444
445 impl ToTokens for Ty {
446 fn to_tokens(&self, tokens: &mut Tokens) {
447 match *self {
David Tolnay16709ba2016-10-05 23:11:32 -0700448 Ty::Slice(ref inner) => {
David Tolnay87d0b442016-09-04 11:52:12 -0700449 tokens.append("[");
450 inner.to_tokens(tokens);
451 tokens.append("]");
452 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700453 Ty::Array(ref inner, ref len) => {
David Tolnay87d0b442016-09-04 11:52:12 -0700454 tokens.append("[");
455 inner.to_tokens(tokens);
456 tokens.append(";");
David Tolnayfa94b6f2016-10-05 23:26:11 -0700457 len.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700458 tokens.append("]");
459 }
460 Ty::Ptr(ref target) => {
461 tokens.append("*");
462 match target.mutability {
463 Mutability::Mutable => tokens.append("mut"),
464 Mutability::Immutable => tokens.append("const"),
465 }
466 target.ty.to_tokens(tokens);
467 }
468 Ty::Rptr(ref lifetime, ref target) => {
469 tokens.append("&");
470 lifetime.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700471 target.mutability.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700472 target.ty.to_tokens(tokens);
473 }
474 Ty::BareFn(ref func) => {
475 func.to_tokens(tokens);
476 }
477 Ty::Never => {
478 tokens.append("!");
479 }
480 Ty::Tup(ref elems) => {
481 tokens.append("(");
David Tolnay94ebdf92016-09-04 13:33:16 -0700482 tokens.append_separated(elems, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700483 if elems.len() == 1 {
484 tokens.append(",");
485 }
486 tokens.append(")");
487 }
David Tolnayf69904a2016-09-04 14:46:07 -0700488 Ty::Path(None, ref path) => {
489 path.to_tokens(tokens);
490 }
491 Ty::Path(Some(ref qself), ref path) => {
492 tokens.append("<");
493 qself.ty.to_tokens(tokens);
494 if qself.position > 0 {
495 tokens.append("as");
David Tolnaydaaf7742016-10-03 11:11:43 -0700496 for (i, segment) in path.segments
497 .iter()
498 .take(qself.position)
499 .enumerate() {
David Tolnayf69904a2016-09-04 14:46:07 -0700500 if i > 0 || path.global {
501 tokens.append("::");
David Tolnay87d0b442016-09-04 11:52:12 -0700502 }
David Tolnayf69904a2016-09-04 14:46:07 -0700503 segment.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700504 }
David Tolnayf69904a2016-09-04 14:46:07 -0700505 }
506 tokens.append(">");
507 for segment in path.segments.iter().skip(qself.position) {
508 tokens.append("::");
509 segment.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700510 }
511 }
512 Ty::ObjectSum(_, _) => unimplemented!(),
513 Ty::PolyTraitRef(_) => unimplemented!(),
514 Ty::ImplTrait(ref bounds) => {
515 tokens.append("impl");
David Tolnay94ebdf92016-09-04 13:33:16 -0700516 tokens.append_separated(bounds, "+");
David Tolnay87d0b442016-09-04 11:52:12 -0700517 }
518 Ty::Paren(ref inner) => {
519 tokens.append("(");
520 inner.to_tokens(tokens);
521 tokens.append(")");
522 }
523 Ty::Infer => {
524 tokens.append("_");
525 }
526 }
527 }
528 }
529
David Tolnayfa94b6f2016-10-05 23:26:11 -0700530 impl ToTokens for ArrayLen {
531 fn to_tokens(&self, tokens: &mut Tokens) {
532 match *self {
533 ArrayLen::Usize(len) => tokens.append(&len.to_string()),
534 ArrayLen::Path(ref path, as_usize) => {
535 path.to_tokens(tokens);
536 if as_usize {
537 tokens.append("as");
538 tokens.append("usize");
539 }
540 }
541 }
542 }
543 }
544
David Tolnay47a877c2016-10-01 16:50:55 -0700545 impl ToTokens for Mutability {
546 fn to_tokens(&self, tokens: &mut Tokens) {
547 if let Mutability::Mutable = *self {
548 tokens.append("mut");
549 }
550 }
551 }
552
David Tolnay87d0b442016-09-04 11:52:12 -0700553 impl ToTokens for Path {
554 fn to_tokens(&self, tokens: &mut Tokens) {
555 for (i, segment) in self.segments.iter().enumerate() {
556 if i > 0 || self.global {
557 tokens.append("::");
558 }
559 segment.to_tokens(tokens);
560 }
561 }
562 }
563
564 impl ToTokens for PathSegment {
565 fn to_tokens(&self, tokens: &mut Tokens) {
566 self.ident.to_tokens(tokens);
567 self.parameters.to_tokens(tokens);
568 }
569 }
570
571 impl ToTokens for PathParameters {
572 fn to_tokens(&self, tokens: &mut Tokens) {
573 match *self {
574 PathParameters::AngleBracketed(ref parameters) => {
575 parameters.to_tokens(tokens);
576 }
577 PathParameters::Parenthesized(ref parameters) => {
578 parameters.to_tokens(tokens);
579 }
580 }
581 }
582 }
583
584 impl ToTokens for AngleBracketedParameterData {
585 fn to_tokens(&self, tokens: &mut Tokens) {
586 let has_lifetimes = !self.lifetimes.is_empty();
587 let has_types = !self.types.is_empty();
588 let has_bindings = !self.bindings.is_empty();
589 if !has_lifetimes && !has_types && !has_bindings {
590 return;
591 }
592
593 tokens.append("<");
594
595 let mut first = true;
596 for lifetime in &self.lifetimes {
597 if !first {
598 tokens.append(",");
599 }
600 lifetime.to_tokens(tokens);
601 first = false;
602 }
603 for ty in &self.types {
604 if !first {
605 tokens.append(",");
606 }
607 ty.to_tokens(tokens);
608 first = false;
609 }
610 for binding in &self.bindings {
611 if !first {
612 tokens.append(",");
613 }
614 binding.to_tokens(tokens);
615 first = false;
616 }
617
618 tokens.append(">");
619 }
620 }
621
622 impl ToTokens for TypeBinding {
623 fn to_tokens(&self, tokens: &mut Tokens) {
624 self.ident.to_tokens(tokens);
625 tokens.append("=");
626 self.ty.to_tokens(tokens);
627 }
628 }
629
630 impl ToTokens for ParenthesizedParameterData {
631 fn to_tokens(&self, tokens: &mut Tokens) {
632 tokens.append("(");
David Tolnay94ebdf92016-09-04 13:33:16 -0700633 tokens.append_separated(&self.inputs, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700634 tokens.append(")");
635 if let Some(ref output) = self.output {
636 tokens.append("->");
637 output.to_tokens(tokens);
638 }
639 }
640 }
641
642 impl ToTokens for PolyTraitRef {
643 fn to_tokens(&self, tokens: &mut Tokens) {
644 if !self.bound_lifetimes.is_empty() {
David Tolnaye8796aa2016-09-04 14:48:22 -0700645 tokens.append("for");
David Tolnay87d0b442016-09-04 11:52:12 -0700646 tokens.append("<");
David Tolnay94ebdf92016-09-04 13:33:16 -0700647 tokens.append_separated(&self.bound_lifetimes, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700648 tokens.append(">");
649 }
650 self.trait_ref.to_tokens(tokens);
651 }
652 }
653
654 impl ToTokens for BareFnTy {
655 fn to_tokens(&self, tokens: &mut Tokens) {
656 tokens.append("fn");
657 if !self.lifetimes.is_empty() {
658 tokens.append("<");
David Tolnay42602292016-10-01 22:25:45 -0700659 tokens.append_separated(&self.lifetimes, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700660 tokens.append(">");
661 }
662 tokens.append("(");
David Tolnay42602292016-10-01 22:25:45 -0700663 tokens.append_separated(&self.inputs, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700664 tokens.append(")");
David Tolnay42602292016-10-01 22:25:45 -0700665 if let FunctionRetTy::Ty(ref ty) = self.output {
666 tokens.append("->");
667 ty.to_tokens(tokens);
668 }
669 }
670 }
671
David Tolnay62f374c2016-10-02 13:37:00 -0700672 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -0700673 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay62f374c2016-10-02 13:37:00 -0700674 if let Some(ref name) = self.name {
675 name.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700676 tokens.append(":");
677 }
678 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700679 }
680 }
681}