blob: 3957ca9c39f2239f9859282471ba718e5c1dd02d [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use delimited::Delimited;
David Tolnayb79ee962016-09-04 09:39:20 -07002use super::*;
3
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_enum_of_structs! {
5 /// The different kinds of types recognized by the compiler
6 pub enum Ty {
7 /// A variable-length array (`[T]`)
8 pub Slice(TySlice {
9 pub ty: Box<Ty>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070010 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070011 }),
12 /// A fixed length array (`[T; n]`)
13 pub Array(TyArray {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070014 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070015 pub ty: Box<Ty>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070016 pub semi_token: tokens::Semi,
Alex Crichton62a0a592017-05-22 13:58:53 -070017 pub amt: ConstExpr,
18 }),
19 /// A raw pointer (`*const T` or `*mut T`)
20 pub Ptr(TyPtr {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070021 pub star_token: tokens::Star,
22 pub const_token: Option<tokens::Const>,
Alex Crichton62a0a592017-05-22 13:58:53 -070023 pub ty: Box<MutTy>,
24 }),
25 /// A reference (`&'a T` or `&'a mut T`)
26 pub Rptr(TyRptr {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070027 pub and_token: tokens::And,
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub lifetime: Option<Lifetime>,
29 pub ty: Box<MutTy>,
30 }),
31 /// A bare function (e.g. `fn(usize) -> bool`)
32 pub BareFn(TyBareFn {
33 pub ty: Box<BareFnTy>,
34 }),
35 /// The never type (`!`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -070036 pub Never(TyNever {
37 pub bang_token: tokens::Bang,
38 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// A tuple (`(A, B, C, D, ...)`)
40 pub Tup(TyTup {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub paren_token: tokens::Paren,
42 pub tys: Delimited<Ty, tokens::Comma>,
43 pub lone_comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -070044 }),
45 /// A path (`module::module::...::Type`), optionally
46 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
47 ///
48 /// Type parameters are stored in the Path itself
49 pub Path(TyPath {
50 pub qself: Option<QSelf>,
51 pub path: Path,
52 }),
53 /// A trait object type `Bound1 + Bound2 + Bound3`
54 /// where `Bound` is a trait or a lifetime.
55 pub TraitObject(TyTraitObject {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070056 pub bounds: Delimited<TyParamBound, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -070057 }),
58 /// An `impl Bound1 + Bound2 + Bound3` type
59 /// where `Bound` is a trait or a lifetime.
60 pub ImplTrait(TyImplTrait {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub impl_token: tokens::Impl,
62 pub bounds: Delimited<TyParamBound, tokens::Add>,
Alex Crichton62a0a592017-05-22 13:58:53 -070063 }),
64 /// No-op; kept solely so that we can pretty-print faithfully
65 pub Paren(TyParen {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070066 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070067 pub ty: Box<Ty>,
68 }),
Michael Layzell93c36282017-06-04 20:43:14 -040069 /// No-op: kept solely so that we can pretty-print faithfully
70 pub Group(TyGroup {
71 pub group_token: tokens::Group,
72 pub ty: Box<Ty>,
73 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070074 /// TyKind::Infer means the type should be inferred instead of it having been
75 /// specified. This can appear anywhere in a type.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 pub Infer(TyInfer {
77 pub underscore_token: tokens::Underscore
78 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A macro in the type position.
80 pub Mac(Mac),
81 }
82}
83
84ast_struct! {
85 pub struct MutTy {
86 pub ty: Ty,
87 pub mutability: Mutability,
88 }
89}
90
91ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -070092 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070093 pub enum Mutability {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070094 Mutable(tokens::Mut),
Alex Crichton62a0a592017-05-22 13:58:53 -070095 Immutable,
96 }
97}
98
99ast_struct! {
100 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -0700101 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// It's represented as a sequence of identifiers,
103 /// along with a bunch of supporting information.
104 ///
105 /// E.g. `std::cmp::PartialEq`
106 pub struct Path {
107 /// A `::foo` path, is relative to the crate root rather than current
108 /// module (like paths in an import).
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700109 pub leading_colon: Option<tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 /// The segments in the path: the things separated by `::`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700111 pub segments: Delimited<PathSegment, tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 }
David Tolnayb79ee962016-09-04 09:39:20 -0700113}
114
David Tolnay570695e2017-06-03 16:15:13 -0700115impl Path {
116 pub fn global(&self) -> bool {
117 self.leading_colon.is_some()
118 }
119}
120
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700121#[cfg(feature = "printing")]
122ast_struct! {
123 pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
124}
125
David Tolnaydaaf7742016-10-03 11:11:43 -0700126impl<T> From<T> for Path
127 where T: Into<PathSegment>
128{
David Tolnay84aa0752016-10-02 23:01:13 -0700129 fn from(segment: T) -> Self {
130 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700131 leading_colon: None,
132 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700133 }
134 }
135}
136
Alex Crichton62a0a592017-05-22 13:58:53 -0700137ast_struct! {
138 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
139 ///
140 /// E.g. `std`, `String` or `Box<T>`
141 pub struct PathSegment {
142 /// The identifier portion of this path segment.
143 pub ident: Ident,
144 /// Type/lifetime parameters attached to this path. They come in
145 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
146 /// this is more than just simple syntactic sugar; the use of
147 /// parens affects the region binding rules, so we preserve the
148 /// distinction.
149 pub parameters: PathParameters,
150 }
David Tolnayb79ee962016-09-04 09:39:20 -0700151}
152
David Tolnaydaaf7742016-10-03 11:11:43 -0700153impl<T> From<T> for PathSegment
154 where T: Into<Ident>
155{
David Tolnay84aa0752016-10-02 23:01:13 -0700156 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700157 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700158 ident: ident.into(),
David Tolnay570695e2017-06-03 16:15:13 -0700159 parameters: PathParameters::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700160 }
161 }
162}
163
Alex Crichton62a0a592017-05-22 13:58:53 -0700164ast_enum! {
165 /// Parameters of a path segment.
166 ///
167 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
168 pub enum PathParameters {
David Tolnay570695e2017-06-03 16:15:13 -0700169 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700170 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
171 AngleBracketed(AngleBracketedParameterData),
172 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
173 Parenthesized(ParenthesizedParameterData),
174 }
David Tolnayb79ee962016-09-04 09:39:20 -0700175}
176
David Tolnay570695e2017-06-03 16:15:13 -0700177impl Default for PathParameters {
178 fn default() -> Self {
179 PathParameters::None
David Tolnayb79ee962016-09-04 09:39:20 -0700180 }
David Tolnay570695e2017-06-03 16:15:13 -0700181}
David Tolnay5332d4b2016-10-30 14:25:22 -0700182
David Tolnay570695e2017-06-03 16:15:13 -0700183impl PathParameters {
David Tolnay5332d4b2016-10-30 14:25:22 -0700184 pub fn is_empty(&self) -> bool {
185 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700186 PathParameters::None => true,
David Tolnay5332d4b2016-10-30 14:25:22 -0700187 PathParameters::AngleBracketed(ref bracketed) => {
David Tolnayc1fea502016-10-30 17:54:02 -0700188 bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
189 bracketed.bindings.is_empty()
David Tolnay5332d4b2016-10-30 14:25:22 -0700190 }
191 PathParameters::Parenthesized(_) => false,
192 }
193 }
David Tolnayb79ee962016-09-04 09:39:20 -0700194}
195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196ast_struct! {
197 /// A path like `Foo<'a, T>`
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub struct AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700199 pub turbofish: Option<tokens::Colon2>,
200 pub lt_token: tokens::Lt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 /// The lifetime parameters for this path segment.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700202 pub lifetimes: Delimited<Lifetime, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 /// The type parameters for this path segment, if present.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700204 pub types: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// Bindings (equality constraints) on associated types, if present.
206 ///
207 /// E.g., `Foo<A=Bar>`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700208 pub bindings: Delimited<TypeBinding, tokens::Comma>,
David Tolnay570695e2017-06-03 16:15:13 -0700209 pub gt_token: tokens::Gt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700210 }
211}
212
213ast_struct! {
214 /// Bind a type to an associated type: `A=Foo`.
215 pub struct TypeBinding {
216 pub ident: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700217 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 pub ty: Ty,
219 }
220}
221
222
223ast_struct! {
224 /// A path like `Foo(A,B) -> C`
225 pub struct ParenthesizedParameterData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700226 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// `(A, B)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700228 pub inputs: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 /// `C`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700230 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 }
232}
233
234ast_struct! {
235 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700236 /// The `for<'a>` in `for<'a> Foo<&'a T>`
237 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
239 pub trait_ref: Path,
240 }
241}
242
243ast_struct! {
244 /// The explicit Self type in a "qualified path". The actual
245 /// path, including the trait and the associated item, is stored
246 /// separately. `position` represents the index of the associated
247 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700248 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 /// ```rust,ignore
250 /// <Vec<T> as a::b::Trait>::AssociatedItem
251 /// ^~~~~ ~~~~~~~~~~~~~~^
252 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700253 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 /// <Vec<T>>::AssociatedItem
255 /// ^~~~~ ^
256 /// ty position = 0
257 /// ```
258 pub struct QSelf {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700259 pub lt_token: tokens::Lt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700260 pub ty: Box<Ty>,
David Tolnay570695e2017-06-03 16:15:13 -0700261 pub position: Option<(tokens::As, usize)>,
262 pub gt_token: tokens::Gt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700263 }
264}
265
266ast_struct! {
267 pub struct BareFnTy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700268 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700269 pub unsafety: Unsafety,
270 pub abi: Option<Abi>,
Alex Crichton954046c2017-05-30 21:49:42 -0700271 pub fn_token: tokens::Fn_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700272 pub paren_token: tokens::Paren,
273 pub inputs: Delimited<BareFnArg, tokens::Comma>,
274 pub variadic: Option<tokens::Dot3>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700276 }
277}
278
279ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700280 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 pub enum Unsafety {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700282 Unsafe(tokens::Unsafe),
Alex Crichton62a0a592017-05-22 13:58:53 -0700283 Normal,
284 }
285}
286
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700287ast_struct! {
288 pub struct Abi {
289 pub extern_token: tokens::Extern,
290 pub kind: AbiKind,
291 }
292}
293
Alex Crichton62a0a592017-05-22 13:58:53 -0700294ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700295 pub enum AbiKind {
296 Named(Lit),
297 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 }
299}
300
301ast_struct! {
302 /// An argument in a function type.
303 ///
304 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
305 pub struct BareFnArg {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700306 pub name: Option<(Ident, tokens::Colon)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700307 pub ty: Ty,
308 }
309}
310
311
312ast_enum! {
313 pub enum FunctionRetTy {
314 /// Return type is not specified.
315 ///
316 /// Functions default to `()` and
317 /// closures default to inference. Span points to where return
318 /// type would be inserted.
319 Default,
320 /// Everything else
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700321 Ty(Ty, tokens::RArrow),
Alex Crichton62a0a592017-05-22 13:58:53 -0700322 }
David Tolnayb79ee962016-09-04 09:39:20 -0700323}
324
David Tolnay86eca752016-09-04 11:26:41 -0700325#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700326pub mod parsing {
327 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400328 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700329 use synom::tokens::*;
David Tolnayda4049b2016-09-04 10:59:23 -0700330
Alex Crichton954046c2017-05-30 21:49:42 -0700331 impl Synom for Ty {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400332 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700333
Alex Crichton954046c2017-05-30 21:49:42 -0700334 fn description() -> Option<&'static str> {
335 Some("type")
336 }
337 }
David Tolnay0047c712016-12-21 21:59:25 -0500338
Michael Layzell9bf2b002017-06-04 18:49:53 -0400339 impl Ty {
340 /// In some positions, types may not contain the `+` character, to
341 /// disambiguate them. For example in the expression `1 as T`, T may not
342 /// contain a `+` character.
343 ///
344 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400345 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400346 }
347
348 named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -0400349 syn!(TyGroup) => { Ty::Group }
350 |
Michael Layzell9bf2b002017-06-04 18:49:53 -0400351 // must be before mac
352 syn!(TyParen) => { Ty::Paren }
353 |
354 // must be before path
355 syn!(Mac) => { Ty::Mac }
356 |
357 // must be before ty_poly_trait_ref
358 call!(ty_path, allow_plus)
359 |
360 syn!(TySlice) => { Ty::Slice }
361 |
362 syn!(TyArray) => { Ty::Array }
363 |
364 syn!(TyPtr) => { Ty::Ptr }
365 |
366 syn!(TyRptr) => { Ty::Rptr }
367 |
368 syn!(TyBareFn) => { Ty::BareFn }
369 |
370 syn!(TyNever) => { Ty::Never }
371 |
372 syn!(TyTup) => { Ty::Tup }
373 |
374 // Don't try parsing poly_trait_ref if we aren't allowing it
375 call!(ty_poly_trait_ref, allow_plus)
376 |
377 syn!(TyImplTrait) => { Ty::ImplTrait }
378 ));
379
Alex Crichton954046c2017-05-30 21:49:42 -0700380 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400381 named!(parse -> Self, map!(
382 brackets!(syn!(Ty)),
383 |(ty, b)| TySlice {
384 ty: Box::new(ty),
385 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700386 }
Michael Layzell92639a52017-06-01 00:07:44 -0400387 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700388 }
David Tolnayb79ee962016-09-04 09:39:20 -0700389
Alex Crichton954046c2017-05-30 21:49:42 -0700390 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400391 named!(parse -> Self, map!(
392 brackets!(do_parse!(
393 elem: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700394 semi: syn!(Semi) >>
395 len: array_len >>
396 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400397 )),
398 |((elem, semi, len), brackets)| {
399 TyArray {
400 ty: Box::new(elem),
401 amt: len,
402 bracket_token: brackets,
403 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700404 }
405 }
Michael Layzell92639a52017-06-01 00:07:44 -0400406 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700407 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700408
David Tolnay514f1292017-02-27 12:30:57 -0800409 #[cfg(not(feature = "full"))]
Alex Crichton954046c2017-05-30 21:49:42 -0700410 named!(array_len -> ConstExpr, syn!(ConstExpr));
David Tolnay514f1292017-02-27 12:30:57 -0800411
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700412 #[cfg(feature = "full")]
David Tolnay514f1292017-02-27 12:30:57 -0800413 named!(array_len -> ConstExpr, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700414 terminated!(syn!(ConstExpr), input_end!())
David Tolnay514f1292017-02-27 12:30:57 -0800415 |
Alex Crichton954046c2017-05-30 21:49:42 -0700416 terminated!(syn!(Expr), input_end!()) => { ConstExpr::Other }
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700417 ));
418
Alex Crichton954046c2017-05-30 21:49:42 -0700419 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400420 named!(parse -> Self, do_parse!(
421 star: syn!(Star) >>
422 mutability: alt!(
423 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
424 |
425 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
426 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400427 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400428 (TyPtr {
429 const_token: mutability.1,
430 star_token: star,
431 ty: Box::new(MutTy {
432 ty: target,
433 mutability: mutability.0,
434 }),
435 })
436 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700437 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700438
Alex Crichton954046c2017-05-30 21:49:42 -0700439 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400440 named!(parse -> Self, do_parse!(
441 amp: syn!(And) >>
442 life: option!(syn!(Lifetime)) >>
443 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400444 // & binds tighter than +, so we don't allow + here.
445 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400446 (TyRptr {
447 lifetime: life,
448 ty: Box::new(MutTy {
449 ty: target,
450 mutability: mutability,
451 }),
452 and_token: amp,
453 })
454 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700455 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700456
Alex Crichton954046c2017-05-30 21:49:42 -0700457 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400458 named!(parse -> Self, do_parse!(
459 lifetimes: option!(syn!(BoundLifetimes)) >>
460 unsafety: syn!(Unsafety) >>
461 abi: option!(syn!(Abi)) >>
462 fn_: syn!(Fn_) >>
463 parens: parens!(do_parse!(
464 inputs: call!(Delimited::parse_terminated) >>
465 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
466 syn!(Dot3))) >>
467 (inputs, variadic)
468 )) >>
469 output: syn!(FunctionRetTy) >>
470 (TyBareFn {
471 ty: Box::new(BareFnTy {
472 unsafety: unsafety,
473 abi: abi,
474 lifetimes: lifetimes,
475 output: output,
476 variadic: (parens.0).1,
477 fn_token: fn_,
478 paren_token: parens.1,
479 inputs: (parens.0).0,
480 }),
481 })
482 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700483 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700484
Alex Crichton954046c2017-05-30 21:49:42 -0700485 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400486 named!(parse -> Self, map!(
487 syn!(Bang),
488 |b| TyNever { bang_token: b }
489 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700490 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700491
Alex Crichton954046c2017-05-30 21:49:42 -0700492 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400493 named!(parse -> Self, do_parse!(
494 data: parens!(call!(Delimited::parse_terminated)) >>
495 (TyTup {
496 tys: data.0,
497 paren_token: data.1,
498 lone_comma: None, // TODO: does this just not parse?
499 })
500 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700501 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700502
Michael Layzell9bf2b002017-06-04 18:49:53 -0400503 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700504 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700505 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700506 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700507 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700508 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400509 // Only allow parsing additional bounds if allow_plus is true.
510 bounds: alt!(
511 cond_reduce!(
512 allow_plus,
513 many0!(tuple!(syn!(Add), syn!(TyParamBound)))
514 )
515 |
516 value!(vec![])
517 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700518 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700519 let (qself, mut path) = qpath;
520 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700521 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700522 let len = path.segments.len();
523 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700524 }
David Tolnay6414da72016-10-08 00:55:17 -0700525 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700526 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700527 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800528 let path = TyParamBound::Trait(
529 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800531 trait_ref: path,
532 },
533 TraitBoundModifier::None,
534 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700535 let mut new_bounds = Delimited::new();
536 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700537 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 new_bounds.push_default(bound);
539 }
540 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700541 }
542 })
543 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700544
David Tolnay9636c052016-10-02 17:11:17 -0700545 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700546 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700547 |
548 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700549 lt: syn!(Lt) >>
David Tolnay570695e2017-06-03 16:15:13 -0700550 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700551 path: option!(do_parse!(
552 as_: syn!(As) >>
553 path: syn!(Path) >>
554 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700555 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700556 gt: syn!(Gt) >>
557 colon2: syn!(Colon2) >>
558 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700559 ({
David Tolnay570695e2017-06-03 16:15:13 -0700560 let (pos, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700561 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700562 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700563 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700564 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700565 }
Alex Crichton954046c2017-05-30 21:49:42 -0700566 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700567 path.segments.push(item);
568 }
David Tolnay570695e2017-06-03 16:15:13 -0700569 (Some((as_, pos)), path)
David Tolnay9636c052016-10-02 17:11:17 -0700570 }
571 None => {
David Tolnay570695e2017-06-03 16:15:13 -0700572 (None, Path {
573 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700574 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700575 })
David Tolnay9636c052016-10-02 17:11:17 -0700576 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700577 };
578 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700579 lt_token: lt,
580 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700581 position: pos,
Alex Crichton954046c2017-05-30 21:49:42 -0700582 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700583 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700584 })
585 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700586 |
David Tolnaybc7d7d92017-06-03 20:54:05 -0700587 map!(syn!(Self_), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700588 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700589
Alex Crichton954046c2017-05-30 21:49:42 -0700590 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400591 named!(parse -> Self, do_parse!(
592 data: parens!(call!(Delimited::parse_terminated)) >>
593 output: syn!(FunctionRetTy) >>
594 (ParenthesizedParameterData {
595 paren_token: data.1,
596 inputs: data.0,
597 output: output,
598 })
599 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700600 }
601
602 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400603 named!(parse -> Self, alt!(
604 do_parse!(
605 arrow: syn!(RArrow) >>
606 ty: syn!(Ty) >>
607 (FunctionRetTy::Ty(ty, arrow))
608 )
609 |
610 epsilon!() => { |_| FunctionRetTy::Default }
611 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700612 }
613
Michael Layzell9bf2b002017-06-04 18:49:53 -0400614 // Only allow multiple trait references if allow_plus is true.
615 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
616 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
617 |x| TyTraitObject { bounds: x }.into()
618 }
619 |
620 syn!(TyParamBound) => {
621 |x| TyTraitObject { bounds: vec![x].into() }.into()
622 }
David Tolnay6414da72016-10-08 00:55:17 -0700623 ));
624
Alex Crichton954046c2017-05-30 21:49:42 -0700625 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400626 named!(parse -> Self, do_parse!(
627 impl_: syn!(Impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400628 // NOTE: rust-lang/rust#34511 includes discussion about whether or
629 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400630 elem: call!(Delimited::parse_separated_nonempty) >>
631 (TyImplTrait {
632 impl_token: impl_,
633 bounds: elem,
634 })
635 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700636 }
David Tolnayb79ee962016-09-04 09:39:20 -0700637
Michael Layzell93c36282017-06-04 20:43:14 -0400638 impl Synom for TyGroup {
639 named!(parse -> Self, do_parse!(
640 data: grouped!(syn!(Ty)) >>
641 (TyGroup {
642 group_token: data.1,
643 ty: Box::new(data.0),
644 })
645 ));
646 }
647
Alex Crichton954046c2017-05-30 21:49:42 -0700648 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400649 named!(parse -> Self, do_parse!(
650 data: parens!(syn!(Ty)) >>
651 (TyParen {
652 paren_token: data.1,
653 ty: Box::new(data.0),
654 })
655 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700656 }
David Tolnayb79ee962016-09-04 09:39:20 -0700657
Alex Crichton954046c2017-05-30 21:49:42 -0700658 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400659 named!(parse -> Self, alt!(
660 syn!(Mut) => { Mutability::Mutable }
661 |
662 epsilon!() => { |_| Mutability::Immutable }
663 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700664 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700665
Alex Crichton954046c2017-05-30 21:49:42 -0700666 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400667 named!(parse -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700668 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400669 segments: call!(Delimited::parse_separated_nonempty) >>
670 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700671 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400672 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400673 })
674 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700675 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700676
Alex Crichton954046c2017-05-30 21:49:42 -0700677 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400678 named!(parse -> Self, alt!(
679 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700680 ident: syn!(Ident) >>
681 turbofish: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400682 lt: syn!(Lt) >>
683 lifetimes: call!(Delimited::parse_terminated) >>
684 types: cond!(
685 lifetimes.is_empty() || lifetimes.trailing_delim(),
686 call!(Delimited::parse_terminated_with,
687 ty_no_eq_after)
688 ) >>
689 bindings: cond!(
690 match types {
691 Some(ref t) => t.is_empty() || t.trailing_delim(),
692 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
693 },
694 call!(Delimited::parse_terminated)
695 ) >>
696 gt: syn!(Gt) >>
697 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700698 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400699 parameters: PathParameters::AngleBracketed(
700 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700701 turbofish: turbofish,
702 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400703 lifetimes: lifetimes,
704 types: types.unwrap_or_default(),
705 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700706 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400707 }
708 ),
709 })
710 )
711 |
712 mod_style_path_segment
713 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700714 }
David Tolnay570695e2017-06-03 16:15:13 -0700715
Alex Crichton954046c2017-05-30 21:49:42 -0700716 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700717
Alex Crichton954046c2017-05-30 21:49:42 -0700718 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400719 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700720 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400721 segments: call!(Delimited::parse_separated_nonempty_with,
722 mod_style_path_segment) >>
723 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700724 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400725 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400726 })
727 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700728 }
Arnavionf2dada12017-04-20 23:55:20 -0700729
730 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700731 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700732 |
Alex Crichton954046c2017-05-30 21:49:42 -0700733 alt!(
734 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700735 |
Alex Crichton954046c2017-05-30 21:49:42 -0700736 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700737 |
Alex Crichton954046c2017-05-30 21:49:42 -0700738 syn!(CapSelf) => { Into::into }
739 )
Arnavionf2dada12017-04-20 23:55:20 -0700740 ));
741
Alex Crichton954046c2017-05-30 21:49:42 -0700742 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400743 named!(parse -> Self, do_parse!(
744 id: syn!(Ident) >>
745 eq: syn!(Eq) >>
746 ty: syn!(Ty) >>
747 (TypeBinding {
748 ident: id,
749 eq_token: eq,
750 ty: ty,
751 })
752 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700753 }
754
755 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400756 named!(parse -> Self, do_parse!(
757 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
758 trait_ref: syn!(Path) >>
759 parenthesized: option!(cond_reduce!(
760 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
761 syn!(ParenthesizedParameterData)
762 )) >>
763 ({
764 let mut trait_ref = trait_ref;
765 if let Some(parenthesized) = parenthesized {
766 let parenthesized = PathParameters::Parenthesized(parenthesized);
767 let len = trait_ref.segments.len();
768 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
769 }
770 PolyTraitRef {
771 bound_lifetimes: bound_lifetimes,
772 trait_ref: trait_ref,
773 }
774 })
775 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700776 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700777
Alex Crichton954046c2017-05-30 21:49:42 -0700778 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400779 named!(parse -> Self, do_parse!(
780 name: option!(do_parse!(
781 name: syn!(Ident) >>
782 not!(syn!(Colon2)) >>
783 colon: syn!(Colon) >>
784 (name, colon)
785 )) >>
786 ty: syn!(Ty) >>
787 (BareFnArg {
788 name: name,
789 ty: ty,
790 })
791 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700792 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700793
Alex Crichton954046c2017-05-30 21:49:42 -0700794 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400795 named!(parse -> Self, alt!(
796 syn!(Unsafe) => { Unsafety::Unsafe }
797 |
798 epsilon!() => { |_| Unsafety::Normal }
799 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700800 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700801
Alex Crichton954046c2017-05-30 21:49:42 -0700802 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400803 named!(parse -> Self, do_parse!(
804 extern_: syn!(Extern) >>
805 // TODO: this parses all literals, not just strings
806 name: option!(syn!(Lit)) >>
807 (Abi {
808 extern_token: extern_,
809 kind: match name {
810 Some(name) => AbiKind::Named(name),
811 None => AbiKind::Default,
812 },
813 })
814 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700815 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700816}
David Tolnay87d0b442016-09-04 11:52:12 -0700817
818#[cfg(feature = "printing")]
819mod printing {
820 use super::*;
821 use quote::{Tokens, ToTokens};
822
Alex Crichton62a0a592017-05-22 13:58:53 -0700823 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700824 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700825 self.bracket_token.surround(tokens, |tokens| {
826 self.ty.to_tokens(tokens);
827 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700828 }
829 }
830
831 impl ToTokens for TyArray {
832 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700833 self.bracket_token.surround(tokens, |tokens| {
834 self.ty.to_tokens(tokens);
835 self.semi_token.to_tokens(tokens);
836 self.amt.to_tokens(tokens);
837 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700838 }
839 }
840
841 impl ToTokens for TyPtr {
842 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700843 self.star_token.to_tokens(tokens);
844 self.const_token.to_tokens(tokens);
845 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700846 self.ty.ty.to_tokens(tokens);
847 }
848 }
849
850 impl ToTokens for TyRptr {
851 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700852 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700853 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700854 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700855 self.ty.ty.to_tokens(tokens);
856 }
857 }
858
859 impl ToTokens for TyBareFn {
860 fn to_tokens(&self, tokens: &mut Tokens) {
861 self.ty.to_tokens(tokens)
862 }
863 }
864
865 impl ToTokens for TyNever {
866 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700867 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700868 }
869 }
870
871 impl ToTokens for TyTup {
872 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700873 self.paren_token.surround(tokens, |tokens| {
874 self.tys.to_tokens(tokens);
875 self.lone_comma.to_tokens(tokens);
876 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700877 }
878 }
879
880 impl ToTokens for TyPath {
881 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700882 PathTokens(&self.qself, &self.path).to_tokens(tokens);
883 }
884 }
885
886 impl<'a> ToTokens for PathTokens<'a> {
887 fn to_tokens(&self, tokens: &mut Tokens) {
888 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700889 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700890 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700891 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700892 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700893 qself.ty.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700894 let mut segments = self.1.segments.iter();
David Tolnayb99e1b02017-06-03 19:00:55 -0700895 if let Some((ref as_token, pos)) = qself.position {
David Tolnay570695e2017-06-03 16:15:13 -0700896 as_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700897 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700898 for (i, segment) in (&mut segments).take(pos).enumerate() {
899 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700900 segment.item().to_tokens(tokens);
901 qself.gt_token.to_tokens(tokens);
902 segment.delimiter().to_tokens(tokens);
903 } else {
904 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700905 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700906 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700907 } else {
908 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700909 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700910 }
David Tolnay570695e2017-06-03 16:15:13 -0700911 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700912 segment.to_tokens(tokens);
913 }
914 }
915 }
916
917 impl ToTokens for TyTraitObject {
918 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700919 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700920 }
921 }
922
923 impl ToTokens for TyImplTrait {
924 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700925 self.impl_token.to_tokens(tokens);
926 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700927 }
928 }
929
Michael Layzell93c36282017-06-04 20:43:14 -0400930 impl ToTokens for TyGroup {
931 fn to_tokens(&self, tokens: &mut Tokens) {
932 self.group_token.surround(tokens, |tokens| {
933 self.ty.to_tokens(tokens);
934 });
935 }
936 }
937
Alex Crichton62a0a592017-05-22 13:58:53 -0700938 impl ToTokens for TyParen {
939 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700940 self.paren_token.surround(tokens, |tokens| {
941 self.ty.to_tokens(tokens);
942 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700943 }
944 }
945
946 impl ToTokens for TyInfer {
947 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700948 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700949 }
950 }
951
David Tolnay47a877c2016-10-01 16:50:55 -0700952 impl ToTokens for Mutability {
953 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700954 if let Mutability::Mutable(ref t) = *self {
955 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700956 }
957 }
958 }
959
David Tolnay87d0b442016-09-04 11:52:12 -0700960 impl ToTokens for Path {
961 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700962 self.leading_colon.to_tokens(tokens);
963 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700964 }
965 }
966
967 impl ToTokens for PathSegment {
968 fn to_tokens(&self, tokens: &mut Tokens) {
969 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700970 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700971 }
972 }
973
974 impl ToTokens for PathParameters {
975 fn to_tokens(&self, tokens: &mut Tokens) {
976 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700977 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -0700978 PathParameters::AngleBracketed(ref parameters) => {
979 parameters.to_tokens(tokens);
980 }
981 PathParameters::Parenthesized(ref parameters) => {
982 parameters.to_tokens(tokens);
983 }
984 }
985 }
986 }
987
988 impl ToTokens for AngleBracketedParameterData {
989 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -0700990 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700991 self.lt_token.to_tokens(tokens);
992 self.lifetimes.to_tokens(tokens);
993 self.types.to_tokens(tokens);
994 self.bindings.to_tokens(tokens);
995 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700996 }
997 }
998
999 impl ToTokens for TypeBinding {
1000 fn to_tokens(&self, tokens: &mut Tokens) {
1001 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001002 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001003 self.ty.to_tokens(tokens);
1004 }
1005 }
1006
1007 impl ToTokens for ParenthesizedParameterData {
1008 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001009 self.paren_token.surround(tokens, |tokens| {
1010 self.inputs.to_tokens(tokens);
1011 });
1012 self.output.to_tokens(tokens);
1013 }
1014 }
1015
1016 impl ToTokens for FunctionRetTy {
1017 fn to_tokens(&self, tokens: &mut Tokens) {
1018 match *self {
1019 FunctionRetTy::Default => {}
1020 FunctionRetTy::Ty(ref ty, ref arrow) => {
1021 arrow.to_tokens(tokens);
1022 ty.to_tokens(tokens);
1023 }
David Tolnay87d0b442016-09-04 11:52:12 -07001024 }
1025 }
1026 }
1027
1028 impl ToTokens for PolyTraitRef {
1029 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001030 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001031 self.trait_ref.to_tokens(tokens);
1032 }
1033 }
1034
1035 impl ToTokens for BareFnTy {
1036 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001037 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001038 self.unsafety.to_tokens(tokens);
1039 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001040 self.fn_token.to_tokens(tokens);
1041 self.paren_token.surround(tokens, |tokens| {
1042 self.inputs.to_tokens(tokens);
1043 self.variadic.to_tokens(tokens);
1044 });
1045 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001046 }
1047 }
1048
David Tolnay62f374c2016-10-02 13:37:00 -07001049 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001050 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001051 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001052 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001053 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001054 }
1055 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001056 }
1057 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001058
1059 impl ToTokens for Unsafety {
1060 fn to_tokens(&self, tokens: &mut Tokens) {
1061 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001062 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001063 Unsafety::Normal => {
1064 // nothing
1065 }
1066 }
1067 }
1068 }
1069
1070 impl ToTokens for Abi {
1071 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001072 self.extern_token.to_tokens(tokens);
1073 match self.kind {
1074 AbiKind::Named(ref named) => named.to_tokens(tokens),
1075 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001076 }
1077 }
1078 }
David Tolnay87d0b442016-09-04 11:52:12 -07001079}