blob: d4852f6be23497af196412ebc82917fbde9bfbf8 [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
David Tolnay2ae520a2017-12-29 11:19:50 -05002use proc_macro2::TokenStream;
David Tolnay94d2b792018-04-29 12:26:10 -07003use punctuated::Punctuated;
David Tolnay2ae520a2017-12-29 11:19:50 -05004#[cfg(feature = "extra-traits")]
5use std::hash::{Hash, Hasher};
6#[cfg(feature = "extra-traits")]
David Tolnayc43b44e2017-12-30 23:55:54 -05007use tt::TokenStreamHelper;
David Tolnayb79ee962016-09-04 09:39:20 -07008
Alex Crichton62a0a592017-05-22 13:58:53 -07009ast_enum_of_structs! {
David Tolnay7949ae22018-01-07 00:14:51 -080010 /// The possible types that a Rust value could have.
David Tolnay614a0142018-01-07 10:25:43 -080011 ///
David Tolnay461d98e2018-01-07 11:07:19 -080012 /// *This type is available if Syn is built with the `"derive"` or `"full"`
13 /// feature.*
14 ///
David Tolnay614a0142018-01-07 10:25:43 -080015 /// # Syntax tree enum
16 ///
17 /// This type is a [syntax tree enum].
18 ///
19 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
David Tolnayfd6bf5c2017-11-12 09:41:14 -080020 pub enum Type {
David Tolnay7949ae22018-01-07 00:14:51 -080021 /// A dynamically sized slice type: `[T]`.
David Tolnay461d98e2018-01-07 11:07:19 -080022 ///
23 /// *This type is available if Syn is built with the `"derive"` or
24 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080025 pub Slice(TypeSlice {
David Tolnay32954ef2017-12-26 22:43:16 -050026 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050027 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070028 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080029
David Tolnay7949ae22018-01-07 00:14:51 -080030 /// A fixed size array type: `[T; n]`.
David Tolnay461d98e2018-01-07 11:07:19 -080031 ///
32 /// *This type is available if Syn is built with the `"derive"` or
33 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080034 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050035 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050036 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080037 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050038 pub len: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070039 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080040
David Tolnay7949ae22018-01-07 00:14:51 -080041 /// A raw pointer type: `*const T` or `*mut T`.
David Tolnay461d98e2018-01-07 11:07:19 -080042 ///
43 /// *This type is available if Syn is built with the `"derive"` or
44 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080045 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080046 pub star_token: Token![*],
47 pub const_token: Option<Token![const]>,
David Tolnay136aaa32017-12-29 02:37:36 -050048 pub mutability: Option<Token![mut]>,
49 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080051
David Tolnay7949ae22018-01-07 00:14:51 -080052 /// A reference type: `&'a T` or `&'a mut T`.
David Tolnay461d98e2018-01-07 11:07:19 -080053 ///
54 /// *This type is available if Syn is built with the `"derive"` or
55 /// `"full"` feature.*
David Tolnay0a89b4d2017-11-13 00:55:45 -080056 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080057 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070058 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050059 pub mutability: Option<Token![mut]>,
60 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070061 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080062
David Tolnay7949ae22018-01-07 00:14:51 -080063 /// A bare function type: `fn(usize) -> bool`.
David Tolnay461d98e2018-01-07 11:07:19 -080064 ///
65 /// *This type is available if Syn is built with the `"derive"` or
66 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080067 pub BareFn(TypeBareFn {
David Tolnaya7d69fc2018-08-26 13:30:24 -040068 pub lifetimes: Option<BoundLifetimes>,
David Tolnaybe7a9592017-12-29 02:39:53 -050069 pub unsafety: Option<Token![unsafe]>,
70 pub abi: Option<Abi>,
71 pub fn_token: Token![fn],
David Tolnaybe7a9592017-12-29 02:39:53 -050072 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050073 pub inputs: Punctuated<BareFnArg, Token![,]>,
David Tolnaybe7a9592017-12-29 02:39:53 -050074 pub variadic: Option<Token![...]>,
75 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070076 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080077
David Tolnay7949ae22018-01-07 00:14:51 -080078 /// The never type: `!`.
David Tolnay461d98e2018-01-07 11:07:19 -080079 ///
80 /// *This type is available if Syn is built with the `"derive"` or
81 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -080082 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080083 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070084 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080085
David Tolnay7949ae22018-01-07 00:14:51 -080086 /// A tuple type: `(A, B, C, String)`.
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 Tolnay05362582017-12-26 01:33:57 -050090 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050091 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050092 pub elems: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070093 }),
David Tolnaya454c8f2018-01-07 01:01:10 -080094
95 /// A path like `std::slice::Iter`, optionally qualified with a
David Tolnay7949ae22018-01-07 00:14:51 -080096 /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
Alex Crichton62a0a592017-05-22 13:58:53 -070097 ///
David Tolnay7949ae22018-01-07 00:14:51 -080098 /// Type arguments are stored in the Path itself.
David Tolnay461d98e2018-01-07 11:07:19 -080099 ///
100 /// *This type is available if Syn is built with the `"derive"` or
101 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800102 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 pub qself: Option<QSelf>,
104 pub path: Path,
105 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800106
David Tolnay7949ae22018-01-07 00:14:51 -0800107 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
108 /// trait or a lifetime.
David Tolnay461d98e2018-01-07 11:07:19 -0800109 ///
110 /// *This type is available if Syn is built with the `"derive"` or
111 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800112 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -0500113 pub dyn_token: Option<Token![dyn]>,
David Tolnayf2cfd722017-12-31 18:02:51 -0500114 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700115 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800116
David Tolnay7949ae22018-01-07 00:14:51 -0800117 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
118 /// a lifetime.
David Tolnay461d98e2018-01-07 11:07:19 -0800119 ///
120 /// *This type is available if Syn is built with the `"derive"` or
121 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800122 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800123 pub impl_token: Token![impl],
David Tolnayf2cfd722017-12-31 18:02:51 -0500124 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700125 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800126
127 /// A parenthesized type equivalent to the inner type.
David Tolnay461d98e2018-01-07 11:07:19 -0800128 ///
129 /// *This type is available if Syn is built with the `"derive"` or
130 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800131 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -0500132 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -0500133 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800135
136 /// A type contained within invisible delimiters.
David Tolnay461d98e2018-01-07 11:07:19 -0800137 ///
138 /// *This type is available if Syn is built with the `"derive"` or
139 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800140 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -0500141 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -0500142 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -0400143 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800144
David Tolnay7949ae22018-01-07 00:14:51 -0800145 /// Indication that a type should be inferred by the compiler: `_`.
David Tolnay461d98e2018-01-07 11:07:19 -0800146 ///
147 /// *This type is available if Syn is built with the `"derive"` or
148 /// `"full"` feature.*
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800149 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800150 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700151 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800152
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 /// A macro in the type position.
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 Tolnay323279a2017-12-29 11:26:32 -0500157 pub Macro(TypeMacro {
158 pub mac: Macro,
159 }),
David Tolnaya454c8f2018-01-07 01:01:10 -0800160
David Tolnay7949ae22018-01-07 00:14:51 -0800161 /// Tokens in type position not interpreted by Syn.
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 Tolnay2ae520a2017-12-29 11:19:50 -0500165 pub Verbatim(TypeVerbatim #manual_extra_traits {
166 pub tts: TokenStream,
167 }),
168 }
169}
170
171#[cfg(feature = "extra-traits")]
172impl Eq for TypeVerbatim {}
173
174#[cfg(feature = "extra-traits")]
175impl PartialEq for TypeVerbatim {
176 fn eq(&self, other: &Self) -> bool {
177 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
178 }
179}
180
181#[cfg(feature = "extra-traits")]
182impl Hash for TypeVerbatim {
183 fn hash<H>(&self, state: &mut H)
184 where
185 H: Hasher,
186 {
187 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 }
189}
190
191ast_struct! {
David Tolnayf01e37b2018-01-06 23:38:26 -0800192 /// The binary interface of a function: `extern "C"`.
David Tolnay461d98e2018-01-07 11:07:19 -0800193 ///
194 /// *This type is available if Syn is built with the `"derive"` or `"full"`
195 /// feature.*
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700196 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800197 pub extern_token: Token![extern],
David Tolnayf01e37b2018-01-06 23:38:26 -0800198 pub name: Option<LitStr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700199 }
200}
201
202ast_struct! {
David Tolnay7949ae22018-01-07 00:14:51 -0800203 /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
David Tolnay461d98e2018-01-07 11:07:19 -0800204 ///
205 /// *This type is available if Syn is built with the `"derive"` or `"full"`
206 /// feature.*
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800208 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800209 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700210 }
211}
212
Alex Crichton23a15f62017-08-28 12:34:23 -0700213ast_enum! {
David Tolnay7949ae22018-01-07 00:14:51 -0800214 /// Name of an argument in a function type: the `n` in `fn(n: usize)`.
David Tolnay461d98e2018-01-07 11:07:19 -0800215 ///
216 /// *This type is available if Syn is built with the `"derive"` or `"full"`
217 /// feature.*
Alex Crichton23a15f62017-08-28 12:34:23 -0700218 pub enum BareFnArgName {
David Tolnay7949ae22018-01-07 00:14:51 -0800219 /// Argument given a name.
Alex Crichton23a15f62017-08-28 12:34:23 -0700220 Named(Ident),
David Tolnay7949ae22018-01-07 00:14:51 -0800221 /// Argument not given a name, matched with `_`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800222 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700223 }
224}
Alex Crichton62a0a592017-05-22 13:58:53 -0700225
226ast_enum! {
David Tolnay7949ae22018-01-07 00:14:51 -0800227 /// Return type of a function signature.
David Tolnay461d98e2018-01-07 11:07:19 -0800228 ///
229 /// *This type is available if Syn is built with the `"derive"` or `"full"`
230 /// feature.*
David Tolnayf93b90d2017-11-11 19:21:26 -0800231 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 /// Return type is not specified.
233 ///
David Tolnay7949ae22018-01-07 00:14:51 -0800234 /// Functions default to `()` and closures default to type inference.
Alex Crichton62a0a592017-05-22 13:58:53 -0700235 Default,
David Tolnay7949ae22018-01-07 00:14:51 -0800236 /// A particular type is returned.
David Tolnay4a3f59a2017-12-28 21:21:12 -0500237 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 }
David Tolnayb79ee962016-09-04 09:39:20 -0700239}
240
David Tolnay86eca752016-09-04 11:26:41 -0700241#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700242pub mod parsing {
243 use super::*;
David Tolnay60291082018-08-28 09:54:49 -0700244
David Tolnay10951d52018-08-31 10:27:39 -0700245 use parse::{Parse, ParseStream, Result};
David Tolnay60291082018-08-28 09:54:49 -0700246 use path;
David Tolnayda4049b2016-09-04 10:59:23 -0700247
David Tolnaya7d69fc2018-08-26 13:30:24 -0400248 impl Parse for Type {
249 fn parse(input: ParseStream) -> Result<Self> {
250 ambig_ty(input, true)
Alex Crichton954046c2017-05-30 21:49:42 -0700251 }
252 }
David Tolnay0047c712016-12-21 21:59:25 -0500253
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800254 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400255 /// In some positions, types may not contain the `+` character, to
256 /// disambiguate them. For example in the expression `1 as T`, T may not
257 /// contain a `+` character.
258 ///
259 /// This parser does not allow a `+`, while the default parser does.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400260 pub fn without_plus(input: ParseStream) -> Result<Self> {
261 ambig_ty(input, false)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800262 }
Alex Crichton954046c2017-05-30 21:49:42 -0700263 }
David Tolnayb79ee962016-09-04 09:39:20 -0700264
David Tolnaya7d69fc2018-08-26 13:30:24 -0400265 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
266 if input.peek(token::Group) {
267 return input.parse().map(Type::Group);
268 }
269
270 let mut lifetimes = None::<BoundLifetimes>;
271 let mut lookahead = input.lookahead1();
272 if lookahead.peek(Token![for]) {
273 lifetimes = input.parse()?;
274 lookahead = input.lookahead1();
275 if !lookahead.peek(Ident)
276 && !lookahead.peek(Token![fn])
277 && !lookahead.peek(Token![unsafe])
278 && !lookahead.peek(Token![extern])
279 && !lookahead.peek(Token![super])
280 && !lookahead.peek(Token![self])
281 && !lookahead.peek(Token![Self])
282 && !lookahead.peek(Token![crate])
283 {
284 return Err(lookahead.error());
285 }
286 }
287
288 if lookahead.peek(token::Paren) {
289 let content;
290 let paren_token = parenthesized!(content in input);
291 if content.is_empty() {
292 return Ok(Type::Tuple(TypeTuple {
293 paren_token: paren_token,
294 elems: Punctuated::new(),
295 }));
296 }
297 if content.peek(Lifetime) {
298 return Ok(Type::Paren(TypeParen {
299 paren_token: paren_token,
300 elem: Box::new(Type::TraitObject(content.parse()?)),
301 }));
302 }
David Tolnay5f7a91c2018-10-27 22:22:58 -0700303 if content.peek(Token![?]) {
304 return Ok(Type::TraitObject(TypeTraitObject {
305 dyn_token: None,
306 bounds: {
307 let mut bounds = Punctuated::new();
David Tolnay7fd41852018-10-27 23:04:25 -0700308 bounds.push_value(TypeParamBound::Trait(TraitBound {
309 paren_token: Some(paren_token),
310 ..content.parse()?
311 }));
David Tolnay5f7a91c2018-10-27 22:22:58 -0700312 while let Some(plus) = input.parse()? {
313 bounds.push_punct(plus);
314 bounds.push_value(input.parse()?);
315 }
316 bounds
317 },
318 }));
319 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400320 let first: Type = content.parse()?;
321 if content.peek(Token![,]) {
David Tolnay4ace1c72018-10-27 21:49:05 -0700322 return Ok(Type::Tuple(TypeTuple {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400323 paren_token: paren_token,
324 elems: {
325 let mut elems = Punctuated::new();
326 elems.push_value(first);
327 elems.push_punct(content.parse()?);
328 let rest: Punctuated<Type, Token![,]> =
329 content.parse_terminated(Parse::parse)?;
330 elems.extend(rest);
331 elems
332 },
David Tolnay4ace1c72018-10-27 21:49:05 -0700333 }));
David Tolnaya7d69fc2018-08-26 13:30:24 -0400334 }
David Tolnay4ace1c72018-10-27 21:49:05 -0700335 if allow_plus && input.peek(Token![+]) {
David Tolnay4df58512018-10-27 22:34:36 -0700336 loop {
337 let first = match first {
338 Type::Path(TypePath { qself: None, path }) => {
339 TypeParamBound::Trait(TraitBound {
David Tolnay4ace1c72018-10-27 21:49:05 -0700340 paren_token: Some(paren_token),
341 modifier: TraitBoundModifier::None,
342 lifetimes: None,
343 path: path,
David Tolnay4df58512018-10-27 22:34:36 -0700344 })
345 }
David Tolnaye614f282018-10-27 22:50:12 -0700346 Type::TraitObject(TypeTraitObject {
347 dyn_token: None,
348 ref bounds,
349 }) => {
David Tolnay4df58512018-10-27 22:34:36 -0700350 if bounds.len() > 1 || bounds.trailing_punct() {
351 break;
352 }
353 match first {
354 Type::TraitObject(TypeTraitObject { bounds, .. }) => {
David Tolnay7fd41852018-10-27 23:04:25 -0700355 match bounds.into_iter().next().unwrap() {
356 TypeParamBound::Trait(trait_bound) => {
357 TypeParamBound::Trait(TraitBound {
358 paren_token: Some(paren_token),
359 ..trait_bound
360 })
361 }
362 other => other,
363 }
David Tolnay4df58512018-10-27 22:34:36 -0700364 }
365 _ => unreachable!(),
366 }
367 }
368 _ => break,
369 };
370 return Ok(Type::TraitObject(TypeTraitObject {
371 dyn_token: None,
372 bounds: {
373 let mut bounds = Punctuated::new();
374 bounds.push_value(first);
David Tolnay4ace1c72018-10-27 21:49:05 -0700375 while let Some(plus) = input.parse()? {
376 bounds.push_punct(plus);
377 bounds.push_value(input.parse()?);
378 }
379 bounds
380 },
381 }));
382 }
383 }
384 Ok(Type::Paren(TypeParen {
385 paren_token: paren_token,
386 elem: Box::new(first),
387 }))
David Tolnaya7d69fc2018-08-26 13:30:24 -0400388 } else if lookahead.peek(Token![fn])
389 || lookahead.peek(Token![unsafe])
390 || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
391 {
392 let mut bare_fn: TypeBareFn = input.parse()?;
393 bare_fn.lifetimes = lifetimes;
394 Ok(Type::BareFn(bare_fn))
395 } else if lookahead.peek(Ident)
396 || input.peek(Token![super])
397 || input.peek(Token![self])
398 || input.peek(Token![Self])
399 || input.peek(Token![crate])
400 || input.peek(Token![extern])
401 || lookahead.peek(Token![::])
402 || lookahead.peek(Token![<])
403 {
404 if input.peek(Token![dyn]) {
405 let mut trait_object: TypeTraitObject = input.parse()?;
406 if lifetimes.is_some() {
407 match *trait_object.bounds.iter_mut().next().unwrap() {
408 TypeParamBound::Trait(ref mut trait_bound) => {
409 trait_bound.lifetimes = lifetimes;
410 }
411 TypeParamBound::Lifetime(_) => unreachable!(),
412 }
413 }
414 return Ok(Type::TraitObject(trait_object));
415 }
416
417 let ty: TypePath = input.parse()?;
418 if ty.qself.is_some() {
419 return Ok(Type::Path(ty));
420 }
421
422 if input.peek(Token![!]) && !input.peek(Token![!=]) {
423 let mut contains_arguments = false;
424 for segment in &ty.path.segments {
425 match segment.arguments {
426 PathArguments::None => {}
427 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
428 contains_arguments = true;
429 }
430 }
431 }
432
433 if !contains_arguments {
434 let bang_token: Token![!] = input.parse()?;
435 let (delimiter, tts) = mac::parse_delimiter(input)?;
436 return Ok(Type::Macro(TypeMacro {
437 mac: Macro {
438 path: ty.path,
439 bang_token: bang_token,
440 delimiter: delimiter,
441 tts: tts,
442 },
443 }));
444 }
445 }
446
447 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
448 let mut bounds = Punctuated::new();
449 bounds.push_value(TypeParamBound::Trait(TraitBound {
450 paren_token: None,
451 modifier: TraitBoundModifier::None,
452 lifetimes: lifetimes,
453 path: ty.path,
454 }));
David Tolnayf5ebc192018-08-30 18:23:46 -0700455 if allow_plus {
456 while input.peek(Token![+]) {
457 bounds.push_punct(input.parse()?);
David Tolnay1b210d12018-10-27 22:07:00 -0700458 if input.peek(Token![>]) {
459 break;
460 }
David Tolnayf5ebc192018-08-30 18:23:46 -0700461 bounds.push_value(input.parse()?);
462 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400463 }
464 return Ok(Type::TraitObject(TypeTraitObject {
465 dyn_token: None,
466 bounds: bounds,
467 }));
468 }
469
470 Ok(Type::Path(ty))
471 } else if lookahead.peek(token::Bracket) {
472 let content;
473 let bracket_token = bracketed!(content in input);
474 let elem: Type = content.parse()?;
475 if content.peek(Token![;]) {
476 Ok(Type::Array(TypeArray {
477 bracket_token: bracket_token,
David Tolnayeadbda32017-12-29 02:33:47 -0500478 elem: Box::new(elem),
David Tolnaya7d69fc2018-08-26 13:30:24 -0400479 semi_token: content.parse()?,
David Tolnay9389c382018-08-27 09:13:37 -0700480 len: content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400481 }))
482 } else {
483 Ok(Type::Slice(TypeSlice {
484 bracket_token: bracket_token,
485 elem: Box::new(elem),
486 }))
Alex Crichton954046c2017-05-30 21:49:42 -0700487 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400488 } else if lookahead.peek(Token![*]) {
489 input.parse().map(Type::Ptr)
490 } else if lookahead.peek(Token![&]) {
491 input.parse().map(Type::Reference)
492 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
493 input.parse().map(Type::Never)
David Tolnay2beee042019-04-03 08:36:59 -0700494 } else if lookahead.peek(Token![impl]) {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400495 input.parse().map(Type::ImplTrait)
496 } else if lookahead.peek(Token![_]) {
497 input.parse().map(Type::Infer)
498 } else if lookahead.peek(Lifetime) {
499 input.parse().map(Type::TraitObject)
500 } else {
501 Err(lookahead.error())
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800502 }
Alex Crichton954046c2017-05-30 21:49:42 -0700503 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700504
David Tolnaya7d69fc2018-08-26 13:30:24 -0400505 impl Parse for TypeSlice {
506 fn parse(input: ParseStream) -> Result<Self> {
507 let content;
508 Ok(TypeSlice {
509 bracket_token: bracketed!(content in input),
510 elem: content.parse()?,
Michael Layzell92639a52017-06-01 00:07:44 -0400511 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800512 }
Alex Crichton954046c2017-05-30 21:49:42 -0700513 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700514
David Tolnaya7d69fc2018-08-26 13:30:24 -0400515 impl Parse for TypeArray {
516 fn parse(input: ParseStream) -> Result<Self> {
517 let content;
518 Ok(TypeArray {
519 bracket_token: bracketed!(content in input),
520 elem: content.parse()?,
521 semi_token: content.parse()?,
David Tolnay9389c382018-08-27 09:13:37 -0700522 len: content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400523 })
524 }
525 }
526
527 impl Parse for TypePtr {
528 fn parse(input: ParseStream) -> Result<Self> {
529 let star_token: Token![*] = input.parse()?;
530
531 let lookahead = input.lookahead1();
532 let (const_token, mutability) = if lookahead.peek(Token![const]) {
533 (Some(input.parse()?), None)
534 } else if lookahead.peek(Token![mut]) {
535 (None, Some(input.parse()?))
536 } else {
537 return Err(lookahead.error());
538 };
539
540 Ok(TypePtr {
541 star_token: star_token,
542 const_token: const_token,
David Tolnay136aaa32017-12-29 02:37:36 -0500543 mutability: mutability,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400544 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400545 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800546 }
Alex Crichton954046c2017-05-30 21:49:42 -0700547 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700548
David Tolnaya7d69fc2018-08-26 13:30:24 -0400549 impl Parse for TypeReference {
550 fn parse(input: ParseStream) -> Result<Self> {
551 Ok(TypeReference {
552 and_token: input.parse()?,
553 lifetime: input.parse()?,
554 mutability: input.parse()?,
555 // & binds tighter than +, so we don't allow + here.
556 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400557 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800558 }
Alex Crichton954046c2017-05-30 21:49:42 -0700559 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700560
David Tolnaya7d69fc2018-08-26 13:30:24 -0400561 impl Parse for TypeBareFn {
562 fn parse(input: ParseStream) -> Result<Self> {
563 let args;
564 let allow_variadic;
565 Ok(TypeBareFn {
566 lifetimes: input.parse()?,
567 unsafety: input.parse()?,
568 abi: input.parse()?,
569 fn_token: input.parse()?,
570 paren_token: parenthesized!(args in input),
571 inputs: {
David Tolnayf5ebc192018-08-30 18:23:46 -0700572 let mut inputs = Punctuated::new();
573 while !args.is_empty() && !args.peek(Token![...]) {
574 inputs.push_value(args.parse()?);
575 if args.is_empty() {
576 break;
577 }
578 inputs.push_punct(args.parse()?);
579 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400580 allow_variadic = inputs.empty_or_trailing();
581 inputs
582 },
583 variadic: {
584 if allow_variadic && args.peek(Token![...]) {
585 Some(args.parse()?)
586 } else {
587 None
588 }
589 },
590 output: input.call(ReturnType::without_plus)?,
Michael Layzell92639a52017-06-01 00:07:44 -0400591 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800592 }
Alex Crichton954046c2017-05-30 21:49:42 -0700593 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700594
David Tolnaya7d69fc2018-08-26 13:30:24 -0400595 impl Parse for TypeNever {
596 fn parse(input: ParseStream) -> Result<Self> {
597 Ok(TypeNever {
598 bang_token: input.parse()?,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500599 })
David Tolnaya7d69fc2018-08-26 13:30:24 -0400600 }
601 }
602
603 impl Parse for TypeInfer {
604 fn parse(input: ParseStream) -> Result<Self> {
605 Ok(TypeInfer {
606 underscore_token: input.parse()?,
607 })
608 }
609 }
610
611 impl Parse for TypeTuple {
612 fn parse(input: ParseStream) -> Result<Self> {
613 let content;
614 Ok(TypeTuple {
615 paren_token: parenthesized!(content in input),
David Tolnay60484fe2018-08-30 18:43:04 -0700616 elems: content.parse_terminated(Type::parse)?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400617 })
618 }
619 }
620
621 impl Parse for TypeMacro {
622 fn parse(input: ParseStream) -> Result<Self> {
623 Ok(TypeMacro {
624 mac: input.parse()?,
625 })
626 }
627 }
628
629 impl Parse for TypePath {
630 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay60291082018-08-28 09:54:49 -0700631 let (qself, mut path) = path::parsing::qpath(input, false)?;
David Tolnaya7d69fc2018-08-26 13:30:24 -0400632
David Tolnay60291082018-08-28 09:54:49 -0700633 if path.segments.last().unwrap().value().arguments.is_empty()
David Tolnaya7d69fc2018-08-26 13:30:24 -0400634 && input.peek(token::Paren)
635 {
636 let args: ParenthesizedGenericArguments = input.parse()?;
David Tolnay60291082018-08-28 09:54:49 -0700637 let parenthesized = PathArguments::Parenthesized(args);
David Tolnaya7d69fc2018-08-26 13:30:24 -0400638 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
639 }
640
641 Ok(TypePath {
642 qself: qself,
643 path: path,
644 })
645 }
David Tolnay7d38c7e2017-12-25 22:31:50 -0500646 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700647
Geoffry Songac02b182018-05-19 22:11:31 -0700648 impl ReturnType {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400649 pub fn without_plus(input: ParseStream) -> Result<Self> {
650 Self::parse(input, false)
651 }
Geoffry Songac02b182018-05-19 22:11:31 -0700652
David Tolnaya7d69fc2018-08-26 13:30:24 -0400653 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
654 if input.peek(Token![->]) {
655 let arrow = input.parse()?;
656 let ty = ambig_ty(input, allow_plus)?;
657 Ok(ReturnType::Type(arrow, Box::new(ty)))
658 } else {
659 Ok(ReturnType::Default)
660 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800661 }
Alex Crichton954046c2017-05-30 21:49:42 -0700662 }
663
David Tolnaya7d69fc2018-08-26 13:30:24 -0400664 impl Parse for ReturnType {
665 fn parse(input: ParseStream) -> Result<Self> {
666 Self::parse(input, true)
667 }
668 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800669
David Tolnaya7d69fc2018-08-26 13:30:24 -0400670 impl Parse for TypeTraitObject {
671 fn parse(input: ParseStream) -> Result<Self> {
672 Self::parse(input, true)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800673 }
David Tolnay0a169d42017-12-29 17:57:29 -0500674 }
675
David Tolnaye39b0702018-01-09 17:57:31 -0800676 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
677 for bound in bounds {
678 if let TypeParamBound::Trait(_) = *bound {
679 return true;
680 }
681 }
682 false
683 }
684
David Tolnay7d38c7e2017-12-25 22:31:50 -0500685 impl TypeTraitObject {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400686 pub fn without_plus(input: ParseStream) -> Result<Self> {
687 Self::parse(input, false)
688 }
David Tolnay0a169d42017-12-29 17:57:29 -0500689
David Tolnay7d38c7e2017-12-25 22:31:50 -0500690 // Only allow multiple trait references if allow_plus is true.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400691 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
692 Ok(TypeTraitObject {
693 dyn_token: input.parse()?,
694 bounds: {
David Tolnayf5ebc192018-08-30 18:23:46 -0700695 let mut bounds = Punctuated::new();
696 if allow_plus {
697 loop {
698 bounds.push_value(input.parse()?);
699 if !input.peek(Token![+]) {
700 break;
701 }
702 bounds.push_punct(input.parse()?);
David Tolnay1b210d12018-10-27 22:07:00 -0700703 if input.peek(Token![>]) {
704 break;
705 }
David Tolnayf5ebc192018-08-30 18:23:46 -0700706 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400707 } else {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400708 bounds.push_value(input.parse()?);
David Tolnayf5ebc192018-08-30 18:23:46 -0700709 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400710 // Just lifetimes like `'a + 'b` is not a TraitObject.
711 if !at_least_one_type(&bounds) {
712 return Err(input.error("expected at least one type"));
713 }
David Tolnayf2cfd722017-12-31 18:02:51 -0500714 bounds
David Tolnaya7d69fc2018-08-26 13:30:24 -0400715 },
David Tolnay7d38c7e2017-12-25 22:31:50 -0500716 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800717 }
Alex Crichton954046c2017-05-30 21:49:42 -0700718 }
David Tolnayb79ee962016-09-04 09:39:20 -0700719
David Tolnaya7d69fc2018-08-26 13:30:24 -0400720 impl Parse for TypeImplTrait {
721 fn parse(input: ParseStream) -> Result<Self> {
722 Ok(TypeImplTrait {
723 impl_token: input.parse()?,
724 // NOTE: rust-lang/rust#34511 includes discussion about whether
725 // or not + should be allowed in ImplTrait directly without ().
David Tolnayf5ebc192018-08-30 18:23:46 -0700726 bounds: {
727 let mut bounds = Punctuated::new();
728 loop {
729 bounds.push_value(input.parse()?);
730 if !input.peek(Token![+]) {
731 break;
732 }
733 bounds.push_punct(input.parse()?);
734 }
735 bounds
736 },
Michael Layzell93c36282017-06-04 20:43:14 -0400737 })
David Tolnay79777332018-01-07 10:04:42 -0800738 }
Michael Layzell93c36282017-06-04 20:43:14 -0400739 }
740
David Tolnaya7d69fc2018-08-26 13:30:24 -0400741 impl Parse for TypeGroup {
742 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay10951d52018-08-31 10:27:39 -0700743 let group = private::parse_group(input)?;
David Tolnaya7d69fc2018-08-26 13:30:24 -0400744 Ok(TypeGroup {
David Tolnayf57f76f2018-08-31 10:23:17 -0700745 group_token: group.token,
746 elem: group.content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400747 })
748 }
749 }
David Tolnay79777332018-01-07 10:04:42 -0800750
David Tolnaya7d69fc2018-08-26 13:30:24 -0400751 impl Parse for TypeParen {
752 fn parse(input: ParseStream) -> Result<Self> {
753 Self::parse(input, false)
David Tolnay79777332018-01-07 10:04:42 -0800754 }
David Tolnay0a169d42017-12-29 17:57:29 -0500755 }
756
757 impl TypeParen {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400758 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
759 let content;
760 Ok(TypeParen {
761 paren_token: parenthesized!(content in input),
762 elem: Box::new(ambig_ty(&content, allow_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400763 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800764 }
Alex Crichton954046c2017-05-30 21:49:42 -0700765 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700766
David Tolnaya7d69fc2018-08-26 13:30:24 -0400767 impl Parse for BareFnArg {
768 fn parse(input: ParseStream) -> Result<Self> {
769 Ok(BareFnArg {
770 name: {
771 if (input.peek(Ident) || input.peek(Token![_]))
772 && !input.peek2(Token![::])
773 && input.peek2(Token![:])
774 {
775 let name: BareFnArgName = input.parse()?;
776 let colon: Token![:] = input.parse()?;
777 Some((name, colon))
778 } else {
779 None
780 }
781 },
782 ty: input.parse()?,
783 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800784 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700785 }
786
David Tolnaya7d69fc2018-08-26 13:30:24 -0400787 impl Parse for BareFnArgName {
788 fn parse(input: ParseStream) -> Result<Self> {
789 let lookahead = input.lookahead1();
790 if lookahead.peek(Ident) {
791 input.parse().map(BareFnArgName::Named)
792 } else if lookahead.peek(Token![_]) {
793 input.parse().map(BareFnArgName::Wild)
794 } else {
795 Err(lookahead.error())
796 }
797 }
798 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800799
David Tolnaya7d69fc2018-08-26 13:30:24 -0400800 impl Parse for Abi {
801 fn parse(input: ParseStream) -> Result<Self> {
802 Ok(Abi {
803 extern_token: input.parse()?,
804 name: input.parse()?,
805 })
806 }
807 }
808
809 impl Parse for Option<Abi> {
810 fn parse(input: ParseStream) -> Result<Self> {
811 if input.peek(Token![extern]) {
812 input.parse().map(Some)
813 } else {
814 Ok(None)
815 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800816 }
Alex Crichton954046c2017-05-30 21:49:42 -0700817 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700818}
David Tolnay87d0b442016-09-04 11:52:12 -0700819
820#[cfg(feature = "printing")]
821mod printing {
822 use super::*;
David Tolnay64023912018-08-31 09:51:12 -0700823
Alex Crichtona74a1c82018-05-16 10:20:44 -0700824 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700825 use quote::ToTokens;
David Tolnay87d0b442016-09-04 11:52:12 -0700826
David Tolnay64023912018-08-31 09:51:12 -0700827 use print::TokensOrDefault;
828
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800829 impl ToTokens for TypeSlice {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700830 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700831 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500832 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700833 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700834 }
835 }
836
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800837 impl ToTokens for TypeArray {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700838 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700839 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500840 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700841 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500842 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700843 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700844 }
845 }
846
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800847 impl ToTokens for TypePtr {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700848 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700849 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500850 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500851 Some(ref tok) => tok.to_tokens(tokens),
852 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700853 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400854 }
855 }
David Tolnay136aaa32017-12-29 02:37:36 -0500856 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700857 }
858 }
859
David Tolnay0a89b4d2017-11-13 00:55:45 -0800860 impl ToTokens for TypeReference {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700861 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700862 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700863 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500864 self.mutability.to_tokens(tokens);
865 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700866 }
867 }
868
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800869 impl ToTokens for TypeBareFn {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700870 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500871 self.lifetimes.to_tokens(tokens);
872 self.unsafety.to_tokens(tokens);
873 self.abi.to_tokens(tokens);
874 self.fn_token.to_tokens(tokens);
875 self.paren_token.surround(tokens, |tokens| {
876 self.inputs.to_tokens(tokens);
877 if let Some(ref variadic) = self.variadic {
878 if !self.inputs.empty_or_trailing() {
David Tolnay7ac699c2018-08-24 14:00:58 -0400879 let span = variadic.spans[0];
880 Token![,](span).to_tokens(tokens);
David Tolnaybe7a9592017-12-29 02:39:53 -0500881 }
882 variadic.to_tokens(tokens);
883 }
884 });
885 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700886 }
887 }
888
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800889 impl ToTokens for TypeNever {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700890 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700891 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700892 }
893 }
894
David Tolnay05362582017-12-26 01:33:57 -0500895 impl ToTokens for TypeTuple {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700896 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700897 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500898 self.elems.to_tokens(tokens);
David Tolnaydb402062018-03-31 22:23:30 +0200899 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700900 }
901 }
902
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800903 impl ToTokens for TypePath {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700904 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay12f3b6f2018-09-01 16:10:53 -0700905 private::print_path(tokens, &self.qself, &self.path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700906 }
907 }
908
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800909 impl ToTokens for TypeTraitObject {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700910 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500911 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700912 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700913 }
914 }
915
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800916 impl ToTokens for TypeImplTrait {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700917 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700918 self.impl_token.to_tokens(tokens);
919 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700920 }
921 }
922
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800923 impl ToTokens for TypeGroup {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700924 fn to_tokens(&self, tokens: &mut TokenStream) {
Michael Layzell93c36282017-06-04 20:43:14 -0400925 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500926 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400927 });
928 }
929 }
930
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800931 impl ToTokens for TypeParen {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700932 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700933 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500934 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700935 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700936 }
937 }
938
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800939 impl ToTokens for TypeInfer {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700940 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700941 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700942 }
943 }
944
David Tolnay323279a2017-12-29 11:26:32 -0500945 impl ToTokens for TypeMacro {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700946 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay323279a2017-12-29 11:26:32 -0500947 self.mac.to_tokens(tokens);
948 }
949 }
950
David Tolnay2ae520a2017-12-29 11:19:50 -0500951 impl ToTokens for TypeVerbatim {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700952 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay2ae520a2017-12-29 11:19:50 -0500953 self.tts.to_tokens(tokens);
954 }
955 }
956
David Tolnayf93b90d2017-11-11 19:21:26 -0800957 impl ToTokens for ReturnType {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700958 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700959 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -0800960 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -0500961 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700962 arrow.to_tokens(tokens);
963 ty.to_tokens(tokens);
964 }
David Tolnay87d0b442016-09-04 11:52:12 -0700965 }
966 }
967 }
968
David Tolnay62f374c2016-10-02 13:37:00 -0700969 impl ToTokens for BareFnArg {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700970 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700971 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700972 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700973 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700974 }
975 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700976 }
977 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700978
Alex Crichton23a15f62017-08-28 12:34:23 -0700979 impl ToTokens for BareFnArgName {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700980 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichton23a15f62017-08-28 12:34:23 -0700981 match *self {
982 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
983 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
984 }
985 }
986 }
987
David Tolnayb8d8ef52016-10-29 14:30:08 -0700988 impl ToTokens for Abi {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700989 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700990 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -0500991 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -0700992 }
993 }
David Tolnay87d0b442016-09-04 11:52:12 -0700994}