blob: 83aecd4af702bf89a40d9feaa1365b8c16e6cf07 [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,
Michael Layzelld7ee9102017-06-07 10:02:19 -040017 pub amt: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070018 }),
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) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400395 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700396 (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
Alex Crichton954046c2017-05-30 21:49:42 -0700409 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400410 named!(parse -> Self, do_parse!(
411 star: syn!(Star) >>
412 mutability: alt!(
413 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
414 |
415 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
416 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400417 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400418 (TyPtr {
419 const_token: mutability.1,
420 star_token: star,
421 ty: Box::new(MutTy {
422 ty: target,
423 mutability: mutability.0,
424 }),
425 })
426 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700427 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700428
Alex Crichton954046c2017-05-30 21:49:42 -0700429 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400430 named!(parse -> Self, do_parse!(
431 amp: syn!(And) >>
432 life: option!(syn!(Lifetime)) >>
433 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400434 // & binds tighter than +, so we don't allow + here.
435 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400436 (TyRptr {
437 lifetime: life,
438 ty: Box::new(MutTy {
439 ty: target,
440 mutability: mutability,
441 }),
442 and_token: amp,
443 })
444 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700445 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700446
Alex Crichton954046c2017-05-30 21:49:42 -0700447 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400448 named!(parse -> Self, do_parse!(
449 lifetimes: option!(syn!(BoundLifetimes)) >>
450 unsafety: syn!(Unsafety) >>
451 abi: option!(syn!(Abi)) >>
452 fn_: syn!(Fn_) >>
453 parens: parens!(do_parse!(
454 inputs: call!(Delimited::parse_terminated) >>
455 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
456 syn!(Dot3))) >>
457 (inputs, variadic)
458 )) >>
459 output: syn!(FunctionRetTy) >>
460 (TyBareFn {
461 ty: Box::new(BareFnTy {
462 unsafety: unsafety,
463 abi: abi,
464 lifetimes: lifetimes,
465 output: output,
466 variadic: (parens.0).1,
467 fn_token: fn_,
468 paren_token: parens.1,
469 inputs: (parens.0).0,
470 }),
471 })
472 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700473 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700474
Alex Crichton954046c2017-05-30 21:49:42 -0700475 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400476 named!(parse -> Self, map!(
477 syn!(Bang),
478 |b| TyNever { bang_token: b }
479 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700480 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700481
Alex Crichton954046c2017-05-30 21:49:42 -0700482 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400483 named!(parse -> Self, do_parse!(
484 data: parens!(call!(Delimited::parse_terminated)) >>
485 (TyTup {
486 tys: data.0,
487 paren_token: data.1,
488 lone_comma: None, // TODO: does this just not parse?
489 })
490 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700491 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700492
Michael Layzell9bf2b002017-06-04 18:49:53 -0400493 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700494 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700495 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700496 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700497 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700498 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400499 // Only allow parsing additional bounds if allow_plus is true.
500 bounds: alt!(
501 cond_reduce!(
502 allow_plus,
503 many0!(tuple!(syn!(Add), syn!(TyParamBound)))
504 )
505 |
506 value!(vec![])
507 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700508 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700509 let (qself, mut path) = qpath;
510 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700511 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700512 let len = path.segments.len();
513 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700514 }
David Tolnay6414da72016-10-08 00:55:17 -0700515 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700516 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700517 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800518 let path = TyParamBound::Trait(
519 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700520 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800521 trait_ref: path,
522 },
523 TraitBoundModifier::None,
524 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 let mut new_bounds = Delimited::new();
526 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700527 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700528 new_bounds.push_default(bound);
529 }
530 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700531 }
532 })
533 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700534
David Tolnay9636c052016-10-02 17:11:17 -0700535 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700536 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700537 |
538 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700539 lt: syn!(Lt) >>
David Tolnay570695e2017-06-03 16:15:13 -0700540 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700541 path: option!(do_parse!(
542 as_: syn!(As) >>
543 path: syn!(Path) >>
544 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700545 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700546 gt: syn!(Gt) >>
547 colon2: syn!(Colon2) >>
548 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700549 ({
David Tolnay570695e2017-06-03 16:15:13 -0700550 let (pos, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700551 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700552 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700553 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700554 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 }
Alex Crichton954046c2017-05-30 21:49:42 -0700556 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700557 path.segments.push(item);
558 }
David Tolnay570695e2017-06-03 16:15:13 -0700559 (Some((as_, pos)), path)
David Tolnay9636c052016-10-02 17:11:17 -0700560 }
561 None => {
David Tolnay570695e2017-06-03 16:15:13 -0700562 (None, Path {
563 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700564 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700565 })
David Tolnay9636c052016-10-02 17:11:17 -0700566 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700567 };
568 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700569 lt_token: lt,
570 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700571 position: pos,
Alex Crichton954046c2017-05-30 21:49:42 -0700572 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700573 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700574 })
575 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700576 |
David Tolnaybc7d7d92017-06-03 20:54:05 -0700577 map!(syn!(Self_), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700578 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700579
Alex Crichton954046c2017-05-30 21:49:42 -0700580 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400581 named!(parse -> Self, do_parse!(
582 data: parens!(call!(Delimited::parse_terminated)) >>
583 output: syn!(FunctionRetTy) >>
584 (ParenthesizedParameterData {
585 paren_token: data.1,
586 inputs: data.0,
587 output: output,
588 })
589 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700590 }
591
592 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400593 named!(parse -> Self, alt!(
594 do_parse!(
595 arrow: syn!(RArrow) >>
596 ty: syn!(Ty) >>
597 (FunctionRetTy::Ty(ty, arrow))
598 )
599 |
600 epsilon!() => { |_| FunctionRetTy::Default }
601 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700602 }
603
Michael Layzell9bf2b002017-06-04 18:49:53 -0400604 // Only allow multiple trait references if allow_plus is true.
605 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
606 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
607 |x| TyTraitObject { bounds: x }.into()
608 }
609 |
610 syn!(TyParamBound) => {
611 |x| TyTraitObject { bounds: vec![x].into() }.into()
612 }
David Tolnay6414da72016-10-08 00:55:17 -0700613 ));
614
Alex Crichton954046c2017-05-30 21:49:42 -0700615 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400616 named!(parse -> Self, do_parse!(
617 impl_: syn!(Impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400618 // NOTE: rust-lang/rust#34511 includes discussion about whether or
619 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400620 elem: call!(Delimited::parse_separated_nonempty) >>
621 (TyImplTrait {
622 impl_token: impl_,
623 bounds: elem,
624 })
625 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700626 }
David Tolnayb79ee962016-09-04 09:39:20 -0700627
Michael Layzell93c36282017-06-04 20:43:14 -0400628 impl Synom for TyGroup {
629 named!(parse -> Self, do_parse!(
630 data: grouped!(syn!(Ty)) >>
631 (TyGroup {
632 group_token: data.1,
633 ty: Box::new(data.0),
634 })
635 ));
636 }
637
Alex Crichton954046c2017-05-30 21:49:42 -0700638 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400639 named!(parse -> Self, do_parse!(
640 data: parens!(syn!(Ty)) >>
641 (TyParen {
642 paren_token: data.1,
643 ty: Box::new(data.0),
644 })
645 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700646 }
David Tolnayb79ee962016-09-04 09:39:20 -0700647
Alex Crichton954046c2017-05-30 21:49:42 -0700648 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400649 named!(parse -> Self, alt!(
650 syn!(Mut) => { Mutability::Mutable }
651 |
652 epsilon!() => { |_| Mutability::Immutable }
653 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700654 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700655
Alex Crichton954046c2017-05-30 21:49:42 -0700656 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400657 named!(parse -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700658 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400659 segments: call!(Delimited::parse_separated_nonempty) >>
660 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700661 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400662 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400663 })
664 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700665
666 fn description() -> Option<&'static str> {
667 Some("path")
668 }
Alex Crichton954046c2017-05-30 21:49:42 -0700669 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700670
Alex Crichton954046c2017-05-30 21:49:42 -0700671 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400672 named!(parse -> Self, alt!(
673 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700674 ident: syn!(Ident) >>
675 turbofish: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400676 lt: syn!(Lt) >>
677 lifetimes: call!(Delimited::parse_terminated) >>
678 types: cond!(
679 lifetimes.is_empty() || lifetimes.trailing_delim(),
680 call!(Delimited::parse_terminated_with,
681 ty_no_eq_after)
682 ) >>
683 bindings: cond!(
684 match types {
685 Some(ref t) => t.is_empty() || t.trailing_delim(),
686 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
687 },
688 call!(Delimited::parse_terminated)
689 ) >>
690 gt: syn!(Gt) >>
691 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700692 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400693 parameters: PathParameters::AngleBracketed(
694 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700695 turbofish: turbofish,
696 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400697 lifetimes: lifetimes,
698 types: types.unwrap_or_default(),
699 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700700 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400701 }
702 ),
703 })
704 )
705 |
706 mod_style_path_segment
707 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700708 }
David Tolnay570695e2017-06-03 16:15:13 -0700709
Alex Crichton954046c2017-05-30 21:49:42 -0700710 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700711
Alex Crichton954046c2017-05-30 21:49:42 -0700712 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400713 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700714 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400715 segments: call!(Delimited::parse_separated_nonempty_with,
716 mod_style_path_segment) >>
717 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700718 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400719 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400720 })
721 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700722 }
Arnavionf2dada12017-04-20 23:55:20 -0700723
724 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700725 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700726 |
Alex Crichton954046c2017-05-30 21:49:42 -0700727 alt!(
728 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700729 |
Alex Crichton954046c2017-05-30 21:49:42 -0700730 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700731 |
Alex Crichton954046c2017-05-30 21:49:42 -0700732 syn!(CapSelf) => { Into::into }
733 )
Arnavionf2dada12017-04-20 23:55:20 -0700734 ));
735
Alex Crichton954046c2017-05-30 21:49:42 -0700736 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400737 named!(parse -> Self, do_parse!(
738 id: syn!(Ident) >>
739 eq: syn!(Eq) >>
740 ty: syn!(Ty) >>
741 (TypeBinding {
742 ident: id,
743 eq_token: eq,
744 ty: ty,
745 })
746 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700747 }
748
749 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400750 named!(parse -> Self, do_parse!(
751 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
752 trait_ref: syn!(Path) >>
753 parenthesized: option!(cond_reduce!(
754 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
755 syn!(ParenthesizedParameterData)
756 )) >>
757 ({
758 let mut trait_ref = trait_ref;
759 if let Some(parenthesized) = parenthesized {
760 let parenthesized = PathParameters::Parenthesized(parenthesized);
761 let len = trait_ref.segments.len();
762 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
763 }
764 PolyTraitRef {
765 bound_lifetimes: bound_lifetimes,
766 trait_ref: trait_ref,
767 }
768 })
769 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700770 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700771
Alex Crichton954046c2017-05-30 21:49:42 -0700772 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400773 named!(parse -> Self, do_parse!(
774 name: option!(do_parse!(
775 name: syn!(Ident) >>
776 not!(syn!(Colon2)) >>
777 colon: syn!(Colon) >>
778 (name, colon)
779 )) >>
780 ty: syn!(Ty) >>
781 (BareFnArg {
782 name: name,
783 ty: ty,
784 })
785 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700786 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700787
Alex Crichton954046c2017-05-30 21:49:42 -0700788 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400789 named!(parse -> Self, alt!(
790 syn!(Unsafe) => { Unsafety::Unsafe }
791 |
792 epsilon!() => { |_| Unsafety::Normal }
793 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700794 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700795
Alex Crichton954046c2017-05-30 21:49:42 -0700796 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400797 named!(parse -> Self, do_parse!(
798 extern_: syn!(Extern) >>
799 // TODO: this parses all literals, not just strings
800 name: option!(syn!(Lit)) >>
801 (Abi {
802 extern_token: extern_,
803 kind: match name {
804 Some(name) => AbiKind::Named(name),
805 None => AbiKind::Default,
806 },
807 })
808 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700809 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700810}
David Tolnay87d0b442016-09-04 11:52:12 -0700811
812#[cfg(feature = "printing")]
813mod printing {
814 use super::*;
815 use quote::{Tokens, ToTokens};
816
Alex Crichton62a0a592017-05-22 13:58:53 -0700817 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700818 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700819 self.bracket_token.surround(tokens, |tokens| {
820 self.ty.to_tokens(tokens);
821 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700822 }
823 }
824
825 impl ToTokens for TyArray {
826 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700827 self.bracket_token.surround(tokens, |tokens| {
828 self.ty.to_tokens(tokens);
829 self.semi_token.to_tokens(tokens);
830 self.amt.to_tokens(tokens);
831 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700832 }
833 }
834
835 impl ToTokens for TyPtr {
836 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700837 self.star_token.to_tokens(tokens);
838 self.const_token.to_tokens(tokens);
839 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700840 self.ty.ty.to_tokens(tokens);
841 }
842 }
843
844 impl ToTokens for TyRptr {
845 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700846 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700847 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700848 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700849 self.ty.ty.to_tokens(tokens);
850 }
851 }
852
853 impl ToTokens for TyBareFn {
854 fn to_tokens(&self, tokens: &mut Tokens) {
855 self.ty.to_tokens(tokens)
856 }
857 }
858
859 impl ToTokens for TyNever {
860 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700861 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700862 }
863 }
864
865 impl ToTokens for TyTup {
866 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700867 self.paren_token.surround(tokens, |tokens| {
868 self.tys.to_tokens(tokens);
869 self.lone_comma.to_tokens(tokens);
870 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700871 }
872 }
873
874 impl ToTokens for TyPath {
875 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700876 PathTokens(&self.qself, &self.path).to_tokens(tokens);
877 }
878 }
879
880 impl<'a> ToTokens for PathTokens<'a> {
881 fn to_tokens(&self, tokens: &mut Tokens) {
882 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700883 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700884 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700885 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700886 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700887 qself.ty.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700888 let mut segments = self.1.segments.iter();
David Tolnayb99e1b02017-06-03 19:00:55 -0700889 if let Some((ref as_token, pos)) = qself.position {
David Tolnay570695e2017-06-03 16:15:13 -0700890 as_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700891 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700892 for (i, segment) in (&mut segments).take(pos).enumerate() {
893 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700894 segment.item().to_tokens(tokens);
895 qself.gt_token.to_tokens(tokens);
896 segment.delimiter().to_tokens(tokens);
897 } else {
898 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700899 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700900 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700901 } else {
902 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700903 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700904 }
David Tolnay570695e2017-06-03 16:15:13 -0700905 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700906 segment.to_tokens(tokens);
907 }
908 }
909 }
910
911 impl ToTokens for TyTraitObject {
912 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700913 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700914 }
915 }
916
917 impl ToTokens for TyImplTrait {
918 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700919 self.impl_token.to_tokens(tokens);
920 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700921 }
922 }
923
Michael Layzell93c36282017-06-04 20:43:14 -0400924 impl ToTokens for TyGroup {
925 fn to_tokens(&self, tokens: &mut Tokens) {
926 self.group_token.surround(tokens, |tokens| {
927 self.ty.to_tokens(tokens);
928 });
929 }
930 }
931
Alex Crichton62a0a592017-05-22 13:58:53 -0700932 impl ToTokens for TyParen {
933 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700934 self.paren_token.surround(tokens, |tokens| {
935 self.ty.to_tokens(tokens);
936 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700937 }
938 }
939
940 impl ToTokens for TyInfer {
941 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700942 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700943 }
944 }
945
David Tolnay47a877c2016-10-01 16:50:55 -0700946 impl ToTokens for Mutability {
947 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700948 if let Mutability::Mutable(ref t) = *self {
949 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700950 }
951 }
952 }
953
David Tolnay87d0b442016-09-04 11:52:12 -0700954 impl ToTokens for Path {
955 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700956 self.leading_colon.to_tokens(tokens);
957 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700958 }
959 }
960
961 impl ToTokens for PathSegment {
962 fn to_tokens(&self, tokens: &mut Tokens) {
963 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700964 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700965 }
966 }
967
968 impl ToTokens for PathParameters {
969 fn to_tokens(&self, tokens: &mut Tokens) {
970 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700971 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -0700972 PathParameters::AngleBracketed(ref parameters) => {
973 parameters.to_tokens(tokens);
974 }
975 PathParameters::Parenthesized(ref parameters) => {
976 parameters.to_tokens(tokens);
977 }
978 }
979 }
980 }
981
982 impl ToTokens for AngleBracketedParameterData {
983 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -0700984 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700985 self.lt_token.to_tokens(tokens);
986 self.lifetimes.to_tokens(tokens);
987 self.types.to_tokens(tokens);
988 self.bindings.to_tokens(tokens);
989 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700990 }
991 }
992
993 impl ToTokens for TypeBinding {
994 fn to_tokens(&self, tokens: &mut Tokens) {
995 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700996 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700997 self.ty.to_tokens(tokens);
998 }
999 }
1000
1001 impl ToTokens for ParenthesizedParameterData {
1002 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001003 self.paren_token.surround(tokens, |tokens| {
1004 self.inputs.to_tokens(tokens);
1005 });
1006 self.output.to_tokens(tokens);
1007 }
1008 }
1009
1010 impl ToTokens for FunctionRetTy {
1011 fn to_tokens(&self, tokens: &mut Tokens) {
1012 match *self {
1013 FunctionRetTy::Default => {}
1014 FunctionRetTy::Ty(ref ty, ref arrow) => {
1015 arrow.to_tokens(tokens);
1016 ty.to_tokens(tokens);
1017 }
David Tolnay87d0b442016-09-04 11:52:12 -07001018 }
1019 }
1020 }
1021
1022 impl ToTokens for PolyTraitRef {
1023 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001024 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001025 self.trait_ref.to_tokens(tokens);
1026 }
1027 }
1028
1029 impl ToTokens for BareFnTy {
1030 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001031 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001032 self.unsafety.to_tokens(tokens);
1033 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001034 self.fn_token.to_tokens(tokens);
1035 self.paren_token.surround(tokens, |tokens| {
1036 self.inputs.to_tokens(tokens);
1037 self.variadic.to_tokens(tokens);
1038 });
1039 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001040 }
1041 }
1042
David Tolnay62f374c2016-10-02 13:37:00 -07001043 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001044 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001045 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001046 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001047 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001048 }
1049 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001050 }
1051 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001052
1053 impl ToTokens for Unsafety {
1054 fn to_tokens(&self, tokens: &mut Tokens) {
1055 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001056 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001057 Unsafety::Normal => {
1058 // nothing
1059 }
1060 }
1061 }
1062 }
1063
1064 impl ToTokens for Abi {
1065 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001066 self.extern_token.to_tokens(tokens);
1067 match self.kind {
1068 AbiKind::Named(ref named) => named.to_tokens(tokens),
1069 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001070 }
1071 }
1072 }
David Tolnay87d0b442016-09-04 11:52:12 -07001073}