blob: ec35b277efc9b9fb0b8de35db6c48a42d9aabc9c [file] [log] [blame]
David Tolnayf2cfd722017-12-31 18:02:51 -05001use punctuated::Punctuated;
David Tolnayb79ee962016-09-04 09:39:20 -07002use super::*;
David Tolnay2ae520a2017-12-29 11:19:50 -05003use proc_macro2::TokenStream;
4#[cfg(feature = "extra-traits")]
5use std::hash::{Hash, Hasher};
6#[cfg(feature = "extra-traits")]
David Tolnayc43b44e2017-12-30 23:55:54 -05007use tt::TokenStreamHelper;
David Tolnayb79ee962016-09-04 09:39:20 -07008
Alex Crichton62a0a592017-05-22 13:58:53 -07009ast_enum_of_structs! {
10 /// The different kinds of types recognized by the compiler
David Tolnayfd6bf5c2017-11-12 09:41:14 -080011 pub enum Type {
Alex Crichton62a0a592017-05-22 13:58:53 -070012 /// A variable-length array (`[T]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080013 pub Slice(TypeSlice {
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>,
Alex Crichton62a0a592017-05-22 13:58:53 -070016 }),
17 /// A fixed length array (`[T; n]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080018 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050019 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050020 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050022 pub len: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070023 }),
24 /// A raw pointer (`*const T` or `*mut T`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080025 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080026 pub star_token: Token![*],
27 pub const_token: Option<Token![const]>,
David Tolnay136aaa32017-12-29 02:37:36 -050028 pub mutability: Option<Token![mut]>,
29 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
31 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080032 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080033 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050035 pub mutability: Option<Token![mut]>,
36 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070037 }),
38 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080039 pub BareFn(TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -050040 pub unsafety: Option<Token![unsafe]>,
41 pub abi: Option<Abi>,
42 pub fn_token: Token![fn],
43 pub lifetimes: Option<BoundLifetimes>,
44 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050045 pub inputs: Punctuated<BareFnArg, Token![,]>,
David Tolnaybe7a9592017-12-29 02:39:53 -050046 pub variadic: Option<Token![...]>,
47 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070048 }),
49 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080050 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080051 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070053 /// A tuple (`(A, B, C, D, ...)`)
David Tolnay05362582017-12-26 01:33:57 -050054 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050055 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050056 pub elems: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070057 }),
58 /// A path (`module::module::...::Type`), optionally
59 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
60 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050061 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080062 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070063 pub qself: Option<QSelf>,
64 pub path: Path,
65 }),
66 /// A trait object type `Bound1 + Bound2 + Bound3`
67 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080068 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050069 pub dyn_token: Option<Token![dyn]>,
David Tolnayf2cfd722017-12-31 18:02:51 -050070 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070071 }),
72 /// An `impl Bound1 + Bound2 + Bound3` type
73 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080074 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080075 pub impl_token: Token![impl],
David Tolnayf2cfd722017-12-31 18:02:51 -050076 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
78 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080079 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -050080 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -050081 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070082 }),
Michael Layzell93c36282017-06-04 20:43:14 -040083 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080084 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -050085 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -050086 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040087 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080088 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070089 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080090 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080091 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070093 /// A macro in the type position.
David Tolnay323279a2017-12-29 11:26:32 -050094 pub Macro(TypeMacro {
95 pub mac: Macro,
96 }),
David Tolnay2ae520a2017-12-29 11:19:50 -050097 pub Verbatim(TypeVerbatim #manual_extra_traits {
98 pub tts: TokenStream,
99 }),
100 }
101}
102
103#[cfg(feature = "extra-traits")]
104impl Eq for TypeVerbatim {}
105
106#[cfg(feature = "extra-traits")]
107impl PartialEq for TypeVerbatim {
108 fn eq(&self, other: &Self) -> bool {
109 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
110 }
111}
112
113#[cfg(feature = "extra-traits")]
114impl Hash for TypeVerbatim {
115 fn hash<H>(&self, state: &mut H)
116 where
117 H: Hasher,
118 {
119 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 }
121}
122
123ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700124 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800125 pub extern_token: Token![extern],
David Tolnayd5125762017-12-29 02:42:17 -0500126 pub name: Option<Lit>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700127 }
128}
129
130ast_struct! {
131 /// An argument in a function type.
132 ///
133 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
134 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800135 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800136 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700137 }
138}
139
Alex Crichton23a15f62017-08-28 12:34:23 -0700140ast_enum! {
141 /// Names of arguments in the `BareFnArg` structure
142 pub enum BareFnArgName {
143 /// Argument with the provided name
144 Named(Ident),
145 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800146 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700147 }
148}
Alex Crichton62a0a592017-05-22 13:58:53 -0700149
150ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800151 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700152 /// Return type is not specified.
153 ///
154 /// Functions default to `()` and
155 /// closures default to inference. Span points to where return
156 /// type would be inserted.
157 Default,
158 /// Everything else
David Tolnay4a3f59a2017-12-28 21:21:12 -0500159 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700160 }
David Tolnayb79ee962016-09-04 09:39:20 -0700161}
162
David Tolnay86eca752016-09-04 11:26:41 -0700163#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700164pub mod parsing {
165 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400166 use synom::Synom;
David Tolnay056de302018-01-05 14:29:05 -0800167 use path::parsing::qpath;
David Tolnayda4049b2016-09-04 10:59:23 -0700168
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800169 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400170 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700171
Alex Crichton954046c2017-05-30 21:49:42 -0700172 fn description() -> Option<&'static str> {
173 Some("type")
174 }
175 }
David Tolnay0047c712016-12-21 21:59:25 -0500176
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800177 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400178 /// In some positions, types may not contain the `+` character, to
179 /// disambiguate them. For example in the expression `1 as T`, T may not
180 /// contain a `+` character.
181 ///
182 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400183 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400184 }
185
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800186 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
187 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400188 |
David Tolnay05362582017-12-26 01:33:57 -0500189 // must be before TypeTuple
David Tolnay0a169d42017-12-29 17:57:29 -0500190 call!(TypeParen::parse, allow_plus) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400191 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500192 // must be before TypePath
David Tolnay323279a2017-12-29 11:26:32 -0500193 syn!(TypeMacro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400194 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500195 // must be before TypeTraitObject
196 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400197 |
David Tolnay0a169d42017-12-29 17:57:29 -0500198 // Don't try parsing more than one trait bound if we aren't allowing it.
199 // must be before TypeTuple
200 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
201 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800202 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400203 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800204 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400205 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800206 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400207 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800208 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400209 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800210 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400211 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800212 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400213 |
David Tolnay05362582017-12-26 01:33:57 -0500214 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400215 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800216 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700217 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800218 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400219 ));
220
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800221 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400222 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800223 brackets!(syn!(Type)),
David Tolnay8875fca2017-12-31 13:52:37 -0500224 |(b, ty)| TypeSlice {
David Tolnayeadbda32017-12-29 02:33:47 -0500225 elem: Box::new(ty),
Michael Layzell92639a52017-06-01 00:07:44 -0400226 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700227 }
Michael Layzell92639a52017-06-01 00:07:44 -0400228 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800229
230 fn description() -> Option<&'static str> {
231 Some("slice type")
232 }
Alex Crichton954046c2017-05-30 21:49:42 -0700233 }
David Tolnayb79ee962016-09-04 09:39:20 -0700234
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800235 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400236 named!(parse -> Self, map!(
237 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800238 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800239 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400240 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700241 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400242 )),
David Tolnay8875fca2017-12-31 13:52:37 -0500243 |(brackets, (elem, semi, len))| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800244 TypeArray {
David Tolnayeadbda32017-12-29 02:33:47 -0500245 elem: Box::new(elem),
246 len: len,
Michael Layzell92639a52017-06-01 00:07:44 -0400247 bracket_token: brackets,
248 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700249 }
250 }
Michael Layzell92639a52017-06-01 00:07:44 -0400251 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800252
253 fn description() -> Option<&'static str> {
254 Some("array type")
255 }
Alex Crichton954046c2017-05-30 21:49:42 -0700256 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700257
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800258 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400259 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800260 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400261 mutability: alt!(
David Tolnay24237fb2017-12-29 02:15:26 -0500262 keyword!(const) => { |c| (None, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400263 |
David Tolnay24237fb2017-12-29 02:15:26 -0500264 keyword!(mut) => { |m| (Some(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400265 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800266 target: call!(Type::without_plus) >>
267 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400268 const_token: mutability.1,
269 star_token: star,
David Tolnay136aaa32017-12-29 02:37:36 -0500270 mutability: mutability.0,
271 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400272 })
273 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800274
275 fn description() -> Option<&'static str> {
276 Some("raw pointer type")
277 }
Alex Crichton954046c2017-05-30 21:49:42 -0700278 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700279
David Tolnay0a89b4d2017-11-13 00:55:45 -0800280 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400281 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800282 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400283 life: option!(syn!(Lifetime)) >>
David Tolnay24237fb2017-12-29 02:15:26 -0500284 mutability: option!(keyword!(mut)) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400285 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800286 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800287 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400288 lifetime: life,
David Tolnay136aaa32017-12-29 02:37:36 -0500289 mutability: mutability,
290 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400291 and_token: amp,
292 })
293 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800294
295 fn description() -> Option<&'static str> {
296 Some("reference type")
297 }
Alex Crichton954046c2017-05-30 21:49:42 -0700298 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700299
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800300 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400301 named!(parse -> Self, do_parse!(
302 lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnay9b258702017-12-29 02:24:41 -0500303 unsafety: option!(keyword!(unsafe)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400304 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800305 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400306 parens: parens!(do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500307 inputs: call!(Punctuated::parse_terminated) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500308 variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400309 (inputs, variadic)
310 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800311 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800312 (TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -0500313 unsafety: unsafety,
314 abi: abi,
315 lifetimes: lifetimes,
316 output: output,
David Tolnay8875fca2017-12-31 13:52:37 -0500317 variadic: (parens.1).1,
David Tolnaybe7a9592017-12-29 02:39:53 -0500318 fn_token: fn_,
David Tolnay8875fca2017-12-31 13:52:37 -0500319 paren_token: parens.0,
320 inputs: (parens.1).0,
Michael Layzell92639a52017-06-01 00:07:44 -0400321 })
322 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800323
324 fn description() -> Option<&'static str> {
325 Some("`fn` type")
326 }
Alex Crichton954046c2017-05-30 21:49:42 -0700327 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700328
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800329 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400330 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800331 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800332 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400333 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800334
335 fn description() -> Option<&'static str> {
336 Some("never type: `!`")
337 }
Alex Crichton954046c2017-05-30 21:49:42 -0700338 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700339
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800340 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700341 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800342 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800343 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700344 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800345
346 fn description() -> Option<&'static str> {
347 Some("inferred type: `_`")
348 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700349 }
350
David Tolnay05362582017-12-26 01:33:57 -0500351 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400352 named!(parse -> Self, do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500353 data: parens!(Punctuated::parse_terminated) >>
David Tolnay05362582017-12-26 01:33:57 -0500354 (TypeTuple {
David Tolnay8875fca2017-12-31 13:52:37 -0500355 paren_token: data.0,
356 elems: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400357 })
358 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800359
360 fn description() -> Option<&'static str> {
361 Some("tuple type")
362 }
Alex Crichton954046c2017-05-30 21:49:42 -0700363 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700364
David Tolnay323279a2017-12-29 11:26:32 -0500365 impl Synom for TypeMacro {
366 named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
367 }
368
David Tolnay0a169d42017-12-29 17:57:29 -0500369 impl Synom for TypePath {
370 named!(parse -> Self, call!(Self::parse, false));
371 }
372
David Tolnay7d38c7e2017-12-25 22:31:50 -0500373 impl TypePath {
374 named!(parse(allow_plus: bool) -> Self, do_parse!(
375 qpath: qpath >>
David Tolnay660fd1f2017-12-31 01:52:57 -0500376 parenthesized: option!(cond_reduce!(
David Tolnay7d38c7e2017-12-25 22:31:50 -0500377 qpath.1.segments.last().unwrap().item().arguments.is_empty(),
David Tolnay660fd1f2017-12-31 01:52:57 -0500378 syn!(ParenthesizedGenericArguments)
379 )) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500380 cond!(allow_plus, not!(punct!(+))) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500381 ({
382 let (qself, mut path) = qpath;
David Tolnay660fd1f2017-12-31 01:52:57 -0500383 if let Some(parenthesized) = parenthesized {
David Tolnay7d38c7e2017-12-25 22:31:50 -0500384 let parenthesized = PathArguments::Parenthesized(parenthesized);
385 path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
386 }
387 TypePath { qself: qself, path: path }
388 })
389 ));
390 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700391
David Tolnayf93b90d2017-11-11 19:21:26 -0800392 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400393 named!(parse -> Self, alt!(
394 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800395 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800396 ty: syn!(Type) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -0500397 (ReturnType::Type(arrow, Box::new(ty)))
Michael Layzell92639a52017-06-01 00:07:44 -0400398 )
399 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800400 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400401 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800402
403 fn description() -> Option<&'static str> {
404 Some("return type")
405 }
Alex Crichton954046c2017-05-30 21:49:42 -0700406 }
407
David Tolnay0a169d42017-12-29 17:57:29 -0500408 impl Synom for TypeTraitObject {
409 named!(parse -> Self, call!(Self::parse, true));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800410
411 fn description() -> Option<&'static str> {
412 Some("trait object type")
413 }
David Tolnay0a169d42017-12-29 17:57:29 -0500414 }
415
David Tolnay7d38c7e2017-12-25 22:31:50 -0500416 impl TypeTraitObject {
David Tolnay0a169d42017-12-29 17:57:29 -0500417 named!(pub without_plus -> Self, call!(Self::parse, false));
418
David Tolnay7d38c7e2017-12-25 22:31:50 -0500419 // Only allow multiple trait references if allow_plus is true.
420 named!(parse(allow_plus: bool) -> Self, do_parse!(
421 dyn_token: option!(keyword!(dyn)) >>
422 bounds: alt!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500423 cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
David Tolnay7d38c7e2017-12-25 22:31:50 -0500424 |
David Tolnay660fd1f2017-12-31 01:52:57 -0500425 syn!(TypeParamBound) => {|x| {
David Tolnayf2cfd722017-12-31 18:02:51 -0500426 let mut bounds = Punctuated::new();
David Tolnaya0834b42018-01-01 21:30:02 -0800427 bounds.push_item(x);
David Tolnayf2cfd722017-12-31 18:02:51 -0500428 bounds
David Tolnay660fd1f2017-12-31 01:52:57 -0500429 }}
David Tolnay7d38c7e2017-12-25 22:31:50 -0500430 ) >>
431 (TypeTraitObject {
432 dyn_token: dyn_token,
433 bounds: bounds,
434 })
435 ));
436 }
David Tolnay6414da72016-10-08 00:55:17 -0700437
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800438 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400439 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800440 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400441 // NOTE: rust-lang/rust#34511 includes discussion about whether or
442 // not + should be allowed in ImplTrait directly without ().
David Tolnayf2cfd722017-12-31 18:02:51 -0500443 elem: call!(Punctuated::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800444 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400445 impl_token: impl_,
446 bounds: elem,
447 })
448 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800449
450 fn description() -> Option<&'static str> {
451 Some("`impl Trait` type")
452 }
Alex Crichton954046c2017-05-30 21:49:42 -0700453 }
David Tolnayb79ee962016-09-04 09:39:20 -0700454
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800455 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400456 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800457 data: grouped!(syn!(Type)) >>
458 (TypeGroup {
David Tolnay8875fca2017-12-31 13:52:37 -0500459 group_token: data.0,
460 elem: Box::new(data.1),
Michael Layzell93c36282017-06-04 20:43:14 -0400461 })
462 ));
463 }
464
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800465 impl Synom for TypeParen {
David Tolnay0a169d42017-12-29 17:57:29 -0500466 named!(parse -> Self, call!(Self::parse, false));
467 }
468
469 impl TypeParen {
470 named!(parse(allow_plus: bool) -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800471 data: parens!(syn!(Type)) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500472 cond!(allow_plus, not!(punct!(+))) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800473 (TypeParen {
David Tolnay8875fca2017-12-31 13:52:37 -0500474 paren_token: data.0,
475 elem: Box::new(data.1),
Michael Layzell92639a52017-06-01 00:07:44 -0400476 })
477 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700478 }
David Tolnayb79ee962016-09-04 09:39:20 -0700479
Alex Crichton954046c2017-05-30 21:49:42 -0700480 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400481 named!(parse -> Self, do_parse!(
482 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700483 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800484 not!(punct!(::)) >>
485 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400486 (name, colon)
487 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800488 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400489 (BareFnArg {
490 name: name,
491 ty: ty,
492 })
493 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800494
495 fn description() -> Option<&'static str> {
496 Some("function type argument")
497 }
Alex Crichton954046c2017-05-30 21:49:42 -0700498 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700499
Alex Crichton23a15f62017-08-28 12:34:23 -0700500 impl Synom for BareFnArgName {
501 named!(parse -> Self, alt!(
502 map!(syn!(Ident), BareFnArgName::Named)
503 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800504 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700505 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800506
507 fn description() -> Option<&'static str> {
508 Some("function argument name")
509 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700510 }
511
Alex Crichton954046c2017-05-30 21:49:42 -0700512 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400513 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800514 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400515 // TODO: this parses all literals, not just strings
516 name: option!(syn!(Lit)) >>
517 (Abi {
518 extern_token: extern_,
David Tolnayd5125762017-12-29 02:42:17 -0500519 name: name,
Michael Layzell92639a52017-06-01 00:07:44 -0400520 })
521 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800522
523 fn description() -> Option<&'static str> {
524 Some("ABI qualifier")
525 }
Alex Crichton954046c2017-05-30 21:49:42 -0700526 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700527}
David Tolnay87d0b442016-09-04 11:52:12 -0700528
529#[cfg(feature = "printing")]
530mod printing {
531 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500532 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700533
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800534 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700535 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500537 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 }
540 }
541
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800542 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700543 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500545 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500547 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700548 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700549 }
550 }
551
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800552 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700553 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700554 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500555 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500556 Some(ref tok) => tok.to_tokens(tokens),
557 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700558 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400559 }
560 }
David Tolnay136aaa32017-12-29 02:37:36 -0500561 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 }
563 }
564
David Tolnay0a89b4d2017-11-13 00:55:45 -0800565 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700566 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700567 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700568 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500569 self.mutability.to_tokens(tokens);
570 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 }
572 }
573
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800574 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700575 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500576 self.lifetimes.to_tokens(tokens);
577 self.unsafety.to_tokens(tokens);
578 self.abi.to_tokens(tokens);
579 self.fn_token.to_tokens(tokens);
580 self.paren_token.surround(tokens, |tokens| {
581 self.inputs.to_tokens(tokens);
582 if let Some(ref variadic) = self.variadic {
583 if !self.inputs.empty_or_trailing() {
584 let span = variadic.0[0];
585 <Token![,]>::new(span).to_tokens(tokens);
586 }
587 variadic.to_tokens(tokens);
588 }
589 });
590 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700591 }
592 }
593
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800594 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700595 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700596 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700597 }
598 }
599
David Tolnay05362582017-12-26 01:33:57 -0500600 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700601 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700602 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500603 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700604 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 }
606 }
607
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800608 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700609 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700610 PathTokens(&self.qself, &self.path).to_tokens(tokens);
611 }
612 }
613
614 impl<'a> ToTokens for PathTokens<'a> {
615 fn to_tokens(&self, tokens: &mut Tokens) {
616 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700617 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700618 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700619 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700620 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700621 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400622
623 // XXX: Gross.
624 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
625 self.1.segments.len() - 1
626 } else {
627 qself.position
628 };
David Tolnay6eff4da2018-01-01 20:27:45 -0800629 let mut segments = self.1.segments.elements();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400630 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700631 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700632 self.1.leading_colon.to_tokens(tokens);
David Tolnay6eff4da2018-01-01 20:27:45 -0800633 for (i, segment) in segments.by_ref().take(pos).enumerate() {
David Tolnay570695e2017-06-03 16:15:13 -0700634 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700635 segment.item().to_tokens(tokens);
636 qself.gt_token.to_tokens(tokens);
David Tolnayf2cfd722017-12-31 18:02:51 -0500637 segment.punct().to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700638 } else {
639 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700640 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700641 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700642 } else {
643 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700644 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700645 }
David Tolnay570695e2017-06-03 16:15:13 -0700646 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700647 segment.to_tokens(tokens);
648 }
649 }
650 }
651
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800652 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700653 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500654 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700655 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700656 }
657 }
658
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800659 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700660 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700661 self.impl_token.to_tokens(tokens);
662 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700663 }
664 }
665
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800666 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400667 fn to_tokens(&self, tokens: &mut Tokens) {
668 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500669 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400670 });
671 }
672 }
673
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800674 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -0700675 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700676 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500677 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700678 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700679 }
680 }
681
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800682 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -0700683 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700684 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700685 }
686 }
687
David Tolnay323279a2017-12-29 11:26:32 -0500688 impl ToTokens for TypeMacro {
689 fn to_tokens(&self, tokens: &mut Tokens) {
690 self.mac.to_tokens(tokens);
691 }
692 }
693
David Tolnay2ae520a2017-12-29 11:19:50 -0500694 impl ToTokens for TypeVerbatim {
695 fn to_tokens(&self, tokens: &mut Tokens) {
696 self.tts.to_tokens(tokens);
697 }
698 }
699
David Tolnayf93b90d2017-11-11 19:21:26 -0800700 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700701 fn to_tokens(&self, tokens: &mut Tokens) {
702 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -0800703 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -0500704 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700705 arrow.to_tokens(tokens);
706 ty.to_tokens(tokens);
707 }
David Tolnay87d0b442016-09-04 11:52:12 -0700708 }
709 }
710 }
711
David Tolnay62f374c2016-10-02 13:37:00 -0700712 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -0700713 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700714 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700715 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700716 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700717 }
718 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700719 }
720 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700721
Alex Crichton23a15f62017-08-28 12:34:23 -0700722 impl ToTokens for BareFnArgName {
723 fn to_tokens(&self, tokens: &mut Tokens) {
724 match *self {
725 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
726 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
727 }
728 }
729 }
730
David Tolnayb8d8ef52016-10-29 14:30:08 -0700731 impl ToTokens for Abi {
732 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700733 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -0500734 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -0700735 }
736 }
David Tolnay87d0b442016-09-04 11:52:12 -0700737}