blob: 201b2574d3131d38aab346b9392d625b01987a4e [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
David Tolnayfd6bf5c2017-11-12 09:41:14 -08006 pub enum Type {
Alex Crichton62a0a592017-05-22 13:58:53 -07007 /// A variable-length array (`[T]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -08008 pub Slice(TypeSlice {
9 pub ty: Box<Type>,
David Tolnay32954ef2017-12-26 22:43:16 -050010 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070011 }),
12 /// A fixed length array (`[T; n]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080013 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050014 pub bracket_token: token::Bracket,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080015 pub ty: Box<Type>,
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`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080020 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 pub star_token: Token![*],
22 pub const_token: Option<Token![const]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080023 pub ty: Box<MutType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070024 }),
25 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080026 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080027 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub lifetime: Option<Lifetime>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080029 pub ty: Box<MutType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
31 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080032 pub BareFn(TypeBareFn {
33 pub ty: Box<BareFnType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
35 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080036 pub Never(TypeNever {
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, ...)`)
David Tolnay05362582017-12-26 01:33:57 -050040 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050041 pub paren_token: token::Paren,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080042 pub tys: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080043 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 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050048 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080049 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070050 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.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080055 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050056 pub dyn_token: Option<Token![dyn]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080057 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070058 }),
59 /// An `impl Bound1 + Bound2 + Bound3` type
60 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080061 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080062 pub impl_token: Token![impl],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080063 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070064 }),
65 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080066 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -050067 pub paren_token: token::Paren,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080068 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070069 }),
Michael Layzell93c36282017-06-04 20:43:14 -040070 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080071 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -050072 pub group_token: token::Group,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080073 pub ty: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040074 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080075 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070076 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080077 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080078 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070079 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070080 /// A macro in the type position.
David Tolnaydecf28d2017-11-11 11:56:45 -080081 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -070082 }
83}
84
85ast_struct! {
David Tolnayfd6bf5c2017-11-12 09:41:14 -080086 pub struct MutType {
87 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070088 pub mutability: Mutability,
89 }
90}
91
92ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -070093 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070094 pub enum Mutability {
David Tolnayf8db7ba2017-11-11 22:52:16 -080095 Mutable(Token![mut]),
Alex Crichton62a0a592017-05-22 13:58:53 -070096 Immutable,
97 }
98}
99
100ast_struct! {
101 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -0700102 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 /// It's represented as a sequence of identifiers,
104 /// along with a bunch of supporting information.
105 ///
106 /// E.g. `std::cmp::PartialEq`
107 pub struct Path {
108 /// A `::foo` path, is relative to the crate root rather than current
109 /// module (like paths in an import).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800110 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 /// The segments in the path: the things separated by `::`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800112 pub segments: Delimited<PathSegment, Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 }
David Tolnayb79ee962016-09-04 09:39:20 -0700114}
115
David Tolnay570695e2017-06-03 16:15:13 -0700116impl Path {
117 pub fn global(&self) -> bool {
118 self.leading_colon.is_some()
119 }
120}
121
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700122#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400123#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
124#[cfg_attr(feature = "clone-impls", derive(Clone))]
125pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126
David Tolnaydaaf7742016-10-03 11:11:43 -0700127impl<T> From<T> for Path
David Tolnay51382052017-12-27 13:46:21 -0500128where
129 T: Into<PathSegment>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700130{
David Tolnay84aa0752016-10-02 23:01:13 -0700131 fn from(segment: T) -> Self {
132 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700133 leading_colon: None,
134 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700135 }
136 }
137}
138
Alex Crichton62a0a592017-05-22 13:58:53 -0700139ast_struct! {
140 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
141 ///
142 /// E.g. `std`, `String` or `Box<T>`
143 pub struct PathSegment {
144 /// The identifier portion of this path segment.
145 pub ident: Ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500146 /// Type/lifetime arguments attached to this path. They come in
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
148 /// this is more than just simple syntactic sugar; the use of
149 /// parens affects the region binding rules, so we preserve the
150 /// distinction.
Nika Layzellc08227a2017-12-04 16:30:17 -0500151 pub arguments: PathArguments,
Alex Crichton62a0a592017-05-22 13:58:53 -0700152 }
David Tolnayb79ee962016-09-04 09:39:20 -0700153}
154
David Tolnaydaaf7742016-10-03 11:11:43 -0700155impl<T> From<T> for PathSegment
David Tolnay51382052017-12-27 13:46:21 -0500156where
157 T: Into<Ident>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700158{
David Tolnay84aa0752016-10-02 23:01:13 -0700159 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700160 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700161 ident: ident.into(),
Nika Layzellc08227a2017-12-04 16:30:17 -0500162 arguments: PathArguments::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700163 }
164 }
165}
166
Alex Crichton62a0a592017-05-22 13:58:53 -0700167ast_enum! {
Nika Layzellc08227a2017-12-04 16:30:17 -0500168 /// Arguments of a path segment.
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 ///
170 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
Nika Layzellc08227a2017-12-04 16:30:17 -0500171 pub enum PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700172 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500174 AngleBracketed(AngleBracketedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700175 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500176 Parenthesized(ParenthesizedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700177 }
David Tolnayb79ee962016-09-04 09:39:20 -0700178}
179
Nika Layzellc08227a2017-12-04 16:30:17 -0500180impl Default for PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700181 fn default() -> Self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500182 PathArguments::None
David Tolnayb79ee962016-09-04 09:39:20 -0700183 }
David Tolnay570695e2017-06-03 16:15:13 -0700184}
David Tolnay5332d4b2016-10-30 14:25:22 -0700185
Nika Layzellc08227a2017-12-04 16:30:17 -0500186impl PathArguments {
David Tolnay5332d4b2016-10-30 14:25:22 -0700187 pub fn is_empty(&self) -> bool {
188 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500189 PathArguments::None => true,
190 PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
191 PathArguments::Parenthesized(_) => false,
David Tolnay5332d4b2016-10-30 14:25:22 -0700192 }
193 }
David Tolnayb79ee962016-09-04 09:39:20 -0700194}
195
Nika Layzell357885a2017-12-04 15:47:07 -0500196ast_enum! {
197 /// A individual generic argument, like `'a`, `T`, or `Item=T`.
Nika Layzellc08227a2017-12-04 16:30:17 -0500198 pub enum GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500199 /// The lifetime parameters for this path segment.
200 Lifetime(Lifetime),
201 /// The type parameters for this path segment, if present.
202 Type(Type),
203 /// Bindings (equality constraints) on associated types, if present.
204 ///
205 /// E.g., `Foo<A=Bar>`.
206 TypeBinding(TypeBinding),
Nika Layzellc680e612017-12-04 19:07:20 -0500207 /// Const expression. Must be inside of a block.
208 ///
209 /// NOTE: Identity expressions are represented as Type arguments, as
210 /// they are indistinguishable syntactically.
Nika Layzellce37f332017-12-05 12:01:22 -0500211 Const(Expr),
Nika Layzell357885a2017-12-04 15:47:07 -0500212 }
213}
214
Alex Crichton62a0a592017-05-22 13:58:53 -0700215ast_struct! {
216 /// A path like `Foo<'a, T>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500217 pub struct AngleBracketedGenericArguments {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800218 pub turbofish: Option<Token![::]>,
219 pub lt_token: Token![<],
Nika Layzellc08227a2017-12-04 16:30:17 -0500220 pub args: Delimited<GenericArgument, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800221 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 }
223}
224
225ast_struct! {
226 /// Bind a type to an associated type: `A=Foo`.
227 pub struct TypeBinding {
228 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800229 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800230 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 }
232}
233
Alex Crichton62a0a592017-05-22 13:58:53 -0700234ast_struct! {
235 /// A path like `Foo(A,B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500236 pub struct ParenthesizedGenericArguments {
David Tolnay32954ef2017-12-26 22:43:16 -0500237 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 /// `(A, B)`
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800239 pub inputs: Delimited<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700240 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800241 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 }
243}
244
245ast_struct! {
246 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 /// The `for<'a>` in `for<'a> Foo<&'a T>`
248 pub bound_lifetimes: Option<BoundLifetimes>,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500249 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 pub trait_ref: Path,
251 }
252}
253
254ast_struct! {
255 /// The explicit Self type in a "qualified path". The actual
256 /// path, including the trait and the associated item, is stored
257 /// separately. `position` represents the index of the associated
258 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700259 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500260 /// ```text
Alex Crichton62a0a592017-05-22 13:58:53 -0700261 /// <Vec<T> as a::b::Trait>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500262 /// ^~~~~~ ~~~~~~~~~~~~~~^
Alex Crichton62a0a592017-05-22 13:58:53 -0700263 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700264 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700265 /// <Vec<T>>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500266 /// ^~~~~~ ^
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 /// ty position = 0
268 /// ```
269 pub struct QSelf {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800270 pub lt_token: Token![<],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800271 pub ty: Box<Type>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400272 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800273 pub as_token: Option<Token![as]>,
274 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 }
276}
277
278ast_struct! {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800279 pub struct BareFnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700280 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 pub unsafety: Unsafety,
282 pub abi: Option<Abi>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800283 pub fn_token: Token![fn],
David Tolnay32954ef2017-12-26 22:43:16 -0500284 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800285 pub inputs: Delimited<BareFnArg, Token![,]>,
286 pub variadic: Option<Token![...]>,
David Tolnayf93b90d2017-11-11 19:21:26 -0800287 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 }
289}
290
291ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700292 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 pub enum Unsafety {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800294 Unsafe(Token![unsafe]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700295 Normal,
296 }
297}
298
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700299ast_struct! {
300 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800301 pub extern_token: Token![extern],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 pub kind: AbiKind,
303 }
304}
305
Alex Crichton62a0a592017-05-22 13:58:53 -0700306ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700307 pub enum AbiKind {
308 Named(Lit),
309 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700310 }
311}
312
313ast_struct! {
314 /// An argument in a function type.
315 ///
316 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
317 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800318 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800319 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 }
321}
322
Alex Crichton23a15f62017-08-28 12:34:23 -0700323ast_enum! {
324 /// Names of arguments in the `BareFnArg` structure
325 pub enum BareFnArgName {
326 /// Argument with the provided name
327 Named(Ident),
328 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800329 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700330 }
331}
Alex Crichton62a0a592017-05-22 13:58:53 -0700332
333ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800334 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 /// Return type is not specified.
336 ///
337 /// Functions default to `()` and
338 /// closures default to inference. Span points to where return
339 /// type would be inserted.
340 Default,
341 /// Everything else
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800342 Type(Type, Token![->]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700343 }
David Tolnayb79ee962016-09-04 09:39:20 -0700344}
345
David Tolnay86eca752016-09-04 11:26:41 -0700346#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700347pub mod parsing {
348 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400349 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700350
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800351 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400352 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700353
Alex Crichton954046c2017-05-30 21:49:42 -0700354 fn description() -> Option<&'static str> {
355 Some("type")
356 }
357 }
David Tolnay0047c712016-12-21 21:59:25 -0500358
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800359 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400360 /// In some positions, types may not contain the `+` character, to
361 /// disambiguate them. For example in the expression `1 as T`, T may not
362 /// contain a `+` character.
363 ///
364 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400365 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400366 }
367
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800368 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
369 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400370 |
David Tolnay05362582017-12-26 01:33:57 -0500371 // must be before TypeTuple
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800372 syn!(TypeParen) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400373 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500374 // must be before TypePath
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800375 syn!(Macro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400376 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500377 // must be before TypeTraitObject
378 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400379 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800380 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400381 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800382 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400383 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800384 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400385 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800386 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400387 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800388 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400389 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800390 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400391 |
David Tolnay05362582017-12-26 01:33:57 -0500392 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400393 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500394 // Don't try parsing more than one trait bound if we aren't allowing it
395 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400396 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800397 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700398 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800399 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400400 ));
401
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800402 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400403 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800404 brackets!(syn!(Type)),
405 |(ty, b)| TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400406 ty: Box::new(ty),
407 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700408 }
Michael Layzell92639a52017-06-01 00:07:44 -0400409 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700410 }
David Tolnayb79ee962016-09-04 09:39:20 -0700411
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800412 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400413 named!(parse -> Self, map!(
414 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800415 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800416 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400417 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700418 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400419 )),
420 |((elem, semi, len), brackets)| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800421 TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400422 ty: Box::new(elem),
423 amt: len,
424 bracket_token: brackets,
425 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700426 }
427 }
Michael Layzell92639a52017-06-01 00:07:44 -0400428 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700429 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700430
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800431 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400432 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800433 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400434 mutability: alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800435 keyword!(const) => { |c| (Mutability::Immutable, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400436 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800437 keyword!(mut) => { |m| (Mutability::Mutable(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400438 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800439 target: call!(Type::without_plus) >>
440 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400441 const_token: mutability.1,
442 star_token: star,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800443 ty: Box::new(MutType {
Michael Layzell92639a52017-06-01 00:07:44 -0400444 ty: target,
445 mutability: mutability.0,
446 }),
447 })
448 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700449 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700450
David Tolnay0a89b4d2017-11-13 00:55:45 -0800451 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400452 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800453 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400454 life: option!(syn!(Lifetime)) >>
455 mutability: syn!(Mutability) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400456 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800457 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800458 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400459 lifetime: life,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800460 ty: Box::new(MutType {
Michael Layzell92639a52017-06-01 00:07:44 -0400461 ty: target,
462 mutability: mutability,
463 }),
464 and_token: amp,
465 })
466 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700467 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700468
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800469 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400470 named!(parse -> Self, do_parse!(
471 lifetimes: option!(syn!(BoundLifetimes)) >>
472 unsafety: syn!(Unsafety) >>
473 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800474 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400475 parens: parens!(do_parse!(
476 inputs: call!(Delimited::parse_terminated) >>
477 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800478 punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400479 (inputs, variadic)
480 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800481 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800482 (TypeBareFn {
483 ty: Box::new(BareFnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400484 unsafety: unsafety,
485 abi: abi,
486 lifetimes: lifetimes,
487 output: output,
488 variadic: (parens.0).1,
489 fn_token: fn_,
490 paren_token: parens.1,
491 inputs: (parens.0).0,
492 }),
493 })
494 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700495 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700496
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800497 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400498 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800499 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800500 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400501 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700502 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700503
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800504 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700505 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800506 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800507 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700508 ));
509 }
510
David Tolnay05362582017-12-26 01:33:57 -0500511 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400512 named!(parse -> Self, do_parse!(
513 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -0500514 (TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400515 tys: data.0,
516 paren_token: data.1,
517 lone_comma: None, // TODO: does this just not parse?
518 })
519 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700520 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700521
David Tolnay7d38c7e2017-12-25 22:31:50 -0500522 impl TypePath {
523 named!(parse(allow_plus: bool) -> Self, do_parse!(
524 qpath: qpath >>
525 parenthesized: cond!(
526 qpath.1.segments.last().unwrap().item().arguments.is_empty(),
527 option!(syn!(ParenthesizedGenericArguments))
528 ) >>
529 cond!(allow_plus, not!(peek!(punct!(+)))) >>
530 ({
531 let (qself, mut path) = qpath;
532 if let Some(Some(parenthesized)) = parenthesized {
533 let parenthesized = PathArguments::Parenthesized(parenthesized);
534 path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
535 }
536 TypePath { qself: qself, path: path }
537 })
538 ));
539 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700540
David Tolnay9636c052016-10-02 17:11:17 -0700541 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700542 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700543 |
544 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800545 lt: punct!(<) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800546 this: syn!(Type) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500547 path: option!(tuple!(keyword!(as), syn!(Path))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800548 gt: punct!(>) >>
549 colon2: punct!(::) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700550 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700551 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400552 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700553 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700554 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700556 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700557 }
Alex Crichton954046c2017-05-30 21:49:42 -0700558 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700559 path.segments.push(item);
560 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400561 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700562 }
563 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400564 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700565 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700566 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700567 })
David Tolnay9636c052016-10-02 17:11:17 -0700568 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700569 };
570 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700571 lt_token: lt,
572 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700573 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400574 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700575 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700576 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700577 })
578 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700579 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800580 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700581 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700582
Nika Layzellc08227a2017-12-04 16:30:17 -0500583 impl Synom for ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400584 named!(parse -> Self, do_parse!(
585 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800586 output: syn!(ReturnType) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500587 (ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400588 paren_token: data.1,
589 inputs: data.0,
590 output: output,
591 })
592 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700593 }
594
David Tolnayf93b90d2017-11-11 19:21:26 -0800595 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400596 named!(parse -> Self, alt!(
597 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800598 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800599 ty: syn!(Type) >>
600 (ReturnType::Type(ty, arrow))
Michael Layzell92639a52017-06-01 00:07:44 -0400601 )
602 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800603 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400604 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700605 }
606
David Tolnay7d38c7e2017-12-25 22:31:50 -0500607 impl TypeTraitObject {
608 // Only allow multiple trait references if allow_plus is true.
609 named!(parse(allow_plus: bool) -> Self, do_parse!(
610 dyn_token: option!(keyword!(dyn)) >>
611 bounds: alt!(
612 cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
613 |
614 syn!(TypeParamBound) => { |x| vec![x].into() }
615 ) >>
616 (TypeTraitObject {
617 dyn_token: dyn_token,
618 bounds: bounds,
619 })
620 ));
621 }
David Tolnay6414da72016-10-08 00:55:17 -0700622
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800623 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400624 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800625 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400626 // NOTE: rust-lang/rust#34511 includes discussion about whether or
627 // not + should be allowed in ImplTrait directly without ().
Nika Layzellb49a9e52017-12-05 13:31:52 -0500628 elem: call!(Delimited::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800629 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400630 impl_token: impl_,
631 bounds: elem,
632 })
633 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700634 }
David Tolnayb79ee962016-09-04 09:39:20 -0700635
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800636 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400637 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800638 data: grouped!(syn!(Type)) >>
639 (TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400640 group_token: data.1,
641 ty: Box::new(data.0),
642 })
643 ));
644 }
645
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800646 impl Synom for TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400647 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800648 data: parens!(syn!(Type)) >>
649 (TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400650 paren_token: data.1,
651 ty: Box::new(data.0),
652 })
653 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700654 }
David Tolnayb79ee962016-09-04 09:39:20 -0700655
Alex Crichton954046c2017-05-30 21:49:42 -0700656 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400657 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800658 keyword!(mut) => { Mutability::Mutable }
Michael Layzell92639a52017-06-01 00:07:44 -0400659 |
660 epsilon!() => { |_| Mutability::Immutable }
661 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700662 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700663
Alex Crichton954046c2017-05-30 21:49:42 -0700664 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400665 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800666 colon: option!(punct!(::)) >>
David Tolnaye45b59f2017-12-25 18:44:49 -0500667 segments: call!(Delimited::<PathSegment, Token![::]>::parse_separated_nonempty) >>
668 cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400669 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700670 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400671 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400672 })
673 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700674
675 fn description() -> Option<&'static str> {
676 Some("path")
677 }
Alex Crichton954046c2017-05-30 21:49:42 -0700678 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700679
Nika Layzellc680e612017-12-04 19:07:20 -0500680 #[cfg(not(feature = "full"))]
Nika Layzellc08227a2017-12-04 16:30:17 -0500681 impl Synom for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500682 named!(parse -> Self, alt!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500683 call!(ty_no_eq_after) => { GenericArgument::Type }
Nika Layzell357885a2017-12-04 15:47:07 -0500684 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500685 syn!(Lifetime) => { GenericArgument::Lifetime }
Nika Layzell357885a2017-12-04 15:47:07 -0500686 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500687 syn!(TypeBinding) => { GenericArgument::TypeBinding }
Nika Layzell357885a2017-12-04 15:47:07 -0500688 ));
689 }
690
Nika Layzellc680e612017-12-04 19:07:20 -0500691 #[cfg(feature = "full")]
692 impl Synom for GenericArgument {
693 named!(parse -> Self, alt!(
694 call!(ty_no_eq_after) => { GenericArgument::Type }
695 |
696 syn!(Lifetime) => { GenericArgument::Lifetime }
697 |
698 syn!(TypeBinding) => { GenericArgument::TypeBinding }
699 |
Nika Layzellce37f332017-12-05 12:01:22 -0500700 syn!(Lit) => { |l| GenericArgument::Const(ExprKind::Lit(l).into()) }
701 |
702 syn!(ExprBlock) => { |b| GenericArgument::Const(ExprKind::Block(b).into()) }
Nika Layzellc680e612017-12-04 19:07:20 -0500703 ));
704 }
705
Nika Layzellc08227a2017-12-04 16:30:17 -0500706 impl Synom for AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500707 named!(parse -> Self, do_parse!(
708 turbofish: option!(punct!(::)) >>
709 lt: punct!(<) >>
710 args: call!(Delimited::parse_terminated) >>
711 gt: punct!(>) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500712 (AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500713 turbofish: turbofish,
714 lt_token: lt,
715 args: args,
716 gt_token: gt,
717 })
718 ));
719 }
720
Alex Crichton954046c2017-05-30 21:49:42 -0700721 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400722 named!(parse -> Self, alt!(
723 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700724 ident: syn!(Ident) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500725 arguments: syn!(AngleBracketedGenericArguments) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400726 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700727 ident: ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500728 arguments: PathArguments::AngleBracketed(arguments),
Michael Layzell92639a52017-06-01 00:07:44 -0400729 })
730 )
731 |
732 mod_style_path_segment
733 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700734 }
David Tolnay570695e2017-06-03 16:15:13 -0700735
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800736 named!(ty_no_eq_after -> Type, terminated!(syn!(Type), not!(punct!(=))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700737
Alex Crichton954046c2017-05-30 21:49:42 -0700738 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400739 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800740 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400741 segments: call!(Delimited::parse_separated_nonempty_with,
742 mod_style_path_segment) >>
743 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700744 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400745 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400746 })
747 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700748 }
Arnavionf2dada12017-04-20 23:55:20 -0700749
750 named!(mod_style_path_segment -> PathSegment, alt!(
David Tolnay5f332a92017-12-26 00:42:45 -0500751 syn!(Ident) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700752 |
David Tolnay5f332a92017-12-26 00:42:45 -0500753 keyword!(super) => { Into::into }
754 |
755 keyword!(self) => { Into::into }
756 |
757 keyword!(Self) => { Into::into }
758 |
759 keyword!(crate) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700760 ));
761
Alex Crichton954046c2017-05-30 21:49:42 -0700762 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400763 named!(parse -> Self, do_parse!(
764 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800765 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800766 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400767 (TypeBinding {
768 ident: id,
769 eq_token: eq,
770 ty: ty,
771 })
772 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700773 }
774
775 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400776 named!(parse -> Self, do_parse!(
777 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
778 trait_ref: syn!(Path) >>
779 parenthesized: option!(cond_reduce!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500780 trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
781 syn!(ParenthesizedGenericArguments)
Michael Layzell92639a52017-06-01 00:07:44 -0400782 )) >>
783 ({
784 let mut trait_ref = trait_ref;
785 if let Some(parenthesized) = parenthesized {
Nika Layzellc08227a2017-12-04 16:30:17 -0500786 let parenthesized = PathArguments::Parenthesized(parenthesized);
Michael Layzell92639a52017-06-01 00:07:44 -0400787 let len = trait_ref.segments.len();
Nika Layzellc08227a2017-12-04 16:30:17 -0500788 trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
Michael Layzell92639a52017-06-01 00:07:44 -0400789 }
790 PolyTraitRef {
791 bound_lifetimes: bound_lifetimes,
792 trait_ref: trait_ref,
793 }
794 })
795 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700796 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700797
Alex Crichton954046c2017-05-30 21:49:42 -0700798 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400799 named!(parse -> Self, do_parse!(
800 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700801 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800802 not!(punct!(::)) >>
803 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400804 (name, colon)
805 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800806 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400807 (BareFnArg {
808 name: name,
809 ty: ty,
810 })
811 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700812 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700813
Alex Crichton23a15f62017-08-28 12:34:23 -0700814 impl Synom for BareFnArgName {
815 named!(parse -> Self, alt!(
816 map!(syn!(Ident), BareFnArgName::Named)
817 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800818 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700819 ));
820 }
821
Alex Crichton954046c2017-05-30 21:49:42 -0700822 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400823 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800824 keyword!(unsafe) => { Unsafety::Unsafe }
Michael Layzell92639a52017-06-01 00:07:44 -0400825 |
826 epsilon!() => { |_| Unsafety::Normal }
827 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700828 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700829
Alex Crichton954046c2017-05-30 21:49:42 -0700830 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400831 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800832 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400833 // TODO: this parses all literals, not just strings
834 name: option!(syn!(Lit)) >>
835 (Abi {
836 extern_token: extern_,
837 kind: match name {
838 Some(name) => AbiKind::Named(name),
839 None => AbiKind::Default,
840 },
841 })
842 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700843 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700844}
David Tolnay87d0b442016-09-04 11:52:12 -0700845
846#[cfg(feature = "printing")]
847mod printing {
848 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500849 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700850
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800851 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700852 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700853 self.bracket_token.surround(tokens, |tokens| {
854 self.ty.to_tokens(tokens);
855 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700856 }
857 }
858
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800859 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700860 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700861 self.bracket_token.surround(tokens, |tokens| {
862 self.ty.to_tokens(tokens);
863 self.semi_token.to_tokens(tokens);
864 self.amt.to_tokens(tokens);
865 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700866 }
867 }
868
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800869 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700870 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700871 self.star_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400872 match self.ty.mutability {
873 Mutability::Mutable(ref tok) => tok.to_tokens(tokens),
874 Mutability::Immutable => {
Alex Crichton259ee532017-07-14 06:51:02 -0700875 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400876 }
877 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700878 self.ty.ty.to_tokens(tokens);
879 }
880 }
881
David Tolnay0a89b4d2017-11-13 00:55:45 -0800882 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700883 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700884 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700885 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700886 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700887 self.ty.ty.to_tokens(tokens);
888 }
889 }
890
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800891 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700892 fn to_tokens(&self, tokens: &mut Tokens) {
893 self.ty.to_tokens(tokens)
894 }
895 }
896
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800897 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700898 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700899 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700900 }
901 }
902
David Tolnay05362582017-12-26 01:33:57 -0500903 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700904 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700905 self.paren_token.surround(tokens, |tokens| {
906 self.tys.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400907 // XXX: I don't think (,) is a thing.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700908 self.lone_comma.to_tokens(tokens);
909 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700910 }
911 }
912
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800913 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700914 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700915 PathTokens(&self.qself, &self.path).to_tokens(tokens);
916 }
917 }
918
919 impl<'a> ToTokens for PathTokens<'a> {
920 fn to_tokens(&self, tokens: &mut Tokens) {
921 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700922 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700923 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700924 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700925 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700926 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400927
928 // XXX: Gross.
929 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
930 self.1.segments.len() - 1
931 } else {
932 qself.position
933 };
David Tolnay570695e2017-06-03 16:15:13 -0700934 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400935 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700936 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700937 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700938 for (i, segment) in (&mut segments).take(pos).enumerate() {
939 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700940 segment.item().to_tokens(tokens);
941 qself.gt_token.to_tokens(tokens);
942 segment.delimiter().to_tokens(tokens);
943 } else {
944 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700945 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700946 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700947 } else {
948 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700949 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700950 }
David Tolnay570695e2017-06-03 16:15:13 -0700951 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700952 segment.to_tokens(tokens);
953 }
954 }
955 }
956
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800957 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700958 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500959 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700960 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700961 }
962 }
963
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800964 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700965 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700966 self.impl_token.to_tokens(tokens);
967 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700968 }
969 }
970
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800971 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400972 fn to_tokens(&self, tokens: &mut Tokens) {
973 self.group_token.surround(tokens, |tokens| {
974 self.ty.to_tokens(tokens);
975 });
976 }
977 }
978
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800979 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -0700980 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700981 self.paren_token.surround(tokens, |tokens| {
982 self.ty.to_tokens(tokens);
983 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700984 }
985 }
986
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800987 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -0700988 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700989 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700990 }
991 }
992
David Tolnay47a877c2016-10-01 16:50:55 -0700993 impl ToTokens for Mutability {
994 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700995 if let Mutability::Mutable(ref t) = *self {
996 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -0700997 }
998 }
999 }
1000
David Tolnay87d0b442016-09-04 11:52:12 -07001001 impl ToTokens for Path {
1002 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001003 self.leading_colon.to_tokens(tokens);
1004 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001005 }
1006 }
1007
1008 impl ToTokens for PathSegment {
1009 fn to_tokens(&self, tokens: &mut Tokens) {
1010 self.ident.to_tokens(tokens);
Nika Layzellc08227a2017-12-04 16:30:17 -05001011 self.arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001012 }
1013 }
1014
Nika Layzellc08227a2017-12-04 16:30:17 -05001015 impl ToTokens for PathArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001016 fn to_tokens(&self, tokens: &mut Tokens) {
1017 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001018 PathArguments::None => {}
1019 PathArguments::AngleBracketed(ref arguments) => {
1020 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001021 }
Nika Layzellc08227a2017-12-04 16:30:17 -05001022 PathArguments::Parenthesized(ref arguments) => {
1023 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001024 }
1025 }
1026 }
1027 }
1028
Nika Layzellc08227a2017-12-04 16:30:17 -05001029 impl ToTokens for GenericArgument {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001030 #[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
Nika Layzell357885a2017-12-04 15:47:07 -05001031 fn to_tokens(&self, tokens: &mut Tokens) {
1032 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001033 GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
1034 GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
1035 GenericArgument::TypeBinding(ref tb) => tb.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001036 GenericArgument::Const(ref e) => match e.node {
1037 ExprKind::Lit(_) => e.to_tokens(tokens),
1038
1039 // NOTE: We should probably support parsing blocks with only
1040 // expressions in them without the full feature for const
1041 // generics.
1042 #[cfg(feature = "full")]
1043 ExprKind::Block(_) => e.to_tokens(tokens),
1044
1045 // ERROR CORRECTION: Add braces to make sure that the
1046 // generated code is valid.
David Tolnay32954ef2017-12-26 22:43:16 -05001047 _ => token::Brace::default().surround(tokens, |tokens| {
Nika Layzellce37f332017-12-05 12:01:22 -05001048 e.to_tokens(tokens);
1049 }),
David Tolnay51382052017-12-27 13:46:21 -05001050 },
Nika Layzell357885a2017-12-04 15:47:07 -05001051 }
1052 }
1053 }
1054
Nika Layzellc08227a2017-12-04 16:30:17 -05001055 impl ToTokens for AngleBracketedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001056 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -07001057 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001058 self.lt_token.to_tokens(tokens);
Nika Layzell357885a2017-12-04 15:47:07 -05001059 self.args.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001060 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001061 }
1062 }
1063
1064 impl ToTokens for TypeBinding {
1065 fn to_tokens(&self, tokens: &mut Tokens) {
1066 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001067 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001068 self.ty.to_tokens(tokens);
1069 }
1070 }
1071
Nika Layzellc08227a2017-12-04 16:30:17 -05001072 impl ToTokens for ParenthesizedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001073 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001074 self.paren_token.surround(tokens, |tokens| {
1075 self.inputs.to_tokens(tokens);
1076 });
1077 self.output.to_tokens(tokens);
1078 }
1079 }
1080
David Tolnayf93b90d2017-11-11 19:21:26 -08001081 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001082 fn to_tokens(&self, tokens: &mut Tokens) {
1083 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001084 ReturnType::Default => {}
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001085 ReturnType::Type(ref ty, ref arrow) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001086 arrow.to_tokens(tokens);
1087 ty.to_tokens(tokens);
1088 }
David Tolnay87d0b442016-09-04 11:52:12 -07001089 }
1090 }
1091 }
1092
1093 impl ToTokens for PolyTraitRef {
1094 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001095 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001096 self.trait_ref.to_tokens(tokens);
1097 }
1098 }
1099
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001100 impl ToTokens for BareFnType {
David Tolnay87d0b442016-09-04 11:52:12 -07001101 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001102 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001103 self.unsafety.to_tokens(tokens);
1104 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001105 self.fn_token.to_tokens(tokens);
1106 self.paren_token.surround(tokens, |tokens| {
1107 self.inputs.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001108 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001109 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001110 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001111 self.variadic.to_tokens(tokens);
1112 });
1113 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001114 }
1115 }
1116
David Tolnay62f374c2016-10-02 13:37:00 -07001117 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001118 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001119 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001120 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001121 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001122 }
1123 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001124 }
1125 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001126
Alex Crichton23a15f62017-08-28 12:34:23 -07001127 impl ToTokens for BareFnArgName {
1128 fn to_tokens(&self, tokens: &mut Tokens) {
1129 match *self {
1130 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1131 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1132 }
1133 }
1134 }
1135
David Tolnayb8d8ef52016-10-29 14:30:08 -07001136 impl ToTokens for Unsafety {
1137 fn to_tokens(&self, tokens: &mut Tokens) {
1138 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001139 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001140 Unsafety::Normal => {
1141 // nothing
1142 }
1143 }
1144 }
1145 }
1146
1147 impl ToTokens for Abi {
1148 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001149 self.extern_token.to_tokens(tokens);
1150 match self.kind {
1151 AbiKind::Named(ref named) => named.to_tokens(tokens),
1152 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001153 }
1154 }
1155 }
David Tolnay87d0b442016-09-04 11:52:12 -07001156}