blob: 284ffb350bc5f081bdbf2e4565ff2965f0c6bdbe [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).
104 pub global: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub leading_colon: Option<tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 /// The segments in the path: the things separated by `::`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700107 pub segments: Delimited<PathSegment, tokens::Colon2>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700108 }
David Tolnayb79ee962016-09-04 09:39:20 -0700109}
110
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700111#[cfg(feature = "printing")]
112ast_struct! {
113 pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
114}
115
David Tolnaydaaf7742016-10-03 11:11:43 -0700116impl<T> From<T> for Path
117 where T: Into<PathSegment>
118{
David Tolnay84aa0752016-10-02 23:01:13 -0700119 fn from(segment: T) -> Self {
120 Path {
121 global: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700122 leading_colon: None,
123 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700124 }
125 }
126}
127
Alex Crichton62a0a592017-05-22 13:58:53 -0700128ast_struct! {
129 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
130 ///
131 /// E.g. `std`, `String` or `Box<T>`
132 pub struct PathSegment {
133 /// The identifier portion of this path segment.
134 pub ident: Ident,
135 /// Type/lifetime parameters attached to this path. They come in
136 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
137 /// this is more than just simple syntactic sugar; the use of
138 /// parens affects the region binding rules, so we preserve the
139 /// distinction.
140 pub parameters: PathParameters,
141 }
David Tolnayb79ee962016-09-04 09:39:20 -0700142}
143
David Tolnaydaaf7742016-10-03 11:11:43 -0700144impl<T> From<T> for PathSegment
145 where T: Into<Ident>
146{
David Tolnay84aa0752016-10-02 23:01:13 -0700147 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700148 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700149 ident: ident.into(),
David Tolnayb79ee962016-09-04 09:39:20 -0700150 parameters: PathParameters::none(),
151 }
152 }
153}
154
Alex Crichton62a0a592017-05-22 13:58:53 -0700155ast_enum! {
156 /// Parameters of a path segment.
157 ///
158 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
159 pub enum PathParameters {
160 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
161 AngleBracketed(AngleBracketedParameterData),
162 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
163 Parenthesized(ParenthesizedParameterData),
164 }
David Tolnayb79ee962016-09-04 09:39:20 -0700165}
166
167impl PathParameters {
168 pub fn none() -> Self {
169 PathParameters::AngleBracketed(AngleBracketedParameterData::default())
170 }
David Tolnay5332d4b2016-10-30 14:25:22 -0700171
172 pub fn is_empty(&self) -> bool {
173 match *self {
174 PathParameters::AngleBracketed(ref bracketed) => {
David Tolnayc1fea502016-10-30 17:54:02 -0700175 bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
176 bracketed.bindings.is_empty()
David Tolnay5332d4b2016-10-30 14:25:22 -0700177 }
178 PathParameters::Parenthesized(_) => false,
179 }
180 }
David Tolnayb79ee962016-09-04 09:39:20 -0700181}
182
Alex Crichton62a0a592017-05-22 13:58:53 -0700183ast_struct! {
184 /// A path like `Foo<'a, T>`
185 #[derive(Default)]
186 pub struct AngleBracketedParameterData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700187 pub lt_token: Option<tokens::Lt>,
188 pub gt_token: Option<tokens::Gt>,
189
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 /// The lifetime parameters for this path segment.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700191 pub lifetimes: Delimited<Lifetime, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 /// The type parameters for this path segment, if present.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700193 pub types: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 /// Bindings (equality constraints) on associated types, if present.
195 ///
196 /// E.g., `Foo<A=Bar>`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700197 pub bindings: Delimited<TypeBinding, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 }
199}
200
201ast_struct! {
202 /// Bind a type to an associated type: `A=Foo`.
203 pub struct TypeBinding {
204 pub ident: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700205 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700206 pub ty: Ty,
207 }
208}
209
210
211ast_struct! {
212 /// A path like `Foo(A,B) -> C`
213 pub struct ParenthesizedParameterData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700214 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700215 /// `(A, B)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700216 pub inputs: Delimited<Ty, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700217 /// `C`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700218 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700219 }
220}
221
222ast_struct! {
223 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700224 /// The `for<'a>` in `for<'a> Foo<&'a T>`
225 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700226 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
227 pub trait_ref: Path,
228 }
229}
230
231ast_struct! {
232 /// The explicit Self type in a "qualified path". The actual
233 /// path, including the trait and the associated item, is stored
234 /// separately. `position` represents the index of the associated
235 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700236 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700237 /// ```rust,ignore
238 /// <Vec<T> as a::b::Trait>::AssociatedItem
239 /// ^~~~~ ~~~~~~~~~~~~~~^
240 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700241 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 /// <Vec<T>>::AssociatedItem
243 /// ^~~~~ ^
244 /// ty position = 0
245 /// ```
246 pub struct QSelf {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 pub lt_token: tokens::Lt,
248 pub gt_token: tokens::Gt,
249 pub as_token: Option<tokens::As>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 pub ty: Box<Ty>,
251 pub position: usize,
252 }
253}
254
255ast_struct! {
256 pub struct BareFnTy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700257 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 pub unsafety: Unsafety,
259 pub abi: Option<Abi>,
Alex Crichton954046c2017-05-30 21:49:42 -0700260 pub fn_token: tokens::Fn_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700261 pub paren_token: tokens::Paren,
262 pub inputs: Delimited<BareFnArg, tokens::Comma>,
263 pub variadic: Option<tokens::Dot3>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700264 pub output: FunctionRetTy,
Alex Crichton62a0a592017-05-22 13:58:53 -0700265 }
266}
267
268ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700269 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub enum Unsafety {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700271 Unsafe(tokens::Unsafe),
Alex Crichton62a0a592017-05-22 13:58:53 -0700272 Normal,
273 }
274}
275
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700276ast_struct! {
277 pub struct Abi {
278 pub extern_token: tokens::Extern,
279 pub kind: AbiKind,
280 }
281}
282
Alex Crichton62a0a592017-05-22 13:58:53 -0700283ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 pub enum AbiKind {
285 Named(Lit),
286 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 }
288}
289
290ast_struct! {
291 /// An argument in a function type.
292 ///
293 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
294 pub struct BareFnArg {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700295 pub name: Option<(Ident, tokens::Colon)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 pub ty: Ty,
297 }
298}
299
300
301ast_enum! {
302 pub enum FunctionRetTy {
303 /// Return type is not specified.
304 ///
305 /// Functions default to `()` and
306 /// closures default to inference. Span points to where return
307 /// type would be inserted.
308 Default,
309 /// Everything else
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700310 Ty(Ty, tokens::RArrow),
Alex Crichton62a0a592017-05-22 13:58:53 -0700311 }
David Tolnayb79ee962016-09-04 09:39:20 -0700312}
313
David Tolnay86eca752016-09-04 11:26:41 -0700314#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700315pub mod parsing {
316 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400317 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700318 use synom::tokens::*;
David Tolnayda4049b2016-09-04 10:59:23 -0700319
Alex Crichton954046c2017-05-30 21:49:42 -0700320 impl Synom for Ty {
Michael Layzell92639a52017-06-01 00:07:44 -0400321 named!(parse -> Self, alt!(
322 // must be before mac
323 syn!(TyParen) => { Ty::Paren }
324 |
325 // must be before path
326 syn!(Mac) => { Ty::Mac }
327 |
328 // must be before ty_poly_trait_ref
329 ty_path
330 |
331 syn!(TySlice) => { Ty::Slice }
332 |
333 syn!(TyArray) => { Ty::Array }
334 |
335 syn!(TyPtr) => { Ty::Ptr }
336 |
337 syn!(TyRptr) => { Ty::Rptr }
338 |
339 syn!(TyBareFn) => { Ty::BareFn }
340 |
341 syn!(TyNever) => { Ty::Never }
342 |
343 syn!(TyTup) => { Ty::Tup }
344 |
345 ty_poly_trait_ref
346 |
347 syn!(TyImplTrait) => { Ty::ImplTrait }
348 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700349
Alex Crichton954046c2017-05-30 21:49:42 -0700350 fn description() -> Option<&'static str> {
351 Some("type")
352 }
353 }
David Tolnay0047c712016-12-21 21:59:25 -0500354
Alex Crichton954046c2017-05-30 21:49:42 -0700355 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400356 named!(parse -> Self, map!(
357 brackets!(syn!(Ty)),
358 |(ty, b)| TySlice {
359 ty: Box::new(ty),
360 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700361 }
Michael Layzell92639a52017-06-01 00:07:44 -0400362 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700363 }
David Tolnayb79ee962016-09-04 09:39:20 -0700364
Alex Crichton954046c2017-05-30 21:49:42 -0700365 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400366 named!(parse -> Self, map!(
367 brackets!(do_parse!(
368 elem: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700369 semi: syn!(Semi) >>
370 len: array_len >>
371 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400372 )),
373 |((elem, semi, len), brackets)| {
374 TyArray {
375 ty: Box::new(elem),
376 amt: len,
377 bracket_token: brackets,
378 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700379 }
380 }
Michael Layzell92639a52017-06-01 00:07:44 -0400381 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700382 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700383
David Tolnay514f1292017-02-27 12:30:57 -0800384 #[cfg(not(feature = "full"))]
Alex Crichton954046c2017-05-30 21:49:42 -0700385 named!(array_len -> ConstExpr, syn!(ConstExpr));
David Tolnay514f1292017-02-27 12:30:57 -0800386
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700387 #[cfg(feature = "full")]
David Tolnay514f1292017-02-27 12:30:57 -0800388 named!(array_len -> ConstExpr, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700389 terminated!(syn!(ConstExpr), input_end!())
David Tolnay514f1292017-02-27 12:30:57 -0800390 |
Alex Crichton954046c2017-05-30 21:49:42 -0700391 terminated!(syn!(Expr), input_end!()) => { ConstExpr::Other }
David Tolnayfe2cc9a2016-10-30 12:47:36 -0700392 ));
393
Alex Crichton954046c2017-05-30 21:49:42 -0700394 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400395 named!(parse -> Self, do_parse!(
396 star: syn!(Star) >>
397 mutability: alt!(
398 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
399 |
400 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
401 ) >>
402 target: syn!(Ty) >>
403 (TyPtr {
404 const_token: mutability.1,
405 star_token: star,
406 ty: Box::new(MutTy {
407 ty: target,
408 mutability: mutability.0,
409 }),
410 })
411 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700412 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700413
Alex Crichton954046c2017-05-30 21:49:42 -0700414 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400415 named!(parse -> Self, do_parse!(
416 amp: syn!(And) >>
417 life: option!(syn!(Lifetime)) >>
418 mutability: syn!(Mutability) >>
419 target: syn!(Ty) >>
420 (TyRptr {
421 lifetime: life,
422 ty: Box::new(MutTy {
423 ty: target,
424 mutability: mutability,
425 }),
426 and_token: amp,
427 })
428 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700429 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700430
Alex Crichton954046c2017-05-30 21:49:42 -0700431 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400432 named!(parse -> Self, do_parse!(
433 lifetimes: option!(syn!(BoundLifetimes)) >>
434 unsafety: syn!(Unsafety) >>
435 abi: option!(syn!(Abi)) >>
436 fn_: syn!(Fn_) >>
437 parens: parens!(do_parse!(
438 inputs: call!(Delimited::parse_terminated) >>
439 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
440 syn!(Dot3))) >>
441 (inputs, variadic)
442 )) >>
443 output: syn!(FunctionRetTy) >>
444 (TyBareFn {
445 ty: Box::new(BareFnTy {
446 unsafety: unsafety,
447 abi: abi,
448 lifetimes: lifetimes,
449 output: output,
450 variadic: (parens.0).1,
451 fn_token: fn_,
452 paren_token: parens.1,
453 inputs: (parens.0).0,
454 }),
455 })
456 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700457 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700458
Alex Crichton954046c2017-05-30 21:49:42 -0700459 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400460 named!(parse -> Self, map!(
461 syn!(Bang),
462 |b| TyNever { bang_token: b }
463 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700464 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700465
Alex Crichton954046c2017-05-30 21:49:42 -0700466 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400467 named!(parse -> Self, do_parse!(
468 data: parens!(call!(Delimited::parse_terminated)) >>
469 (TyTup {
470 tys: data.0,
471 paren_token: data.1,
472 lone_comma: None, // TODO: does this just not parse?
473 })
474 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700475 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700476
David Tolnay6414da72016-10-08 00:55:17 -0700477 named!(ty_path -> Ty, do_parse!(
478 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700479 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700481 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700482 ) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700483 bounds: many0!(tuple!(syn!(Add), syn!(TyParamBound))) >>
David Tolnay6414da72016-10-08 00:55:17 -0700484 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700485 let (qself, mut path) = qpath;
486 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700487 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700488 let len = path.segments.len();
489 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700490 }
David Tolnay6414da72016-10-08 00:55:17 -0700491 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700492 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700493 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800494 let path = TyParamBound::Trait(
495 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700496 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800497 trait_ref: path,
498 },
499 TraitBoundModifier::None,
500 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700501 let mut new_bounds = Delimited::new();
502 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700503 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700504 new_bounds.push_default(bound);
505 }
506 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700507 }
508 })
509 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700510
David Tolnay9636c052016-10-02 17:11:17 -0700511 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700512 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700513 |
514 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700515 lt: syn!(Lt) >>
516 this: map!(syn!(Ty), Box::new) >>
517 path: option!(do_parse!(
518 as_: syn!(As) >>
519 path: syn!(Path) >>
520 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700521 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700522 gt: syn!(Gt) >>
523 colon2: syn!(Colon2) >>
524 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700525 ({
Alex Crichton954046c2017-05-30 21:49:42 -0700526 let (pos, path, as_) = match path {
527 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700528 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700529 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700530 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 }
Alex Crichton954046c2017-05-30 21:49:42 -0700532 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700533 path.segments.push(item);
534 }
Alex Crichton954046c2017-05-30 21:49:42 -0700535 (pos, path, Some(as_))
David Tolnay9636c052016-10-02 17:11:17 -0700536 }
537 None => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 (0, Path {
539 leading_colon: None,
David Tolnay9636c052016-10-02 17:11:17 -0700540 global: false,
541 segments: rest,
Alex Crichton954046c2017-05-30 21:49:42 -0700542 }, None)
David Tolnay9636c052016-10-02 17:11:17 -0700543 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 };
545 (Some(QSelf {
546 ty: this,
547 position: pos,
Alex Crichton954046c2017-05-30 21:49:42 -0700548 gt_token: gt,
549 lt_token: lt,
550 as_token: as_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700551 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700552 })
553 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700554 |
Alex Crichton954046c2017-05-30 21:49:42 -0700555 map!(syn!(Self_), |s: Self_| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700556 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700557
Alex Crichton954046c2017-05-30 21:49:42 -0700558 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400559 named!(parse -> Self, do_parse!(
560 data: parens!(call!(Delimited::parse_terminated)) >>
561 output: syn!(FunctionRetTy) >>
562 (ParenthesizedParameterData {
563 paren_token: data.1,
564 inputs: data.0,
565 output: output,
566 })
567 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700568 }
569
570 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400571 named!(parse -> Self, alt!(
572 do_parse!(
573 arrow: syn!(RArrow) >>
574 ty: syn!(Ty) >>
575 (FunctionRetTy::Ty(ty, arrow))
576 )
577 |
578 epsilon!() => { |_| FunctionRetTy::Default }
579 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700580 }
581
David Tolnay4f0f2512016-10-30 09:28:14 -0700582 named!(ty_poly_trait_ref -> Ty, map!(
Alex Crichton954046c2017-05-30 21:49:42 -0700583 call!(Delimited::parse_separated_nonempty),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 |x| TyTraitObject { bounds: x }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700585 ));
586
Alex Crichton954046c2017-05-30 21:49:42 -0700587 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400588 named!(parse -> Self, do_parse!(
589 impl_: syn!(Impl) >>
590 elem: call!(Delimited::parse_separated_nonempty) >>
591 (TyImplTrait {
592 impl_token: impl_,
593 bounds: elem,
594 })
595 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700596 }
David Tolnayb79ee962016-09-04 09:39:20 -0700597
Alex Crichton954046c2017-05-30 21:49:42 -0700598 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400599 named!(parse -> Self, do_parse!(
600 data: parens!(syn!(Ty)) >>
601 (TyParen {
602 paren_token: data.1,
603 ty: Box::new(data.0),
604 })
605 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700606 }
David Tolnayb79ee962016-09-04 09:39:20 -0700607
Alex Crichton954046c2017-05-30 21:49:42 -0700608 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400609 named!(parse -> Self, alt!(
610 syn!(Mut) => { Mutability::Mutable }
611 |
612 epsilon!() => { |_| Mutability::Immutable }
613 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700614 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700615
Alex Crichton954046c2017-05-30 21:49:42 -0700616 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400617 named!(parse -> Self, do_parse!(
618 global: option!(syn!(Colon2)) >>
619 segments: call!(Delimited::parse_separated_nonempty) >>
620 (Path {
621 global: global.is_some(),
622 segments: segments,
623 leading_colon: global,
624 })
625 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700626 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700627
Alex Crichton954046c2017-05-30 21:49:42 -0700628 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400629 named!(parse -> Self, alt!(
630 do_parse!(
631 id: option!(syn!(Ident)) >>
632 lt: syn!(Lt) >>
633 lifetimes: call!(Delimited::parse_terminated) >>
634 types: cond!(
635 lifetimes.is_empty() || lifetimes.trailing_delim(),
636 call!(Delimited::parse_terminated_with,
637 ty_no_eq_after)
638 ) >>
639 bindings: cond!(
640 match types {
641 Some(ref t) => t.is_empty() || t.trailing_delim(),
642 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
643 },
644 call!(Delimited::parse_terminated)
645 ) >>
646 gt: syn!(Gt) >>
647 (PathSegment {
648 ident: id.unwrap_or_else(|| "".into()),
649 parameters: PathParameters::AngleBracketed(
650 AngleBracketedParameterData {
651 gt_token: Some(gt),
652 lt_token: Some(lt),
653 lifetimes: lifetimes,
654 types: types.unwrap_or_default(),
655 bindings: bindings.unwrap_or_default(),
656 }
657 ),
658 })
659 )
660 |
661 mod_style_path_segment
662 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700663 }
664 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700665
Alex Crichton954046c2017-05-30 21:49:42 -0700666 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400667 named!(pub parse_mod_style -> Self, do_parse!(
668 global: option!(syn!(Colon2)) >>
669 segments: call!(Delimited::parse_separated_nonempty_with,
670 mod_style_path_segment) >>
671 (Path {
672 global: global.is_some(),
673 segments: segments,
674 leading_colon: global,
675 })
676 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700677 }
Arnavionf2dada12017-04-20 23:55:20 -0700678
679 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700680 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700681 |
Alex Crichton954046c2017-05-30 21:49:42 -0700682 alt!(
683 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700684 |
Alex Crichton954046c2017-05-30 21:49:42 -0700685 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700686 |
Alex Crichton954046c2017-05-30 21:49:42 -0700687 syn!(CapSelf) => { Into::into }
688 )
Arnavionf2dada12017-04-20 23:55:20 -0700689 ));
690
Alex Crichton954046c2017-05-30 21:49:42 -0700691 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400692 named!(parse -> Self, do_parse!(
693 id: syn!(Ident) >>
694 eq: syn!(Eq) >>
695 ty: syn!(Ty) >>
696 (TypeBinding {
697 ident: id,
698 eq_token: eq,
699 ty: ty,
700 })
701 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700702 }
703
704 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400705 named!(parse -> Self, do_parse!(
706 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
707 trait_ref: syn!(Path) >>
708 parenthesized: option!(cond_reduce!(
709 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
710 syn!(ParenthesizedParameterData)
711 )) >>
712 ({
713 let mut trait_ref = trait_ref;
714 if let Some(parenthesized) = parenthesized {
715 let parenthesized = PathParameters::Parenthesized(parenthesized);
716 let len = trait_ref.segments.len();
717 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
718 }
719 PolyTraitRef {
720 bound_lifetimes: bound_lifetimes,
721 trait_ref: trait_ref,
722 }
723 })
724 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700725 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700726
Alex Crichton954046c2017-05-30 21:49:42 -0700727 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400728 named!(parse -> Self, do_parse!(
729 name: option!(do_parse!(
730 name: syn!(Ident) >>
731 not!(syn!(Colon2)) >>
732 colon: syn!(Colon) >>
733 (name, colon)
734 )) >>
735 ty: syn!(Ty) >>
736 (BareFnArg {
737 name: name,
738 ty: ty,
739 })
740 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700741 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700742
Alex Crichton954046c2017-05-30 21:49:42 -0700743 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400744 named!(parse -> Self, alt!(
745 syn!(Unsafe) => { Unsafety::Unsafe }
746 |
747 epsilon!() => { |_| Unsafety::Normal }
748 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700749 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700750
Alex Crichton954046c2017-05-30 21:49:42 -0700751 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400752 named!(parse -> Self, do_parse!(
753 extern_: syn!(Extern) >>
754 // TODO: this parses all literals, not just strings
755 name: option!(syn!(Lit)) >>
756 (Abi {
757 extern_token: extern_,
758 kind: match name {
759 Some(name) => AbiKind::Named(name),
760 None => AbiKind::Default,
761 },
762 })
763 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700764 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700765}
David Tolnay87d0b442016-09-04 11:52:12 -0700766
767#[cfg(feature = "printing")]
768mod printing {
769 use super::*;
770 use quote::{Tokens, ToTokens};
771
Alex Crichton62a0a592017-05-22 13:58:53 -0700772 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700773 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700774 self.bracket_token.surround(tokens, |tokens| {
775 self.ty.to_tokens(tokens);
776 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700777 }
778 }
779
780 impl ToTokens for TyArray {
781 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700782 self.bracket_token.surround(tokens, |tokens| {
783 self.ty.to_tokens(tokens);
784 self.semi_token.to_tokens(tokens);
785 self.amt.to_tokens(tokens);
786 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700787 }
788 }
789
790 impl ToTokens for TyPtr {
791 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700792 self.star_token.to_tokens(tokens);
793 self.const_token.to_tokens(tokens);
794 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700795 self.ty.ty.to_tokens(tokens);
796 }
797 }
798
799 impl ToTokens for TyRptr {
800 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700801 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700802 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700803 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700804 self.ty.ty.to_tokens(tokens);
805 }
806 }
807
808 impl ToTokens for TyBareFn {
809 fn to_tokens(&self, tokens: &mut Tokens) {
810 self.ty.to_tokens(tokens)
811 }
812 }
813
814 impl ToTokens for TyNever {
815 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700816 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700817 }
818 }
819
820 impl ToTokens for TyTup {
821 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700822 self.paren_token.surround(tokens, |tokens| {
823 self.tys.to_tokens(tokens);
824 self.lone_comma.to_tokens(tokens);
825 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700826 }
827 }
828
829 impl ToTokens for TyPath {
830 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700831 PathTokens(&self.qself, &self.path).to_tokens(tokens);
832 }
833 }
834
835 impl<'a> ToTokens for PathTokens<'a> {
836 fn to_tokens(&self, tokens: &mut Tokens) {
837 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700838 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700839 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700840 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700841 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700842 qself.ty.to_tokens(tokens);
843 if qself.position > 0 {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700844 qself.as_token.to_tokens(tokens);
845 self.1.leading_colon.to_tokens(tokens);
846 for (i, segment) in self.1.segments
Alex Crichton62a0a592017-05-22 13:58:53 -0700847 .iter()
848 .take(qself.position)
849 .enumerate() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700850 if i == qself.position - 1 {
851 segment.item().to_tokens(tokens);
852 qself.gt_token.to_tokens(tokens);
853 segment.delimiter().to_tokens(tokens);
854 } else {
855 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700856 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700857 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700858 } else {
859 qself.gt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700860 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700861 for segment in self.1.segments.iter().skip(qself.position) {
Alex Crichton62a0a592017-05-22 13:58:53 -0700862 segment.to_tokens(tokens);
863 }
864 }
865 }
866
867 impl ToTokens for TyTraitObject {
868 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700869 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700870 }
871 }
872
873 impl ToTokens for TyImplTrait {
874 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700875 self.impl_token.to_tokens(tokens);
876 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700877 }
878 }
879
880 impl ToTokens for TyParen {
881 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700882 self.paren_token.surround(tokens, |tokens| {
883 self.ty.to_tokens(tokens);
884 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700885 }
886 }
887
888 impl ToTokens for TyInfer {
889 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700890 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700891 }
892 }
893
David Tolnay47a877c2016-10-01 16:50:55 -0700894 impl ToTokens for Mutability {
895 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700896 if let Mutability::Mutable(ref t) = *self {
897 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700898 }
899 }
900 }
901
David Tolnay87d0b442016-09-04 11:52:12 -0700902 impl ToTokens for Path {
903 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700904 self.leading_colon.to_tokens(tokens);
905 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700906 }
907 }
908
909 impl ToTokens for PathSegment {
910 fn to_tokens(&self, tokens: &mut Tokens) {
911 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700912 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700913 }
914 }
915
916 impl ToTokens for PathParameters {
917 fn to_tokens(&self, tokens: &mut Tokens) {
918 match *self {
919 PathParameters::AngleBracketed(ref parameters) => {
920 parameters.to_tokens(tokens);
921 }
922 PathParameters::Parenthesized(ref parameters) => {
923 parameters.to_tokens(tokens);
924 }
925 }
926 }
927 }
928
929 impl ToTokens for AngleBracketedParameterData {
930 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700931 self.lt_token.to_tokens(tokens);
932 self.lifetimes.to_tokens(tokens);
933 self.types.to_tokens(tokens);
934 self.bindings.to_tokens(tokens);
935 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700936 }
937 }
938
939 impl ToTokens for TypeBinding {
940 fn to_tokens(&self, tokens: &mut Tokens) {
941 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700942 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700943 self.ty.to_tokens(tokens);
944 }
945 }
946
947 impl ToTokens for ParenthesizedParameterData {
948 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700949 self.paren_token.surround(tokens, |tokens| {
950 self.inputs.to_tokens(tokens);
951 });
952 self.output.to_tokens(tokens);
953 }
954 }
955
956 impl ToTokens for FunctionRetTy {
957 fn to_tokens(&self, tokens: &mut Tokens) {
958 match *self {
959 FunctionRetTy::Default => {}
960 FunctionRetTy::Ty(ref ty, ref arrow) => {
961 arrow.to_tokens(tokens);
962 ty.to_tokens(tokens);
963 }
David Tolnay87d0b442016-09-04 11:52:12 -0700964 }
965 }
966 }
967
968 impl ToTokens for PolyTraitRef {
969 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700970 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700971 self.trait_ref.to_tokens(tokens);
972 }
973 }
974
975 impl ToTokens for BareFnTy {
976 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700977 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -0700978 self.unsafety.to_tokens(tokens);
979 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700980 self.fn_token.to_tokens(tokens);
981 self.paren_token.surround(tokens, |tokens| {
982 self.inputs.to_tokens(tokens);
983 self.variadic.to_tokens(tokens);
984 });
985 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700986 }
987 }
988
David Tolnay62f374c2016-10-02 13:37:00 -0700989 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -0700990 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700991 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700992 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700993 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700994 }
995 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700996 }
997 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700998
999 impl ToTokens for Unsafety {
1000 fn to_tokens(&self, tokens: &mut Tokens) {
1001 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001002 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001003 Unsafety::Normal => {
1004 // nothing
1005 }
1006 }
1007 }
1008 }
1009
1010 impl ToTokens for Abi {
1011 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001012 self.extern_token.to_tokens(tokens);
1013 match self.kind {
1014 AbiKind::Named(ref named) => named.to_tokens(tokens),
1015 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001016 }
1017 }
1018 }
David Tolnay87d0b442016-09-04 11:52:12 -07001019}