blob: 64acae8f7a3ec7c8fff2b42f462bd042538099d8 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
David Tolnayf2cfd722017-12-31 18:02:51 -05009use punctuated::Punctuated;
David Tolnayb79ee962016-09-04 09:39:20 -070010use super::*;
David Tolnay2ae520a2017-12-29 11:19:50 -050011use proc_macro2::TokenStream;
12#[cfg(feature = "extra-traits")]
13use std::hash::{Hash, Hasher};
14#[cfg(feature = "extra-traits")]
David Tolnayc43b44e2017-12-30 23:55:54 -050015use tt::TokenStreamHelper;
David Tolnayb79ee962016-09-04 09:39:20 -070016
Alex Crichton62a0a592017-05-22 13:58:53 -070017ast_enum_of_structs! {
18 /// The different kinds of types recognized by the compiler
David Tolnayfd6bf5c2017-11-12 09:41:14 -080019 pub enum Type {
Alex Crichton62a0a592017-05-22 13:58:53 -070020 /// A variable-length array (`[T]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080021 pub Slice(TypeSlice {
David Tolnay32954ef2017-12-26 22:43:16 -050022 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050023 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070024 }),
25 /// A fixed length array (`[T; n]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080026 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050027 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050028 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080029 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050030 pub len: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070031 }),
32 /// A raw pointer (`*const T` or `*mut T`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080033 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080034 pub star_token: Token![*],
35 pub const_token: Option<Token![const]>,
David Tolnay136aaa32017-12-29 02:37:36 -050036 pub mutability: Option<Token![mut]>,
37 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070038 }),
39 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080040 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080041 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070042 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050043 pub mutability: Option<Token![mut]>,
44 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070045 }),
46 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080047 pub BareFn(TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -050048 pub unsafety: Option<Token![unsafe]>,
49 pub abi: Option<Abi>,
50 pub fn_token: Token![fn],
51 pub lifetimes: Option<BoundLifetimes>,
52 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050053 pub inputs: Punctuated<BareFnArg, Token![,]>,
David Tolnaybe7a9592017-12-29 02:39:53 -050054 pub variadic: Option<Token![...]>,
55 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070056 }),
57 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080058 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080059 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070060 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070061 /// A tuple (`(A, B, C, D, ...)`)
David Tolnay05362582017-12-26 01:33:57 -050062 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050063 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050064 pub elems: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070065 }),
66 /// A path (`module::module::...::Type`), optionally
67 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
68 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050069 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080070 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070071 pub qself: Option<QSelf>,
72 pub path: Path,
73 }),
74 /// A trait object type `Bound1 + Bound2 + Bound3`
75 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080076 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050077 pub dyn_token: Option<Token![dyn]>,
David Tolnayf2cfd722017-12-31 18:02:51 -050078 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070079 }),
80 /// An `impl Bound1 + Bound2 + Bound3` type
81 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080082 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080083 pub impl_token: Token![impl],
David Tolnayf2cfd722017-12-31 18:02:51 -050084 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070085 }),
86 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080087 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -050088 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -050089 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070090 }),
Michael Layzell93c36282017-06-04 20:43:14 -040091 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080092 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -050093 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -050094 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040095 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080096 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070097 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080098 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080099 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700100 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700101 /// A macro in the type position.
David Tolnay323279a2017-12-29 11:26:32 -0500102 pub Macro(TypeMacro {
103 pub mac: Macro,
104 }),
David Tolnay2ae520a2017-12-29 11:19:50 -0500105 pub Verbatim(TypeVerbatim #manual_extra_traits {
106 pub tts: TokenStream,
107 }),
108 }
109}
110
111#[cfg(feature = "extra-traits")]
112impl Eq for TypeVerbatim {}
113
114#[cfg(feature = "extra-traits")]
115impl PartialEq for TypeVerbatim {
116 fn eq(&self, other: &Self) -> bool {
117 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
118 }
119}
120
121#[cfg(feature = "extra-traits")]
122impl Hash for TypeVerbatim {
123 fn hash<H>(&self, state: &mut H)
124 where
125 H: Hasher,
126 {
127 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700128 }
129}
130
131ast_struct! {
David Tolnayf01e37b2018-01-06 23:38:26 -0800132 /// The binary interface of a function: `extern "C"`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700133 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800134 pub extern_token: Token![extern],
David Tolnayf01e37b2018-01-06 23:38:26 -0800135 pub name: Option<LitStr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 }
137}
138
139ast_struct! {
140 /// An argument in a function type.
141 ///
142 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
143 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800144 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800145 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700146 }
147}
148
Alex Crichton23a15f62017-08-28 12:34:23 -0700149ast_enum! {
150 /// Names of arguments in the `BareFnArg` structure
151 pub enum BareFnArgName {
152 /// Argument with the provided name
153 Named(Ident),
154 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800155 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700156 }
157}
Alex Crichton62a0a592017-05-22 13:58:53 -0700158
159ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800160 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 /// Return type is not specified.
162 ///
163 /// Functions default to `()` and
164 /// closures default to inference. Span points to where return
165 /// type would be inserted.
166 Default,
167 /// Everything else
David Tolnay4a3f59a2017-12-28 21:21:12 -0500168 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 }
David Tolnayb79ee962016-09-04 09:39:20 -0700170}
171
David Tolnay86eca752016-09-04 11:26:41 -0700172#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700173pub mod parsing {
174 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400175 use synom::Synom;
David Tolnay056de302018-01-05 14:29:05 -0800176 use path::parsing::qpath;
David Tolnayda4049b2016-09-04 10:59:23 -0700177
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800178 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400179 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700180
Alex Crichton954046c2017-05-30 21:49:42 -0700181 fn description() -> Option<&'static str> {
182 Some("type")
183 }
184 }
David Tolnay0047c712016-12-21 21:59:25 -0500185
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800186 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400187 /// In some positions, types may not contain the `+` character, to
188 /// disambiguate them. For example in the expression `1 as T`, T may not
189 /// contain a `+` character.
190 ///
191 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400192 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400193 }
194
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800195 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
196 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400197 |
David Tolnay05362582017-12-26 01:33:57 -0500198 // must be before TypeTuple
David Tolnay0a169d42017-12-29 17:57:29 -0500199 call!(TypeParen::parse, allow_plus) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400200 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500201 // must be before TypePath
David Tolnay323279a2017-12-29 11:26:32 -0500202 syn!(TypeMacro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400203 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500204 // must be before TypeTraitObject
205 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400206 |
David Tolnay0a169d42017-12-29 17:57:29 -0500207 // Don't try parsing more than one trait bound if we aren't allowing it.
208 // must be before TypeTuple
209 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
210 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800211 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400212 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800213 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400214 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800215 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400216 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800217 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400218 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800219 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400220 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800221 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400222 |
David Tolnay05362582017-12-26 01:33:57 -0500223 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400224 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800225 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700226 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800227 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400228 ));
229
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800230 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400231 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800232 brackets!(syn!(Type)),
David Tolnay8875fca2017-12-31 13:52:37 -0500233 |(b, ty)| TypeSlice {
David Tolnayeadbda32017-12-29 02:33:47 -0500234 elem: Box::new(ty),
Michael Layzell92639a52017-06-01 00:07:44 -0400235 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700236 }
Michael Layzell92639a52017-06-01 00:07:44 -0400237 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800238
239 fn description() -> Option<&'static str> {
240 Some("slice type")
241 }
Alex Crichton954046c2017-05-30 21:49:42 -0700242 }
David Tolnayb79ee962016-09-04 09:39:20 -0700243
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800244 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400245 named!(parse -> Self, map!(
246 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800247 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800248 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400249 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700250 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400251 )),
David Tolnay8875fca2017-12-31 13:52:37 -0500252 |(brackets, (elem, semi, len))| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800253 TypeArray {
David Tolnayeadbda32017-12-29 02:33:47 -0500254 elem: Box::new(elem),
255 len: len,
Michael Layzell92639a52017-06-01 00:07:44 -0400256 bracket_token: brackets,
257 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700258 }
259 }
Michael Layzell92639a52017-06-01 00:07:44 -0400260 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800261
262 fn description() -> Option<&'static str> {
263 Some("array type")
264 }
Alex Crichton954046c2017-05-30 21:49:42 -0700265 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700266
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800267 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400268 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800269 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400270 mutability: alt!(
David Tolnay24237fb2017-12-29 02:15:26 -0500271 keyword!(const) => { |c| (None, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400272 |
David Tolnay24237fb2017-12-29 02:15:26 -0500273 keyword!(mut) => { |m| (Some(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400274 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800275 target: call!(Type::without_plus) >>
276 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400277 const_token: mutability.1,
278 star_token: star,
David Tolnay136aaa32017-12-29 02:37:36 -0500279 mutability: mutability.0,
280 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400281 })
282 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800283
284 fn description() -> Option<&'static str> {
285 Some("raw pointer type")
286 }
Alex Crichton954046c2017-05-30 21:49:42 -0700287 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700288
David Tolnay0a89b4d2017-11-13 00:55:45 -0800289 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400290 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800291 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400292 life: option!(syn!(Lifetime)) >>
David Tolnay24237fb2017-12-29 02:15:26 -0500293 mutability: option!(keyword!(mut)) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400294 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800295 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800296 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400297 lifetime: life,
David Tolnay136aaa32017-12-29 02:37:36 -0500298 mutability: mutability,
299 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400300 and_token: amp,
301 })
302 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800303
304 fn description() -> Option<&'static str> {
305 Some("reference type")
306 }
Alex Crichton954046c2017-05-30 21:49:42 -0700307 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700308
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800309 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400310 named!(parse -> Self, do_parse!(
311 lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnay9b258702017-12-29 02:24:41 -0500312 unsafety: option!(keyword!(unsafe)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400313 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800314 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400315 parens: parens!(do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500316 inputs: call!(Punctuated::parse_terminated) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500317 variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400318 (inputs, variadic)
319 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800320 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800321 (TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -0500322 unsafety: unsafety,
323 abi: abi,
324 lifetimes: lifetimes,
325 output: output,
David Tolnay8875fca2017-12-31 13:52:37 -0500326 variadic: (parens.1).1,
David Tolnaybe7a9592017-12-29 02:39:53 -0500327 fn_token: fn_,
David Tolnay8875fca2017-12-31 13:52:37 -0500328 paren_token: parens.0,
329 inputs: (parens.1).0,
Michael Layzell92639a52017-06-01 00:07:44 -0400330 })
331 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800332
333 fn description() -> Option<&'static str> {
334 Some("`fn` type")
335 }
Alex Crichton954046c2017-05-30 21:49:42 -0700336 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700337
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800338 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400339 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800340 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800341 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400342 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800343
344 fn description() -> Option<&'static str> {
345 Some("never type: `!`")
346 }
Alex Crichton954046c2017-05-30 21:49:42 -0700347 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700348
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800349 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700350 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800351 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800352 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700353 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800354
355 fn description() -> Option<&'static str> {
356 Some("inferred type: `_`")
357 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700358 }
359
David Tolnay05362582017-12-26 01:33:57 -0500360 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400361 named!(parse -> Self, do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500362 data: parens!(Punctuated::parse_terminated) >>
David Tolnay05362582017-12-26 01:33:57 -0500363 (TypeTuple {
David Tolnay8875fca2017-12-31 13:52:37 -0500364 paren_token: data.0,
365 elems: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400366 })
367 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800368
369 fn description() -> Option<&'static str> {
370 Some("tuple type")
371 }
Alex Crichton954046c2017-05-30 21:49:42 -0700372 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700373
David Tolnay323279a2017-12-29 11:26:32 -0500374 impl Synom for TypeMacro {
375 named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
376 }
377
David Tolnay0a169d42017-12-29 17:57:29 -0500378 impl Synom for TypePath {
379 named!(parse -> Self, call!(Self::parse, false));
380 }
381
David Tolnay7d38c7e2017-12-25 22:31:50 -0500382 impl TypePath {
383 named!(parse(allow_plus: bool) -> Self, do_parse!(
384 qpath: qpath >>
David Tolnay660fd1f2017-12-31 01:52:57 -0500385 parenthesized: option!(cond_reduce!(
David Tolnay56080682018-01-06 14:01:52 -0800386 qpath.1.segments.last().unwrap().value().arguments.is_empty(),
David Tolnay660fd1f2017-12-31 01:52:57 -0500387 syn!(ParenthesizedGenericArguments)
388 )) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500389 cond!(allow_plus, not!(punct!(+))) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500390 ({
391 let (qself, mut path) = qpath;
David Tolnay660fd1f2017-12-31 01:52:57 -0500392 if let Some(parenthesized) = parenthesized {
David Tolnay7d38c7e2017-12-25 22:31:50 -0500393 let parenthesized = PathArguments::Parenthesized(parenthesized);
David Tolnay56080682018-01-06 14:01:52 -0800394 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
David Tolnay7d38c7e2017-12-25 22:31:50 -0500395 }
396 TypePath { qself: qself, path: path }
397 })
398 ));
399 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700400
David Tolnayf93b90d2017-11-11 19:21:26 -0800401 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400402 named!(parse -> Self, alt!(
403 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800404 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800405 ty: syn!(Type) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -0500406 (ReturnType::Type(arrow, Box::new(ty)))
Michael Layzell92639a52017-06-01 00:07:44 -0400407 )
408 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800409 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400410 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800411
412 fn description() -> Option<&'static str> {
413 Some("return type")
414 }
Alex Crichton954046c2017-05-30 21:49:42 -0700415 }
416
David Tolnay0a169d42017-12-29 17:57:29 -0500417 impl Synom for TypeTraitObject {
418 named!(parse -> Self, call!(Self::parse, true));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800419
420 fn description() -> Option<&'static str> {
421 Some("trait object type")
422 }
David Tolnay0a169d42017-12-29 17:57:29 -0500423 }
424
David Tolnay7d38c7e2017-12-25 22:31:50 -0500425 impl TypeTraitObject {
David Tolnay0a169d42017-12-29 17:57:29 -0500426 named!(pub without_plus -> Self, call!(Self::parse, false));
427
David Tolnay7d38c7e2017-12-25 22:31:50 -0500428 // Only allow multiple trait references if allow_plus is true.
429 named!(parse(allow_plus: bool) -> Self, do_parse!(
430 dyn_token: option!(keyword!(dyn)) >>
431 bounds: alt!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500432 cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
David Tolnay7d38c7e2017-12-25 22:31:50 -0500433 |
David Tolnay660fd1f2017-12-31 01:52:57 -0500434 syn!(TypeParamBound) => {|x| {
David Tolnayf2cfd722017-12-31 18:02:51 -0500435 let mut bounds = Punctuated::new();
David Tolnay56080682018-01-06 14:01:52 -0800436 bounds.push_value(x);
David Tolnayf2cfd722017-12-31 18:02:51 -0500437 bounds
David Tolnay660fd1f2017-12-31 01:52:57 -0500438 }}
David Tolnay7d38c7e2017-12-25 22:31:50 -0500439 ) >>
440 (TypeTraitObject {
441 dyn_token: dyn_token,
442 bounds: bounds,
443 })
444 ));
445 }
David Tolnay6414da72016-10-08 00:55:17 -0700446
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800447 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400448 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800449 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400450 // NOTE: rust-lang/rust#34511 includes discussion about whether or
451 // not + should be allowed in ImplTrait directly without ().
David Tolnayf2cfd722017-12-31 18:02:51 -0500452 elem: call!(Punctuated::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800453 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400454 impl_token: impl_,
455 bounds: elem,
456 })
457 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800458
459 fn description() -> Option<&'static str> {
460 Some("`impl Trait` type")
461 }
Alex Crichton954046c2017-05-30 21:49:42 -0700462 }
David Tolnayb79ee962016-09-04 09:39:20 -0700463
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800464 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400465 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800466 data: grouped!(syn!(Type)) >>
467 (TypeGroup {
David Tolnay8875fca2017-12-31 13:52:37 -0500468 group_token: data.0,
469 elem: Box::new(data.1),
Michael Layzell93c36282017-06-04 20:43:14 -0400470 })
471 ));
472 }
473
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800474 impl Synom for TypeParen {
David Tolnay0a169d42017-12-29 17:57:29 -0500475 named!(parse -> Self, call!(Self::parse, false));
476 }
477
478 impl TypeParen {
479 named!(parse(allow_plus: bool) -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800480 data: parens!(syn!(Type)) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500481 cond!(allow_plus, not!(punct!(+))) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800482 (TypeParen {
David Tolnay8875fca2017-12-31 13:52:37 -0500483 paren_token: data.0,
484 elem: Box::new(data.1),
Michael Layzell92639a52017-06-01 00:07:44 -0400485 })
486 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700487 }
David Tolnayb79ee962016-09-04 09:39:20 -0700488
Alex Crichton954046c2017-05-30 21:49:42 -0700489 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400490 named!(parse -> Self, do_parse!(
491 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700492 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800493 not!(punct!(::)) >>
494 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400495 (name, colon)
496 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800497 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400498 (BareFnArg {
499 name: name,
500 ty: ty,
501 })
502 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800503
504 fn description() -> Option<&'static str> {
505 Some("function type argument")
506 }
Alex Crichton954046c2017-05-30 21:49:42 -0700507 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700508
Alex Crichton23a15f62017-08-28 12:34:23 -0700509 impl Synom for BareFnArgName {
510 named!(parse -> Self, alt!(
511 map!(syn!(Ident), BareFnArgName::Named)
512 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800513 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700514 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800515
516 fn description() -> Option<&'static str> {
517 Some("function argument name")
518 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700519 }
520
Alex Crichton954046c2017-05-30 21:49:42 -0700521 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400522 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800523 extern_: keyword!(extern) >>
David Tolnayf01e37b2018-01-06 23:38:26 -0800524 name: option!(syn!(LitStr)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400525 (Abi {
526 extern_token: extern_,
David Tolnayd5125762017-12-29 02:42:17 -0500527 name: name,
Michael Layzell92639a52017-06-01 00:07:44 -0400528 })
529 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800530
531 fn description() -> Option<&'static str> {
532 Some("ABI qualifier")
533 }
Alex Crichton954046c2017-05-30 21:49:42 -0700534 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700535}
David Tolnay87d0b442016-09-04 11:52:12 -0700536
537#[cfg(feature = "printing")]
538mod printing {
539 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500540 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700541
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800542 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -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 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700547 }
548 }
549
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800550 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700551 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700552 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500553 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700554 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500555 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700557 }
558 }
559
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800560 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700561 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700562 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500563 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500564 Some(ref tok) => tok.to_tokens(tokens),
565 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700566 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400567 }
568 }
David Tolnay136aaa32017-12-29 02:37:36 -0500569 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700570 }
571 }
572
David Tolnay0a89b4d2017-11-13 00:55:45 -0800573 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700574 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500577 self.mutability.to_tokens(tokens);
578 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700579 }
580 }
581
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800582 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700583 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500584 self.lifetimes.to_tokens(tokens);
585 self.unsafety.to_tokens(tokens);
586 self.abi.to_tokens(tokens);
587 self.fn_token.to_tokens(tokens);
588 self.paren_token.surround(tokens, |tokens| {
589 self.inputs.to_tokens(tokens);
590 if let Some(ref variadic) = self.variadic {
591 if !self.inputs.empty_or_trailing() {
592 let span = variadic.0[0];
593 <Token![,]>::new(span).to_tokens(tokens);
594 }
595 variadic.to_tokens(tokens);
596 }
597 });
598 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700599 }
600 }
601
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800602 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700604 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 }
606 }
607
David Tolnay05362582017-12-26 01:33:57 -0500608 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700609 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700610 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500611 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700612 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700613 }
614 }
615
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800616 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700617 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700618 PathTokens(&self.qself, &self.path).to_tokens(tokens);
619 }
620 }
621
622 impl<'a> ToTokens for PathTokens<'a> {
623 fn to_tokens(&self, tokens: &mut Tokens) {
624 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700625 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700626 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700627 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700628 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700629 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400630
631 // XXX: Gross.
632 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
633 self.1.segments.len() - 1
634 } else {
635 qself.position
636 };
David Tolnay56080682018-01-06 14:01:52 -0800637 let mut segments = self.1.segments.pairs();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400638 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700639 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700640 self.1.leading_colon.to_tokens(tokens);
David Tolnay6eff4da2018-01-01 20:27:45 -0800641 for (i, segment) in segments.by_ref().take(pos).enumerate() {
David Tolnay570695e2017-06-03 16:15:13 -0700642 if i + 1 == pos {
David Tolnay56080682018-01-06 14:01:52 -0800643 segment.value().to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700644 qself.gt_token.to_tokens(tokens);
David Tolnayf2cfd722017-12-31 18:02:51 -0500645 segment.punct().to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700646 } else {
647 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700648 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700649 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700650 } else {
651 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700652 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700653 }
David Tolnay570695e2017-06-03 16:15:13 -0700654 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700655 segment.to_tokens(tokens);
656 }
657 }
658 }
659
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800660 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700661 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500662 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700663 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700664 }
665 }
666
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800667 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700668 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700669 self.impl_token.to_tokens(tokens);
670 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700671 }
672 }
673
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800674 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400675 fn to_tokens(&self, tokens: &mut Tokens) {
676 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500677 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400678 });
679 }
680 }
681
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800682 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -0700683 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700684 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500685 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700686 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700687 }
688 }
689
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800690 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -0700691 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700692 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700693 }
694 }
695
David Tolnay323279a2017-12-29 11:26:32 -0500696 impl ToTokens for TypeMacro {
697 fn to_tokens(&self, tokens: &mut Tokens) {
698 self.mac.to_tokens(tokens);
699 }
700 }
701
David Tolnay2ae520a2017-12-29 11:19:50 -0500702 impl ToTokens for TypeVerbatim {
703 fn to_tokens(&self, tokens: &mut Tokens) {
704 self.tts.to_tokens(tokens);
705 }
706 }
707
David Tolnayf93b90d2017-11-11 19:21:26 -0800708 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700709 fn to_tokens(&self, tokens: &mut Tokens) {
710 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -0800711 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -0500712 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700713 arrow.to_tokens(tokens);
714 ty.to_tokens(tokens);
715 }
David Tolnay87d0b442016-09-04 11:52:12 -0700716 }
717 }
718 }
719
David Tolnay62f374c2016-10-02 13:37:00 -0700720 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -0700721 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700722 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700723 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700724 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700725 }
726 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700727 }
728 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700729
Alex Crichton23a15f62017-08-28 12:34:23 -0700730 impl ToTokens for BareFnArgName {
731 fn to_tokens(&self, tokens: &mut Tokens) {
732 match *self {
733 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
734 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
735 }
736 }
737 }
738
David Tolnayb8d8ef52016-10-29 14:30:08 -0700739 impl ToTokens for Abi {
740 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700741 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -0500742 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -0700743 }
744 }
David Tolnay87d0b442016-09-04 11:52:12 -0700745}