blob: 4716b6f354c8ee54f62985e5fc559f89bef7fdad [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>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400261 pub position: usize,
262 pub as_token: Option<tokens::As>,
David Tolnay570695e2017-06-03 16:15:13 -0700263 pub gt_token: tokens::Gt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700264 }
265}
266
267ast_struct! {
268 pub struct BareFnTy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub unsafety: Unsafety,
271 pub abi: Option<Abi>,
Alex Crichton954046c2017-05-30 21:49:42 -0700272 pub fn_token: tokens::Fn_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700273 pub paren_token: tokens::Paren,
274 pub inputs: Delimited<BareFnArg, tokens::Comma>,
275 pub variadic: Option<tokens::Dot3>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700276 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 }
278}
279
280ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700281 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 pub enum Unsafety {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 Unsafe(tokens::Unsafe),
Alex Crichton62a0a592017-05-22 13:58:53 -0700284 Normal,
285 }
286}
287
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700288ast_struct! {
289 pub struct Abi {
290 pub extern_token: tokens::Extern,
291 pub kind: AbiKind,
292 }
293}
294
Alex Crichton62a0a592017-05-22 13:58:53 -0700295ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700296 pub enum AbiKind {
297 Named(Lit),
298 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700299 }
300}
301
302ast_struct! {
303 /// An argument in a function type.
304 ///
305 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
306 pub struct BareFnArg {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700307 pub name: Option<(Ident, tokens::Colon)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 pub ty: Ty,
309 }
310}
311
312
313ast_enum! {
314 pub enum FunctionRetTy {
315 /// Return type is not specified.
316 ///
317 /// Functions default to `()` and
318 /// closures default to inference. Span points to where return
319 /// type would be inserted.
320 Default,
321 /// Everything else
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700322 Ty(Ty, tokens::RArrow),
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 }
David Tolnayb79ee962016-09-04 09:39:20 -0700324}
325
David Tolnay86eca752016-09-04 11:26:41 -0700326#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700327pub mod parsing {
328 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400329 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700330 use synom::tokens::*;
David Tolnayda4049b2016-09-04 10:59:23 -0700331
Alex Crichton954046c2017-05-30 21:49:42 -0700332 impl Synom for Ty {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400333 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700334
Alex Crichton954046c2017-05-30 21:49:42 -0700335 fn description() -> Option<&'static str> {
336 Some("type")
337 }
338 }
David Tolnay0047c712016-12-21 21:59:25 -0500339
Michael Layzell9bf2b002017-06-04 18:49:53 -0400340 impl Ty {
341 /// In some positions, types may not contain the `+` character, to
342 /// disambiguate them. For example in the expression `1 as T`, T may not
343 /// contain a `+` character.
344 ///
345 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400346 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400347 }
348
349 named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -0400350 syn!(TyGroup) => { Ty::Group }
351 |
Michael Layzell9bf2b002017-06-04 18:49:53 -0400352 // must be before mac
353 syn!(TyParen) => { Ty::Paren }
354 |
355 // must be before path
356 syn!(Mac) => { Ty::Mac }
357 |
358 // must be before ty_poly_trait_ref
359 call!(ty_path, allow_plus)
360 |
361 syn!(TySlice) => { Ty::Slice }
362 |
363 syn!(TyArray) => { Ty::Array }
364 |
365 syn!(TyPtr) => { Ty::Ptr }
366 |
367 syn!(TyRptr) => { Ty::Rptr }
368 |
369 syn!(TyBareFn) => { Ty::BareFn }
370 |
371 syn!(TyNever) => { Ty::Never }
372 |
373 syn!(TyTup) => { Ty::Tup }
374 |
375 // Don't try parsing poly_trait_ref if we aren't allowing it
376 call!(ty_poly_trait_ref, allow_plus)
377 |
378 syn!(TyImplTrait) => { Ty::ImplTrait }
379 ));
380
Alex Crichton954046c2017-05-30 21:49:42 -0700381 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400382 named!(parse -> Self, map!(
383 brackets!(syn!(Ty)),
384 |(ty, b)| TySlice {
385 ty: Box::new(ty),
386 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700387 }
Michael Layzell92639a52017-06-01 00:07:44 -0400388 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700389 }
David Tolnayb79ee962016-09-04 09:39:20 -0700390
Alex Crichton954046c2017-05-30 21:49:42 -0700391 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400392 named!(parse -> Self, map!(
393 brackets!(do_parse!(
394 elem: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700395 semi: syn!(Semi) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400396 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700397 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400398 )),
399 |((elem, semi, len), brackets)| {
400 TyArray {
401 ty: Box::new(elem),
402 amt: len,
403 bracket_token: brackets,
404 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700405 }
406 }
Michael Layzell92639a52017-06-01 00:07:44 -0400407 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700408 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700409
Alex Crichton954046c2017-05-30 21:49:42 -0700410 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400411 named!(parse -> Self, do_parse!(
412 star: syn!(Star) >>
413 mutability: alt!(
414 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
415 |
416 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
417 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400418 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400419 (TyPtr {
420 const_token: mutability.1,
421 star_token: star,
422 ty: Box::new(MutTy {
423 ty: target,
424 mutability: mutability.0,
425 }),
426 })
427 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700428 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700429
Alex Crichton954046c2017-05-30 21:49:42 -0700430 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400431 named!(parse -> Self, do_parse!(
432 amp: syn!(And) >>
433 life: option!(syn!(Lifetime)) >>
434 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400435 // & binds tighter than +, so we don't allow + here.
436 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400437 (TyRptr {
438 lifetime: life,
439 ty: Box::new(MutTy {
440 ty: target,
441 mutability: mutability,
442 }),
443 and_token: amp,
444 })
445 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700446 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700447
Alex Crichton954046c2017-05-30 21:49:42 -0700448 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400449 named!(parse -> Self, do_parse!(
450 lifetimes: option!(syn!(BoundLifetimes)) >>
451 unsafety: syn!(Unsafety) >>
452 abi: option!(syn!(Abi)) >>
453 fn_: syn!(Fn_) >>
454 parens: parens!(do_parse!(
455 inputs: call!(Delimited::parse_terminated) >>
456 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
457 syn!(Dot3))) >>
458 (inputs, variadic)
459 )) >>
460 output: syn!(FunctionRetTy) >>
461 (TyBareFn {
462 ty: Box::new(BareFnTy {
463 unsafety: unsafety,
464 abi: abi,
465 lifetimes: lifetimes,
466 output: output,
467 variadic: (parens.0).1,
468 fn_token: fn_,
469 paren_token: parens.1,
470 inputs: (parens.0).0,
471 }),
472 })
473 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700474 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700475
Alex Crichton954046c2017-05-30 21:49:42 -0700476 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400477 named!(parse -> Self, map!(
478 syn!(Bang),
479 |b| TyNever { bang_token: b }
480 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700481 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700482
Alex Crichton954046c2017-05-30 21:49:42 -0700483 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400484 named!(parse -> Self, do_parse!(
485 data: parens!(call!(Delimited::parse_terminated)) >>
486 (TyTup {
487 tys: data.0,
488 paren_token: data.1,
489 lone_comma: None, // TODO: does this just not parse?
490 })
491 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700492 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700493
Michael Layzell9bf2b002017-06-04 18:49:53 -0400494 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700495 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700496 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700497 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700498 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700499 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400500 // Only allow parsing additional bounds if allow_plus is true.
501 bounds: alt!(
502 cond_reduce!(
503 allow_plus,
504 many0!(tuple!(syn!(Add), syn!(TyParamBound)))
505 )
506 |
507 value!(vec![])
508 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700509 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700510 let (qself, mut path) = qpath;
511 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700512 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 let len = path.segments.len();
514 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700515 }
David Tolnay6414da72016-10-08 00:55:17 -0700516 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700517 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700518 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800519 let path = TyParamBound::Trait(
520 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800522 trait_ref: path,
523 },
524 TraitBoundModifier::None,
525 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700526 let mut new_bounds = Delimited::new();
527 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700528 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700529 new_bounds.push_default(bound);
530 }
531 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700532 }
533 })
534 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700535
David Tolnay9636c052016-10-02 17:11:17 -0700536 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700537 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700538 |
539 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700540 lt: syn!(Lt) >>
David Tolnay570695e2017-06-03 16:15:13 -0700541 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700542 path: option!(do_parse!(
543 as_: syn!(As) >>
544 path: syn!(Path) >>
545 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700546 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700547 gt: syn!(Gt) >>
548 colon2: syn!(Colon2) >>
549 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700550 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400551 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700552 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700553 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700554 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700555 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556 }
Alex Crichton954046c2017-05-30 21:49:42 -0700557 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 path.segments.push(item);
559 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400560 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700561 }
562 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400563 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700564 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700565 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700566 })
David Tolnay9636c052016-10-02 17:11:17 -0700567 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700568 };
569 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700570 lt_token: lt,
571 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400573 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700574 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700576 })
577 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700578 |
David Tolnaybc7d7d92017-06-03 20:54:05 -0700579 map!(syn!(Self_), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700580 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700581
Alex Crichton954046c2017-05-30 21:49:42 -0700582 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400583 named!(parse -> Self, do_parse!(
584 data: parens!(call!(Delimited::parse_terminated)) >>
585 output: syn!(FunctionRetTy) >>
586 (ParenthesizedParameterData {
587 paren_token: data.1,
588 inputs: data.0,
589 output: output,
590 })
591 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700592 }
593
594 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400595 named!(parse -> Self, alt!(
596 do_parse!(
597 arrow: syn!(RArrow) >>
598 ty: syn!(Ty) >>
599 (FunctionRetTy::Ty(ty, arrow))
600 )
601 |
602 epsilon!() => { |_| FunctionRetTy::Default }
603 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700604 }
605
Michael Layzell9bf2b002017-06-04 18:49:53 -0400606 // Only allow multiple trait references if allow_plus is true.
607 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
608 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
609 |x| TyTraitObject { bounds: x }.into()
610 }
611 |
612 syn!(TyParamBound) => {
613 |x| TyTraitObject { bounds: vec![x].into() }.into()
614 }
David Tolnay6414da72016-10-08 00:55:17 -0700615 ));
616
Alex Crichton954046c2017-05-30 21:49:42 -0700617 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400618 named!(parse -> Self, do_parse!(
619 impl_: syn!(Impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400620 // NOTE: rust-lang/rust#34511 includes discussion about whether or
621 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400622 elem: call!(Delimited::parse_separated_nonempty) >>
623 (TyImplTrait {
624 impl_token: impl_,
625 bounds: elem,
626 })
627 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700628 }
David Tolnayb79ee962016-09-04 09:39:20 -0700629
Michael Layzell93c36282017-06-04 20:43:14 -0400630 impl Synom for TyGroup {
631 named!(parse -> Self, do_parse!(
632 data: grouped!(syn!(Ty)) >>
633 (TyGroup {
634 group_token: data.1,
635 ty: Box::new(data.0),
636 })
637 ));
638 }
639
Alex Crichton954046c2017-05-30 21:49:42 -0700640 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400641 named!(parse -> Self, do_parse!(
642 data: parens!(syn!(Ty)) >>
643 (TyParen {
644 paren_token: data.1,
645 ty: Box::new(data.0),
646 })
647 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700648 }
David Tolnayb79ee962016-09-04 09:39:20 -0700649
Alex Crichton954046c2017-05-30 21:49:42 -0700650 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400651 named!(parse -> Self, alt!(
652 syn!(Mut) => { Mutability::Mutable }
653 |
654 epsilon!() => { |_| Mutability::Immutable }
655 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700656 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700657
Alex Crichton954046c2017-05-30 21:49:42 -0700658 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400659 named!(parse -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700660 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400661 segments: call!(Delimited::parse_separated_nonempty) >>
662 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700663 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400664 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400665 })
666 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700667
668 fn description() -> Option<&'static str> {
669 Some("path")
670 }
Alex Crichton954046c2017-05-30 21:49:42 -0700671 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700672
Alex Crichton954046c2017-05-30 21:49:42 -0700673 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400674 named!(parse -> Self, alt!(
675 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700676 ident: syn!(Ident) >>
677 turbofish: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400678 lt: syn!(Lt) >>
679 lifetimes: call!(Delimited::parse_terminated) >>
680 types: cond!(
681 lifetimes.is_empty() || lifetimes.trailing_delim(),
682 call!(Delimited::parse_terminated_with,
683 ty_no_eq_after)
684 ) >>
685 bindings: cond!(
686 match types {
687 Some(ref t) => t.is_empty() || t.trailing_delim(),
688 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
689 },
690 call!(Delimited::parse_terminated)
691 ) >>
692 gt: syn!(Gt) >>
693 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700694 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400695 parameters: PathParameters::AngleBracketed(
696 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700697 turbofish: turbofish,
698 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400699 lifetimes: lifetimes,
700 types: types.unwrap_or_default(),
701 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700702 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400703 }
704 ),
705 })
706 )
707 |
708 mod_style_path_segment
709 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700710 }
David Tolnay570695e2017-06-03 16:15:13 -0700711
Alex Crichton954046c2017-05-30 21:49:42 -0700712 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700713
Alex Crichton954046c2017-05-30 21:49:42 -0700714 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400715 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700716 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400717 segments: call!(Delimited::parse_separated_nonempty_with,
718 mod_style_path_segment) >>
719 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700720 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400721 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400722 })
723 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700724 }
Arnavionf2dada12017-04-20 23:55:20 -0700725
726 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700727 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700728 |
Alex Crichton954046c2017-05-30 21:49:42 -0700729 alt!(
730 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700731 |
Alex Crichton954046c2017-05-30 21:49:42 -0700732 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700733 |
Alex Crichton954046c2017-05-30 21:49:42 -0700734 syn!(CapSelf) => { Into::into }
735 )
Arnavionf2dada12017-04-20 23:55:20 -0700736 ));
737
Alex Crichton954046c2017-05-30 21:49:42 -0700738 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400739 named!(parse -> Self, do_parse!(
740 id: syn!(Ident) >>
741 eq: syn!(Eq) >>
742 ty: syn!(Ty) >>
743 (TypeBinding {
744 ident: id,
745 eq_token: eq,
746 ty: ty,
747 })
748 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700749 }
750
751 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400752 named!(parse -> Self, do_parse!(
753 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
754 trait_ref: syn!(Path) >>
755 parenthesized: option!(cond_reduce!(
756 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
757 syn!(ParenthesizedParameterData)
758 )) >>
759 ({
760 let mut trait_ref = trait_ref;
761 if let Some(parenthesized) = parenthesized {
762 let parenthesized = PathParameters::Parenthesized(parenthesized);
763 let len = trait_ref.segments.len();
764 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
765 }
766 PolyTraitRef {
767 bound_lifetimes: bound_lifetimes,
768 trait_ref: trait_ref,
769 }
770 })
771 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700772 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700773
Alex Crichton954046c2017-05-30 21:49:42 -0700774 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400775 named!(parse -> Self, do_parse!(
776 name: option!(do_parse!(
777 name: syn!(Ident) >>
778 not!(syn!(Colon2)) >>
779 colon: syn!(Colon) >>
780 (name, colon)
781 )) >>
782 ty: syn!(Ty) >>
783 (BareFnArg {
784 name: name,
785 ty: ty,
786 })
787 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700788 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700789
Alex Crichton954046c2017-05-30 21:49:42 -0700790 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400791 named!(parse -> Self, alt!(
792 syn!(Unsafe) => { Unsafety::Unsafe }
793 |
794 epsilon!() => { |_| Unsafety::Normal }
795 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700796 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700797
Alex Crichton954046c2017-05-30 21:49:42 -0700798 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400799 named!(parse -> Self, do_parse!(
800 extern_: syn!(Extern) >>
801 // TODO: this parses all literals, not just strings
802 name: option!(syn!(Lit)) >>
803 (Abi {
804 extern_token: extern_,
805 kind: match name {
806 Some(name) => AbiKind::Named(name),
807 None => AbiKind::Default,
808 },
809 })
810 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700811 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700812}
David Tolnay87d0b442016-09-04 11:52:12 -0700813
814#[cfg(feature = "printing")]
815mod printing {
816 use super::*;
817 use quote::{Tokens, ToTokens};
818
Alex Crichton62a0a592017-05-22 13:58:53 -0700819 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700820 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700821 self.bracket_token.surround(tokens, |tokens| {
822 self.ty.to_tokens(tokens);
823 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700824 }
825 }
826
827 impl ToTokens for TyArray {
828 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700829 self.bracket_token.surround(tokens, |tokens| {
830 self.ty.to_tokens(tokens);
831 self.semi_token.to_tokens(tokens);
832 self.amt.to_tokens(tokens);
833 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700834 }
835 }
836
837 impl ToTokens for TyPtr {
838 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700839 self.star_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400840 match self.ty.mutability {
841 Mutability::Mutable(ref tok) => tok.to_tokens(tokens),
842 Mutability::Immutable => {
Alex Crichton259ee532017-07-14 06:51:02 -0700843 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400844 }
845 }
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);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400875 // XXX: I don't think (,) is a thing.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700876 self.lone_comma.to_tokens(tokens);
877 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700878 }
879 }
880
881 impl ToTokens for TyPath {
882 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700883 PathTokens(&self.qself, &self.path).to_tokens(tokens);
884 }
885 }
886
887 impl<'a> ToTokens for PathTokens<'a> {
888 fn to_tokens(&self, tokens: &mut Tokens) {
889 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700890 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700891 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700892 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700893 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700894 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400895
896 // XXX: Gross.
897 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
898 self.1.segments.len() - 1
899 } else {
900 qself.position
901 };
David Tolnay570695e2017-06-03 16:15:13 -0700902 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400903 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700904 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700905 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700906 for (i, segment) in (&mut segments).take(pos).enumerate() {
907 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700908 segment.item().to_tokens(tokens);
909 qself.gt_token.to_tokens(tokens);
910 segment.delimiter().to_tokens(tokens);
911 } else {
912 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700913 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700914 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700915 } else {
916 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700917 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700918 }
David Tolnay570695e2017-06-03 16:15:13 -0700919 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700920 segment.to_tokens(tokens);
921 }
922 }
923 }
924
925 impl ToTokens for TyTraitObject {
926 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700927 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700928 }
929 }
930
931 impl ToTokens for TyImplTrait {
932 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700933 self.impl_token.to_tokens(tokens);
934 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700935 }
936 }
937
Michael Layzell93c36282017-06-04 20:43:14 -0400938 impl ToTokens for TyGroup {
939 fn to_tokens(&self, tokens: &mut Tokens) {
940 self.group_token.surround(tokens, |tokens| {
941 self.ty.to_tokens(tokens);
942 });
943 }
944 }
945
Alex Crichton62a0a592017-05-22 13:58:53 -0700946 impl ToTokens for TyParen {
947 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700948 self.paren_token.surround(tokens, |tokens| {
949 self.ty.to_tokens(tokens);
950 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700951 }
952 }
953
954 impl ToTokens for TyInfer {
955 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700956 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700957 }
958 }
959
David Tolnay47a877c2016-10-01 16:50:55 -0700960 impl ToTokens for Mutability {
961 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700962 if let Mutability::Mutable(ref t) = *self {
963 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700964 }
965 }
966 }
967
David Tolnay87d0b442016-09-04 11:52:12 -0700968 impl ToTokens for Path {
969 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700970 self.leading_colon.to_tokens(tokens);
971 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700972 }
973 }
974
975 impl ToTokens for PathSegment {
976 fn to_tokens(&self, tokens: &mut Tokens) {
977 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700978 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700979 }
980 }
981
982 impl ToTokens for PathParameters {
983 fn to_tokens(&self, tokens: &mut Tokens) {
984 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700985 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -0700986 PathParameters::AngleBracketed(ref parameters) => {
987 parameters.to_tokens(tokens);
988 }
989 PathParameters::Parenthesized(ref parameters) => {
990 parameters.to_tokens(tokens);
991 }
992 }
993 }
994 }
995
996 impl ToTokens for AngleBracketedParameterData {
997 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -0700998 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700999 self.lt_token.to_tokens(tokens);
1000 self.lifetimes.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001001 if !self.lifetimes.empty_or_trailing() && !self.types.is_empty() {
1002 tokens::Comma::default().to_tokens(tokens);
1003 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001004 self.types.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001005 if (
1006 // If we have no trailing delimiter after a non-empty types list, or
1007 !self.types.empty_or_trailing() ||
1008 // If we have no trailing delimiter after a non-empty lifetimes
1009 // list before an empty types list, and
1010 (self.types.is_empty() && !self.lifetimes.empty_or_trailing())) &&
1011 // We have some bindings, then we need a comma.
1012 !self.bindings.is_empty()
1013 {
1014 tokens::Comma::default().to_tokens(tokens);
1015 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001016 self.bindings.to_tokens(tokens);
1017 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001018 }
1019 }
1020
1021 impl ToTokens for TypeBinding {
1022 fn to_tokens(&self, tokens: &mut Tokens) {
1023 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001024 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001025 self.ty.to_tokens(tokens);
1026 }
1027 }
1028
1029 impl ToTokens for ParenthesizedParameterData {
1030 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001031 self.paren_token.surround(tokens, |tokens| {
1032 self.inputs.to_tokens(tokens);
1033 });
1034 self.output.to_tokens(tokens);
1035 }
1036 }
1037
1038 impl ToTokens for FunctionRetTy {
1039 fn to_tokens(&self, tokens: &mut Tokens) {
1040 match *self {
1041 FunctionRetTy::Default => {}
1042 FunctionRetTy::Ty(ref ty, ref arrow) => {
1043 arrow.to_tokens(tokens);
1044 ty.to_tokens(tokens);
1045 }
David Tolnay87d0b442016-09-04 11:52:12 -07001046 }
1047 }
1048 }
1049
1050 impl ToTokens for PolyTraitRef {
1051 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001052 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001053 self.trait_ref.to_tokens(tokens);
1054 }
1055 }
1056
1057 impl ToTokens for BareFnTy {
1058 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001059 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001060 self.unsafety.to_tokens(tokens);
1061 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001062 self.fn_token.to_tokens(tokens);
1063 self.paren_token.surround(tokens, |tokens| {
1064 self.inputs.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001065 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
1066 tokens::Comma::default().to_tokens(tokens);
1067 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001068 self.variadic.to_tokens(tokens);
1069 });
1070 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001071 }
1072 }
1073
David Tolnay62f374c2016-10-02 13:37:00 -07001074 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001075 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001076 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001077 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001078 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001079 }
1080 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001081 }
1082 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001083
1084 impl ToTokens for Unsafety {
1085 fn to_tokens(&self, tokens: &mut Tokens) {
1086 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001087 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001088 Unsafety::Normal => {
1089 // nothing
1090 }
1091 }
1092 }
1093 }
1094
1095 impl ToTokens for Abi {
1096 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001097 self.extern_token.to_tokens(tokens);
1098 match self.kind {
1099 AbiKind::Named(ref named) => named.to_tokens(tokens),
1100 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001101 }
1102 }
1103 }
David Tolnay87d0b442016-09-04 11:52:12 -07001104}