blob: fa1083f33a937b682ee974ebc8663d965634d5bf [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 Tolnayb79ee962016-09-04 09:39:20 -07009use super::*;
David Tolnay2ae520a2017-12-29 11:19:50 -050010use proc_macro2::TokenStream;
David Tolnay94d2b792018-04-29 12:26:10 -070011use punctuated::Punctuated;
David Tolnay2ae520a2017-12-29 11:19:50 -050012#[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! {
David Tolnay7949ae22018-01-07 00:14:51 -080018 /// The possible types that a Rust value could have.
David Tolnay614a0142018-01-07 10:25:43 -080019 ///
David Tolnay461d98e2018-01-07 11:07:19 -080020 /// *This type is available if Syn is built with the `"derive"` or `"full"`
21 /// feature.*
22 ///
David Tolnay614a0142018-01-07 10:25:43 -080023 /// # Syntax tree enum
24 ///
25 /// This type is a [syntax tree enum].
26 ///
27 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
David Tolnayfd6bf5c2017-11-12 09:41:14 -080028 pub enum Type {
David Tolnay7949ae22018-01-07 00:14:51 -080029 /// A dynamically sized slice type: `[T]`.
David Tolnay461d98e2018-01-07 11:07:19 -080030 ///
31 /// *This type is available if Syn is built with the `"derive"` or
32 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080033 pub Slice(TypeSlice {
David Tolnay32954ef2017-12-26 22:43:16 -050034 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050035 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080037
David Tolnay7949ae22018-01-07 00:14:51 -080038 /// A fixed size array type: `[T; n]`.
David Tolnay461d98e2018-01-07 11:07:19 -080039 ///
40 /// *This type is available if Syn is built with the `"derive"` or
41 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080042 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050043 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050044 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080045 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050046 pub len: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070047 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080048
David Tolnay7949ae22018-01-07 00:14:51 -080049 /// A raw pointer type: `*const T` or `*mut T`.
David Tolnay461d98e2018-01-07 11:07:19 -080050 ///
51 /// *This type is available if Syn is built with the `"derive"` or
52 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080053 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080054 pub star_token: Token![*],
55 pub const_token: Option<Token![const]>,
David Tolnay136aaa32017-12-29 02:37:36 -050056 pub mutability: Option<Token![mut]>,
57 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070058 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080059
David Tolnay7949ae22018-01-07 00:14:51 -080060 /// A reference type: `&'a T` or `&'a mut T`.
David Tolnay461d98e2018-01-07 11:07:19 -080061 ///
62 /// *This type is available if Syn is built with the `"derive"` or
63 /// `"full"` feature.*
David Tolnay0a89b4d2017-11-13 00:55:45 -080064 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080065 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070066 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050067 pub mutability: Option<Token![mut]>,
68 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070069 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080070
David Tolnay7949ae22018-01-07 00:14:51 -080071 /// A bare function type: `fn(usize) -> bool`.
David Tolnay461d98e2018-01-07 11:07:19 -080072 ///
73 /// *This type is available if Syn is built with the `"derive"` or
74 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080075 pub BareFn(TypeBareFn {
David Tolnaya7d69fc2018-08-26 13:30:24 -040076 pub lifetimes: Option<BoundLifetimes>,
David Tolnaybe7a9592017-12-29 02:39:53 -050077 pub unsafety: Option<Token![unsafe]>,
78 pub abi: Option<Abi>,
79 pub fn_token: Token![fn],
David Tolnaybe7a9592017-12-29 02:39:53 -050080 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050081 pub inputs: Punctuated<BareFnArg, Token![,]>,
David Tolnaybe7a9592017-12-29 02:39:53 -050082 pub variadic: Option<Token![...]>,
83 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070084 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080085
David Tolnay7949ae22018-01-07 00:14:51 -080086 /// The never type: `!`.
David Tolnay461d98e2018-01-07 11:07:19 -080087 ///
88 /// *This type is available if Syn is built with the `"derive"` or
89 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080090 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080091 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080093
David Tolnay7949ae22018-01-07 00:14:51 -080094 /// A tuple type: `(A, B, C, String)`.
David Tolnay461d98e2018-01-07 11:07:19 -080095 ///
96 /// *This type is available if Syn is built with the `"derive"` or
97 /// `"full"` feature.*
David Tolnay05362582017-12-26 01:33:57 -050098 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050099 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -0500100 pub elems: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700101 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800102
103 /// A path like `std::slice::Iter`, optionally qualified with a
David Tolnay7949ae22018-01-07 00:14:51 -0800104 /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 ///
David Tolnay7949ae22018-01-07 00:14:51 -0800106 /// Type arguments are stored in the Path itself.
David Tolnay461d98e2018-01-07 11:07:19 -0800107 ///
108 /// *This type is available if Syn is built with the `"derive"` or
109 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800110 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 pub qself: Option<QSelf>,
112 pub path: Path,
113 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800114
David Tolnay7949ae22018-01-07 00:14:51 -0800115 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
116 /// trait or a lifetime.
David Tolnay461d98e2018-01-07 11:07:19 -0800117 ///
118 /// *This type is available if Syn is built with the `"derive"` or
119 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800120 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -0500121 pub dyn_token: Option<Token![dyn]>,
David Tolnayf2cfd722017-12-31 18:02:51 -0500122 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700123 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800124
David Tolnay7949ae22018-01-07 00:14:51 -0800125 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
126 /// a lifetime.
David Tolnay461d98e2018-01-07 11:07:19 -0800127 ///
128 /// *This type is available if Syn is built with the `"derive"` or
129 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800130 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800131 pub impl_token: Token![impl],
David Tolnayf2cfd722017-12-31 18:02:51 -0500132 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700133 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800134
135 /// A parenthesized type equivalent to the inner type.
David Tolnay461d98e2018-01-07 11:07:19 -0800136 ///
137 /// *This type is available if Syn is built with the `"derive"` or
138 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800139 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -0500140 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -0500141 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700142 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800143
144 /// A type contained within invisible delimiters.
David Tolnay461d98e2018-01-07 11:07:19 -0800145 ///
146 /// *This type is available if Syn is built with the `"derive"` or
147 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800148 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -0500149 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -0500150 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -0400151 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800152
David Tolnay7949ae22018-01-07 00:14:51 -0800153 /// Indication that a type should be inferred by the compiler: `_`.
David Tolnay461d98e2018-01-07 11:07:19 -0800154 ///
155 /// *This type is available if Syn is built with the `"derive"` or
156 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800157 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800158 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700159 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800160
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 /// A macro in the type position.
David Tolnay461d98e2018-01-07 11:07:19 -0800162 ///
163 /// *This type is available if Syn is built with the `"derive"` or
164 /// `"full"` feature.*
David Tolnay323279a2017-12-29 11:26:32 -0500165 pub Macro(TypeMacro {
166 pub mac: Macro,
167 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800168
David Tolnay7949ae22018-01-07 00:14:51 -0800169 /// Tokens in type position not interpreted by Syn.
David Tolnay461d98e2018-01-07 11:07:19 -0800170 ///
171 /// *This type is available if Syn is built with the `"derive"` or
172 /// `"full"` feature.*
David Tolnay2ae520a2017-12-29 11:19:50 -0500173 pub Verbatim(TypeVerbatim #manual_extra_traits {
174 pub tts: TokenStream,
175 }),
176 }
177}
178
179#[cfg(feature = "extra-traits")]
180impl Eq for TypeVerbatim {}
181
182#[cfg(feature = "extra-traits")]
183impl PartialEq for TypeVerbatim {
184 fn eq(&self, other: &Self) -> bool {
185 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
186 }
187}
188
189#[cfg(feature = "extra-traits")]
190impl Hash for TypeVerbatim {
191 fn hash<H>(&self, state: &mut H)
192 where
193 H: Hasher,
194 {
195 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 }
197}
198
199ast_struct! {
David Tolnayf01e37b2018-01-06 23:38:26 -0800200 /// The binary interface of a function: `extern "C"`.
David Tolnay461d98e2018-01-07 11:07:19 -0800201 ///
202 /// *This type is available if Syn is built with the `"derive"` or `"full"`
203 /// feature.*
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700204 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800205 pub extern_token: Token![extern],
David Tolnayf01e37b2018-01-06 23:38:26 -0800206 pub name: Option<LitStr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 }
208}
209
210ast_struct! {
David Tolnay7949ae22018-01-07 00:14:51 -0800211 /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
David Tolnay461d98e2018-01-07 11:07:19 -0800212 ///
213 /// *This type is available if Syn is built with the `"derive"` or `"full"`
214 /// feature.*
Alex Crichton62a0a592017-05-22 13:58:53 -0700215 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800216 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800217 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 }
219}
220
Alex Crichton23a15f62017-08-28 12:34:23 -0700221ast_enum! {
David Tolnay7949ae22018-01-07 00:14:51 -0800222 /// Name of an argument in a function type: the `n` in `fn(n: usize)`.
David Tolnay461d98e2018-01-07 11:07:19 -0800223 ///
224 /// *This type is available if Syn is built with the `"derive"` or `"full"`
225 /// feature.*
Alex Crichton23a15f62017-08-28 12:34:23 -0700226 pub enum BareFnArgName {
David Tolnay7949ae22018-01-07 00:14:51 -0800227 /// Argument given a name.
Alex Crichton23a15f62017-08-28 12:34:23 -0700228 Named(Ident),
David Tolnay7949ae22018-01-07 00:14:51 -0800229 /// Argument not given a name, matched with `_`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800230 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700231 }
232}
Alex Crichton62a0a592017-05-22 13:58:53 -0700233
234ast_enum! {
David Tolnay7949ae22018-01-07 00:14:51 -0800235 /// Return type of a function signature.
David Tolnay461d98e2018-01-07 11:07:19 -0800236 ///
237 /// *This type is available if Syn is built with the `"derive"` or `"full"`
238 /// feature.*
David Tolnayf93b90d2017-11-11 19:21:26 -0800239 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700240 /// Return type is not specified.
241 ///
David Tolnay7949ae22018-01-07 00:14:51 -0800242 /// Functions default to `()` and closures default to type inference.
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 Default,
David Tolnay7949ae22018-01-07 00:14:51 -0800244 /// A particular type is returned.
David Tolnay4a3f59a2017-12-28 21:21:12 -0500245 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700246 }
David Tolnayb79ee962016-09-04 09:39:20 -0700247}
248
David Tolnay86eca752016-09-04 11:26:41 -0700249#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700250pub mod parsing {
251 use super::*;
David Tolnaya7d69fc2018-08-26 13:30:24 -0400252 use parse::{Parse, ParseStream, Result};
David Tolnay94d2b792018-04-29 12:26:10 -0700253 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700254
David Tolnaya7d69fc2018-08-26 13:30:24 -0400255 impl Parse for Type {
256 fn parse(input: ParseStream) -> Result<Self> {
257 ambig_ty(input, true)
Alex Crichton954046c2017-05-30 21:49:42 -0700258 }
259 }
David Tolnay0047c712016-12-21 21:59:25 -0500260
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800261 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400262 /// In some positions, types may not contain the `+` character, to
263 /// disambiguate them. For example in the expression `1 as T`, T may not
264 /// contain a `+` character.
265 ///
266 /// This parser does not allow a `+`, while the default parser does.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400267 pub fn without_plus(input: ParseStream) -> Result<Self> {
268 ambig_ty(input, false)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800269 }
Alex Crichton954046c2017-05-30 21:49:42 -0700270 }
David Tolnayb79ee962016-09-04 09:39:20 -0700271
David Tolnaya7d69fc2018-08-26 13:30:24 -0400272 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
273 if input.peek(token::Group) {
274 return input.parse().map(Type::Group);
275 }
276
277 let mut lifetimes = None::<BoundLifetimes>;
278 let mut lookahead = input.lookahead1();
279 if lookahead.peek(Token![for]) {
280 lifetimes = input.parse()?;
281 lookahead = input.lookahead1();
282 if !lookahead.peek(Ident)
283 && !lookahead.peek(Token![fn])
284 && !lookahead.peek(Token![unsafe])
285 && !lookahead.peek(Token![extern])
286 && !lookahead.peek(Token![super])
287 && !lookahead.peek(Token![self])
288 && !lookahead.peek(Token![Self])
289 && !lookahead.peek(Token![crate])
290 {
291 return Err(lookahead.error());
292 }
293 }
294
295 if lookahead.peek(token::Paren) {
296 let content;
297 let paren_token = parenthesized!(content in input);
298 if content.is_empty() {
299 return Ok(Type::Tuple(TypeTuple {
300 paren_token: paren_token,
301 elems: Punctuated::new(),
302 }));
303 }
304 if content.peek(Lifetime) {
305 return Ok(Type::Paren(TypeParen {
306 paren_token: paren_token,
307 elem: Box::new(Type::TraitObject(content.parse()?)),
308 }));
309 }
310 let first: Type = content.parse()?;
311 if content.peek(Token![,]) {
312 Ok(Type::Tuple(TypeTuple {
313 paren_token: paren_token,
314 elems: {
315 let mut elems = Punctuated::new();
316 elems.push_value(first);
317 elems.push_punct(content.parse()?);
318 let rest: Punctuated<Type, Token![,]> =
319 content.parse_terminated(Parse::parse)?;
320 elems.extend(rest);
321 elems
322 },
323 }))
324 } else {
325 Ok(Type::Paren(TypeParen {
326 paren_token: paren_token,
327 elem: Box::new(first),
328 }))
329 }
330 } else if lookahead.peek(Token![fn])
331 || lookahead.peek(Token![unsafe])
332 || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
333 {
334 let mut bare_fn: TypeBareFn = input.parse()?;
335 bare_fn.lifetimes = lifetimes;
336 Ok(Type::BareFn(bare_fn))
337 } else if lookahead.peek(Ident)
338 || input.peek(Token![super])
339 || input.peek(Token![self])
340 || input.peek(Token![Self])
341 || input.peek(Token![crate])
342 || input.peek(Token![extern])
343 || lookahead.peek(Token![::])
344 || lookahead.peek(Token![<])
345 {
346 if input.peek(Token![dyn]) {
347 let mut trait_object: TypeTraitObject = input.parse()?;
348 if lifetimes.is_some() {
349 match *trait_object.bounds.iter_mut().next().unwrap() {
350 TypeParamBound::Trait(ref mut trait_bound) => {
351 trait_bound.lifetimes = lifetimes;
352 }
353 TypeParamBound::Lifetime(_) => unreachable!(),
354 }
355 }
356 return Ok(Type::TraitObject(trait_object));
357 }
358
359 let ty: TypePath = input.parse()?;
360 if ty.qself.is_some() {
361 return Ok(Type::Path(ty));
362 }
363
364 if input.peek(Token![!]) && !input.peek(Token![!=]) {
365 let mut contains_arguments = false;
366 for segment in &ty.path.segments {
367 match segment.arguments {
368 PathArguments::None => {}
369 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
370 contains_arguments = true;
371 }
372 }
373 }
374
375 if !contains_arguments {
376 let bang_token: Token![!] = input.parse()?;
377 let (delimiter, tts) = mac::parse_delimiter(input)?;
378 return Ok(Type::Macro(TypeMacro {
379 mac: Macro {
380 path: ty.path,
381 bang_token: bang_token,
382 delimiter: delimiter,
383 tts: tts,
384 },
385 }));
386 }
387 }
388
389 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
390 let mut bounds = Punctuated::new();
391 bounds.push_value(TypeParamBound::Trait(TraitBound {
392 paren_token: None,
393 modifier: TraitBoundModifier::None,
394 lifetimes: lifetimes,
395 path: ty.path,
396 }));
397 if allow_plus && input.peek(Token![+]) {
398 bounds.push_punct(input.parse()?);
399 let rest: Punctuated<TypeParamBound, Token![+]> =
400 input.parse_synom(Punctuated::parse_terminated_nonempty)?;
401 bounds.extend(rest);
402 }
403 return Ok(Type::TraitObject(TypeTraitObject {
404 dyn_token: None,
405 bounds: bounds,
406 }));
407 }
408
409 Ok(Type::Path(ty))
410 } else if lookahead.peek(token::Bracket) {
411 let content;
412 let bracket_token = bracketed!(content in input);
413 let elem: Type = content.parse()?;
414 if content.peek(Token![;]) {
415 Ok(Type::Array(TypeArray {
416 bracket_token: bracket_token,
David Tolnayeadbda32017-12-29 02:33:47 -0500417 elem: Box::new(elem),
David Tolnaya7d69fc2018-08-26 13:30:24 -0400418 semi_token: content.parse()?,
419 len: content.parse_synom(Expr::parse)?,
420 }))
421 } else {
422 Ok(Type::Slice(TypeSlice {
423 bracket_token: bracket_token,
424 elem: Box::new(elem),
425 }))
Alex Crichton954046c2017-05-30 21:49:42 -0700426 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400427 } else if lookahead.peek(Token![*]) {
428 input.parse().map(Type::Ptr)
429 } else if lookahead.peek(Token![&]) {
430 input.parse().map(Type::Reference)
431 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
432 input.parse().map(Type::Never)
433 } else if lookahead.peek(Token![impl ]) {
434 input.parse().map(Type::ImplTrait)
435 } else if lookahead.peek(Token![_]) {
436 input.parse().map(Type::Infer)
437 } else if lookahead.peek(Lifetime) {
438 input.parse().map(Type::TraitObject)
439 } else {
440 Err(lookahead.error())
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800441 }
Alex Crichton954046c2017-05-30 21:49:42 -0700442 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700443
David Tolnaya7d69fc2018-08-26 13:30:24 -0400444 impl Parse for TypeSlice {
445 fn parse(input: ParseStream) -> Result<Self> {
446 let content;
447 Ok(TypeSlice {
448 bracket_token: bracketed!(content in input),
449 elem: content.parse()?,
Michael Layzell92639a52017-06-01 00:07:44 -0400450 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800451 }
Alex Crichton954046c2017-05-30 21:49:42 -0700452 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700453
David Tolnaya7d69fc2018-08-26 13:30:24 -0400454 impl Parse for TypeArray {
455 fn parse(input: ParseStream) -> Result<Self> {
456 let content;
457 Ok(TypeArray {
458 bracket_token: bracketed!(content in input),
459 elem: content.parse()?,
460 semi_token: content.parse()?,
461 len: content.parse_synom(Expr::parse)?,
462 })
463 }
464 }
465
466 impl Parse for TypePtr {
467 fn parse(input: ParseStream) -> Result<Self> {
468 let star_token: Token![*] = input.parse()?;
469
470 let lookahead = input.lookahead1();
471 let (const_token, mutability) = if lookahead.peek(Token![const]) {
472 (Some(input.parse()?), None)
473 } else if lookahead.peek(Token![mut]) {
474 (None, Some(input.parse()?))
475 } else {
476 return Err(lookahead.error());
477 };
478
479 Ok(TypePtr {
480 star_token: star_token,
481 const_token: const_token,
David Tolnay136aaa32017-12-29 02:37:36 -0500482 mutability: mutability,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400483 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400484 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800485 }
Alex Crichton954046c2017-05-30 21:49:42 -0700486 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700487
David Tolnaya7d69fc2018-08-26 13:30:24 -0400488 impl Parse for TypeReference {
489 fn parse(input: ParseStream) -> Result<Self> {
490 Ok(TypeReference {
491 and_token: input.parse()?,
492 lifetime: input.parse()?,
493 mutability: input.parse()?,
494 // & binds tighter than +, so we don't allow + here.
495 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400496 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800497 }
Alex Crichton954046c2017-05-30 21:49:42 -0700498 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700499
David Tolnaya7d69fc2018-08-26 13:30:24 -0400500 impl Parse for TypeBareFn {
501 fn parse(input: ParseStream) -> Result<Self> {
502 let args;
503 let allow_variadic;
504 Ok(TypeBareFn {
505 lifetimes: input.parse()?,
506 unsafety: input.parse()?,
507 abi: input.parse()?,
508 fn_token: input.parse()?,
509 paren_token: parenthesized!(args in input),
510 inputs: {
511 let inputs = args.parse_synom(Punctuated::parse_terminated)?;
512 allow_variadic = inputs.empty_or_trailing();
513 inputs
514 },
515 variadic: {
516 if allow_variadic && args.peek(Token![...]) {
517 Some(args.parse()?)
518 } else {
519 None
520 }
521 },
522 output: input.call(ReturnType::without_plus)?,
Michael Layzell92639a52017-06-01 00:07:44 -0400523 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800524 }
Alex Crichton954046c2017-05-30 21:49:42 -0700525 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700526
David Tolnaya7d69fc2018-08-26 13:30:24 -0400527 impl Parse for TypeNever {
528 fn parse(input: ParseStream) -> Result<Self> {
529 Ok(TypeNever {
530 bang_token: input.parse()?,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500531 })
David Tolnaya7d69fc2018-08-26 13:30:24 -0400532 }
533 }
534
535 impl Parse for TypeInfer {
536 fn parse(input: ParseStream) -> Result<Self> {
537 Ok(TypeInfer {
538 underscore_token: input.parse()?,
539 })
540 }
541 }
542
543 impl Parse for TypeTuple {
544 fn parse(input: ParseStream) -> Result<Self> {
545 let content;
546 Ok(TypeTuple {
547 paren_token: parenthesized!(content in input),
548 elems: content.parse_terminated(<Type as Parse>::parse)?,
549 })
550 }
551 }
552
553 impl Parse for TypeMacro {
554 fn parse(input: ParseStream) -> Result<Self> {
555 Ok(TypeMacro {
556 mac: input.parse()?,
557 })
558 }
559 }
560
561 impl Parse for TypePath {
562 fn parse(input: ParseStream) -> Result<Self> {
563 let (qself, mut path) = if input.peek(Token![<]) {
564 let lt_token: Token![<] = input.parse()?;
565 let this: Type = input.parse()?;
566 let path = if input.peek(Token![as]) {
567 let as_token: Token![as] = input.parse()?;
568 let path: Path = input.parse()?;
569 Some((as_token, path))
570 } else {
571 None
572 };
573 let gt_token: Token![>] = input.parse()?;
574 let colon2_token: Token![::] = input.parse()?;
575 let rest = input.parse_synom(Punctuated::parse_separated_nonempty)?;
576 let (position, as_token, path) = match path {
577 Some((as_token, mut path)) => {
578 let pos = path.segments.len();
579 path.segments.push_punct(colon2_token);
580 path.segments.extend(rest.into_pairs());
581 (pos, Some(as_token), path)
582 }
583 None => {
584 let path = Path {
585 leading_colon: Some(colon2_token),
586 segments: rest,
587 };
588 (0, None, path)
589 }
590 };
591 let qself = QSelf {
592 lt_token: lt_token,
593 ty: Box::new(this),
594 position: position,
595 as_token: as_token,
596 gt_token: gt_token,
597 };
598 (Some(qself), path)
599 } else {
600 let path: Path = input.parse()?;
601 (None, path)
602 };
603
604 let parenthesized = if path.segments.last().unwrap().value().arguments.is_empty()
605 && input.peek(token::Paren)
606 {
607 let args: ParenthesizedGenericArguments = input.parse()?;
608 Some(args)
609 } else {
610 None
611 };
612
613 if let Some(parenthesized) = parenthesized {
614 let parenthesized = PathArguments::Parenthesized(parenthesized);
615 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
616 }
617
618 Ok(TypePath {
619 qself: qself,
620 path: path,
621 })
622 }
David Tolnay7d38c7e2017-12-25 22:31:50 -0500623 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700624
Geoffry Songac02b182018-05-19 22:11:31 -0700625 impl ReturnType {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400626 pub fn without_plus(input: ParseStream) -> Result<Self> {
627 Self::parse(input, false)
628 }
Geoffry Songac02b182018-05-19 22:11:31 -0700629
David Tolnaya7d69fc2018-08-26 13:30:24 -0400630 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
631 if input.peek(Token![->]) {
632 let arrow = input.parse()?;
633 let ty = ambig_ty(input, allow_plus)?;
634 Ok(ReturnType::Type(arrow, Box::new(ty)))
635 } else {
636 Ok(ReturnType::Default)
637 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800638 }
Alex Crichton954046c2017-05-30 21:49:42 -0700639 }
640
David Tolnaya7d69fc2018-08-26 13:30:24 -0400641 impl Parse for ReturnType {
642 fn parse(input: ParseStream) -> Result<Self> {
643 Self::parse(input, true)
644 }
645 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800646
David Tolnaya7d69fc2018-08-26 13:30:24 -0400647 impl Parse for TypeTraitObject {
648 fn parse(input: ParseStream) -> Result<Self> {
649 Self::parse(input, true)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800650 }
David Tolnay0a169d42017-12-29 17:57:29 -0500651 }
652
David Tolnaye39b0702018-01-09 17:57:31 -0800653 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
654 for bound in bounds {
655 if let TypeParamBound::Trait(_) = *bound {
656 return true;
657 }
658 }
659 false
660 }
661
David Tolnay7d38c7e2017-12-25 22:31:50 -0500662 impl TypeTraitObject {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400663 pub fn without_plus(input: ParseStream) -> Result<Self> {
664 Self::parse(input, false)
665 }
David Tolnay0a169d42017-12-29 17:57:29 -0500666
David Tolnay7d38c7e2017-12-25 22:31:50 -0500667 // Only allow multiple trait references if allow_plus is true.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400668 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
669 Ok(TypeTraitObject {
670 dyn_token: input.parse()?,
671 bounds: {
672 let bounds = if allow_plus {
673 input.parse_synom(Punctuated::parse_terminated_nonempty)?
674 } else {
675 let mut bounds = Punctuated::new();
676 bounds.push_value(input.parse()?);
677 bounds
678 };
679 // Just lifetimes like `'a + 'b` is not a TraitObject.
680 if !at_least_one_type(&bounds) {
681 return Err(input.error("expected at least one type"));
682 }
David Tolnayf2cfd722017-12-31 18:02:51 -0500683 bounds
David Tolnaya7d69fc2018-08-26 13:30:24 -0400684 },
David Tolnay7d38c7e2017-12-25 22:31:50 -0500685 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800686 }
Alex Crichton954046c2017-05-30 21:49:42 -0700687 }
David Tolnayb79ee962016-09-04 09:39:20 -0700688
David Tolnaya7d69fc2018-08-26 13:30:24 -0400689 impl Parse for TypeImplTrait {
690 fn parse(input: ParseStream) -> Result<Self> {
691 Ok(TypeImplTrait {
692 impl_token: input.parse()?,
693 // NOTE: rust-lang/rust#34511 includes discussion about whether
694 // or not + should be allowed in ImplTrait directly without ().
695 bounds: input.parse_synom(Punctuated::parse_terminated_nonempty)?,
Michael Layzell93c36282017-06-04 20:43:14 -0400696 })
David Tolnay79777332018-01-07 10:04:42 -0800697 }
Michael Layzell93c36282017-06-04 20:43:14 -0400698 }
699
David Tolnaya7d69fc2018-08-26 13:30:24 -0400700 impl Parse for TypeGroup {
701 fn parse(input: ParseStream) -> Result<Self> {
702 let content;
703 Ok(TypeGroup {
704 group_token: grouped!(content in input),
705 elem: content.parse()?,
706 })
707 }
708 }
David Tolnay79777332018-01-07 10:04:42 -0800709
David Tolnaya7d69fc2018-08-26 13:30:24 -0400710 impl Parse for TypeParen {
711 fn parse(input: ParseStream) -> Result<Self> {
712 Self::parse(input, false)
David Tolnay79777332018-01-07 10:04:42 -0800713 }
David Tolnay0a169d42017-12-29 17:57:29 -0500714 }
715
716 impl TypeParen {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400717 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
718 let content;
719 Ok(TypeParen {
720 paren_token: parenthesized!(content in input),
721 elem: Box::new(ambig_ty(&content, allow_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400722 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800723 }
Alex Crichton954046c2017-05-30 21:49:42 -0700724 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700725
David Tolnaya7d69fc2018-08-26 13:30:24 -0400726 impl Parse for BareFnArg {
727 fn parse(input: ParseStream) -> Result<Self> {
728 Ok(BareFnArg {
729 name: {
730 if (input.peek(Ident) || input.peek(Token![_]))
731 && !input.peek2(Token![::])
732 && input.peek2(Token![:])
733 {
734 let name: BareFnArgName = input.parse()?;
735 let colon: Token![:] = input.parse()?;
736 Some((name, colon))
737 } else {
738 None
739 }
740 },
741 ty: input.parse()?,
742 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800743 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700744 }
745
David Tolnaya7d69fc2018-08-26 13:30:24 -0400746 impl Parse for BareFnArgName {
747 fn parse(input: ParseStream) -> Result<Self> {
748 let lookahead = input.lookahead1();
749 if lookahead.peek(Ident) {
750 input.parse().map(BareFnArgName::Named)
751 } else if lookahead.peek(Token![_]) {
752 input.parse().map(BareFnArgName::Wild)
753 } else {
754 Err(lookahead.error())
755 }
756 }
757 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800758
David Tolnaya7d69fc2018-08-26 13:30:24 -0400759 impl Parse for Abi {
760 fn parse(input: ParseStream) -> Result<Self> {
761 Ok(Abi {
762 extern_token: input.parse()?,
763 name: input.parse()?,
764 })
765 }
766 }
767
768 impl Parse for Option<Abi> {
769 fn parse(input: ParseStream) -> Result<Self> {
770 if input.peek(Token![extern]) {
771 input.parse().map(Some)
772 } else {
773 Ok(None)
774 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800775 }
Alex Crichton954046c2017-05-30 21:49:42 -0700776 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700777}
David Tolnay87d0b442016-09-04 11:52:12 -0700778
779#[cfg(feature = "printing")]
780mod printing {
781 use super::*;
Alex Crichtona74a1c82018-05-16 10:20:44 -0700782 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700783 use quote::ToTokens;
David Tolnay87d0b442016-09-04 11:52:12 -0700784
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800785 impl ToTokens for TypeSlice {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700786 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700787 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500788 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700789 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700790 }
791 }
792
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800793 impl ToTokens for TypeArray {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700794 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700795 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500796 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700797 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500798 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700799 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700800 }
801 }
802
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800803 impl ToTokens for TypePtr {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700804 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700805 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500806 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500807 Some(ref tok) => tok.to_tokens(tokens),
808 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700809 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400810 }
811 }
David Tolnay136aaa32017-12-29 02:37:36 -0500812 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700813 }
814 }
815
David Tolnay0a89b4d2017-11-13 00:55:45 -0800816 impl ToTokens for TypeReference {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700817 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700818 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700819 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500820 self.mutability.to_tokens(tokens);
821 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700822 }
823 }
824
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800825 impl ToTokens for TypeBareFn {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700826 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500827 self.lifetimes.to_tokens(tokens);
828 self.unsafety.to_tokens(tokens);
829 self.abi.to_tokens(tokens);
830 self.fn_token.to_tokens(tokens);
831 self.paren_token.surround(tokens, |tokens| {
832 self.inputs.to_tokens(tokens);
833 if let Some(ref variadic) = self.variadic {
834 if !self.inputs.empty_or_trailing() {
David Tolnay7ac699c2018-08-24 14:00:58 -0400835 let span = variadic.spans[0];
836 Token![,](span).to_tokens(tokens);
David Tolnaybe7a9592017-12-29 02:39:53 -0500837 }
838 variadic.to_tokens(tokens);
839 }
840 });
841 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700842 }
843 }
844
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800845 impl ToTokens for TypeNever {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700846 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700847 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700848 }
849 }
850
David Tolnay05362582017-12-26 01:33:57 -0500851 impl ToTokens for TypeTuple {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700852 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700853 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500854 self.elems.to_tokens(tokens);
David Tolnaydb402062018-03-31 22:23:30 +0200855 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700856 }
857 }
858
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800859 impl ToTokens for TypePath {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700860 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700861 PathTokens(&self.qself, &self.path).to_tokens(tokens);
862 }
863 }
864
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800865 impl ToTokens for TypeTraitObject {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700866 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500867 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700868 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700869 }
870 }
871
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800872 impl ToTokens for TypeImplTrait {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700873 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700874 self.impl_token.to_tokens(tokens);
875 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700876 }
877 }
878
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800879 impl ToTokens for TypeGroup {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700880 fn to_tokens(&self, tokens: &mut TokenStream) {
Michael Layzell93c36282017-06-04 20:43:14 -0400881 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500882 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400883 });
884 }
885 }
886
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800887 impl ToTokens for TypeParen {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700888 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700889 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500890 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700891 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700892 }
893 }
894
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800895 impl ToTokens for TypeInfer {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700896 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700897 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700898 }
899 }
900
David Tolnay323279a2017-12-29 11:26:32 -0500901 impl ToTokens for TypeMacro {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700902 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay323279a2017-12-29 11:26:32 -0500903 self.mac.to_tokens(tokens);
904 }
905 }
906
David Tolnay2ae520a2017-12-29 11:19:50 -0500907 impl ToTokens for TypeVerbatim {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700908 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay2ae520a2017-12-29 11:19:50 -0500909 self.tts.to_tokens(tokens);
910 }
911 }
912
David Tolnayf93b90d2017-11-11 19:21:26 -0800913 impl ToTokens for ReturnType {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700914 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700915 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -0800916 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -0500917 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700918 arrow.to_tokens(tokens);
919 ty.to_tokens(tokens);
920 }
David Tolnay87d0b442016-09-04 11:52:12 -0700921 }
922 }
923 }
924
David Tolnay62f374c2016-10-02 13:37:00 -0700925 impl ToTokens for BareFnArg {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700926 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700927 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700928 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700929 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700930 }
931 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700932 }
933 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700934
Alex Crichton23a15f62017-08-28 12:34:23 -0700935 impl ToTokens for BareFnArgName {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700936 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichton23a15f62017-08-28 12:34:23 -0700937 match *self {
938 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
939 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
940 }
941 }
942 }
943
David Tolnayb8d8ef52016-10-29 14:30:08 -0700944 impl ToTokens for Abi {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700945 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700946 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -0500947 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -0700948 }
949 }
David Tolnay87d0b442016-09-04 11:52:12 -0700950}