blob: 33211764b0cafa3ef41e80c03879f5ae83acad2a [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>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080016 pub semi_token: Token![;],
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 pub star_token: Token![*],
22 pub const_token: Option<Token![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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080027 pub and_token: Token![&],
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080037 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070038 }),
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,
David Tolnayf8db7ba2017-11-11 22:52:16 -080042 pub tys: Delimited<Ty, Token![,]>,
43 pub lone_comma: Option<Token![,]>,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080056 pub bounds: Delimited<TyParamBound, Token![+]>,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080061 pub impl_token: Token![impl],
62 pub bounds: Delimited<TyParamBound, Token![+]>,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080077 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070078 }),
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080094 Mutable(Token![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).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800109 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 /// The segments in the path: the things separated by `::`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800111 pub segments: Delimited<PathSegment, Token![::]>,
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 Tolnayf8db7ba2017-11-11 22:52:16 -0800199 pub turbofish: Option<Token![::]>,
200 pub lt_token: Token![<],
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 /// The lifetime parameters for this path segment.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800202 pub lifetimes: Delimited<Lifetime, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 /// The type parameters for this path segment, if present.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800204 pub types: Delimited<Ty, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// Bindings (equality constraints) on associated types, if present.
206 ///
207 /// E.g., `Foo<A=Bar>`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800208 pub bindings: Delimited<TypeBinding, Token![,]>,
209 pub gt_token: Token![>],
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,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800217 pub eq_token: Token![=],
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)`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800228 pub inputs: Delimited<Ty, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800230 pub output: ReturnType,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800259 pub lt_token: Token![<],
Alex Crichton62a0a592017-05-22 13:58:53 -0700260 pub ty: Box<Ty>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400261 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800262 pub as_token: Option<Token![as]>,
263 pub gt_token: Token![>],
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>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800272 pub fn_token: Token![fn],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700273 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800274 pub inputs: Delimited<BareFnArg, Token![,]>,
275 pub variadic: Option<Token![...]>,
David Tolnayf93b90d2017-11-11 19:21:26 -0800276 pub output: ReturnType,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800283 Unsafe(Token![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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800290 pub extern_token: Token![extern],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700291 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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800307 pub name: Option<(BareFnArgName, Token![:])>,
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 `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800318 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700319 }
320}
Alex Crichton62a0a592017-05-22 13:58:53 -0700321
322ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800323 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 /// 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
David Tolnayf8db7ba2017-11-11 22:52:16 -0800331 Ty(Ty, Token![->]),
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;
David Tolnayda4049b2016-09-04 10:59:23 -0700339
Alex Crichton954046c2017-05-30 21:49:42 -0700340 impl Synom for Ty {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400341 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700342
Alex Crichton954046c2017-05-30 21:49:42 -0700343 fn description() -> Option<&'static str> {
344 Some("type")
345 }
346 }
David Tolnay0047c712016-12-21 21:59:25 -0500347
Michael Layzell9bf2b002017-06-04 18:49:53 -0400348 impl Ty {
349 /// In some positions, types may not contain the `+` character, to
350 /// disambiguate them. For example in the expression `1 as T`, T may not
351 /// contain a `+` character.
352 ///
353 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400354 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400355 }
356
357 named!(ambig_ty(allow_plus: bool) -> Ty, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -0400358 syn!(TyGroup) => { Ty::Group }
359 |
Michael Layzell9bf2b002017-06-04 18:49:53 -0400360 // must be before mac
361 syn!(TyParen) => { Ty::Paren }
362 |
363 // must be before path
David Tolnaydecf28d2017-11-11 11:56:45 -0800364 syn!(Macro) => { Ty::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400365 |
366 // must be before ty_poly_trait_ref
367 call!(ty_path, allow_plus)
368 |
369 syn!(TySlice) => { Ty::Slice }
370 |
371 syn!(TyArray) => { Ty::Array }
372 |
373 syn!(TyPtr) => { Ty::Ptr }
374 |
375 syn!(TyRptr) => { Ty::Rptr }
376 |
377 syn!(TyBareFn) => { Ty::BareFn }
378 |
379 syn!(TyNever) => { Ty::Never }
380 |
381 syn!(TyTup) => { Ty::Tup }
382 |
383 // Don't try parsing poly_trait_ref if we aren't allowing it
384 call!(ty_poly_trait_ref, allow_plus)
385 |
386 syn!(TyImplTrait) => { Ty::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700387 |
388 syn!(TyInfer) => { Ty::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400389 ));
390
Alex Crichton954046c2017-05-30 21:49:42 -0700391 impl Synom for TySlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400392 named!(parse -> Self, map!(
393 brackets!(syn!(Ty)),
394 |(ty, b)| TySlice {
395 ty: Box::new(ty),
396 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700397 }
Michael Layzell92639a52017-06-01 00:07:44 -0400398 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700399 }
David Tolnayb79ee962016-09-04 09:39:20 -0700400
Alex Crichton954046c2017-05-30 21:49:42 -0700401 impl Synom for TyArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400402 named!(parse -> Self, map!(
403 brackets!(do_parse!(
404 elem: syn!(Ty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800405 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400406 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700407 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400408 )),
409 |((elem, semi, len), brackets)| {
410 TyArray {
411 ty: Box::new(elem),
412 amt: len,
413 bracket_token: brackets,
414 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700415 }
416 }
Michael Layzell92639a52017-06-01 00:07:44 -0400417 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700418 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700419
Alex Crichton954046c2017-05-30 21:49:42 -0700420 impl Synom for TyPtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400421 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800422 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400423 mutability: alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800424 keyword!(const) => { |c| (Mutability::Immutable, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400425 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800426 keyword!(mut) => { |m| (Mutability::Mutable(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400427 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400428 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400429 (TyPtr {
430 const_token: mutability.1,
431 star_token: star,
432 ty: Box::new(MutTy {
433 ty: target,
434 mutability: mutability.0,
435 }),
436 })
437 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700438 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700439
Alex Crichton954046c2017-05-30 21:49:42 -0700440 impl Synom for TyRptr {
Michael Layzell92639a52017-06-01 00:07:44 -0400441 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800442 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400443 life: option!(syn!(Lifetime)) >>
444 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400445 // & binds tighter than +, so we don't allow + here.
446 target: call!(Ty::without_plus) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400447 (TyRptr {
448 lifetime: life,
449 ty: Box::new(MutTy {
450 ty: target,
451 mutability: mutability,
452 }),
453 and_token: amp,
454 })
455 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700456 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700457
Alex Crichton954046c2017-05-30 21:49:42 -0700458 impl Synom for TyBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400459 named!(parse -> Self, do_parse!(
460 lifetimes: option!(syn!(BoundLifetimes)) >>
461 unsafety: syn!(Unsafety) >>
462 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800463 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400464 parens: parens!(do_parse!(
465 inputs: call!(Delimited::parse_terminated) >>
466 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800467 punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400468 (inputs, variadic)
469 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800470 output: syn!(ReturnType) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400471 (TyBareFn {
472 ty: Box::new(BareFnTy {
473 unsafety: unsafety,
474 abi: abi,
475 lifetimes: lifetimes,
476 output: output,
477 variadic: (parens.0).1,
478 fn_token: fn_,
479 paren_token: parens.1,
480 inputs: (parens.0).0,
481 }),
482 })
483 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700484 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700485
Alex Crichton954046c2017-05-30 21:49:42 -0700486 impl Synom for TyNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400487 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800488 punct!(!),
Michael Layzell92639a52017-06-01 00:07:44 -0400489 |b| TyNever { bang_token: b }
490 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700491 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700492
Alex Crichton23a15f62017-08-28 12:34:23 -0700493 impl Synom for TyInfer {
494 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800495 punct!(_),
Alex Crichton23a15f62017-08-28 12:34:23 -0700496 |u| TyInfer { underscore_token: u }
497 ));
498 }
499
Alex Crichton954046c2017-05-30 21:49:42 -0700500 impl Synom for TyTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400501 named!(parse -> Self, do_parse!(
502 data: parens!(call!(Delimited::parse_terminated)) >>
503 (TyTup {
504 tys: data.0,
505 paren_token: data.1,
506 lone_comma: None, // TODO: does this just not parse?
507 })
508 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700509 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700510
Michael Layzell9bf2b002017-06-04 18:49:53 -0400511 named!(ty_path(allow_plus: bool) -> Ty, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700512 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700513 parenthesized: cond!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700514 qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
Alex Crichton954046c2017-05-30 21:49:42 -0700515 option!(syn!(ParenthesizedParameterData))
David Tolnayf6c74402016-10-08 02:31:26 -0700516 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400517 // Only allow parsing additional bounds if allow_plus is true.
518 bounds: alt!(
519 cond_reduce!(
520 allow_plus,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800521 many0!(tuple!(punct!(+), syn!(TyParamBound)))
Michael Layzell9bf2b002017-06-04 18:49:53 -0400522 )
523 |
524 value!(vec![])
525 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700526 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700527 let (qself, mut path) = qpath;
528 if let Some(Some(parenthesized)) = parenthesized {
Alex Crichton954046c2017-05-30 21:49:42 -0700529 let parenthesized = PathParameters::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 let len = path.segments.len();
531 path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700532 }
David Tolnay6414da72016-10-08 00:55:17 -0700533 if bounds.is_empty() {
Alex Crichton62a0a592017-05-22 13:58:53 -0700534 TyPath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700535 } else {
David Tolnay02c907f2017-01-23 00:06:37 -0800536 let path = TyParamBound::Trait(
537 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800539 trait_ref: path,
540 },
541 TraitBoundModifier::None,
542 );
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700543 let mut new_bounds = Delimited::new();
544 new_bounds.push_first(path);
Alex Crichton954046c2017-05-30 21:49:42 -0700545 for (_tok, bound) in bounds {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 new_bounds.push_default(bound);
547 }
548 TyTraitObject { bounds: new_bounds }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700549 }
550 })
551 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700552
David Tolnay9636c052016-10-02 17:11:17 -0700553 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700554 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700555 |
556 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800557 lt: punct!(<) >>
David Tolnay570695e2017-06-03 16:15:13 -0700558 this: syn!(Ty) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700559 path: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800560 as_: keyword!(as) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700561 path: syn!(Path) >>
562 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700563 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800564 gt: punct!(>) >>
565 colon2: punct!(::) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700566 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700567 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400568 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700569 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700570 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700571 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700572 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700573 }
Alex Crichton954046c2017-05-30 21:49:42 -0700574 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 path.segments.push(item);
576 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400577 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700578 }
579 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400580 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700581 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700582 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700583 })
David Tolnay9636c052016-10-02 17:11:17 -0700584 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700585 };
586 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700587 lt_token: lt,
588 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700589 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400590 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700591 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700592 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700593 })
594 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700595 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800596 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700597 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700598
Alex Crichton954046c2017-05-30 21:49:42 -0700599 impl Synom for ParenthesizedParameterData {
Michael Layzell92639a52017-06-01 00:07:44 -0400600 named!(parse -> Self, do_parse!(
601 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800602 output: syn!(ReturnType) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400603 (ParenthesizedParameterData {
604 paren_token: data.1,
605 inputs: data.0,
606 output: output,
607 })
608 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700609 }
610
David Tolnayf93b90d2017-11-11 19:21:26 -0800611 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400612 named!(parse -> Self, alt!(
613 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800614 arrow: punct!(->) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400615 ty: syn!(Ty) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800616 (ReturnType::Ty(ty, arrow))
Michael Layzell92639a52017-06-01 00:07:44 -0400617 )
618 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800619 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400620 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700621 }
622
Michael Layzell9bf2b002017-06-04 18:49:53 -0400623 // Only allow multiple trait references if allow_plus is true.
624 named!(ty_poly_trait_ref(allow_plus: bool) -> Ty, alt!(
625 cond_reduce!(allow_plus, call!(Delimited::parse_separated_nonempty)) => {
626 |x| TyTraitObject { bounds: x }.into()
627 }
628 |
629 syn!(TyParamBound) => {
630 |x| TyTraitObject { bounds: vec![x].into() }.into()
631 }
David Tolnay6414da72016-10-08 00:55:17 -0700632 ));
633
Alex Crichton954046c2017-05-30 21:49:42 -0700634 impl Synom for TyImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400635 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800636 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400637 // NOTE: rust-lang/rust#34511 includes discussion about whether or
638 // not + should be allowed in ImplTrait directly without ().
Michael Layzell92639a52017-06-01 00:07:44 -0400639 elem: call!(Delimited::parse_separated_nonempty) >>
640 (TyImplTrait {
641 impl_token: impl_,
642 bounds: elem,
643 })
644 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700645 }
David Tolnayb79ee962016-09-04 09:39:20 -0700646
Michael Layzell93c36282017-06-04 20:43:14 -0400647 impl Synom for TyGroup {
648 named!(parse -> Self, do_parse!(
649 data: grouped!(syn!(Ty)) >>
650 (TyGroup {
651 group_token: data.1,
652 ty: Box::new(data.0),
653 })
654 ));
655 }
656
Alex Crichton954046c2017-05-30 21:49:42 -0700657 impl Synom for TyParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400658 named!(parse -> Self, do_parse!(
659 data: parens!(syn!(Ty)) >>
660 (TyParen {
661 paren_token: data.1,
662 ty: Box::new(data.0),
663 })
664 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700665 }
David Tolnayb79ee962016-09-04 09:39:20 -0700666
Alex Crichton954046c2017-05-30 21:49:42 -0700667 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400668 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800669 keyword!(mut) => { Mutability::Mutable }
Michael Layzell92639a52017-06-01 00:07:44 -0400670 |
671 epsilon!() => { |_| Mutability::Immutable }
672 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700673 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700674
Alex Crichton954046c2017-05-30 21:49:42 -0700675 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400676 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800677 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400678 segments: call!(Delimited::parse_separated_nonempty) >>
679 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700680 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400681 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400682 })
683 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700684
685 fn description() -> Option<&'static str> {
686 Some("path")
687 }
Alex Crichton954046c2017-05-30 21:49:42 -0700688 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700689
Alex Crichton954046c2017-05-30 21:49:42 -0700690 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400691 named!(parse -> Self, alt!(
692 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700693 ident: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800694 turbofish: option!(punct!(::)) >>
695 lt: punct!(<) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400696 lifetimes: call!(Delimited::parse_terminated) >>
697 types: cond!(
698 lifetimes.is_empty() || lifetimes.trailing_delim(),
699 call!(Delimited::parse_terminated_with,
700 ty_no_eq_after)
701 ) >>
702 bindings: cond!(
703 match types {
704 Some(ref t) => t.is_empty() || t.trailing_delim(),
705 None => lifetimes.is_empty() || lifetimes.trailing_delim(),
706 },
707 call!(Delimited::parse_terminated)
708 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800709 gt: punct!(>) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400710 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700711 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -0400712 parameters: PathParameters::AngleBracketed(
713 AngleBracketedParameterData {
David Tolnay570695e2017-06-03 16:15:13 -0700714 turbofish: turbofish,
715 lt_token: lt,
Michael Layzell92639a52017-06-01 00:07:44 -0400716 lifetimes: lifetimes,
717 types: types.unwrap_or_default(),
718 bindings: bindings.unwrap_or_default(),
David Tolnay570695e2017-06-03 16:15:13 -0700719 gt_token: gt,
Michael Layzell92639a52017-06-01 00:07:44 -0400720 }
721 ),
722 })
723 )
724 |
725 mod_style_path_segment
726 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700727 }
David Tolnay570695e2017-06-03 16:15:13 -0700728
David Tolnayf8db7ba2017-11-11 22:52:16 -0800729 named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(punct!(=))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700730
Alex Crichton954046c2017-05-30 21:49:42 -0700731 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400732 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800733 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400734 segments: call!(Delimited::parse_separated_nonempty_with,
735 mod_style_path_segment) >>
736 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700737 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400738 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400739 })
740 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700741 }
Arnavionf2dada12017-04-20 23:55:20 -0700742
743 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700744 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700745 |
Alex Crichton954046c2017-05-30 21:49:42 -0700746 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800747 keyword!(super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700748 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800749 keyword!(self) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700750 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800751 keyword!(Self) => { Into::into }
Alex Crichton954046c2017-05-30 21:49:42 -0700752 )
Arnavionf2dada12017-04-20 23:55:20 -0700753 ));
754
Alex Crichton954046c2017-05-30 21:49:42 -0700755 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400756 named!(parse -> Self, do_parse!(
757 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800758 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400759 ty: syn!(Ty) >>
760 (TypeBinding {
761 ident: id,
762 eq_token: eq,
763 ty: ty,
764 })
765 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700766 }
767
768 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400769 named!(parse -> Self, do_parse!(
770 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
771 trait_ref: syn!(Path) >>
772 parenthesized: option!(cond_reduce!(
773 trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
774 syn!(ParenthesizedParameterData)
775 )) >>
776 ({
777 let mut trait_ref = trait_ref;
778 if let Some(parenthesized) = parenthesized {
779 let parenthesized = PathParameters::Parenthesized(parenthesized);
780 let len = trait_ref.segments.len();
781 trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
782 }
783 PolyTraitRef {
784 bound_lifetimes: bound_lifetimes,
785 trait_ref: trait_ref,
786 }
787 })
788 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700789 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700790
Alex Crichton954046c2017-05-30 21:49:42 -0700791 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400792 named!(parse -> Self, do_parse!(
793 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700794 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800795 not!(punct!(::)) >>
796 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400797 (name, colon)
798 )) >>
799 ty: syn!(Ty) >>
800 (BareFnArg {
801 name: name,
802 ty: ty,
803 })
804 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700805 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700806
Alex Crichton23a15f62017-08-28 12:34:23 -0700807 impl Synom for BareFnArgName {
808 named!(parse -> Self, alt!(
809 map!(syn!(Ident), BareFnArgName::Named)
810 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800811 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700812 ));
813 }
814
Alex Crichton954046c2017-05-30 21:49:42 -0700815 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400816 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800817 keyword!(unsafe) => { Unsafety::Unsafe }
Michael Layzell92639a52017-06-01 00:07:44 -0400818 |
819 epsilon!() => { |_| Unsafety::Normal }
820 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700821 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700822
Alex Crichton954046c2017-05-30 21:49:42 -0700823 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400824 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800825 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400826 // TODO: this parses all literals, not just strings
827 name: option!(syn!(Lit)) >>
828 (Abi {
829 extern_token: extern_,
830 kind: match name {
831 Some(name) => AbiKind::Named(name),
832 None => AbiKind::Default,
833 },
834 })
835 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700836 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700837}
David Tolnay87d0b442016-09-04 11:52:12 -0700838
839#[cfg(feature = "printing")]
840mod printing {
841 use super::*;
842 use quote::{Tokens, ToTokens};
843
Alex Crichton62a0a592017-05-22 13:58:53 -0700844 impl ToTokens for TySlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700845 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700846 self.bracket_token.surround(tokens, |tokens| {
847 self.ty.to_tokens(tokens);
848 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700849 }
850 }
851
852 impl ToTokens for TyArray {
853 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700854 self.bracket_token.surround(tokens, |tokens| {
855 self.ty.to_tokens(tokens);
856 self.semi_token.to_tokens(tokens);
857 self.amt.to_tokens(tokens);
858 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700859 }
860 }
861
862 impl ToTokens for TyPtr {
863 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700864 self.star_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400865 match self.ty.mutability {
866 Mutability::Mutable(ref tok) => tok.to_tokens(tokens),
867 Mutability::Immutable => {
Alex Crichton259ee532017-07-14 06:51:02 -0700868 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400869 }
870 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700871 self.ty.ty.to_tokens(tokens);
872 }
873 }
874
875 impl ToTokens for TyRptr {
876 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700877 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700878 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700879 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700880 self.ty.ty.to_tokens(tokens);
881 }
882 }
883
884 impl ToTokens for TyBareFn {
885 fn to_tokens(&self, tokens: &mut Tokens) {
886 self.ty.to_tokens(tokens)
887 }
888 }
889
890 impl ToTokens for TyNever {
891 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700892 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700893 }
894 }
895
896 impl ToTokens for TyTup {
897 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700898 self.paren_token.surround(tokens, |tokens| {
899 self.tys.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400900 // XXX: I don't think (,) is a thing.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700901 self.lone_comma.to_tokens(tokens);
902 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700903 }
904 }
905
906 impl ToTokens for TyPath {
907 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700908 PathTokens(&self.qself, &self.path).to_tokens(tokens);
909 }
910 }
911
912 impl<'a> ToTokens for PathTokens<'a> {
913 fn to_tokens(&self, tokens: &mut Tokens) {
914 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700915 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700916 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700917 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700918 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700919 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400920
921 // XXX: Gross.
922 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
923 self.1.segments.len() - 1
924 } else {
925 qself.position
926 };
David Tolnay570695e2017-06-03 16:15:13 -0700927 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400928 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700929 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700930 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700931 for (i, segment) in (&mut segments).take(pos).enumerate() {
932 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700933 segment.item().to_tokens(tokens);
934 qself.gt_token.to_tokens(tokens);
935 segment.delimiter().to_tokens(tokens);
936 } else {
937 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700938 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700939 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700940 } else {
941 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700942 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700943 }
David Tolnay570695e2017-06-03 16:15:13 -0700944 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700945 segment.to_tokens(tokens);
946 }
947 }
948 }
949
950 impl ToTokens for TyTraitObject {
951 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700952 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700953 }
954 }
955
956 impl ToTokens for TyImplTrait {
957 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700958 self.impl_token.to_tokens(tokens);
959 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700960 }
961 }
962
Michael Layzell93c36282017-06-04 20:43:14 -0400963 impl ToTokens for TyGroup {
964 fn to_tokens(&self, tokens: &mut Tokens) {
965 self.group_token.surround(tokens, |tokens| {
966 self.ty.to_tokens(tokens);
967 });
968 }
969 }
970
Alex Crichton62a0a592017-05-22 13:58:53 -0700971 impl ToTokens for TyParen {
972 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700973 self.paren_token.surround(tokens, |tokens| {
974 self.ty.to_tokens(tokens);
975 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700976 }
977 }
978
979 impl ToTokens for TyInfer {
980 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700981 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700982 }
983 }
984
David Tolnay47a877c2016-10-01 16:50:55 -0700985 impl ToTokens for Mutability {
986 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700987 if let Mutability::Mutable(ref t) = *self {
988 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700989 }
990 }
991 }
992
David Tolnay87d0b442016-09-04 11:52:12 -0700993 impl ToTokens for Path {
994 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700995 self.leading_colon.to_tokens(tokens);
996 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700997 }
998 }
999
1000 impl ToTokens for PathSegment {
1001 fn to_tokens(&self, tokens: &mut Tokens) {
1002 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001003 self.parameters.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001004 }
1005 }
1006
1007 impl ToTokens for PathParameters {
1008 fn to_tokens(&self, tokens: &mut Tokens) {
1009 match *self {
David Tolnay570695e2017-06-03 16:15:13 -07001010 PathParameters::None => {}
David Tolnay87d0b442016-09-04 11:52:12 -07001011 PathParameters::AngleBracketed(ref parameters) => {
1012 parameters.to_tokens(tokens);
1013 }
1014 PathParameters::Parenthesized(ref parameters) => {
1015 parameters.to_tokens(tokens);
1016 }
1017 }
1018 }
1019 }
1020
1021 impl ToTokens for AngleBracketedParameterData {
1022 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -07001023 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001024 self.lt_token.to_tokens(tokens);
1025 self.lifetimes.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001026 if !self.lifetimes.empty_or_trailing() && !self.types.is_empty() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001027 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001028 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001029 self.types.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001030 if (
1031 // If we have no trailing delimiter after a non-empty types list, or
1032 !self.types.empty_or_trailing() ||
1033 // If we have no trailing delimiter after a non-empty lifetimes
1034 // list before an empty types list, and
1035 (self.types.is_empty() && !self.lifetimes.empty_or_trailing())) &&
1036 // We have some bindings, then we need a comma.
1037 !self.bindings.is_empty()
1038 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001039 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001040 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001041 self.bindings.to_tokens(tokens);
1042 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001043 }
1044 }
1045
1046 impl ToTokens for TypeBinding {
1047 fn to_tokens(&self, tokens: &mut Tokens) {
1048 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001049 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001050 self.ty.to_tokens(tokens);
1051 }
1052 }
1053
1054 impl ToTokens for ParenthesizedParameterData {
1055 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001056 self.paren_token.surround(tokens, |tokens| {
1057 self.inputs.to_tokens(tokens);
1058 });
1059 self.output.to_tokens(tokens);
1060 }
1061 }
1062
David Tolnayf93b90d2017-11-11 19:21:26 -08001063 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001064 fn to_tokens(&self, tokens: &mut Tokens) {
1065 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001066 ReturnType::Default => {}
1067 ReturnType::Ty(ref ty, ref arrow) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001068 arrow.to_tokens(tokens);
1069 ty.to_tokens(tokens);
1070 }
David Tolnay87d0b442016-09-04 11:52:12 -07001071 }
1072 }
1073 }
1074
1075 impl ToTokens for PolyTraitRef {
1076 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001077 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001078 self.trait_ref.to_tokens(tokens);
1079 }
1080 }
1081
1082 impl ToTokens for BareFnTy {
1083 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001084 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001085 self.unsafety.to_tokens(tokens);
1086 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001087 self.fn_token.to_tokens(tokens);
1088 self.paren_token.surround(tokens, |tokens| {
1089 self.inputs.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001090 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001091 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001092 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001093 self.variadic.to_tokens(tokens);
1094 });
1095 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001096 }
1097 }
1098
David Tolnay62f374c2016-10-02 13:37:00 -07001099 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001100 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001101 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001102 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001103 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001104 }
1105 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001106 }
1107 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001108
Alex Crichton23a15f62017-08-28 12:34:23 -07001109 impl ToTokens for BareFnArgName {
1110 fn to_tokens(&self, tokens: &mut Tokens) {
1111 match *self {
1112 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1113 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1114 }
1115 }
1116 }
1117
David Tolnayb8d8ef52016-10-29 14:30:08 -07001118 impl ToTokens for Unsafety {
1119 fn to_tokens(&self, tokens: &mut Tokens) {
1120 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001121 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001122 Unsafety::Normal => {
1123 // nothing
1124 }
1125 }
1126 }
1127 }
1128
1129 impl ToTokens for Abi {
1130 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001131 self.extern_token.to_tokens(tokens);
1132 match self.kind {
1133 AbiKind::Named(ref named) => named.to_tokens(tokens),
1134 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001135 }
1136 }
1137 }
David Tolnay87d0b442016-09-04 11:52:12 -07001138}