blob: 1f9717e8f2dd5e4961ce2d28ee0fe1facc237e63 [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 }),
69 /// TyKind::Infer means the type should be inferred instead of it having been
70 /// specified. This can appear anywhere in a type.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070071 pub Infer(TyInfer {
72 pub underscore_token: tokens::Underscore
73 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070074 /// A macro in the type position.
75 pub Mac(Mac),
76 }
77}
78
79ast_struct! {
80 pub struct MutTy {
81 pub ty: Ty,
82 pub mutability: Mutability,
83 }
84}
85
86ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -070087 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070088 pub enum Mutability {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070089 Mutable(tokens::Mut),
Alex Crichton62a0a592017-05-22 13:58:53 -070090 Immutable,
91 }
92}
93
94ast_struct! {
95 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -070096 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070097 /// It's represented as a sequence of identifiers,
98 /// along with a bunch of supporting information.
99 ///
100 /// E.g. `std::cmp::PartialEq`
101 pub struct Path {
102 /// A `::foo` path, is relative to the crate root rather than current
103 /// module (like paths in an import).
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700104 pub leading_colon: Option<tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 /// The segments in the path: the things separated by `::`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700106 pub segments: Delimited<PathSegment, tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700107 }
David Tolnayb79ee962016-09-04 09:39:20 -0700108}
109
David Tolnay570695e2017-06-03 16:15:13 -0700110impl Path {
111 pub fn global(&self) -> bool {
112 self.leading_colon.is_some()
113 }
114}
115
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116#[cfg(feature = "printing")]
117ast_struct! {
118 pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
119}
120
David Tolnaydaaf7742016-10-03 11:11:43 -0700121impl<T> From<T> for Path
122 where T: Into<PathSegment>
123{
David Tolnay84aa0752016-10-02 23:01:13 -0700124 fn from(segment: T) -> Self {
125 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126 leading_colon: None,
127 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700128 }
129 }
130}
131
Alex Crichton62a0a592017-05-22 13:58:53 -0700132ast_struct! {
133 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
134 ///
135 /// E.g. `std`, `String` or `Box<T>`
136 pub struct PathSegment {
137 /// The identifier portion of this path segment.
138 pub ident: Ident,
139 /// Type/lifetime parameters attached to this path. They come in
140 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
141 /// this is more than just simple syntactic sugar; the use of
142 /// parens affects the region binding rules, so we preserve the
143 /// distinction.
144 pub parameters: PathParameters,
145 }
David Tolnayb79ee962016-09-04 09:39:20 -0700146}
147
David Tolnaydaaf7742016-10-03 11:11:43 -0700148impl<T> From<T> for PathSegment
149 where T: Into<Ident>
150{
David Tolnay84aa0752016-10-02 23:01:13 -0700151 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700152 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700153 ident: ident.into(),
David Tolnay570695e2017-06-03 16:15:13 -0700154 parameters: PathParameters::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700155 }
156 }
157}
158
Alex Crichton62a0a592017-05-22 13:58:53 -0700159ast_enum! {
160 /// Parameters of a path segment.
161 ///
162 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
163 pub enum PathParameters {
David Tolnay570695e2017-06-03 16:15:13 -0700164 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700165 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
166 AngleBracketed(AngleBracketedParameterData),
167 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
168 Parenthesized(ParenthesizedParameterData),
169 }
David Tolnayb79ee962016-09-04 09:39:20 -0700170}
171
David Tolnay570695e2017-06-03 16:15:13 -0700172impl Default for PathParameters {
173 fn default() -> Self {
174 PathParameters::None
David Tolnayb79ee962016-09-04 09:39:20 -0700175 }
David Tolnay570695e2017-06-03 16:15:13 -0700176}
David Tolnay5332d4b2016-10-30 14:25:22 -0700177
David Tolnay570695e2017-06-03 16:15:13 -0700178impl PathParameters {
David Tolnay5332d4b2016-10-30 14:25:22 -0700179 pub fn is_empty(&self) -> bool {
180 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700181 PathParameters::None => true,
David Tolnay5332d4b2016-10-30 14:25:22 -0700182 PathParameters::AngleBracketed(ref bracketed) => {
David Tolnayc1fea502016-10-30 17:54:02 -0700183 bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
184 bracketed.bindings.is_empty()
David Tolnay5332d4b2016-10-30 14:25:22 -0700185 }
186 PathParameters::Parenthesized(_) => false,
187 }
188 }
David Tolnayb79ee962016-09-04 09:39:20 -0700189}
190
Alex Crichton62a0a592017-05-22 13:58:53 -0700191ast_struct! {
192 /// A path like `Foo<'a, T>`
Alex Crichton62a0a592017-05-22 13:58:53 -0700193 pub struct AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700194 pub turbofish: Option<tokens::Colon2>,
195 pub lt_token: tokens::Lt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// The lifetime parameters for this path segment.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700197 pub lifetimes: Delimited<Lifetime, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 /// The type parameters for this path segment, if present.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700199 pub types: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700200 /// Bindings (equality constraints) on associated types, if present.
201 ///
202 /// E.g., `Foo<A=Bar>`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700203 pub bindings: Delimited<TypeBinding, tokens::Comma>,
David Tolnay570695e2017-06-03 16:15:13 -0700204 pub gt_token: tokens::Gt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 }
206}
207
208ast_struct! {
209 /// Bind a type to an associated type: `A=Foo`.
210 pub struct TypeBinding {
211 pub ident: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700212 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub ty: Ty,
214 }
215}
216
217
218ast_struct! {
219 /// A path like `Foo(A,B) -> C`
220 pub struct ParenthesizedParameterData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700221 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 /// `(A, B)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700223 pub inputs: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700224 /// `C`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700225 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700226 }
227}
228
229ast_struct! {
230 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 /// The `for<'a>` in `for<'a> Foo<&'a T>`
232 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700233 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
234 pub trait_ref: Path,
235 }
236}
237
238ast_struct! {
239 /// The explicit Self type in a "qualified path". The actual
240 /// path, including the trait and the associated item, is stored
241 /// separately. `position` represents the index of the associated
242 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700243 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700244 /// ```rust,ignore
245 /// <Vec<T> as a::b::Trait>::AssociatedItem
246 /// ^~~~~ ~~~~~~~~~~~~~~^
247 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700248 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 /// <Vec<T>>::AssociatedItem
250 /// ^~~~~ ^
251 /// ty position = 0
252 /// ```
253 pub struct QSelf {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700254 pub lt_token: tokens::Lt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700255 pub ty: Box<Ty>,
David Tolnay570695e2017-06-03 16:15:13 -0700256 pub position: Option<(tokens::As, usize)>,
257 pub gt_token: tokens::Gt,
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 }
259}
260
261ast_struct! {
262 pub struct BareFnTy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700263 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700264 pub unsafety: Unsafety,
265 pub abi: Option<Abi>,
Alex Crichton954046c2017-05-30 21:49:42 -0700266 pub fn_token: tokens::Fn_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700267 pub paren_token: tokens::Paren,
268 pub inputs: Delimited<BareFnArg, tokens::Comma>,
269 pub variadic: Option<tokens::Dot3>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 }
272}
273
274ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700275 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700276 pub enum Unsafety {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700277 Unsafe(tokens::Unsafe),
Alex Crichton62a0a592017-05-22 13:58:53 -0700278 Normal,
279 }
280}
281
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700282ast_struct! {
283 pub struct Abi {
284 pub extern_token: tokens::Extern,
285 pub kind: AbiKind,
286 }
287}
288
Alex Crichton62a0a592017-05-22 13:58:53 -0700289ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 pub enum AbiKind {
291 Named(Lit),
292 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 }
294}
295
296ast_struct! {
297 /// An argument in a function type.
298 ///
299 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
300 pub struct BareFnArg {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700301 pub name: Option<(Ident, tokens::Colon)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700302 pub ty: Ty,
303 }
304}
305
306
307ast_enum! {
308 pub enum FunctionRetTy {
309 /// Return type is not specified.
310 ///
311 /// Functions default to `()` and
312 /// closures default to inference. Span points to where return
313 /// type would be inserted.
314 Default,
315 /// Everything else
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700316 Ty(Ty, tokens::RArrow),
Alex Crichton62a0a592017-05-22 13:58:53 -0700317 }
David Tolnayb79ee962016-09-04 09:39:20 -0700318}
319
David Tolnay86eca752016-09-04 11:26:41 -0700320#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700321pub mod parsing {
322 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400323 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700324 use synom::tokens::*;
David Tolnayda4049b2016-09-04 10:59:23 -0700325
Alex Crichton954046c2017-05-30 21:49:42 -0700326 impl Synom for Ty {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400327 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700328
Alex Crichton954046c2017-05-30 21:49:42 -0700329 fn description() -> Option<&'static str> {
330 Some("type")
331 }
332 }
David Tolnay0047c712016-12-21 21:59:25 -0500333
Michael Layzell9bf2b002017-06-04 18:49:53 -0400334 impl Ty {
335 /// In some positions, types may not contain the `+` character, to
336 /// disambiguate them. For example in the expression `1 as T`, T may not
337 /// contain a `+` character.
338 ///
339 /// This parser does not allow a `+`, while the default parser does.
340 named!(without_plus -> Self, call!(ambig_ty, false));
341 }
342
343 named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
344 // must be before mac
345 syn!(TyParen) => { Ty::Paren }
346 |
347 // must be before path
348 syn!(Mac) => { Ty::Mac }
349 |
350 // must be before ty_poly_trait_ref
351 call!(ty_path, allow_plus)
352 |
353 syn!(TySlice) => { Ty::Slice }
354 |
355 syn!(TyArray) => { Ty::Array }
356 |
357 syn!(TyPtr) => { Ty::Ptr }
358 |
359 syn!(TyRptr) => { Ty::Rptr }
360 |
361 syn!(TyBareFn) => { Ty::BareFn }
362 |
363 syn!(TyNever) => { Ty::Never }
364 |
365 syn!(TyTup) => { Ty::Tup }
366 |
367 // Don't try parsing poly_trait_ref if we aren't allowing it
368 call!(ty_poly_trait_ref, allow_plus)
369 |
370 syn!(TyImplTrait) => { Ty::ImplTrait }
371 ));
372
Alex Crichton954046c2017-05-30 21:49:42 -0700373 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400374 named!(parse -> Self, map!(
375 brackets!(syn!(Ty)),
376 |(ty, b)| TySlice {
377 ty: Box::new(ty),
378 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700379 }
Michael Layzell92639a52017-06-01 00:07:44 -0400380 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700381 }
David Tolnayb79ee962016-09-04 09:39:20 -0700382
Alex Crichton954046c2017-05-30 21:49:42 -0700383 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400384 named!(parse -> Self, map!(
385 brackets!(do_parse!(
386 elem: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700387 semi: syn!(Semi) >>
388 len: array_len >>
389 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400390 )),
391 |((elem, semi, len), brackets)| {
392 TyArray {
393 ty: Box::new(elem),
394 amt: len,
395 bracket_token: brackets,
396 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700397 }
398 }
Michael Layzell92639a52017-06-01 00:07:44 -0400399 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700400 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700401
David Tolnay514f1292017-02-27 12:30:57 -0800402 #[cfg(not(feature = "full"))]
Alex Crichton954046c2017-05-30 21:49:42 -0700403 named!(array_len -> ConstExpr, syn!(ConstExpr));
David Tolnay514f1292017-02-27 12:30:57 -0800404
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700405 #[cfg(feature = "full")]
David Tolnay514f1292017-02-27 12:30:57 -0800406 named!(array_len -> ConstExpr, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700407 terminated!(syn!(ConstExpr), input_end!())
David Tolnay514f1292017-02-27 12:30:57 -0800408 |
Alex Crichton954046c2017-05-30 21:49:42 -0700409 terminated!(syn!(Expr), input_end!()) => { ConstExpr::Other }
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700410 ));
411
Alex Crichton954046c2017-05-30 21:49:42 -0700412 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400413 named!(parse -> Self, do_parse!(
414 star: syn!(Star) >>
415 mutability: alt!(
416 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
417 |
418 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
419 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400420 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400421 (TyPtr {
422 const_token: mutability.1,
423 star_token: star,
424 ty: Box::new(MutTy {
425 ty: target,
426 mutability: mutability.0,
427 }),
428 })
429 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700430 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700431
Alex Crichton954046c2017-05-30 21:49:42 -0700432 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400433 named!(parse -> Self, do_parse!(
434 amp: syn!(And) >>
435 life: option!(syn!(Lifetime)) >>
436 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400437 // & binds tighter than +, so we don't allow + here.
438 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400439 (TyRptr {
440 lifetime: life,
441 ty: Box::new(MutTy {
442 ty: target,
443 mutability: mutability,
444 }),
445 and_token: amp,
446 })
447 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700448 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700449
Alex Crichton954046c2017-05-30 21:49:42 -0700450 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400451 named!(parse -> Self, do_parse!(
452 lifetimes: option!(syn!(BoundLifetimes)) >>
453 unsafety: syn!(Unsafety) >>
454 abi: option!(syn!(Abi)) >>
455 fn_: syn!(Fn_) >>
456 parens: parens!(do_parse!(
457 inputs: call!(Delimited::parse_terminated) >>
458 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
459 syn!(Dot3))) >>
460 (inputs, variadic)
461 )) >>
462 output: syn!(FunctionRetTy) >>
463 (TyBareFn {
464 ty: Box::new(BareFnTy {
465 unsafety: unsafety,
466 abi: abi,
467 lifetimes: lifetimes,
468 output: output,
469 variadic: (parens.0).1,
470 fn_token: fn_,
471 paren_token: parens.1,
472 inputs: (parens.0).0,
473 }),
474 })
475 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700476 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700477
Alex Crichton954046c2017-05-30 21:49:42 -0700478 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400479 named!(parse -> Self, map!(
480 syn!(Bang),
481 |b| TyNever { bang_token: b }
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 TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400486 named!(parse -> Self, do_parse!(
487 data: parens!(call!(Delimited::parse_terminated)) >>
488 (TyTup {
489 tys: data.0,
490 paren_token: data.1,
491 lone_comma: None, // TODO: does this just not parse?
492 })
493 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700494 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700495
Michael Layzell9bf2b002017-06-04 18:49:53 -0400496 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700497 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700498 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700499 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700500 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700501 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400502 // Only allow parsing additional bounds if allow_plus is true.
503 bounds: alt!(
504 cond_reduce!(
505 allow_plus,
506 many0!(tuple!(syn!(Add), syn!(TyParamBound)))
507 )
508 |
509 value!(vec![])
510 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700511 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700512 let (qself, mut path) = qpath;
513 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700514 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 let len = path.segments.len();
516 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700517 }
David Tolnay6414da72016-10-08 00:55:17 -0700518 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700519 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700520 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800521 let path = TyParamBound::Trait(
522 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700523 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800524 trait_ref: path,
525 },
526 TraitBoundModifier::None,
527 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700528 let mut new_bounds = Delimited::new();
529 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700530 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 new_bounds.push_default(bound);
532 }
533 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700534 }
535 })
536 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700537
David Tolnay9636c052016-10-02 17:11:17 -0700538 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700539 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700540 |
541 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700542 lt: syn!(Lt) >>
David Tolnay570695e2017-06-03 16:15:13 -0700543 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700544 path: option!(do_parse!(
545 as_: syn!(As) >>
546 path: syn!(Path) >>
547 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700548 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700549 gt: syn!(Gt) >>
550 colon2: syn!(Colon2) >>
551 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700552 ({
David Tolnay570695e2017-06-03 16:15:13 -0700553 let (pos, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700554 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700555 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700557 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 }
Alex Crichton954046c2017-05-30 21:49:42 -0700559 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700560 path.segments.push(item);
561 }
David Tolnay570695e2017-06-03 16:15:13 -0700562 (Some((as_, pos)), path)
David Tolnay9636c052016-10-02 17:11:17 -0700563 }
564 None => {
David Tolnay570695e2017-06-03 16:15:13 -0700565 (None, Path {
566 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700567 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700568 })
David Tolnay9636c052016-10-02 17:11:17 -0700569 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700570 };
571 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700572 lt_token: lt,
573 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700574 position: pos,
Alex Crichton954046c2017-05-30 21:49:42 -0700575 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700576 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700577 })
578 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700579 |
David Tolnaybc7d7d92017-06-03 20:54:05 -0700580 map!(syn!(Self_), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700581 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700582
Alex Crichton954046c2017-05-30 21:49:42 -0700583 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400584 named!(parse -> Self, do_parse!(
585 data: parens!(call!(Delimited::parse_terminated)) >>
586 output: syn!(FunctionRetTy) >>
587 (ParenthesizedParameterData {
588 paren_token: data.1,
589 inputs: data.0,
590 output: output,
591 })
592 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700593 }
594
595 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400596 named!(parse -> Self, alt!(
597 do_parse!(
598 arrow: syn!(RArrow) >>
599 ty: syn!(Ty) >>
600 (FunctionRetTy::Ty(ty, arrow))
601 )
602 |
603 epsilon!() => { |_| FunctionRetTy::Default }
604 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700605 }
606
Michael Layzell9bf2b002017-06-04 18:49:53 -0400607 // Only allow multiple trait references if allow_plus is true.
608 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
609 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
610 |x| TyTraitObject { bounds: x }.into()
611 }
612 |
613 syn!(TyParamBound) => {
614 |x| TyTraitObject { bounds: vec![x].into() }.into()
615 }
David Tolnay6414da72016-10-08 00:55:17 -0700616 ));
617
Alex Crichton954046c2017-05-30 21:49:42 -0700618 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400619 named!(parse -> Self, do_parse!(
620 impl_: syn!(Impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400621 // NOTE: rust-lang/rust#34511 includes discussion about whether or
622 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400623 elem: call!(Delimited::parse_separated_nonempty) >>
624 (TyImplTrait {
625 impl_token: impl_,
626 bounds: elem,
627 })
628 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700629 }
David Tolnayb79ee962016-09-04 09:39:20 -0700630
Alex Crichton954046c2017-05-30 21:49:42 -0700631 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400632 named!(parse -> Self, do_parse!(
633 data: parens!(syn!(Ty)) >>
634 (TyParen {
635 paren_token: data.1,
636 ty: Box::new(data.0),
637 })
638 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700639 }
David Tolnayb79ee962016-09-04 09:39:20 -0700640
Alex Crichton954046c2017-05-30 21:49:42 -0700641 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400642 named!(parse -> Self, alt!(
643 syn!(Mut) => { Mutability::Mutable }
644 |
645 epsilon!() => { |_| Mutability::Immutable }
646 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700647 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700648
Alex Crichton954046c2017-05-30 21:49:42 -0700649 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400650 named!(parse -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700651 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400652 segments: call!(Delimited::parse_separated_nonempty) >>
653 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700654 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400655 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400656 })
657 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700658 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700659
Alex Crichton954046c2017-05-30 21:49:42 -0700660 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400661 named!(parse -> Self, alt!(
662 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700663 ident: syn!(Ident) >>
664 turbofish: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400665 lt: syn!(Lt) >>
666 lifetimes: call!(Delimited::parse_terminated) >>
667 types: cond!(
668 lifetimes.is_empty() || lifetimes.trailing_delim(),
669 call!(Delimited::parse_terminated_with,
670 ty_no_eq_after)
671 ) >>
672 bindings: cond!(
673 match types {
674 Some(ref t) => t.is_empty() || t.trailing_delim(),
675 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
676 },
677 call!(Delimited::parse_terminated)
678 ) >>
679 gt: syn!(Gt) >>
680 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700681 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400682 parameters: PathParameters::AngleBracketed(
683 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700684 turbofish: turbofish,
685 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400686 lifetimes: lifetimes,
687 types: types.unwrap_or_default(),
688 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700689 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400690 }
691 ),
692 })
693 )
694 |
695 mod_style_path_segment
696 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700697 }
David Tolnay570695e2017-06-03 16:15:13 -0700698
Alex Crichton954046c2017-05-30 21:49:42 -0700699 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700700
Alex Crichton954046c2017-05-30 21:49:42 -0700701 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400702 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700703 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400704 segments: call!(Delimited::parse_separated_nonempty_with,
705 mod_style_path_segment) >>
706 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700707 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400708 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400709 })
710 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700711 }
Arnavionf2dada12017-04-20 23:55:20 -0700712
713 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700714 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700715 |
Alex Crichton954046c2017-05-30 21:49:42 -0700716 alt!(
717 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700718 |
Alex Crichton954046c2017-05-30 21:49:42 -0700719 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700720 |
Alex Crichton954046c2017-05-30 21:49:42 -0700721 syn!(CapSelf) => { Into::into }
722 )
Arnavionf2dada12017-04-20 23:55:20 -0700723 ));
724
Alex Crichton954046c2017-05-30 21:49:42 -0700725 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400726 named!(parse -> Self, do_parse!(
727 id: syn!(Ident) >>
728 eq: syn!(Eq) >>
729 ty: syn!(Ty) >>
730 (TypeBinding {
731 ident: id,
732 eq_token: eq,
733 ty: ty,
734 })
735 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700736 }
737
738 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400739 named!(parse -> Self, do_parse!(
740 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
741 trait_ref: syn!(Path) >>
742 parenthesized: option!(cond_reduce!(
743 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
744 syn!(ParenthesizedParameterData)
745 )) >>
746 ({
747 let mut trait_ref = trait_ref;
748 if let Some(parenthesized) = parenthesized {
749 let parenthesized = PathParameters::Parenthesized(parenthesized);
750 let len = trait_ref.segments.len();
751 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
752 }
753 PolyTraitRef {
754 bound_lifetimes: bound_lifetimes,
755 trait_ref: trait_ref,
756 }
757 })
758 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700759 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700760
Alex Crichton954046c2017-05-30 21:49:42 -0700761 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400762 named!(parse -> Self, do_parse!(
763 name: option!(do_parse!(
764 name: syn!(Ident) >>
765 not!(syn!(Colon2)) >>
766 colon: syn!(Colon) >>
767 (name, colon)
768 )) >>
769 ty: syn!(Ty) >>
770 (BareFnArg {
771 name: name,
772 ty: ty,
773 })
774 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700775 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700776
Alex Crichton954046c2017-05-30 21:49:42 -0700777 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400778 named!(parse -> Self, alt!(
779 syn!(Unsafe) => { Unsafety::Unsafe }
780 |
781 epsilon!() => { |_| Unsafety::Normal }
782 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700783 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700784
Alex Crichton954046c2017-05-30 21:49:42 -0700785 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400786 named!(parse -> Self, do_parse!(
787 extern_: syn!(Extern) >>
788 // TODO: this parses all literals, not just strings
789 name: option!(syn!(Lit)) >>
790 (Abi {
791 extern_token: extern_,
792 kind: match name {
793 Some(name) => AbiKind::Named(name),
794 None => AbiKind::Default,
795 },
796 })
797 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700798 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700799}
David Tolnay87d0b442016-09-04 11:52:12 -0700800
801#[cfg(feature = "printing")]
802mod printing {
803 use super::*;
804 use quote::{Tokens, ToTokens};
805
Alex Crichton62a0a592017-05-22 13:58:53 -0700806 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700807 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700808 self.bracket_token.surround(tokens, |tokens| {
809 self.ty.to_tokens(tokens);
810 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700811 }
812 }
813
814 impl ToTokens for TyArray {
815 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700816 self.bracket_token.surround(tokens, |tokens| {
817 self.ty.to_tokens(tokens);
818 self.semi_token.to_tokens(tokens);
819 self.amt.to_tokens(tokens);
820 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700821 }
822 }
823
824 impl ToTokens for TyPtr {
825 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700826 self.star_token.to_tokens(tokens);
827 self.const_token.to_tokens(tokens);
828 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700829 self.ty.ty.to_tokens(tokens);
830 }
831 }
832
833 impl ToTokens for TyRptr {
834 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700835 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700836 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700837 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700838 self.ty.ty.to_tokens(tokens);
839 }
840 }
841
842 impl ToTokens for TyBareFn {
843 fn to_tokens(&self, tokens: &mut Tokens) {
844 self.ty.to_tokens(tokens)
845 }
846 }
847
848 impl ToTokens for TyNever {
849 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700850 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700851 }
852 }
853
854 impl ToTokens for TyTup {
855 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700856 self.paren_token.surround(tokens, |tokens| {
857 self.tys.to_tokens(tokens);
858 self.lone_comma.to_tokens(tokens);
859 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700860 }
861 }
862
863 impl ToTokens for TyPath {
864 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700865 PathTokens(&self.qself, &self.path).to_tokens(tokens);
866 }
867 }
868
869 impl<'a> ToTokens for PathTokens<'a> {
870 fn to_tokens(&self, tokens: &mut Tokens) {
871 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700872 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700873 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700874 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700875 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700876 qself.ty.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700877 let mut segments = self.1.segments.iter();
David Tolnayb99e1b02017-06-03 19:00:55 -0700878 if let Some((ref as_token, pos)) = qself.position {
David Tolnay570695e2017-06-03 16:15:13 -0700879 as_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700880 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700881 for (i, segment) in (&mut segments).take(pos).enumerate() {
882 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700883 segment.item().to_tokens(tokens);
884 qself.gt_token.to_tokens(tokens);
885 segment.delimiter().to_tokens(tokens);
886 } else {
887 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700888 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700889 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700890 } else {
891 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700892 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700893 }
David Tolnay570695e2017-06-03 16:15:13 -0700894 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700895 segment.to_tokens(tokens);
896 }
897 }
898 }
899
900 impl ToTokens for TyTraitObject {
901 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700902 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700903 }
904 }
905
906 impl ToTokens for TyImplTrait {
907 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700908 self.impl_token.to_tokens(tokens);
909 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700910 }
911 }
912
913 impl ToTokens for TyParen {
914 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700915 self.paren_token.surround(tokens, |tokens| {
916 self.ty.to_tokens(tokens);
917 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700918 }
919 }
920
921 impl ToTokens for TyInfer {
922 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700923 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700924 }
925 }
926
David Tolnay47a877c2016-10-01 16:50:55 -0700927 impl ToTokens for Mutability {
928 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700929 if let Mutability::Mutable(ref t) = *self {
930 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700931 }
932 }
933 }
934
David Tolnay87d0b442016-09-04 11:52:12 -0700935 impl ToTokens for Path {
936 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700937 self.leading_colon.to_tokens(tokens);
938 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700939 }
940 }
941
942 impl ToTokens for PathSegment {
943 fn to_tokens(&self, tokens: &mut Tokens) {
944 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700945 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700946 }
947 }
948
949 impl ToTokens for PathParameters {
950 fn to_tokens(&self, tokens: &mut Tokens) {
951 match *self {
David Tolnay570695e2017-06-03 16:15:13 -0700952 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -0700953 PathParameters::AngleBracketed(ref parameters) => {
954 parameters.to_tokens(tokens);
955 }
956 PathParameters::Parenthesized(ref parameters) => {
957 parameters.to_tokens(tokens);
958 }
959 }
960 }
961 }
962
963 impl ToTokens for AngleBracketedParameterData {
964 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -0700965 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700966 self.lt_token.to_tokens(tokens);
967 self.lifetimes.to_tokens(tokens);
968 self.types.to_tokens(tokens);
969 self.bindings.to_tokens(tokens);
970 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700971 }
972 }
973
974 impl ToTokens for TypeBinding {
975 fn to_tokens(&self, tokens: &mut Tokens) {
976 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700977 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700978 self.ty.to_tokens(tokens);
979 }
980 }
981
982 impl ToTokens for ParenthesizedParameterData {
983 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700984 self.paren_token.surround(tokens, |tokens| {
985 self.inputs.to_tokens(tokens);
986 });
987 self.output.to_tokens(tokens);
988 }
989 }
990
991 impl ToTokens for FunctionRetTy {
992 fn to_tokens(&self, tokens: &mut Tokens) {
993 match *self {
994 FunctionRetTy::Default => {}
995 FunctionRetTy::Ty(ref ty, ref arrow) => {
996 arrow.to_tokens(tokens);
997 ty.to_tokens(tokens);
998 }
David Tolnay87d0b442016-09-04 11:52:12 -0700999 }
1000 }
1001 }
1002
1003 impl ToTokens for PolyTraitRef {
1004 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001005 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001006 self.trait_ref.to_tokens(tokens);
1007 }
1008 }
1009
1010 impl ToTokens for BareFnTy {
1011 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001012 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001013 self.unsafety.to_tokens(tokens);
1014 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001015 self.fn_token.to_tokens(tokens);
1016 self.paren_token.surround(tokens, |tokens| {
1017 self.inputs.to_tokens(tokens);
1018 self.variadic.to_tokens(tokens);
1019 });
1020 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001021 }
1022 }
1023
David Tolnay62f374c2016-10-02 13:37:00 -07001024 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001025 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001026 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001027 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001028 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001029 }
1030 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001031 }
1032 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001033
1034 impl ToTokens for Unsafety {
1035 fn to_tokens(&self, tokens: &mut Tokens) {
1036 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001037 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001038 Unsafety::Normal => {
1039 // nothing
1040 }
1041 }
1042 }
1043 }
1044
1045 impl ToTokens for Abi {
1046 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001047 self.extern_token.to_tokens(tokens);
1048 match self.kind {
1049 AbiKind::Named(ref named) => named.to_tokens(tokens),
1050 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001051 }
1052 }
1053 }
David Tolnay87d0b442016-09-04 11:52:12 -07001054}