blob: e26c52ec84291bfeb51bf9ec66a5be57988a9cf1 [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use delimited::Delimited;
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")]
7use mac::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,
45 pub inputs: Delimited<BareFnArg, Token![,]>,
46 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 Tolnayeadbda32017-12-29 02:33:47 -050056 pub elems: Delimited<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 Tolnayfd6bf5c2017-11-12 09:41:14 -080070 pub bounds: Delimited<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 Tolnayfd6bf5c2017-11-12 09:41:14 -080076 pub bounds: Delimited<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 Tolnaydecf28d2017-11-11 11:56:45 -080094 pub Macro(Macro),
David Tolnay2ae520a2017-12-29 11:19:50 -050095 pub Verbatim(TypeVerbatim #manual_extra_traits {
96 pub tts: TokenStream,
97 }),
98 }
99}
100
101#[cfg(feature = "extra-traits")]
102impl Eq for TypeVerbatim {}
103
104#[cfg(feature = "extra-traits")]
105impl PartialEq for TypeVerbatim {
106 fn eq(&self, other: &Self) -> bool {
107 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
108 }
109}
110
111#[cfg(feature = "extra-traits")]
112impl Hash for TypeVerbatim {
113 fn hash<H>(&self, state: &mut H)
114 where
115 H: Hasher,
116 {
117 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }
119}
120
121ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700122 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -0700123 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700124 /// It's represented as a sequence of identifiers,
125 /// along with a bunch of supporting information.
126 ///
127 /// E.g. `std::cmp::PartialEq`
128 pub struct Path {
129 /// A `::foo` path, is relative to the crate root rather than current
130 /// module (like paths in an import).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800131 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700132 /// The segments in the path: the things separated by `::`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800133 pub segments: Delimited<PathSegment, Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }
David Tolnayb79ee962016-09-04 09:39:20 -0700135}
136
David Tolnay570695e2017-06-03 16:15:13 -0700137impl Path {
138 pub fn global(&self) -> bool {
139 self.leading_colon.is_some()
140 }
141}
142
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400144#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
145#[cfg_attr(feature = "clone-impls", derive(Clone))]
146pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700147
David Tolnaydaaf7742016-10-03 11:11:43 -0700148impl<T> From<T> for Path
David Tolnay51382052017-12-27 13:46:21 -0500149where
150 T: Into<PathSegment>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700151{
David Tolnay84aa0752016-10-02 23:01:13 -0700152 fn from(segment: T) -> Self {
153 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700154 leading_colon: None,
155 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700156 }
157 }
158}
159
Alex Crichton62a0a592017-05-22 13:58:53 -0700160ast_struct! {
161 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
162 ///
163 /// E.g. `std`, `String` or `Box<T>`
164 pub struct PathSegment {
165 /// The identifier portion of this path segment.
166 pub ident: Ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500167 /// Type/lifetime arguments attached to this path. They come in
Alex Crichton62a0a592017-05-22 13:58:53 -0700168 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
169 /// this is more than just simple syntactic sugar; the use of
170 /// parens affects the region binding rules, so we preserve the
171 /// distinction.
Nika Layzellc08227a2017-12-04 16:30:17 -0500172 pub arguments: PathArguments,
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 }
David Tolnayb79ee962016-09-04 09:39:20 -0700174}
175
David Tolnaydaaf7742016-10-03 11:11:43 -0700176impl<T> From<T> for PathSegment
David Tolnay51382052017-12-27 13:46:21 -0500177where
178 T: Into<Ident>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700179{
David Tolnay84aa0752016-10-02 23:01:13 -0700180 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700181 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700182 ident: ident.into(),
Nika Layzellc08227a2017-12-04 16:30:17 -0500183 arguments: PathArguments::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700184 }
185 }
186}
187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188ast_enum! {
Nika Layzellc08227a2017-12-04 16:30:17 -0500189 /// Arguments of a path segment.
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 ///
191 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
Nika Layzellc08227a2017-12-04 16:30:17 -0500192 pub enum PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700193 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500195 AngleBracketed(AngleBracketedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500197 Parenthesized(ParenthesizedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 }
David Tolnayb79ee962016-09-04 09:39:20 -0700199}
200
Nika Layzellc08227a2017-12-04 16:30:17 -0500201impl Default for PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700202 fn default() -> Self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500203 PathArguments::None
David Tolnayb79ee962016-09-04 09:39:20 -0700204 }
David Tolnay570695e2017-06-03 16:15:13 -0700205}
David Tolnay5332d4b2016-10-30 14:25:22 -0700206
Nika Layzellc08227a2017-12-04 16:30:17 -0500207impl PathArguments {
David Tolnay5332d4b2016-10-30 14:25:22 -0700208 pub fn is_empty(&self) -> bool {
209 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500210 PathArguments::None => true,
211 PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
212 PathArguments::Parenthesized(_) => false,
David Tolnay5332d4b2016-10-30 14:25:22 -0700213 }
214 }
David Tolnayb79ee962016-09-04 09:39:20 -0700215}
216
Nika Layzell357885a2017-12-04 15:47:07 -0500217ast_enum! {
218 /// A individual generic argument, like `'a`, `T`, or `Item=T`.
Nika Layzellc08227a2017-12-04 16:30:17 -0500219 pub enum GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500220 /// The lifetime parameters for this path segment.
221 Lifetime(Lifetime),
222 /// The type parameters for this path segment, if present.
223 Type(Type),
224 /// Bindings (equality constraints) on associated types, if present.
225 ///
226 /// E.g., `Foo<A=Bar>`.
227 TypeBinding(TypeBinding),
Nika Layzellc680e612017-12-04 19:07:20 -0500228 /// Const expression. Must be inside of a block.
229 ///
230 /// NOTE: Identity expressions are represented as Type arguments, as
231 /// they are indistinguishable syntactically.
Nika Layzellce37f332017-12-05 12:01:22 -0500232 Const(Expr),
Nika Layzell357885a2017-12-04 15:47:07 -0500233 }
234}
235
Alex Crichton62a0a592017-05-22 13:58:53 -0700236ast_struct! {
237 /// A path like `Foo<'a, T>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500238 pub struct AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500239 pub colon2_token: Option<Token![::]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800240 pub lt_token: Token![<],
Nika Layzellc08227a2017-12-04 16:30:17 -0500241 pub args: Delimited<GenericArgument, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800242 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 }
244}
245
246ast_struct! {
247 /// Bind a type to an associated type: `A=Foo`.
248 pub struct TypeBinding {
249 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800250 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800251 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 }
253}
254
Alex Crichton62a0a592017-05-22 13:58:53 -0700255ast_struct! {
256 /// A path like `Foo(A,B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500257 pub struct ParenthesizedGenericArguments {
David Tolnay32954ef2017-12-26 22:43:16 -0500258 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700259 /// `(A, B)`
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800260 pub inputs: Delimited<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700261 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800262 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700263 }
264}
265
266ast_struct! {
267 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700268 /// The `for<'a>` in `for<'a> Foo<&'a T>`
269 pub bound_lifetimes: Option<BoundLifetimes>,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500270 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 pub trait_ref: Path,
272 }
273}
274
275ast_struct! {
276 /// The explicit Self type in a "qualified path". The actual
277 /// path, including the trait and the associated item, is stored
278 /// separately. `position` represents the index of the associated
279 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700280 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500281 /// ```text
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 /// <Vec<T> as a::b::Trait>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500283 /// ^~~~~~ ~~~~~~~~~~~~~~^
Alex Crichton62a0a592017-05-22 13:58:53 -0700284 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700285 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 /// <Vec<T>>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500287 /// ^~~~~~ ^
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 /// ty position = 0
289 /// ```
290 pub struct QSelf {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800291 pub lt_token: Token![<],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800292 pub ty: Box<Type>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400293 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800294 pub as_token: Option<Token![as]>,
295 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 }
297}
298
299ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700300 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800301 pub extern_token: Token![extern],
David Tolnayd5125762017-12-29 02:42:17 -0500302 pub name: Option<Lit>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 }
304}
305
306ast_struct! {
307 /// An argument in a function type.
308 ///
309 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
310 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800311 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800312 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700313 }
314}
315
Alex Crichton23a15f62017-08-28 12:34:23 -0700316ast_enum! {
317 /// Names of arguments in the `BareFnArg` structure
318 pub enum BareFnArgName {
319 /// Argument with the provided name
320 Named(Ident),
321 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800322 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700323 }
324}
Alex Crichton62a0a592017-05-22 13:58:53 -0700325
326ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800327 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700328 /// Return type is not specified.
329 ///
330 /// Functions default to `()` and
331 /// closures default to inference. Span points to where return
332 /// type would be inserted.
333 Default,
334 /// Everything else
David Tolnay4a3f59a2017-12-28 21:21:12 -0500335 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 }
David Tolnayb79ee962016-09-04 09:39:20 -0700337}
338
David Tolnay86eca752016-09-04 11:26:41 -0700339#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700340pub mod parsing {
341 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400342 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700343
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800344 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400345 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700346
Alex Crichton954046c2017-05-30 21:49:42 -0700347 fn description() -> Option<&'static str> {
348 Some("type")
349 }
350 }
David Tolnay0047c712016-12-21 21:59:25 -0500351
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800352 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400353 /// In some positions, types may not contain the `+` character, to
354 /// disambiguate them. For example in the expression `1 as T`, T may not
355 /// contain a `+` character.
356 ///
357 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400358 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400359 }
360
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800361 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
362 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400363 |
David Tolnay05362582017-12-26 01:33:57 -0500364 // must be before TypeTuple
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800365 syn!(TypeParen) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400366 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500367 // must be before TypePath
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800368 syn!(Macro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400369 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500370 // must be before TypeTraitObject
371 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400372 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800373 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400374 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800375 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400376 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800377 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400378 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800379 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400380 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800381 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400382 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800383 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400384 |
David Tolnay05362582017-12-26 01:33:57 -0500385 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400386 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500387 // Don't try parsing more than one trait bound if we aren't allowing it
388 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400389 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800390 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700391 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800392 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400393 ));
394
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800395 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400396 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800397 brackets!(syn!(Type)),
398 |(ty, b)| TypeSlice {
David Tolnayeadbda32017-12-29 02:33:47 -0500399 elem: Box::new(ty),
Michael Layzell92639a52017-06-01 00:07:44 -0400400 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700401 }
Michael Layzell92639a52017-06-01 00:07:44 -0400402 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700403 }
David Tolnayb79ee962016-09-04 09:39:20 -0700404
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800405 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400406 named!(parse -> Self, map!(
407 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800408 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800409 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400410 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700411 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400412 )),
413 |((elem, semi, len), brackets)| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800414 TypeArray {
David Tolnayeadbda32017-12-29 02:33:47 -0500415 elem: Box::new(elem),
416 len: len,
Michael Layzell92639a52017-06-01 00:07:44 -0400417 bracket_token: brackets,
418 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700419 }
420 }
Michael Layzell92639a52017-06-01 00:07:44 -0400421 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700422 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700423
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800424 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400425 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800426 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400427 mutability: alt!(
David Tolnay24237fb2017-12-29 02:15:26 -0500428 keyword!(const) => { |c| (None, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400429 |
David Tolnay24237fb2017-12-29 02:15:26 -0500430 keyword!(mut) => { |m| (Some(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400431 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800432 target: call!(Type::without_plus) >>
433 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400434 const_token: mutability.1,
435 star_token: star,
David Tolnay136aaa32017-12-29 02:37:36 -0500436 mutability: mutability.0,
437 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400438 })
439 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700440 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700441
David Tolnay0a89b4d2017-11-13 00:55:45 -0800442 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400443 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800444 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400445 life: option!(syn!(Lifetime)) >>
David Tolnay24237fb2017-12-29 02:15:26 -0500446 mutability: option!(keyword!(mut)) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400447 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800448 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800449 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400450 lifetime: life,
David Tolnay136aaa32017-12-29 02:37:36 -0500451 mutability: mutability,
452 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400453 and_token: amp,
454 })
455 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700456 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700457
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800458 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400459 named!(parse -> Self, do_parse!(
460 lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnay9b258702017-12-29 02:24:41 -0500461 unsafety: option!(keyword!(unsafe)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400462 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800463 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400464 parens: parens!(do_parse!(
465 inputs: call!(Delimited::parse_terminated) >>
466 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800467 punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400468 (inputs, variadic)
469 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800470 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800471 (TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -0500472 unsafety: unsafety,
473 abi: abi,
474 lifetimes: lifetimes,
475 output: output,
476 variadic: (parens.0).1,
477 fn_token: fn_,
478 paren_token: parens.1,
479 inputs: (parens.0).0,
Michael Layzell92639a52017-06-01 00:07:44 -0400480 })
481 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700482 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700483
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800484 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400485 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800486 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800487 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400488 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700489 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700490
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800491 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700492 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800493 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800494 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700495 ));
496 }
497
David Tolnay05362582017-12-26 01:33:57 -0500498 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400499 named!(parse -> Self, do_parse!(
500 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -0500501 (TypeTuple {
David Tolnayeadbda32017-12-29 02:33:47 -0500502 elems: data.0,
Michael Layzell92639a52017-06-01 00:07:44 -0400503 paren_token: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400504 })
505 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700506 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700507
David Tolnay7d38c7e2017-12-25 22:31:50 -0500508 impl TypePath {
509 named!(parse(allow_plus: bool) -> Self, do_parse!(
510 qpath: qpath >>
511 parenthesized: cond!(
512 qpath.1.segments.last().unwrap().item().arguments.is_empty(),
513 option!(syn!(ParenthesizedGenericArguments))
514 ) >>
515 cond!(allow_plus, not!(peek!(punct!(+)))) >>
516 ({
517 let (qself, mut path) = qpath;
518 if let Some(Some(parenthesized)) = parenthesized {
519 let parenthesized = PathArguments::Parenthesized(parenthesized);
520 path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
521 }
522 TypePath { qself: qself, path: path }
523 })
524 ));
525 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700526
David Tolnay9636c052016-10-02 17:11:17 -0700527 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700528 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700529 |
530 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800531 lt: punct!(<) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800532 this: syn!(Type) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500533 path: option!(tuple!(keyword!(as), syn!(Path))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800534 gt: punct!(>) >>
535 colon2: punct!(::) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700536 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700537 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400538 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700539 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700540 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700541 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700542 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700543 }
Alex Crichton954046c2017-05-30 21:49:42 -0700544 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700545 path.segments.push(item);
546 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400547 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700548 }
549 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400550 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700551 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700552 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700553 })
David Tolnay9636c052016-10-02 17:11:17 -0700554 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 };
556 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700557 lt_token: lt,
558 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700559 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400560 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700561 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700562 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700563 })
564 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700565 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800566 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700567 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700568
Nika Layzellc08227a2017-12-04 16:30:17 -0500569 impl Synom for ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400570 named!(parse -> Self, do_parse!(
571 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800572 output: syn!(ReturnType) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500573 (ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400574 paren_token: data.1,
575 inputs: data.0,
576 output: output,
577 })
578 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700579 }
580
David Tolnayf93b90d2017-11-11 19:21:26 -0800581 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400582 named!(parse -> Self, alt!(
583 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800584 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800585 ty: syn!(Type) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -0500586 (ReturnType::Type(arrow, Box::new(ty)))
Michael Layzell92639a52017-06-01 00:07:44 -0400587 )
588 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800589 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400590 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700591 }
592
David Tolnay7d38c7e2017-12-25 22:31:50 -0500593 impl TypeTraitObject {
594 // Only allow multiple trait references if allow_plus is true.
595 named!(parse(allow_plus: bool) -> Self, do_parse!(
596 dyn_token: option!(keyword!(dyn)) >>
597 bounds: alt!(
598 cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
599 |
600 syn!(TypeParamBound) => { |x| vec![x].into() }
601 ) >>
602 (TypeTraitObject {
603 dyn_token: dyn_token,
604 bounds: bounds,
605 })
606 ));
607 }
David Tolnay6414da72016-10-08 00:55:17 -0700608
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800609 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400610 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800611 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400612 // NOTE: rust-lang/rust#34511 includes discussion about whether or
613 // not + should be allowed in ImplTrait directly without ().
Nika Layzellb49a9e52017-12-05 13:31:52 -0500614 elem: call!(Delimited::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800615 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400616 impl_token: impl_,
617 bounds: elem,
618 })
619 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700620 }
David Tolnayb79ee962016-09-04 09:39:20 -0700621
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800622 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400623 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800624 data: grouped!(syn!(Type)) >>
625 (TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400626 group_token: data.1,
David Tolnayeadbda32017-12-29 02:33:47 -0500627 elem: Box::new(data.0),
Michael Layzell93c36282017-06-04 20:43:14 -0400628 })
629 ));
630 }
631
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800632 impl Synom for TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400633 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800634 data: parens!(syn!(Type)) >>
635 (TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400636 paren_token: data.1,
David Tolnayeadbda32017-12-29 02:33:47 -0500637 elem: Box::new(data.0),
Michael Layzell92639a52017-06-01 00:07:44 -0400638 })
639 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700640 }
David Tolnayb79ee962016-09-04 09:39:20 -0700641
Alex Crichton954046c2017-05-30 21:49:42 -0700642 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400643 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800644 colon: option!(punct!(::)) >>
David Tolnaye45b59f2017-12-25 18:44:49 -0500645 segments: call!(Delimited::<PathSegment, Token![::]>::parse_separated_nonempty) >>
646 cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400647 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700648 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400649 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400650 })
651 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700652
653 fn description() -> Option<&'static str> {
654 Some("path")
655 }
Alex Crichton954046c2017-05-30 21:49:42 -0700656 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700657
Nika Layzellc680e612017-12-04 19:07:20 -0500658 #[cfg(not(feature = "full"))]
Nika Layzellc08227a2017-12-04 16:30:17 -0500659 impl Synom for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500660 named!(parse -> Self, alt!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500661 call!(ty_no_eq_after) => { GenericArgument::Type }
Nika Layzell357885a2017-12-04 15:47:07 -0500662 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500663 syn!(Lifetime) => { GenericArgument::Lifetime }
Nika Layzell357885a2017-12-04 15:47:07 -0500664 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500665 syn!(TypeBinding) => { GenericArgument::TypeBinding }
Nika Layzell357885a2017-12-04 15:47:07 -0500666 ));
667 }
668
Nika Layzellc680e612017-12-04 19:07:20 -0500669 #[cfg(feature = "full")]
670 impl Synom for GenericArgument {
671 named!(parse -> Self, alt!(
672 call!(ty_no_eq_after) => { GenericArgument::Type }
673 |
674 syn!(Lifetime) => { GenericArgument::Lifetime }
675 |
676 syn!(TypeBinding) => { GenericArgument::TypeBinding }
677 |
David Tolnay8c91b882017-12-28 23:04:32 -0500678 syn!(ExprLit) => { |l| GenericArgument::Const(Expr::Lit(l).into()) }
Nika Layzellce37f332017-12-05 12:01:22 -0500679 |
David Tolnay8c91b882017-12-28 23:04:32 -0500680 syn!(ExprBlock) => { |b| GenericArgument::Const(Expr::Block(b).into()) }
Nika Layzellc680e612017-12-04 19:07:20 -0500681 ));
682 }
683
Nika Layzellc08227a2017-12-04 16:30:17 -0500684 impl Synom for AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500685 named!(parse -> Self, do_parse!(
David Tolnay2d4e08a2017-12-28 23:54:07 -0500686 colon2: option!(punct!(::)) >>
Nika Layzell357885a2017-12-04 15:47:07 -0500687 lt: punct!(<) >>
688 args: call!(Delimited::parse_terminated) >>
689 gt: punct!(>) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500690 (AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500691 colon2_token: colon2,
Nika Layzell357885a2017-12-04 15:47:07 -0500692 lt_token: lt,
693 args: args,
694 gt_token: gt,
695 })
696 ));
697 }
698
Alex Crichton954046c2017-05-30 21:49:42 -0700699 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400700 named!(parse -> Self, alt!(
701 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700702 ident: syn!(Ident) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500703 arguments: syn!(AngleBracketedGenericArguments) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400704 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700705 ident: ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500706 arguments: PathArguments::AngleBracketed(arguments),
Michael Layzell92639a52017-06-01 00:07:44 -0400707 })
708 )
709 |
710 mod_style_path_segment
711 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700712 }
David Tolnay570695e2017-06-03 16:15:13 -0700713
David Tolnayd60cfec2017-12-29 00:21:38 -0500714 named!(pub ty_no_eq_after -> Type, terminated!(syn!(Type), not!(punct!(=))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700715
Alex Crichton954046c2017-05-30 21:49:42 -0700716 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400717 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800718 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400719 segments: call!(Delimited::parse_separated_nonempty_with,
720 mod_style_path_segment) >>
721 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700722 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400723 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400724 })
725 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700726 }
Arnavionf2dada12017-04-20 23:55:20 -0700727
728 named!(mod_style_path_segment -> PathSegment, alt!(
David Tolnay5f332a92017-12-26 00:42:45 -0500729 syn!(Ident) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700730 |
David Tolnay5f332a92017-12-26 00:42:45 -0500731 keyword!(super) => { Into::into }
732 |
733 keyword!(self) => { Into::into }
734 |
735 keyword!(Self) => { Into::into }
736 |
737 keyword!(crate) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700738 ));
739
Alex Crichton954046c2017-05-30 21:49:42 -0700740 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400741 named!(parse -> Self, do_parse!(
742 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800743 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800744 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400745 (TypeBinding {
746 ident: id,
747 eq_token: eq,
748 ty: ty,
749 })
750 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700751 }
752
753 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400754 named!(parse -> Self, do_parse!(
755 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
756 trait_ref: syn!(Path) >>
757 parenthesized: option!(cond_reduce!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500758 trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
759 syn!(ParenthesizedGenericArguments)
Michael Layzell92639a52017-06-01 00:07:44 -0400760 )) >>
761 ({
762 let mut trait_ref = trait_ref;
763 if let Some(parenthesized) = parenthesized {
Nika Layzellc08227a2017-12-04 16:30:17 -0500764 let parenthesized = PathArguments::Parenthesized(parenthesized);
Michael Layzell92639a52017-06-01 00:07:44 -0400765 let len = trait_ref.segments.len();
Nika Layzellc08227a2017-12-04 16:30:17 -0500766 trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
Michael Layzell92639a52017-06-01 00:07:44 -0400767 }
768 PolyTraitRef {
769 bound_lifetimes: bound_lifetimes,
770 trait_ref: trait_ref,
771 }
772 })
773 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700774 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700775
Alex Crichton954046c2017-05-30 21:49:42 -0700776 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400777 named!(parse -> Self, do_parse!(
778 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700779 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800780 not!(punct!(::)) >>
781 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400782 (name, colon)
783 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800784 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400785 (BareFnArg {
786 name: name,
787 ty: ty,
788 })
789 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700790 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700791
Alex Crichton23a15f62017-08-28 12:34:23 -0700792 impl Synom for BareFnArgName {
793 named!(parse -> Self, alt!(
794 map!(syn!(Ident), BareFnArgName::Named)
795 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800796 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700797 ));
798 }
799
Alex Crichton954046c2017-05-30 21:49:42 -0700800 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400801 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800802 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400803 // TODO: this parses all literals, not just strings
804 name: option!(syn!(Lit)) >>
805 (Abi {
806 extern_token: extern_,
David Tolnayd5125762017-12-29 02:42:17 -0500807 name: name,
Michael Layzell92639a52017-06-01 00:07:44 -0400808 })
809 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700810 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700811}
David Tolnay87d0b442016-09-04 11:52:12 -0700812
813#[cfg(feature = "printing")]
814mod printing {
815 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500816 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700817
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800818 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700819 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700820 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500821 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700822 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700823 }
824 }
825
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800826 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700827 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700828 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500829 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700830 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500831 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700832 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700833 }
834 }
835
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800836 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700837 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700838 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500839 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500840 Some(ref tok) => tok.to_tokens(tokens),
841 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700842 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400843 }
844 }
David Tolnay136aaa32017-12-29 02:37:36 -0500845 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700846 }
847 }
848
David Tolnay0a89b4d2017-11-13 00:55:45 -0800849 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700850 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700851 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700852 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500853 self.mutability.to_tokens(tokens);
854 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700855 }
856 }
857
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800858 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700859 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500860 self.lifetimes.to_tokens(tokens);
861 self.unsafety.to_tokens(tokens);
862 self.abi.to_tokens(tokens);
863 self.fn_token.to_tokens(tokens);
864 self.paren_token.surround(tokens, |tokens| {
865 self.inputs.to_tokens(tokens);
866 if let Some(ref variadic) = self.variadic {
867 if !self.inputs.empty_or_trailing() {
868 let span = variadic.0[0];
869 <Token![,]>::new(span).to_tokens(tokens);
870 }
871 variadic.to_tokens(tokens);
872 }
873 });
874 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700875 }
876 }
877
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800878 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700879 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700880 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700881 }
882 }
883
David Tolnay05362582017-12-26 01:33:57 -0500884 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700885 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700886 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500887 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700888 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700889 }
890 }
891
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800892 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700893 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700894 PathTokens(&self.qself, &self.path).to_tokens(tokens);
895 }
896 }
897
898 impl<'a> ToTokens for PathTokens<'a> {
899 fn to_tokens(&self, tokens: &mut Tokens) {
900 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700901 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700902 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700903 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700904 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700905 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400906
907 // XXX: Gross.
908 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
909 self.1.segments.len() - 1
910 } else {
911 qself.position
912 };
David Tolnay570695e2017-06-03 16:15:13 -0700913 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400914 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700915 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700916 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700917 for (i, segment) in (&mut segments).take(pos).enumerate() {
918 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700919 segment.item().to_tokens(tokens);
920 qself.gt_token.to_tokens(tokens);
921 segment.delimiter().to_tokens(tokens);
922 } else {
923 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700924 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700925 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700926 } else {
927 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700928 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700929 }
David Tolnay570695e2017-06-03 16:15:13 -0700930 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700931 segment.to_tokens(tokens);
932 }
933 }
934 }
935
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800936 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700937 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500938 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700939 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700940 }
941 }
942
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800943 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700944 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700945 self.impl_token.to_tokens(tokens);
946 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700947 }
948 }
949
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800950 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400951 fn to_tokens(&self, tokens: &mut Tokens) {
952 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500953 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400954 });
955 }
956 }
957
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800958 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -0700959 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700960 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500961 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700962 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700963 }
964 }
965
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800966 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -0700967 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700968 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700969 }
970 }
971
David Tolnay2ae520a2017-12-29 11:19:50 -0500972 impl ToTokens for TypeVerbatim {
973 fn to_tokens(&self, tokens: &mut Tokens) {
974 self.tts.to_tokens(tokens);
975 }
976 }
977
David Tolnay87d0b442016-09-04 11:52:12 -0700978 impl ToTokens for Path {
979 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700980 self.leading_colon.to_tokens(tokens);
981 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700982 }
983 }
984
985 impl ToTokens for PathSegment {
986 fn to_tokens(&self, tokens: &mut Tokens) {
987 self.ident.to_tokens(tokens);
Nika Layzellc08227a2017-12-04 16:30:17 -0500988 self.arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700989 }
990 }
991
Nika Layzellc08227a2017-12-04 16:30:17 -0500992 impl ToTokens for PathArguments {
David Tolnay87d0b442016-09-04 11:52:12 -0700993 fn to_tokens(&self, tokens: &mut Tokens) {
994 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500995 PathArguments::None => {}
996 PathArguments::AngleBracketed(ref arguments) => {
997 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700998 }
Nika Layzellc08227a2017-12-04 16:30:17 -0500999 PathArguments::Parenthesized(ref arguments) => {
1000 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001001 }
1002 }
1003 }
1004 }
1005
Nika Layzellc08227a2017-12-04 16:30:17 -05001006 impl ToTokens for GenericArgument {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001007 #[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
Nika Layzell357885a2017-12-04 15:47:07 -05001008 fn to_tokens(&self, tokens: &mut Tokens) {
1009 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001010 GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
1011 GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
1012 GenericArgument::TypeBinding(ref tb) => tb.to_tokens(tokens),
David Tolnay8c91b882017-12-28 23:04:32 -05001013 GenericArgument::Const(ref e) => match *e {
1014 Expr::Lit(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001015
1016 // NOTE: We should probably support parsing blocks with only
1017 // expressions in them without the full feature for const
1018 // generics.
1019 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001020 Expr::Block(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001021
1022 // ERROR CORRECTION: Add braces to make sure that the
1023 // generated code is valid.
David Tolnay32954ef2017-12-26 22:43:16 -05001024 _ => token::Brace::default().surround(tokens, |tokens| {
Nika Layzellce37f332017-12-05 12:01:22 -05001025 e.to_tokens(tokens);
1026 }),
David Tolnay51382052017-12-27 13:46:21 -05001027 },
Nika Layzell357885a2017-12-04 15:47:07 -05001028 }
1029 }
1030 }
1031
Nika Layzellc08227a2017-12-04 16:30:17 -05001032 impl ToTokens for AngleBracketedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001033 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay2d4e08a2017-12-28 23:54:07 -05001034 self.colon2_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001035 self.lt_token.to_tokens(tokens);
Nika Layzell357885a2017-12-04 15:47:07 -05001036 self.args.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001037 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001038 }
1039 }
1040
1041 impl ToTokens for TypeBinding {
1042 fn to_tokens(&self, tokens: &mut Tokens) {
1043 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001044 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001045 self.ty.to_tokens(tokens);
1046 }
1047 }
1048
Nika Layzellc08227a2017-12-04 16:30:17 -05001049 impl ToTokens for ParenthesizedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001050 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001051 self.paren_token.surround(tokens, |tokens| {
1052 self.inputs.to_tokens(tokens);
1053 });
1054 self.output.to_tokens(tokens);
1055 }
1056 }
1057
David Tolnayf93b90d2017-11-11 19:21:26 -08001058 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001059 fn to_tokens(&self, tokens: &mut Tokens) {
1060 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001061 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -05001062 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001063 arrow.to_tokens(tokens);
1064 ty.to_tokens(tokens);
1065 }
David Tolnay87d0b442016-09-04 11:52:12 -07001066 }
1067 }
1068 }
1069
1070 impl ToTokens for PolyTraitRef {
1071 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001072 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001073 self.trait_ref.to_tokens(tokens);
1074 }
1075 }
1076
David Tolnay62f374c2016-10-02 13:37:00 -07001077 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001078 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001079 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001080 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001081 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001082 }
1083 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001084 }
1085 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001086
Alex Crichton23a15f62017-08-28 12:34:23 -07001087 impl ToTokens for BareFnArgName {
1088 fn to_tokens(&self, tokens: &mut Tokens) {
1089 match *self {
1090 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1091 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1092 }
1093 }
1094 }
1095
David Tolnayb8d8ef52016-10-29 14:30:08 -07001096 impl ToTokens for Abi {
1097 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001098 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -05001099 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001100 }
1101 }
David Tolnay87d0b442016-09-04 11:52:12 -07001102}