blob: 5b8c81937182ccc6139e80354cc049d329d975b7 [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 {
David Tolnay32954ef2017-12-26 22:43:16 -05009 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050010 pub elem: Box<Type>,
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 Tolnayeadbda32017-12-29 02:33:47 -050015 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080016 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050017 pub len: 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 Tolnay136aaa32017-12-29 02:37:36 -050023 pub mutability: Option<Token![mut]>,
24 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070025 }),
26 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080027 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080028 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070029 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050030 pub mutability: Option<Token![mut]>,
31 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070032 }),
33 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080034 pub BareFn(TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -050035 pub unsafety: Option<Token![unsafe]>,
36 pub abi: Option<Abi>,
37 pub fn_token: Token![fn],
38 pub lifetimes: Option<BoundLifetimes>,
39 pub paren_token: token::Paren,
40 pub inputs: Delimited<BareFnArg, Token![,]>,
41 pub variadic: Option<Token![...]>,
42 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
44 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080045 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080046 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070047 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070048 /// A tuple (`(A, B, C, D, ...)`)
David Tolnay05362582017-12-26 01:33:57 -050049 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050050 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -050051 pub elems: Delimited<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070052 }),
53 /// A path (`module::module::...::Type`), optionally
54 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
55 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050056 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080057 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070058 pub qself: Option<QSelf>,
59 pub path: Path,
60 }),
61 /// A trait object type `Bound1 + Bound2 + Bound3`
62 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080063 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050064 pub dyn_token: Option<Token![dyn]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080065 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070066 }),
67 /// An `impl Bound1 + Bound2 + Bound3` type
68 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080069 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080070 pub impl_token: Token![impl],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080071 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070072 }),
73 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080074 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -050075 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -050076 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Michael Layzell93c36282017-06-04 20:43:14 -040078 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080079 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -050080 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -050081 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040082 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080083 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070084 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080085 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080086 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070087 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070088 /// A macro in the type position.
David Tolnaydecf28d2017-11-11 11:56:45 -080089 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -070090 }
91}
92
93ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -070094 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -070095 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070096 /// It's represented as a sequence of identifiers,
97 /// along with a bunch of supporting information.
98 ///
99 /// E.g. `std::cmp::PartialEq`
100 pub struct Path {
101 /// A `::foo` path, is relative to the crate root rather than current
102 /// module (like paths in an import).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800103 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 /// The segments in the path: the things separated by `::`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800105 pub segments: Delimited<PathSegment, Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 }
David Tolnayb79ee962016-09-04 09:39:20 -0700107}
108
David Tolnay570695e2017-06-03 16:15:13 -0700109impl Path {
110 pub fn global(&self) -> bool {
111 self.leading_colon.is_some()
112 }
113}
114
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700115#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400116#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
117#[cfg_attr(feature = "clone-impls", derive(Clone))]
118pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700119
David Tolnaydaaf7742016-10-03 11:11:43 -0700120impl<T> From<T> for Path
David Tolnay51382052017-12-27 13:46:21 -0500121where
122 T: Into<PathSegment>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700123{
David Tolnay84aa0752016-10-02 23:01:13 -0700124 fn from(segment: T) -> Self {
125 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126 leading_colon: None,
127 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700128 }
129 }
130}
131
Alex Crichton62a0a592017-05-22 13:58:53 -0700132ast_struct! {
133 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
134 ///
135 /// E.g. `std`, `String` or `Box<T>`
136 pub struct PathSegment {
137 /// The identifier portion of this path segment.
138 pub ident: Ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500139 /// Type/lifetime arguments attached to this path. They come in
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
141 /// this is more than just simple syntactic sugar; the use of
142 /// parens affects the region binding rules, so we preserve the
143 /// distinction.
Nika Layzellc08227a2017-12-04 16:30:17 -0500144 pub arguments: PathArguments,
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }
David Tolnayb79ee962016-09-04 09:39:20 -0700146}
147
David Tolnaydaaf7742016-10-03 11:11:43 -0700148impl<T> From<T> for PathSegment
David Tolnay51382052017-12-27 13:46:21 -0500149where
150 T: Into<Ident>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700151{
David Tolnay84aa0752016-10-02 23:01:13 -0700152 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700153 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700154 ident: ident.into(),
Nika Layzellc08227a2017-12-04 16:30:17 -0500155 arguments: PathArguments::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700156 }
157 }
158}
159
Alex Crichton62a0a592017-05-22 13:58:53 -0700160ast_enum! {
Nika Layzellc08227a2017-12-04 16:30:17 -0500161 /// Arguments of a path segment.
Alex Crichton62a0a592017-05-22 13:58:53 -0700162 ///
163 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
Nika Layzellc08227a2017-12-04 16:30:17 -0500164 pub enum PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700165 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700166 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500167 AngleBracketed(AngleBracketedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700168 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500169 Parenthesized(ParenthesizedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700170 }
David Tolnayb79ee962016-09-04 09:39:20 -0700171}
172
Nika Layzellc08227a2017-12-04 16:30:17 -0500173impl Default for PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700174 fn default() -> Self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500175 PathArguments::None
David Tolnayb79ee962016-09-04 09:39:20 -0700176 }
David Tolnay570695e2017-06-03 16:15:13 -0700177}
David Tolnay5332d4b2016-10-30 14:25:22 -0700178
Nika Layzellc08227a2017-12-04 16:30:17 -0500179impl PathArguments {
David Tolnay5332d4b2016-10-30 14:25:22 -0700180 pub fn is_empty(&self) -> bool {
181 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500182 PathArguments::None => true,
183 PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
184 PathArguments::Parenthesized(_) => false,
David Tolnay5332d4b2016-10-30 14:25:22 -0700185 }
186 }
David Tolnayb79ee962016-09-04 09:39:20 -0700187}
188
Nika Layzell357885a2017-12-04 15:47:07 -0500189ast_enum! {
190 /// A individual generic argument, like `'a`, `T`, or `Item=T`.
Nika Layzellc08227a2017-12-04 16:30:17 -0500191 pub enum GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500192 /// The lifetime parameters for this path segment.
193 Lifetime(Lifetime),
194 /// The type parameters for this path segment, if present.
195 Type(Type),
196 /// Bindings (equality constraints) on associated types, if present.
197 ///
198 /// E.g., `Foo<A=Bar>`.
199 TypeBinding(TypeBinding),
Nika Layzellc680e612017-12-04 19:07:20 -0500200 /// Const expression. Must be inside of a block.
201 ///
202 /// NOTE: Identity expressions are represented as Type arguments, as
203 /// they are indistinguishable syntactically.
Nika Layzellce37f332017-12-05 12:01:22 -0500204 Const(Expr),
Nika Layzell357885a2017-12-04 15:47:07 -0500205 }
206}
207
Alex Crichton62a0a592017-05-22 13:58:53 -0700208ast_struct! {
209 /// A path like `Foo<'a, T>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500210 pub struct AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500211 pub colon2_token: Option<Token![::]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800212 pub lt_token: Token![<],
Nika Layzellc08227a2017-12-04 16:30:17 -0500213 pub args: Delimited<GenericArgument, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800214 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700215 }
216}
217
218ast_struct! {
219 /// Bind a type to an associated type: `A=Foo`.
220 pub struct TypeBinding {
221 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800222 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800223 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700224 }
225}
226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227ast_struct! {
228 /// A path like `Foo(A,B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500229 pub struct ParenthesizedGenericArguments {
David Tolnay32954ef2017-12-26 22:43:16 -0500230 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 /// `(A, B)`
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800232 pub inputs: Delimited<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700233 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800234 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700235 }
236}
237
238ast_struct! {
239 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700240 /// The `for<'a>` in `for<'a> Foo<&'a T>`
241 pub bound_lifetimes: Option<BoundLifetimes>,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500242 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 pub trait_ref: Path,
244 }
245}
246
247ast_struct! {
248 /// The explicit Self type in a "qualified path". The actual
249 /// path, including the trait and the associated item, is stored
250 /// separately. `position` represents the index of the associated
251 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700252 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500253 /// ```text
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 /// <Vec<T> as a::b::Trait>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500255 /// ^~~~~~ ~~~~~~~~~~~~~~^
Alex Crichton62a0a592017-05-22 13:58:53 -0700256 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700257 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 /// <Vec<T>>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500259 /// ^~~~~~ ^
Alex Crichton62a0a592017-05-22 13:58:53 -0700260 /// ty position = 0
261 /// ```
262 pub struct QSelf {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800263 pub lt_token: Token![<],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800264 pub ty: Box<Type>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400265 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800266 pub as_token: Option<Token![as]>,
267 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700268 }
269}
270
271ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700272 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800273 pub extern_token: Token![extern],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700274 pub kind: AbiKind,
275 }
276}
277
Alex Crichton62a0a592017-05-22 13:58:53 -0700278ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700279 pub enum AbiKind {
280 Named(Lit),
281 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 }
283}
284
285ast_struct! {
286 /// An argument in a function type.
287 ///
288 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
289 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800290 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800291 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 }
293}
294
Alex Crichton23a15f62017-08-28 12:34:23 -0700295ast_enum! {
296 /// Names of arguments in the `BareFnArg` structure
297 pub enum BareFnArgName {
298 /// Argument with the provided name
299 Named(Ident),
300 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800301 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700302 }
303}
Alex Crichton62a0a592017-05-22 13:58:53 -0700304
305ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800306 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700307 /// Return type is not specified.
308 ///
309 /// Functions default to `()` and
310 /// closures default to inference. Span points to where return
311 /// type would be inserted.
312 Default,
313 /// Everything else
David Tolnay4a3f59a2017-12-28 21:21:12 -0500314 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 }
David Tolnayb79ee962016-09-04 09:39:20 -0700316}
317
David Tolnay86eca752016-09-04 11:26:41 -0700318#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700319pub mod parsing {
320 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400321 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700322
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800323 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400324 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700325
Alex Crichton954046c2017-05-30 21:49:42 -0700326 fn description() -> Option<&'static str> {
327 Some("type")
328 }
329 }
David Tolnay0047c712016-12-21 21:59:25 -0500330
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800331 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400332 /// In some positions, types may not contain the `+` character, to
333 /// disambiguate them. For example in the expression `1 as T`, T may not
334 /// contain a `+` character.
335 ///
336 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400337 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400338 }
339
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800340 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
341 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400342 |
David Tolnay05362582017-12-26 01:33:57 -0500343 // must be before TypeTuple
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800344 syn!(TypeParen) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400345 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500346 // must be before TypePath
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800347 syn!(Macro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400348 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500349 // must be before TypeTraitObject
350 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400351 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800352 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400353 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800354 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400355 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800356 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400357 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800358 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400359 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800360 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400361 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800362 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400363 |
David Tolnay05362582017-12-26 01:33:57 -0500364 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400365 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500366 // Don't try parsing more than one trait bound if we aren't allowing it
367 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400368 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800369 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700370 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800371 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400372 ));
373
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800374 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400375 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800376 brackets!(syn!(Type)),
377 |(ty, b)| TypeSlice {
David Tolnayeadbda32017-12-29 02:33:47 -0500378 elem: Box::new(ty),
Michael Layzell92639a52017-06-01 00:07:44 -0400379 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700380 }
Michael Layzell92639a52017-06-01 00:07:44 -0400381 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700382 }
David Tolnayb79ee962016-09-04 09:39:20 -0700383
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800384 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400385 named!(parse -> Self, map!(
386 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800387 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800388 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400389 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700390 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400391 )),
392 |((elem, semi, len), brackets)| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800393 TypeArray {
David Tolnayeadbda32017-12-29 02:33:47 -0500394 elem: Box::new(elem),
395 len: len,
Michael Layzell92639a52017-06-01 00:07:44 -0400396 bracket_token: brackets,
397 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700398 }
399 }
Michael Layzell92639a52017-06-01 00:07:44 -0400400 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700401 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700402
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800403 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400404 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800405 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400406 mutability: alt!(
David Tolnay24237fb2017-12-29 02:15:26 -0500407 keyword!(const) => { |c| (None, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400408 |
David Tolnay24237fb2017-12-29 02:15:26 -0500409 keyword!(mut) => { |m| (Some(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400410 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800411 target: call!(Type::without_plus) >>
412 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400413 const_token: mutability.1,
414 star_token: star,
David Tolnay136aaa32017-12-29 02:37:36 -0500415 mutability: mutability.0,
416 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400417 })
418 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700419 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700420
David Tolnay0a89b4d2017-11-13 00:55:45 -0800421 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400422 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800423 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400424 life: option!(syn!(Lifetime)) >>
David Tolnay24237fb2017-12-29 02:15:26 -0500425 mutability: option!(keyword!(mut)) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400426 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800427 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800428 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400429 lifetime: life,
David Tolnay136aaa32017-12-29 02:37:36 -0500430 mutability: mutability,
431 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400432 and_token: amp,
433 })
434 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700435 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700436
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800437 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400438 named!(parse -> Self, do_parse!(
439 lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnay9b258702017-12-29 02:24:41 -0500440 unsafety: option!(keyword!(unsafe)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400441 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800442 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400443 parens: parens!(do_parse!(
444 inputs: call!(Delimited::parse_terminated) >>
445 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800446 punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400447 (inputs, variadic)
448 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800449 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800450 (TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -0500451 unsafety: unsafety,
452 abi: abi,
453 lifetimes: lifetimes,
454 output: output,
455 variadic: (parens.0).1,
456 fn_token: fn_,
457 paren_token: parens.1,
458 inputs: (parens.0).0,
Michael Layzell92639a52017-06-01 00:07:44 -0400459 })
460 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700461 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700462
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800463 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400464 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800465 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800466 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400467 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700468 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700469
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800470 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700471 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800472 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800473 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700474 ));
475 }
476
David Tolnay05362582017-12-26 01:33:57 -0500477 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400478 named!(parse -> Self, do_parse!(
479 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -0500480 (TypeTuple {
David Tolnayeadbda32017-12-29 02:33:47 -0500481 elems: data.0,
Michael Layzell92639a52017-06-01 00:07:44 -0400482 paren_token: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400483 })
484 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700485 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700486
David Tolnay7d38c7e2017-12-25 22:31:50 -0500487 impl TypePath {
488 named!(parse(allow_plus: bool) -> Self, do_parse!(
489 qpath: qpath >>
490 parenthesized: cond!(
491 qpath.1.segments.last().unwrap().item().arguments.is_empty(),
492 option!(syn!(ParenthesizedGenericArguments))
493 ) >>
494 cond!(allow_plus, not!(peek!(punct!(+)))) >>
495 ({
496 let (qself, mut path) = qpath;
497 if let Some(Some(parenthesized)) = parenthesized {
498 let parenthesized = PathArguments::Parenthesized(parenthesized);
499 path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
500 }
501 TypePath { qself: qself, path: path }
502 })
503 ));
504 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700505
David Tolnay9636c052016-10-02 17:11:17 -0700506 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700507 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700508 |
509 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800510 lt: punct!(<) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800511 this: syn!(Type) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500512 path: option!(tuple!(keyword!(as), syn!(Path))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800513 gt: punct!(>) >>
514 colon2: punct!(::) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700515 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700516 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400517 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700518 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700519 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700520 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700521 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700522 }
Alex Crichton954046c2017-05-30 21:49:42 -0700523 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700524 path.segments.push(item);
525 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400526 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700527 }
528 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400529 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700530 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700531 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700532 })
David Tolnay9636c052016-10-02 17:11:17 -0700533 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700534 };
535 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700536 lt_token: lt,
537 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400539 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700540 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700541 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700542 })
543 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700544 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800545 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700546 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700547
Nika Layzellc08227a2017-12-04 16:30:17 -0500548 impl Synom for ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400549 named!(parse -> Self, do_parse!(
550 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800551 output: syn!(ReturnType) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500552 (ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400553 paren_token: data.1,
554 inputs: data.0,
555 output: output,
556 })
557 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700558 }
559
David Tolnayf93b90d2017-11-11 19:21:26 -0800560 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400561 named!(parse -> Self, alt!(
562 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800563 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800564 ty: syn!(Type) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -0500565 (ReturnType::Type(arrow, Box::new(ty)))
Michael Layzell92639a52017-06-01 00:07:44 -0400566 )
567 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800568 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400569 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700570 }
571
David Tolnay7d38c7e2017-12-25 22:31:50 -0500572 impl TypeTraitObject {
573 // Only allow multiple trait references if allow_plus is true.
574 named!(parse(allow_plus: bool) -> Self, do_parse!(
575 dyn_token: option!(keyword!(dyn)) >>
576 bounds: alt!(
577 cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
578 |
579 syn!(TypeParamBound) => { |x| vec![x].into() }
580 ) >>
581 (TypeTraitObject {
582 dyn_token: dyn_token,
583 bounds: bounds,
584 })
585 ));
586 }
David Tolnay6414da72016-10-08 00:55:17 -0700587
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800588 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400589 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800590 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400591 // NOTE: rust-lang/rust#34511 includes discussion about whether or
592 // not + should be allowed in ImplTrait directly without ().
Nika Layzellb49a9e52017-12-05 13:31:52 -0500593 elem: call!(Delimited::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800594 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400595 impl_token: impl_,
596 bounds: elem,
597 })
598 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700599 }
David Tolnayb79ee962016-09-04 09:39:20 -0700600
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800601 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400602 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800603 data: grouped!(syn!(Type)) >>
604 (TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400605 group_token: data.1,
David Tolnayeadbda32017-12-29 02:33:47 -0500606 elem: Box::new(data.0),
Michael Layzell93c36282017-06-04 20:43:14 -0400607 })
608 ));
609 }
610
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800611 impl Synom for TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400612 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800613 data: parens!(syn!(Type)) >>
614 (TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400615 paren_token: data.1,
David Tolnayeadbda32017-12-29 02:33:47 -0500616 elem: Box::new(data.0),
Michael Layzell92639a52017-06-01 00:07:44 -0400617 })
618 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700619 }
David Tolnayb79ee962016-09-04 09:39:20 -0700620
Alex Crichton954046c2017-05-30 21:49:42 -0700621 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400622 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800623 colon: option!(punct!(::)) >>
David Tolnaye45b59f2017-12-25 18:44:49 -0500624 segments: call!(Delimited::<PathSegment, Token![::]>::parse_separated_nonempty) >>
625 cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400626 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700627 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400628 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400629 })
630 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700631
632 fn description() -> Option<&'static str> {
633 Some("path")
634 }
Alex Crichton954046c2017-05-30 21:49:42 -0700635 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700636
Nika Layzellc680e612017-12-04 19:07:20 -0500637 #[cfg(not(feature = "full"))]
Nika Layzellc08227a2017-12-04 16:30:17 -0500638 impl Synom for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500639 named!(parse -> Self, alt!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500640 call!(ty_no_eq_after) => { GenericArgument::Type }
Nika Layzell357885a2017-12-04 15:47:07 -0500641 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500642 syn!(Lifetime) => { GenericArgument::Lifetime }
Nika Layzell357885a2017-12-04 15:47:07 -0500643 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500644 syn!(TypeBinding) => { GenericArgument::TypeBinding }
Nika Layzell357885a2017-12-04 15:47:07 -0500645 ));
646 }
647
Nika Layzellc680e612017-12-04 19:07:20 -0500648 #[cfg(feature = "full")]
649 impl Synom for GenericArgument {
650 named!(parse -> Self, alt!(
651 call!(ty_no_eq_after) => { GenericArgument::Type }
652 |
653 syn!(Lifetime) => { GenericArgument::Lifetime }
654 |
655 syn!(TypeBinding) => { GenericArgument::TypeBinding }
656 |
David Tolnay8c91b882017-12-28 23:04:32 -0500657 syn!(ExprLit) => { |l| GenericArgument::Const(Expr::Lit(l).into()) }
Nika Layzellce37f332017-12-05 12:01:22 -0500658 |
David Tolnay8c91b882017-12-28 23:04:32 -0500659 syn!(ExprBlock) => { |b| GenericArgument::Const(Expr::Block(b).into()) }
Nika Layzellc680e612017-12-04 19:07:20 -0500660 ));
661 }
662
Nika Layzellc08227a2017-12-04 16:30:17 -0500663 impl Synom for AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500664 named!(parse -> Self, do_parse!(
David Tolnay2d4e08a2017-12-28 23:54:07 -0500665 colon2: option!(punct!(::)) >>
Nika Layzell357885a2017-12-04 15:47:07 -0500666 lt: punct!(<) >>
667 args: call!(Delimited::parse_terminated) >>
668 gt: punct!(>) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500669 (AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500670 colon2_token: colon2,
Nika Layzell357885a2017-12-04 15:47:07 -0500671 lt_token: lt,
672 args: args,
673 gt_token: gt,
674 })
675 ));
676 }
677
Alex Crichton954046c2017-05-30 21:49:42 -0700678 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400679 named!(parse -> Self, alt!(
680 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700681 ident: syn!(Ident) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500682 arguments: syn!(AngleBracketedGenericArguments) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400683 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700684 ident: ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500685 arguments: PathArguments::AngleBracketed(arguments),
Michael Layzell92639a52017-06-01 00:07:44 -0400686 })
687 )
688 |
689 mod_style_path_segment
690 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700691 }
David Tolnay570695e2017-06-03 16:15:13 -0700692
David Tolnayd60cfec2017-12-29 00:21:38 -0500693 named!(pub ty_no_eq_after -> Type, terminated!(syn!(Type), not!(punct!(=))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700694
Alex Crichton954046c2017-05-30 21:49:42 -0700695 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400696 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800697 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400698 segments: call!(Delimited::parse_separated_nonempty_with,
699 mod_style_path_segment) >>
700 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700701 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400702 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400703 })
704 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700705 }
Arnavionf2dada12017-04-20 23:55:20 -0700706
707 named!(mod_style_path_segment -> PathSegment, alt!(
David Tolnay5f332a92017-12-26 00:42:45 -0500708 syn!(Ident) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700709 |
David Tolnay5f332a92017-12-26 00:42:45 -0500710 keyword!(super) => { Into::into }
711 |
712 keyword!(self) => { Into::into }
713 |
714 keyword!(Self) => { Into::into }
715 |
716 keyword!(crate) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700717 ));
718
Alex Crichton954046c2017-05-30 21:49:42 -0700719 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400720 named!(parse -> Self, do_parse!(
721 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800722 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800723 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400724 (TypeBinding {
725 ident: id,
726 eq_token: eq,
727 ty: ty,
728 })
729 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700730 }
731
732 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400733 named!(parse -> Self, do_parse!(
734 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
735 trait_ref: syn!(Path) >>
736 parenthesized: option!(cond_reduce!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500737 trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
738 syn!(ParenthesizedGenericArguments)
Michael Layzell92639a52017-06-01 00:07:44 -0400739 )) >>
740 ({
741 let mut trait_ref = trait_ref;
742 if let Some(parenthesized) = parenthesized {
Nika Layzellc08227a2017-12-04 16:30:17 -0500743 let parenthesized = PathArguments::Parenthesized(parenthesized);
Michael Layzell92639a52017-06-01 00:07:44 -0400744 let len = trait_ref.segments.len();
Nika Layzellc08227a2017-12-04 16:30:17 -0500745 trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
Michael Layzell92639a52017-06-01 00:07:44 -0400746 }
747 PolyTraitRef {
748 bound_lifetimes: bound_lifetimes,
749 trait_ref: trait_ref,
750 }
751 })
752 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700753 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700754
Alex Crichton954046c2017-05-30 21:49:42 -0700755 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400756 named!(parse -> Self, do_parse!(
757 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700758 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800759 not!(punct!(::)) >>
760 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400761 (name, colon)
762 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800763 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400764 (BareFnArg {
765 name: name,
766 ty: ty,
767 })
768 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700769 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700770
Alex Crichton23a15f62017-08-28 12:34:23 -0700771 impl Synom for BareFnArgName {
772 named!(parse -> Self, alt!(
773 map!(syn!(Ident), BareFnArgName::Named)
774 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800775 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700776 ));
777 }
778
Alex Crichton954046c2017-05-30 21:49:42 -0700779 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400780 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800781 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400782 // TODO: this parses all literals, not just strings
783 name: option!(syn!(Lit)) >>
784 (Abi {
785 extern_token: extern_,
786 kind: match name {
787 Some(name) => AbiKind::Named(name),
788 None => AbiKind::Default,
789 },
790 })
791 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700792 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700793}
David Tolnay87d0b442016-09-04 11:52:12 -0700794
795#[cfg(feature = "printing")]
796mod printing {
797 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500798 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700799
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800800 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700801 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700802 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500803 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700804 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700805 }
806 }
807
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800808 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700809 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700810 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500811 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700812 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500813 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700814 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700815 }
816 }
817
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800818 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700819 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700820 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500821 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500822 Some(ref tok) => tok.to_tokens(tokens),
823 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700824 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400825 }
826 }
David Tolnay136aaa32017-12-29 02:37:36 -0500827 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700828 }
829 }
830
David Tolnay0a89b4d2017-11-13 00:55:45 -0800831 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700832 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700833 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700834 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500835 self.mutability.to_tokens(tokens);
836 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700837 }
838 }
839
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800840 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700841 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500842 self.lifetimes.to_tokens(tokens);
843 self.unsafety.to_tokens(tokens);
844 self.abi.to_tokens(tokens);
845 self.fn_token.to_tokens(tokens);
846 self.paren_token.surround(tokens, |tokens| {
847 self.inputs.to_tokens(tokens);
848 if let Some(ref variadic) = self.variadic {
849 if !self.inputs.empty_or_trailing() {
850 let span = variadic.0[0];
851 <Token![,]>::new(span).to_tokens(tokens);
852 }
853 variadic.to_tokens(tokens);
854 }
855 });
856 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700857 }
858 }
859
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800860 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700861 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700862 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700863 }
864 }
865
David Tolnay05362582017-12-26 01:33:57 -0500866 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700867 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700868 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500869 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700870 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700871 }
872 }
873
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800874 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700875 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700876 PathTokens(&self.qself, &self.path).to_tokens(tokens);
877 }
878 }
879
880 impl<'a> ToTokens for PathTokens<'a> {
881 fn to_tokens(&self, tokens: &mut Tokens) {
882 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700883 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700884 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700885 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700886 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700887 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400888
889 // XXX: Gross.
890 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
891 self.1.segments.len() - 1
892 } else {
893 qself.position
894 };
David Tolnay570695e2017-06-03 16:15:13 -0700895 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400896 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700897 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700898 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700899 for (i, segment) in (&mut segments).take(pos).enumerate() {
900 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700901 segment.item().to_tokens(tokens);
902 qself.gt_token.to_tokens(tokens);
903 segment.delimiter().to_tokens(tokens);
904 } else {
905 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700906 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700907 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700908 } else {
909 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700910 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700911 }
David Tolnay570695e2017-06-03 16:15:13 -0700912 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700913 segment.to_tokens(tokens);
914 }
915 }
916 }
917
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800918 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700919 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500920 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700921 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700922 }
923 }
924
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800925 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700926 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700927 self.impl_token.to_tokens(tokens);
928 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700929 }
930 }
931
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800932 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400933 fn to_tokens(&self, tokens: &mut Tokens) {
934 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500935 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400936 });
937 }
938 }
939
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800940 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -0700941 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700942 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500943 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700944 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700945 }
946 }
947
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800948 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -0700949 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700950 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700951 }
952 }
953
954 impl ToTokens for Path {
955 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700956 self.leading_colon.to_tokens(tokens);
957 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700958 }
959 }
960
961 impl ToTokens for PathSegment {
962 fn to_tokens(&self, tokens: &mut Tokens) {
963 self.ident.to_tokens(tokens);
Nika Layzellc08227a2017-12-04 16:30:17 -0500964 self.arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700965 }
966 }
967
Nika Layzellc08227a2017-12-04 16:30:17 -0500968 impl ToTokens for PathArguments {
David Tolnay87d0b442016-09-04 11:52:12 -0700969 fn to_tokens(&self, tokens: &mut Tokens) {
970 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500971 PathArguments::None => {}
972 PathArguments::AngleBracketed(ref arguments) => {
973 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700974 }
Nika Layzellc08227a2017-12-04 16:30:17 -0500975 PathArguments::Parenthesized(ref arguments) => {
976 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700977 }
978 }
979 }
980 }
981
Nika Layzellc08227a2017-12-04 16:30:17 -0500982 impl ToTokens for GenericArgument {
David Tolnaybb4ca9f2017-12-26 12:28:58 -0500983 #[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
Nika Layzell357885a2017-12-04 15:47:07 -0500984 fn to_tokens(&self, tokens: &mut Tokens) {
985 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500986 GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
987 GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
988 GenericArgument::TypeBinding(ref tb) => tb.to_tokens(tokens),
David Tolnay8c91b882017-12-28 23:04:32 -0500989 GenericArgument::Const(ref e) => match *e {
990 Expr::Lit(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -0500991
992 // NOTE: We should probably support parsing blocks with only
993 // expressions in them without the full feature for const
994 // generics.
995 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500996 Expr::Block(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -0500997
998 // ERROR CORRECTION: Add braces to make sure that the
999 // generated code is valid.
David Tolnay32954ef2017-12-26 22:43:16 -05001000 _ => token::Brace::default().surround(tokens, |tokens| {
Nika Layzellce37f332017-12-05 12:01:22 -05001001 e.to_tokens(tokens);
1002 }),
David Tolnay51382052017-12-27 13:46:21 -05001003 },
Nika Layzell357885a2017-12-04 15:47:07 -05001004 }
1005 }
1006 }
1007
Nika Layzellc08227a2017-12-04 16:30:17 -05001008 impl ToTokens for AngleBracketedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001009 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay2d4e08a2017-12-28 23:54:07 -05001010 self.colon2_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001011 self.lt_token.to_tokens(tokens);
Nika Layzell357885a2017-12-04 15:47:07 -05001012 self.args.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001013 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001014 }
1015 }
1016
1017 impl ToTokens for TypeBinding {
1018 fn to_tokens(&self, tokens: &mut Tokens) {
1019 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001020 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001021 self.ty.to_tokens(tokens);
1022 }
1023 }
1024
Nika Layzellc08227a2017-12-04 16:30:17 -05001025 impl ToTokens for ParenthesizedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001026 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001027 self.paren_token.surround(tokens, |tokens| {
1028 self.inputs.to_tokens(tokens);
1029 });
1030 self.output.to_tokens(tokens);
1031 }
1032 }
1033
David Tolnayf93b90d2017-11-11 19:21:26 -08001034 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001035 fn to_tokens(&self, tokens: &mut Tokens) {
1036 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001037 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -05001038 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001039 arrow.to_tokens(tokens);
1040 ty.to_tokens(tokens);
1041 }
David Tolnay87d0b442016-09-04 11:52:12 -07001042 }
1043 }
1044 }
1045
1046 impl ToTokens for PolyTraitRef {
1047 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001048 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001049 self.trait_ref.to_tokens(tokens);
1050 }
1051 }
1052
David Tolnay62f374c2016-10-02 13:37:00 -07001053 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001054 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001055 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001056 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001057 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001058 }
1059 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001060 }
1061 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001062
Alex Crichton23a15f62017-08-28 12:34:23 -07001063 impl ToTokens for BareFnArgName {
1064 fn to_tokens(&self, tokens: &mut Tokens) {
1065 match *self {
1066 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1067 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1068 }
1069 }
1070 }
1071
David Tolnayb8d8ef52016-10-29 14:30:08 -07001072 impl ToTokens for Abi {
1073 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001074 self.extern_token.to_tokens(tokens);
1075 match self.kind {
1076 AbiKind::Named(ref named) => named.to_tokens(tokens),
1077 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001078 }
1079 }
1080 }
David Tolnay87d0b442016-09-04 11:52:12 -07001081}