blob: 2f671a6308d3103e195cd6a11fa185c3c8bb09f4 [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.
David Tolnaydecf28d2017-11-11 11:56:45 -080080 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -070081 }
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")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400122#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
123#[cfg_attr(feature = "clone-impls", derive(Clone))]
124pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700125
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 Crichton23a15f62017-08-28 12:34:23 -0700307 pub name: Option<(BareFnArgName, tokens::Colon)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 pub ty: Ty,
309 }
310}
311
Alex Crichton23a15f62017-08-28 12:34:23 -0700312ast_enum! {
313 /// Names of arguments in the `BareFnArg` structure
314 pub enum BareFnArgName {
315 /// Argument with the provided name
316 Named(Ident),
317 /// Argument matched with `_`
318 Wild(tokens::Underscore),
319 }
320}
Alex Crichton62a0a592017-05-22 13:58:53 -0700321
322ast_enum! {
323 pub enum FunctionRetTy {
324 /// Return type is not specified.
325 ///
326 /// Functions default to `()` and
327 /// closures default to inference. Span points to where return
328 /// type would be inserted.
329 Default,
330 /// Everything else
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700331 Ty(Ty, tokens::RArrow),
Alex Crichton62a0a592017-05-22 13:58:53 -0700332 }
David Tolnayb79ee962016-09-04 09:39:20 -0700333}
334
David Tolnay86eca752016-09-04 11:26:41 -0700335#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700336pub mod parsing {
337 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400338 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700339 use synom::tokens::*;
David Tolnayda4049b2016-09-04 10:59:23 -0700340
Alex Crichton954046c2017-05-30 21:49:42 -0700341 impl Synom for Ty {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400342 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700343
Alex Crichton954046c2017-05-30 21:49:42 -0700344 fn description() -> Option<&'static str> {
345 Some("type")
346 }
347 }
David Tolnay0047c712016-12-21 21:59:25 -0500348
Michael Layzell9bf2b002017-06-04 18:49:53 -0400349 impl Ty {
350 /// In some positions, types may not contain the `+` character, to
351 /// disambiguate them. For example in the expression `1 as T`, T may not
352 /// contain a `+` character.
353 ///
354 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400355 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400356 }
357
358 named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -0400359 syn!(TyGroup) => { Ty::Group }
360 |
Michael Layzell9bf2b002017-06-04 18:49:53 -0400361 // must be before mac
362 syn!(TyParen) => { Ty::Paren }
363 |
364 // must be before path
David Tolnaydecf28d2017-11-11 11:56:45 -0800365 syn!(Macro) => { Ty::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400366 |
367 // must be before ty_poly_trait_ref
368 call!(ty_path, allow_plus)
369 |
370 syn!(TySlice) => { Ty::Slice }
371 |
372 syn!(TyArray) => { Ty::Array }
373 |
374 syn!(TyPtr) => { Ty::Ptr }
375 |
376 syn!(TyRptr) => { Ty::Rptr }
377 |
378 syn!(TyBareFn) => { Ty::BareFn }
379 |
380 syn!(TyNever) => { Ty::Never }
381 |
382 syn!(TyTup) => { Ty::Tup }
383 |
384 // Don't try parsing poly_trait_ref if we aren't allowing it
385 call!(ty_poly_trait_ref, allow_plus)
386 |
387 syn!(TyImplTrait) => { Ty::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700388 |
389 syn!(TyInfer) => { Ty::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400390 ));
391
Alex Crichton954046c2017-05-30 21:49:42 -0700392 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400393 named!(parse -> Self, map!(
394 brackets!(syn!(Ty)),
395 |(ty, b)| TySlice {
396 ty: Box::new(ty),
397 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700398 }
Michael Layzell92639a52017-06-01 00:07:44 -0400399 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700400 }
David Tolnayb79ee962016-09-04 09:39:20 -0700401
Alex Crichton954046c2017-05-30 21:49:42 -0700402 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400403 named!(parse -> Self, map!(
404 brackets!(do_parse!(
405 elem: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700406 semi: syn!(Semi) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400407 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700408 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400409 )),
410 |((elem, semi, len), brackets)| {
411 TyArray {
412 ty: Box::new(elem),
413 amt: len,
414 bracket_token: brackets,
415 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700416 }
417 }
Michael Layzell92639a52017-06-01 00:07:44 -0400418 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700419 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700420
Alex Crichton954046c2017-05-30 21:49:42 -0700421 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400422 named!(parse -> Self, do_parse!(
423 star: syn!(Star) >>
424 mutability: alt!(
425 syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
426 |
427 syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
428 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400429 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400430 (TyPtr {
431 const_token: mutability.1,
432 star_token: star,
433 ty: Box::new(MutTy {
434 ty: target,
435 mutability: mutability.0,
436 }),
437 })
438 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700439 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700440
Alex Crichton954046c2017-05-30 21:49:42 -0700441 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400442 named!(parse -> Self, do_parse!(
443 amp: syn!(And) >>
444 life: option!(syn!(Lifetime)) >>
445 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400446 // & binds tighter than +, so we don't allow + here.
447 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400448 (TyRptr {
449 lifetime: life,
450 ty: Box::new(MutTy {
451 ty: target,
452 mutability: mutability,
453 }),
454 and_token: amp,
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 TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400460 named!(parse -> Self, do_parse!(
461 lifetimes: option!(syn!(BoundLifetimes)) >>
462 unsafety: syn!(Unsafety) >>
463 abi: option!(syn!(Abi)) >>
464 fn_: syn!(Fn_) >>
465 parens: parens!(do_parse!(
466 inputs: call!(Delimited::parse_terminated) >>
467 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
468 syn!(Dot3))) >>
469 (inputs, variadic)
470 )) >>
471 output: syn!(FunctionRetTy) >>
472 (TyBareFn {
473 ty: Box::new(BareFnTy {
474 unsafety: unsafety,
475 abi: abi,
476 lifetimes: lifetimes,
477 output: output,
478 variadic: (parens.0).1,
479 fn_token: fn_,
480 paren_token: parens.1,
481 inputs: (parens.0).0,
482 }),
483 })
484 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700485 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700486
Alex Crichton954046c2017-05-30 21:49:42 -0700487 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400488 named!(parse -> Self, map!(
489 syn!(Bang),
490 |b| TyNever { bang_token: b }
491 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700492 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700493
Alex Crichton23a15f62017-08-28 12:34:23 -0700494 impl Synom for TyInfer {
495 named!(parse -> Self, map!(
496 syn!(Underscore),
497 |u| TyInfer { underscore_token: u }
498 ));
499 }
500
Alex Crichton954046c2017-05-30 21:49:42 -0700501 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400502 named!(parse -> Self, do_parse!(
503 data: parens!(call!(Delimited::parse_terminated)) >>
504 (TyTup {
505 tys: data.0,
506 paren_token: data.1,
507 lone_comma: None, // TODO: does this just not parse?
508 })
509 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700510 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700511
Michael Layzell9bf2b002017-06-04 18:49:53 -0400512 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700513 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700514 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700516 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700517 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400518 // Only allow parsing additional bounds if allow_plus is true.
519 bounds: alt!(
520 cond_reduce!(
521 allow_plus,
522 many0!(tuple!(syn!(Add), syn!(TyParamBound)))
523 )
524 |
525 value!(vec![])
526 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700527 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700528 let (qself, mut path) = qpath;
529 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700530 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 let len = path.segments.len();
532 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700533 }
David Tolnay6414da72016-10-08 00:55:17 -0700534 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700535 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700536 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800537 let path = TyParamBound::Trait(
538 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700539 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800540 trait_ref: path,
541 },
542 TraitBoundModifier::None,
543 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 let mut new_bounds = Delimited::new();
545 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700546 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700547 new_bounds.push_default(bound);
548 }
549 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700550 }
551 })
552 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700553
David Tolnay9636c052016-10-02 17:11:17 -0700554 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700555 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700556 |
557 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700558 lt: syn!(Lt) >>
David Tolnay570695e2017-06-03 16:15:13 -0700559 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700560 path: option!(do_parse!(
561 as_: syn!(As) >>
562 path: syn!(Path) >>
563 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700564 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700565 gt: syn!(Gt) >>
566 colon2: syn!(Colon2) >>
567 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700568 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400569 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700570 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700571 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700573 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700574 }
Alex Crichton954046c2017-05-30 21:49:42 -0700575 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700576 path.segments.push(item);
577 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400578 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700579 }
580 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400581 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700582 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700583 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700584 })
David Tolnay9636c052016-10-02 17:11:17 -0700585 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700586 };
587 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700588 lt_token: lt,
589 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700590 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400591 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700592 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700593 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700594 })
595 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700596 |
David Tolnaybc7d7d92017-06-03 20:54:05 -0700597 map!(syn!(Self_), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700598 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700599
Alex Crichton954046c2017-05-30 21:49:42 -0700600 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400601 named!(parse -> Self, do_parse!(
602 data: parens!(call!(Delimited::parse_terminated)) >>
603 output: syn!(FunctionRetTy) >>
604 (ParenthesizedParameterData {
605 paren_token: data.1,
606 inputs: data.0,
607 output: output,
608 })
609 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700610 }
611
612 impl Synom for FunctionRetTy {
Michael Layzell92639a52017-06-01 00:07:44 -0400613 named!(parse -> Self, alt!(
614 do_parse!(
615 arrow: syn!(RArrow) >>
616 ty: syn!(Ty) >>
617 (FunctionRetTy::Ty(ty, arrow))
618 )
619 |
620 epsilon!() => { |_| FunctionRetTy::Default }
621 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700622 }
623
Michael Layzell9bf2b002017-06-04 18:49:53 -0400624 // Only allow multiple trait references if allow_plus is true.
625 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
626 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
627 |x| TyTraitObject { bounds: x }.into()
628 }
629 |
630 syn!(TyParamBound) => {
631 |x| TyTraitObject { bounds: vec![x].into() }.into()
632 }
David Tolnay6414da72016-10-08 00:55:17 -0700633 ));
634
Alex Crichton954046c2017-05-30 21:49:42 -0700635 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400636 named!(parse -> Self, do_parse!(
637 impl_: syn!(Impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400638 // NOTE: rust-lang/rust#34511 includes discussion about whether or
639 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400640 elem: call!(Delimited::parse_separated_nonempty) >>
641 (TyImplTrait {
642 impl_token: impl_,
643 bounds: elem,
644 })
645 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700646 }
David Tolnayb79ee962016-09-04 09:39:20 -0700647
Michael Layzell93c36282017-06-04 20:43:14 -0400648 impl Synom for TyGroup {
649 named!(parse -> Self, do_parse!(
650 data: grouped!(syn!(Ty)) >>
651 (TyGroup {
652 group_token: data.1,
653 ty: Box::new(data.0),
654 })
655 ));
656 }
657
Alex Crichton954046c2017-05-30 21:49:42 -0700658 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400659 named!(parse -> Self, do_parse!(
660 data: parens!(syn!(Ty)) >>
661 (TyParen {
662 paren_token: data.1,
663 ty: Box::new(data.0),
664 })
665 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700666 }
David Tolnayb79ee962016-09-04 09:39:20 -0700667
Alex Crichton954046c2017-05-30 21:49:42 -0700668 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400669 named!(parse -> Self, alt!(
670 syn!(Mut) => { Mutability::Mutable }
671 |
672 epsilon!() => { |_| Mutability::Immutable }
673 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700674 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700675
Alex Crichton954046c2017-05-30 21:49:42 -0700676 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400677 named!(parse -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700678 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400679 segments: call!(Delimited::parse_separated_nonempty) >>
680 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700681 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400682 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400683 })
684 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700685
686 fn description() -> Option<&'static str> {
687 Some("path")
688 }
Alex Crichton954046c2017-05-30 21:49:42 -0700689 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700690
Alex Crichton954046c2017-05-30 21:49:42 -0700691 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400692 named!(parse -> Self, alt!(
693 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700694 ident: syn!(Ident) >>
695 turbofish: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400696 lt: syn!(Lt) >>
697 lifetimes: call!(Delimited::parse_terminated) >>
698 types: cond!(
699 lifetimes.is_empty() || lifetimes.trailing_delim(),
700 call!(Delimited::parse_terminated_with,
701 ty_no_eq_after)
702 ) >>
703 bindings: cond!(
704 match types {
705 Some(ref t) => t.is_empty() || t.trailing_delim(),
706 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
707 },
708 call!(Delimited::parse_terminated)
709 ) >>
710 gt: syn!(Gt) >>
711 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700712 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400713 parameters: PathParameters::AngleBracketed(
714 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700715 turbofish: turbofish,
716 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400717 lifetimes: lifetimes,
718 types: types.unwrap_or_default(),
719 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700720 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400721 }
722 ),
723 })
724 )
725 |
726 mod_style_path_segment
727 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700728 }
David Tolnay570695e2017-06-03 16:15:13 -0700729
Alex Crichton954046c2017-05-30 21:49:42 -0700730 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700731
Alex Crichton954046c2017-05-30 21:49:42 -0700732 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400733 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700734 colon: option!(syn!(Colon2)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400735 segments: call!(Delimited::parse_separated_nonempty_with,
736 mod_style_path_segment) >>
737 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700738 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400739 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400740 })
741 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700742 }
Arnavionf2dada12017-04-20 23:55:20 -0700743
744 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700745 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700746 |
Alex Crichton954046c2017-05-30 21:49:42 -0700747 alt!(
748 syn!(Super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700749 |
Alex Crichton954046c2017-05-30 21:49:42 -0700750 syn!(Self_) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700751 |
Alex Crichton954046c2017-05-30 21:49:42 -0700752 syn!(CapSelf) => { Into::into }
753 )
Arnavionf2dada12017-04-20 23:55:20 -0700754 ));
755
Alex Crichton954046c2017-05-30 21:49:42 -0700756 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400757 named!(parse -> Self, do_parse!(
758 id: syn!(Ident) >>
759 eq: syn!(Eq) >>
760 ty: syn!(Ty) >>
761 (TypeBinding {
762 ident: id,
763 eq_token: eq,
764 ty: ty,
765 })
766 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700767 }
768
769 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400770 named!(parse -> Self, do_parse!(
771 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
772 trait_ref: syn!(Path) >>
773 parenthesized: option!(cond_reduce!(
774 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
775 syn!(ParenthesizedParameterData)
776 )) >>
777 ({
778 let mut trait_ref = trait_ref;
779 if let Some(parenthesized) = parenthesized {
780 let parenthesized = PathParameters::Parenthesized(parenthesized);
781 let len = trait_ref.segments.len();
782 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
783 }
784 PolyTraitRef {
785 bound_lifetimes: bound_lifetimes,
786 trait_ref: trait_ref,
787 }
788 })
789 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700790 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700791
Alex Crichton954046c2017-05-30 21:49:42 -0700792 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400793 named!(parse -> Self, do_parse!(
794 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700795 name: syn!(BareFnArgName) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400796 not!(syn!(Colon2)) >>
797 colon: syn!(Colon) >>
798 (name, colon)
799 )) >>
800 ty: syn!(Ty) >>
801 (BareFnArg {
802 name: name,
803 ty: ty,
804 })
805 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700806 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700807
Alex Crichton23a15f62017-08-28 12:34:23 -0700808 impl Synom for BareFnArgName {
809 named!(parse -> Self, alt!(
810 map!(syn!(Ident), BareFnArgName::Named)
811 |
812 map!(syn!(Underscore), BareFnArgName::Wild)
813 ));
814 }
815
Alex Crichton954046c2017-05-30 21:49:42 -0700816 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400817 named!(parse -> Self, alt!(
818 syn!(Unsafe) => { Unsafety::Unsafe }
819 |
820 epsilon!() => { |_| Unsafety::Normal }
821 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700822 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700823
Alex Crichton954046c2017-05-30 21:49:42 -0700824 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400825 named!(parse -> Self, do_parse!(
826 extern_: syn!(Extern) >>
827 // TODO: this parses all literals, not just strings
828 name: option!(syn!(Lit)) >>
829 (Abi {
830 extern_token: extern_,
831 kind: match name {
832 Some(name) => AbiKind::Named(name),
833 None => AbiKind::Default,
834 },
835 })
836 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700837 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700838}
David Tolnay87d0b442016-09-04 11:52:12 -0700839
840#[cfg(feature = "printing")]
841mod printing {
842 use super::*;
843 use quote::{Tokens, ToTokens};
844
Alex Crichton62a0a592017-05-22 13:58:53 -0700845 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700846 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700847 self.bracket_token.surround(tokens, |tokens| {
848 self.ty.to_tokens(tokens);
849 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700850 }
851 }
852
853 impl ToTokens for TyArray {
854 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700855 self.bracket_token.surround(tokens, |tokens| {
856 self.ty.to_tokens(tokens);
857 self.semi_token.to_tokens(tokens);
858 self.amt.to_tokens(tokens);
859 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700860 }
861 }
862
863 impl ToTokens for TyPtr {
864 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700865 self.star_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400866 match self.ty.mutability {
867 Mutability::Mutable(ref tok) => tok.to_tokens(tokens),
868 Mutability::Immutable => {
Alex Crichton259ee532017-07-14 06:51:02 -0700869 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400870 }
871 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700872 self.ty.ty.to_tokens(tokens);
873 }
874 }
875
876 impl ToTokens for TyRptr {
877 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700878 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700879 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700880 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700881 self.ty.ty.to_tokens(tokens);
882 }
883 }
884
885 impl ToTokens for TyBareFn {
886 fn to_tokens(&self, tokens: &mut Tokens) {
887 self.ty.to_tokens(tokens)
888 }
889 }
890
891 impl ToTokens for TyNever {
892 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700893 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700894 }
895 }
896
897 impl ToTokens for TyTup {
898 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700899 self.paren_token.surround(tokens, |tokens| {
900 self.tys.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400901 // XXX: I don't think (,) is a thing.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700902 self.lone_comma.to_tokens(tokens);
903 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700904 }
905 }
906
907 impl ToTokens for TyPath {
908 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700909 PathTokens(&self.qself, &self.path).to_tokens(tokens);
910 }
911 }
912
913 impl<'a> ToTokens for PathTokens<'a> {
914 fn to_tokens(&self, tokens: &mut Tokens) {
915 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700916 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700917 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700918 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700919 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700920 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400921
922 // XXX: Gross.
923 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
924 self.1.segments.len() - 1
925 } else {
926 qself.position
927 };
David Tolnay570695e2017-06-03 16:15:13 -0700928 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400929 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700930 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700931 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700932 for (i, segment) in (&mut segments).take(pos).enumerate() {
933 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700934 segment.item().to_tokens(tokens);
935 qself.gt_token.to_tokens(tokens);
936 segment.delimiter().to_tokens(tokens);
937 } else {
938 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700939 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700940 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700941 } else {
942 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700943 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700944 }
David Tolnay570695e2017-06-03 16:15:13 -0700945 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700946 segment.to_tokens(tokens);
947 }
948 }
949 }
950
951 impl ToTokens for TyTraitObject {
952 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700953 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700954 }
955 }
956
957 impl ToTokens for TyImplTrait {
958 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700959 self.impl_token.to_tokens(tokens);
960 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700961 }
962 }
963
Michael Layzell93c36282017-06-04 20:43:14 -0400964 impl ToTokens for TyGroup {
965 fn to_tokens(&self, tokens: &mut Tokens) {
966 self.group_token.surround(tokens, |tokens| {
967 self.ty.to_tokens(tokens);
968 });
969 }
970 }
971
Alex Crichton62a0a592017-05-22 13:58:53 -0700972 impl ToTokens for TyParen {
973 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700974 self.paren_token.surround(tokens, |tokens| {
975 self.ty.to_tokens(tokens);
976 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700977 }
978 }
979
980 impl ToTokens for TyInfer {
981 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700982 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700983 }
984 }
985
David Tolnay47a877c2016-10-01 16:50:55 -0700986 impl ToTokens for Mutability {
987 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700988 if let Mutability::Mutable(ref t) = *self {
989 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700990 }
991 }
992 }
993
David Tolnay87d0b442016-09-04 11:52:12 -0700994 impl ToTokens for Path {
995 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700996 self.leading_colon.to_tokens(tokens);
997 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700998 }
999 }
1000
1001 impl ToTokens for PathSegment {
1002 fn to_tokens(&self, tokens: &mut Tokens) {
1003 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001004 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001005 }
1006 }
1007
1008 impl ToTokens for PathParameters {
1009 fn to_tokens(&self, tokens: &mut Tokens) {
1010 match *self {
David Tolnay570695e2017-06-03 16:15:13 -07001011 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -07001012 PathParameters::AngleBracketed(ref parameters) => {
1013 parameters.to_tokens(tokens);
1014 }
1015 PathParameters::Parenthesized(ref parameters) => {
1016 parameters.to_tokens(tokens);
1017 }
1018 }
1019 }
1020 }
1021
1022 impl ToTokens for AngleBracketedParameterData {
1023 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -07001024 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001025 self.lt_token.to_tokens(tokens);
1026 self.lifetimes.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001027 if !self.lifetimes.empty_or_trailing() && !self.types.is_empty() {
1028 tokens::Comma::default().to_tokens(tokens);
1029 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001030 self.types.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001031 if (
1032 // If we have no trailing delimiter after a non-empty types list, or
1033 !self.types.empty_or_trailing() ||
1034 // If we have no trailing delimiter after a non-empty lifetimes
1035 // list before an empty types list, and
1036 (self.types.is_empty() && !self.lifetimes.empty_or_trailing())) &&
1037 // We have some bindings, then we need a comma.
1038 !self.bindings.is_empty()
1039 {
1040 tokens::Comma::default().to_tokens(tokens);
1041 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001042 self.bindings.to_tokens(tokens);
1043 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001044 }
1045 }
1046
1047 impl ToTokens for TypeBinding {
1048 fn to_tokens(&self, tokens: &mut Tokens) {
1049 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001050 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001051 self.ty.to_tokens(tokens);
1052 }
1053 }
1054
1055 impl ToTokens for ParenthesizedParameterData {
1056 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001057 self.paren_token.surround(tokens, |tokens| {
1058 self.inputs.to_tokens(tokens);
1059 });
1060 self.output.to_tokens(tokens);
1061 }
1062 }
1063
1064 impl ToTokens for FunctionRetTy {
1065 fn to_tokens(&self, tokens: &mut Tokens) {
1066 match *self {
1067 FunctionRetTy::Default => {}
1068 FunctionRetTy::Ty(ref ty, ref arrow) => {
1069 arrow.to_tokens(tokens);
1070 ty.to_tokens(tokens);
1071 }
David Tolnay87d0b442016-09-04 11:52:12 -07001072 }
1073 }
1074 }
1075
1076 impl ToTokens for PolyTraitRef {
1077 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001078 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001079 self.trait_ref.to_tokens(tokens);
1080 }
1081 }
1082
1083 impl ToTokens for BareFnTy {
1084 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001085 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001086 self.unsafety.to_tokens(tokens);
1087 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001088 self.fn_token.to_tokens(tokens);
1089 self.paren_token.surround(tokens, |tokens| {
1090 self.inputs.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001091 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
1092 tokens::Comma::default().to_tokens(tokens);
1093 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001094 self.variadic.to_tokens(tokens);
1095 });
1096 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001097 }
1098 }
1099
David Tolnay62f374c2016-10-02 13:37:00 -07001100 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001101 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001102 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001103 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001104 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001105 }
1106 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001107 }
1108 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001109
Alex Crichton23a15f62017-08-28 12:34:23 -07001110 impl ToTokens for BareFnArgName {
1111 fn to_tokens(&self, tokens: &mut Tokens) {
1112 match *self {
1113 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1114 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1115 }
1116 }
1117 }
1118
David Tolnayb8d8ef52016-10-29 14:30:08 -07001119 impl ToTokens for Unsafety {
1120 fn to_tokens(&self, tokens: &mut Tokens) {
1121 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001122 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001123 Unsafety::Normal => {
1124 // nothing
1125 }
1126 }
1127 }
1128 }
1129
1130 impl ToTokens for Abi {
1131 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001132 self.extern_token.to_tokens(tokens);
1133 match self.kind {
1134 AbiKind::Named(ref named) => named.to_tokens(tokens),
1135 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001136 }
1137 }
1138 }
David Tolnay87d0b442016-09-04 11:52:12 -07001139}