blob: 548bfb06b326b8893a8c4c7aa2942ca5da99f8c0 [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 Tolnay60291082018-08-28 09:54:49 -0700252
David Tolnay10951d52018-08-31 10:27:39 -0700253 use parse::{Parse, ParseStream, Result};
David Tolnay60291082018-08-28 09:54:49 -0700254 use path;
David Tolnayda4049b2016-09-04 10:59:23 -0700255
David Tolnaya7d69fc2018-08-26 13:30:24 -0400256 impl Parse for Type {
257 fn parse(input: ParseStream) -> Result<Self> {
258 ambig_ty(input, true)
Alex Crichton954046c2017-05-30 21:49:42 -0700259 }
260 }
David Tolnay0047c712016-12-21 21:59:25 -0500261
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800262 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400263 /// In some positions, types may not contain the `+` character, to
264 /// disambiguate them. For example in the expression `1 as T`, T may not
265 /// contain a `+` character.
266 ///
267 /// This parser does not allow a `+`, while the default parser does.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400268 pub fn without_plus(input: ParseStream) -> Result<Self> {
269 ambig_ty(input, false)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800270 }
Alex Crichton954046c2017-05-30 21:49:42 -0700271 }
David Tolnayb79ee962016-09-04 09:39:20 -0700272
David Tolnaya7d69fc2018-08-26 13:30:24 -0400273 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
274 if input.peek(token::Group) {
275 return input.parse().map(Type::Group);
276 }
277
278 let mut lifetimes = None::<BoundLifetimes>;
279 let mut lookahead = input.lookahead1();
280 if lookahead.peek(Token![for]) {
281 lifetimes = input.parse()?;
282 lookahead = input.lookahead1();
283 if !lookahead.peek(Ident)
284 && !lookahead.peek(Token![fn])
285 && !lookahead.peek(Token![unsafe])
286 && !lookahead.peek(Token![extern])
287 && !lookahead.peek(Token![super])
288 && !lookahead.peek(Token![self])
289 && !lookahead.peek(Token![Self])
290 && !lookahead.peek(Token![crate])
291 {
292 return Err(lookahead.error());
293 }
294 }
295
296 if lookahead.peek(token::Paren) {
297 let content;
298 let paren_token = parenthesized!(content in input);
299 if content.is_empty() {
300 return Ok(Type::Tuple(TypeTuple {
301 paren_token: paren_token,
302 elems: Punctuated::new(),
303 }));
304 }
305 if content.peek(Lifetime) {
306 return Ok(Type::Paren(TypeParen {
307 paren_token: paren_token,
308 elem: Box::new(Type::TraitObject(content.parse()?)),
309 }));
310 }
David Tolnay5f7a91c2018-10-27 22:22:58 -0700311 if content.peek(Token![?]) {
312 return Ok(Type::TraitObject(TypeTraitObject {
313 dyn_token: None,
314 bounds: {
315 let mut bounds = Punctuated::new();
David Tolnay7fd41852018-10-27 23:04:25 -0700316 bounds.push_value(TypeParamBound::Trait(TraitBound {
317 paren_token: Some(paren_token),
318 ..content.parse()?
319 }));
David Tolnay5f7a91c2018-10-27 22:22:58 -0700320 while let Some(plus) = input.parse()? {
321 bounds.push_punct(plus);
322 bounds.push_value(input.parse()?);
323 }
324 bounds
325 },
326 }));
327 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400328 let first: Type = content.parse()?;
329 if content.peek(Token![,]) {
David Tolnay4ace1c72018-10-27 21:49:05 -0700330 return Ok(Type::Tuple(TypeTuple {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400331 paren_token: paren_token,
332 elems: {
333 let mut elems = Punctuated::new();
334 elems.push_value(first);
335 elems.push_punct(content.parse()?);
336 let rest: Punctuated<Type, Token![,]> =
337 content.parse_terminated(Parse::parse)?;
338 elems.extend(rest);
339 elems
340 },
David Tolnay4ace1c72018-10-27 21:49:05 -0700341 }));
David Tolnaya7d69fc2018-08-26 13:30:24 -0400342 }
David Tolnay4ace1c72018-10-27 21:49:05 -0700343 if allow_plus && input.peek(Token![+]) {
David Tolnay4df58512018-10-27 22:34:36 -0700344 loop {
345 let first = match first {
346 Type::Path(TypePath { qself: None, path }) => {
347 TypeParamBound::Trait(TraitBound {
David Tolnay4ace1c72018-10-27 21:49:05 -0700348 paren_token: Some(paren_token),
349 modifier: TraitBoundModifier::None,
350 lifetimes: None,
351 path: path,
David Tolnay4df58512018-10-27 22:34:36 -0700352 })
353 }
David Tolnaye614f282018-10-27 22:50:12 -0700354 Type::TraitObject(TypeTraitObject {
355 dyn_token: None,
356 ref bounds,
357 }) => {
David Tolnay4df58512018-10-27 22:34:36 -0700358 if bounds.len() > 1 || bounds.trailing_punct() {
359 break;
360 }
361 match first {
362 Type::TraitObject(TypeTraitObject { bounds, .. }) => {
David Tolnay7fd41852018-10-27 23:04:25 -0700363 match bounds.into_iter().next().unwrap() {
364 TypeParamBound::Trait(trait_bound) => {
365 TypeParamBound::Trait(TraitBound {
366 paren_token: Some(paren_token),
367 ..trait_bound
368 })
369 }
370 other => other,
371 }
David Tolnay4df58512018-10-27 22:34:36 -0700372 }
373 _ => unreachable!(),
374 }
375 }
376 _ => break,
377 };
378 return Ok(Type::TraitObject(TypeTraitObject {
379 dyn_token: None,
380 bounds: {
381 let mut bounds = Punctuated::new();
382 bounds.push_value(first);
David Tolnay4ace1c72018-10-27 21:49:05 -0700383 while let Some(plus) = input.parse()? {
384 bounds.push_punct(plus);
385 bounds.push_value(input.parse()?);
386 }
387 bounds
388 },
389 }));
390 }
391 }
392 Ok(Type::Paren(TypeParen {
393 paren_token: paren_token,
394 elem: Box::new(first),
395 }))
David Tolnaya7d69fc2018-08-26 13:30:24 -0400396 } else if lookahead.peek(Token![fn])
397 || lookahead.peek(Token![unsafe])
398 || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
399 {
400 let mut bare_fn: TypeBareFn = input.parse()?;
401 bare_fn.lifetimes = lifetimes;
402 Ok(Type::BareFn(bare_fn))
403 } else if lookahead.peek(Ident)
404 || input.peek(Token![super])
405 || input.peek(Token![self])
406 || input.peek(Token![Self])
407 || input.peek(Token![crate])
408 || input.peek(Token![extern])
409 || lookahead.peek(Token![::])
410 || lookahead.peek(Token![<])
411 {
412 if input.peek(Token![dyn]) {
413 let mut trait_object: TypeTraitObject = input.parse()?;
414 if lifetimes.is_some() {
415 match *trait_object.bounds.iter_mut().next().unwrap() {
416 TypeParamBound::Trait(ref mut trait_bound) => {
417 trait_bound.lifetimes = lifetimes;
418 }
419 TypeParamBound::Lifetime(_) => unreachable!(),
420 }
421 }
422 return Ok(Type::TraitObject(trait_object));
423 }
424
425 let ty: TypePath = input.parse()?;
426 if ty.qself.is_some() {
427 return Ok(Type::Path(ty));
428 }
429
430 if input.peek(Token![!]) && !input.peek(Token![!=]) {
431 let mut contains_arguments = false;
432 for segment in &ty.path.segments {
433 match segment.arguments {
434 PathArguments::None => {}
435 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
436 contains_arguments = true;
437 }
438 }
439 }
440
441 if !contains_arguments {
442 let bang_token: Token![!] = input.parse()?;
443 let (delimiter, tts) = mac::parse_delimiter(input)?;
444 return Ok(Type::Macro(TypeMacro {
445 mac: Macro {
446 path: ty.path,
447 bang_token: bang_token,
448 delimiter: delimiter,
449 tts: tts,
450 },
451 }));
452 }
453 }
454
455 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
456 let mut bounds = Punctuated::new();
457 bounds.push_value(TypeParamBound::Trait(TraitBound {
458 paren_token: None,
459 modifier: TraitBoundModifier::None,
460 lifetimes: lifetimes,
461 path: ty.path,
462 }));
David Tolnayf5ebc192018-08-30 18:23:46 -0700463 if allow_plus {
464 while input.peek(Token![+]) {
465 bounds.push_punct(input.parse()?);
David Tolnay1b210d12018-10-27 22:07:00 -0700466 if input.peek(Token![>]) {
467 break;
468 }
David Tolnayf5ebc192018-08-30 18:23:46 -0700469 bounds.push_value(input.parse()?);
470 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400471 }
472 return Ok(Type::TraitObject(TypeTraitObject {
473 dyn_token: None,
474 bounds: bounds,
475 }));
476 }
477
478 Ok(Type::Path(ty))
479 } else if lookahead.peek(token::Bracket) {
480 let content;
481 let bracket_token = bracketed!(content in input);
482 let elem: Type = content.parse()?;
483 if content.peek(Token![;]) {
484 Ok(Type::Array(TypeArray {
485 bracket_token: bracket_token,
David Tolnayeadbda32017-12-29 02:33:47 -0500486 elem: Box::new(elem),
David Tolnaya7d69fc2018-08-26 13:30:24 -0400487 semi_token: content.parse()?,
David Tolnay9389c382018-08-27 09:13:37 -0700488 len: content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400489 }))
490 } else {
491 Ok(Type::Slice(TypeSlice {
492 bracket_token: bracket_token,
493 elem: Box::new(elem),
494 }))
Alex Crichton954046c2017-05-30 21:49:42 -0700495 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400496 } else if lookahead.peek(Token![*]) {
497 input.parse().map(Type::Ptr)
498 } else if lookahead.peek(Token![&]) {
499 input.parse().map(Type::Reference)
500 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
501 input.parse().map(Type::Never)
502 } else if lookahead.peek(Token![impl ]) {
503 input.parse().map(Type::ImplTrait)
504 } else if lookahead.peek(Token![_]) {
505 input.parse().map(Type::Infer)
506 } else if lookahead.peek(Lifetime) {
507 input.parse().map(Type::TraitObject)
508 } else {
509 Err(lookahead.error())
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800510 }
Alex Crichton954046c2017-05-30 21:49:42 -0700511 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700512
David Tolnaya7d69fc2018-08-26 13:30:24 -0400513 impl Parse for TypeSlice {
514 fn parse(input: ParseStream) -> Result<Self> {
515 let content;
516 Ok(TypeSlice {
517 bracket_token: bracketed!(content in input),
518 elem: content.parse()?,
Michael Layzell92639a52017-06-01 00:07:44 -0400519 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800520 }
Alex Crichton954046c2017-05-30 21:49:42 -0700521 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700522
David Tolnaya7d69fc2018-08-26 13:30:24 -0400523 impl Parse for TypeArray {
524 fn parse(input: ParseStream) -> Result<Self> {
525 let content;
526 Ok(TypeArray {
527 bracket_token: bracketed!(content in input),
528 elem: content.parse()?,
529 semi_token: content.parse()?,
David Tolnay9389c382018-08-27 09:13:37 -0700530 len: content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400531 })
532 }
533 }
534
535 impl Parse for TypePtr {
536 fn parse(input: ParseStream) -> Result<Self> {
537 let star_token: Token![*] = input.parse()?;
538
539 let lookahead = input.lookahead1();
540 let (const_token, mutability) = if lookahead.peek(Token![const]) {
541 (Some(input.parse()?), None)
542 } else if lookahead.peek(Token![mut]) {
543 (None, Some(input.parse()?))
544 } else {
545 return Err(lookahead.error());
546 };
547
548 Ok(TypePtr {
549 star_token: star_token,
550 const_token: const_token,
David Tolnay136aaa32017-12-29 02:37:36 -0500551 mutability: mutability,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400552 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400553 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800554 }
Alex Crichton954046c2017-05-30 21:49:42 -0700555 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700556
David Tolnaya7d69fc2018-08-26 13:30:24 -0400557 impl Parse for TypeReference {
558 fn parse(input: ParseStream) -> Result<Self> {
559 Ok(TypeReference {
560 and_token: input.parse()?,
561 lifetime: input.parse()?,
562 mutability: input.parse()?,
563 // & binds tighter than +, so we don't allow + here.
564 elem: Box::new(input.call(Type::without_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400565 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800566 }
Alex Crichton954046c2017-05-30 21:49:42 -0700567 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700568
David Tolnaya7d69fc2018-08-26 13:30:24 -0400569 impl Parse for TypeBareFn {
570 fn parse(input: ParseStream) -> Result<Self> {
571 let args;
572 let allow_variadic;
573 Ok(TypeBareFn {
574 lifetimes: input.parse()?,
575 unsafety: input.parse()?,
576 abi: input.parse()?,
577 fn_token: input.parse()?,
578 paren_token: parenthesized!(args in input),
579 inputs: {
David Tolnayf5ebc192018-08-30 18:23:46 -0700580 let mut inputs = Punctuated::new();
581 while !args.is_empty() && !args.peek(Token![...]) {
582 inputs.push_value(args.parse()?);
583 if args.is_empty() {
584 break;
585 }
586 inputs.push_punct(args.parse()?);
587 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400588 allow_variadic = inputs.empty_or_trailing();
589 inputs
590 },
591 variadic: {
592 if allow_variadic && args.peek(Token![...]) {
593 Some(args.parse()?)
594 } else {
595 None
596 }
597 },
598 output: input.call(ReturnType::without_plus)?,
Michael Layzell92639a52017-06-01 00:07:44 -0400599 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800600 }
Alex Crichton954046c2017-05-30 21:49:42 -0700601 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700602
David Tolnaya7d69fc2018-08-26 13:30:24 -0400603 impl Parse for TypeNever {
604 fn parse(input: ParseStream) -> Result<Self> {
605 Ok(TypeNever {
606 bang_token: input.parse()?,
David Tolnay7d38c7e2017-12-25 22:31:50 -0500607 })
David Tolnaya7d69fc2018-08-26 13:30:24 -0400608 }
609 }
610
611 impl Parse for TypeInfer {
612 fn parse(input: ParseStream) -> Result<Self> {
613 Ok(TypeInfer {
614 underscore_token: input.parse()?,
615 })
616 }
617 }
618
619 impl Parse for TypeTuple {
620 fn parse(input: ParseStream) -> Result<Self> {
621 let content;
622 Ok(TypeTuple {
623 paren_token: parenthesized!(content in input),
David Tolnay60484fe2018-08-30 18:43:04 -0700624 elems: content.parse_terminated(Type::parse)?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400625 })
626 }
627 }
628
629 impl Parse for TypeMacro {
630 fn parse(input: ParseStream) -> Result<Self> {
631 Ok(TypeMacro {
632 mac: input.parse()?,
633 })
634 }
635 }
636
637 impl Parse for TypePath {
638 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay60291082018-08-28 09:54:49 -0700639 let (qself, mut path) = path::parsing::qpath(input, false)?;
David Tolnaya7d69fc2018-08-26 13:30:24 -0400640
David Tolnay60291082018-08-28 09:54:49 -0700641 if path.segments.last().unwrap().value().arguments.is_empty()
David Tolnaya7d69fc2018-08-26 13:30:24 -0400642 && input.peek(token::Paren)
643 {
644 let args: ParenthesizedGenericArguments = input.parse()?;
David Tolnay60291082018-08-28 09:54:49 -0700645 let parenthesized = PathArguments::Parenthesized(args);
David Tolnaya7d69fc2018-08-26 13:30:24 -0400646 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
647 }
648
649 Ok(TypePath {
650 qself: qself,
651 path: path,
652 })
653 }
David Tolnay7d38c7e2017-12-25 22:31:50 -0500654 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700655
Geoffry Songac02b182018-05-19 22:11:31 -0700656 impl ReturnType {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400657 pub fn without_plus(input: ParseStream) -> Result<Self> {
658 Self::parse(input, false)
659 }
Geoffry Songac02b182018-05-19 22:11:31 -0700660
David Tolnaya7d69fc2018-08-26 13:30:24 -0400661 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
662 if input.peek(Token![->]) {
663 let arrow = input.parse()?;
664 let ty = ambig_ty(input, allow_plus)?;
665 Ok(ReturnType::Type(arrow, Box::new(ty)))
666 } else {
667 Ok(ReturnType::Default)
668 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800669 }
Alex Crichton954046c2017-05-30 21:49:42 -0700670 }
671
David Tolnaya7d69fc2018-08-26 13:30:24 -0400672 impl Parse for ReturnType {
673 fn parse(input: ParseStream) -> Result<Self> {
674 Self::parse(input, true)
675 }
676 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800677
David Tolnaya7d69fc2018-08-26 13:30:24 -0400678 impl Parse for TypeTraitObject {
679 fn parse(input: ParseStream) -> Result<Self> {
680 Self::parse(input, true)
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800681 }
David Tolnay0a169d42017-12-29 17:57:29 -0500682 }
683
David Tolnaye39b0702018-01-09 17:57:31 -0800684 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
685 for bound in bounds {
686 if let TypeParamBound::Trait(_) = *bound {
687 return true;
688 }
689 }
690 false
691 }
692
David Tolnay7d38c7e2017-12-25 22:31:50 -0500693 impl TypeTraitObject {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400694 pub fn without_plus(input: ParseStream) -> Result<Self> {
695 Self::parse(input, false)
696 }
David Tolnay0a169d42017-12-29 17:57:29 -0500697
David Tolnay7d38c7e2017-12-25 22:31:50 -0500698 // Only allow multiple trait references if allow_plus is true.
David Tolnaya7d69fc2018-08-26 13:30:24 -0400699 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
700 Ok(TypeTraitObject {
701 dyn_token: input.parse()?,
702 bounds: {
David Tolnayf5ebc192018-08-30 18:23:46 -0700703 let mut bounds = Punctuated::new();
704 if allow_plus {
705 loop {
706 bounds.push_value(input.parse()?);
707 if !input.peek(Token![+]) {
708 break;
709 }
710 bounds.push_punct(input.parse()?);
David Tolnay1b210d12018-10-27 22:07:00 -0700711 if input.peek(Token![>]) {
712 break;
713 }
David Tolnayf5ebc192018-08-30 18:23:46 -0700714 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400715 } else {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400716 bounds.push_value(input.parse()?);
David Tolnayf5ebc192018-08-30 18:23:46 -0700717 }
David Tolnaya7d69fc2018-08-26 13:30:24 -0400718 // Just lifetimes like `'a + 'b` is not a TraitObject.
719 if !at_least_one_type(&bounds) {
720 return Err(input.error("expected at least one type"));
721 }
David Tolnayf2cfd722017-12-31 18:02:51 -0500722 bounds
David Tolnaya7d69fc2018-08-26 13:30:24 -0400723 },
David Tolnay7d38c7e2017-12-25 22:31:50 -0500724 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800725 }
Alex Crichton954046c2017-05-30 21:49:42 -0700726 }
David Tolnayb79ee962016-09-04 09:39:20 -0700727
David Tolnaya7d69fc2018-08-26 13:30:24 -0400728 impl Parse for TypeImplTrait {
729 fn parse(input: ParseStream) -> Result<Self> {
730 Ok(TypeImplTrait {
731 impl_token: input.parse()?,
732 // NOTE: rust-lang/rust#34511 includes discussion about whether
733 // or not + should be allowed in ImplTrait directly without ().
David Tolnayf5ebc192018-08-30 18:23:46 -0700734 bounds: {
735 let mut bounds = Punctuated::new();
736 loop {
737 bounds.push_value(input.parse()?);
738 if !input.peek(Token![+]) {
739 break;
740 }
741 bounds.push_punct(input.parse()?);
742 }
743 bounds
744 },
Michael Layzell93c36282017-06-04 20:43:14 -0400745 })
David Tolnay79777332018-01-07 10:04:42 -0800746 }
Michael Layzell93c36282017-06-04 20:43:14 -0400747 }
748
David Tolnaya7d69fc2018-08-26 13:30:24 -0400749 impl Parse for TypeGroup {
750 fn parse(input: ParseStream) -> Result<Self> {
David Tolnay10951d52018-08-31 10:27:39 -0700751 let group = private::parse_group(input)?;
David Tolnaya7d69fc2018-08-26 13:30:24 -0400752 Ok(TypeGroup {
David Tolnayf57f76f2018-08-31 10:23:17 -0700753 group_token: group.token,
754 elem: group.content.parse()?,
David Tolnaya7d69fc2018-08-26 13:30:24 -0400755 })
756 }
757 }
David Tolnay79777332018-01-07 10:04:42 -0800758
David Tolnaya7d69fc2018-08-26 13:30:24 -0400759 impl Parse for TypeParen {
760 fn parse(input: ParseStream) -> Result<Self> {
761 Self::parse(input, false)
David Tolnay79777332018-01-07 10:04:42 -0800762 }
David Tolnay0a169d42017-12-29 17:57:29 -0500763 }
764
765 impl TypeParen {
David Tolnaya7d69fc2018-08-26 13:30:24 -0400766 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
767 let content;
768 Ok(TypeParen {
769 paren_token: parenthesized!(content in input),
770 elem: Box::new(ambig_ty(&content, allow_plus)?),
Michael Layzell92639a52017-06-01 00:07:44 -0400771 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800772 }
Alex Crichton954046c2017-05-30 21:49:42 -0700773 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700774
David Tolnaya7d69fc2018-08-26 13:30:24 -0400775 impl Parse for BareFnArg {
776 fn parse(input: ParseStream) -> Result<Self> {
777 Ok(BareFnArg {
778 name: {
779 if (input.peek(Ident) || input.peek(Token![_]))
780 && !input.peek2(Token![::])
781 && input.peek2(Token![:])
782 {
783 let name: BareFnArgName = input.parse()?;
784 let colon: Token![:] = input.parse()?;
785 Some((name, colon))
786 } else {
787 None
788 }
789 },
790 ty: input.parse()?,
791 })
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800792 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700793 }
794
David Tolnaya7d69fc2018-08-26 13:30:24 -0400795 impl Parse for BareFnArgName {
796 fn parse(input: ParseStream) -> Result<Self> {
797 let lookahead = input.lookahead1();
798 if lookahead.peek(Ident) {
799 input.parse().map(BareFnArgName::Named)
800 } else if lookahead.peek(Token![_]) {
801 input.parse().map(BareFnArgName::Wild)
802 } else {
803 Err(lookahead.error())
804 }
805 }
806 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800807
David Tolnaya7d69fc2018-08-26 13:30:24 -0400808 impl Parse for Abi {
809 fn parse(input: ParseStream) -> Result<Self> {
810 Ok(Abi {
811 extern_token: input.parse()?,
812 name: input.parse()?,
813 })
814 }
815 }
816
817 impl Parse for Option<Abi> {
818 fn parse(input: ParseStream) -> Result<Self> {
819 if input.peek(Token![extern]) {
820 input.parse().map(Some)
821 } else {
822 Ok(None)
823 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800824 }
Alex Crichton954046c2017-05-30 21:49:42 -0700825 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700826}
David Tolnay87d0b442016-09-04 11:52:12 -0700827
828#[cfg(feature = "printing")]
829mod printing {
830 use super::*;
David Tolnay64023912018-08-31 09:51:12 -0700831
Alex Crichtona74a1c82018-05-16 10:20:44 -0700832 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700833 use quote::ToTokens;
David Tolnay87d0b442016-09-04 11:52:12 -0700834
David Tolnay64023912018-08-31 09:51:12 -0700835 use print::TokensOrDefault;
836
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800837 impl ToTokens for TypeSlice {
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 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700842 }
843 }
844
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800845 impl ToTokens for TypeArray {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700846 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700847 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500848 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700849 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500850 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700851 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700852 }
853 }
854
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800855 impl ToTokens for TypePtr {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700856 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700857 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500858 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500859 Some(ref tok) => tok.to_tokens(tokens),
860 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700861 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400862 }
863 }
David Tolnay136aaa32017-12-29 02:37:36 -0500864 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700865 }
866 }
867
David Tolnay0a89b4d2017-11-13 00:55:45 -0800868 impl ToTokens for TypeReference {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700869 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700870 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700871 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500872 self.mutability.to_tokens(tokens);
873 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700874 }
875 }
876
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800877 impl ToTokens for TypeBareFn {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700878 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500879 self.lifetimes.to_tokens(tokens);
880 self.unsafety.to_tokens(tokens);
881 self.abi.to_tokens(tokens);
882 self.fn_token.to_tokens(tokens);
883 self.paren_token.surround(tokens, |tokens| {
884 self.inputs.to_tokens(tokens);
885 if let Some(ref variadic) = self.variadic {
886 if !self.inputs.empty_or_trailing() {
David Tolnay7ac699c2018-08-24 14:00:58 -0400887 let span = variadic.spans[0];
888 Token![,](span).to_tokens(tokens);
David Tolnaybe7a9592017-12-29 02:39:53 -0500889 }
890 variadic.to_tokens(tokens);
891 }
892 });
893 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700894 }
895 }
896
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800897 impl ToTokens for TypeNever {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700898 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700899 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700900 }
901 }
902
David Tolnay05362582017-12-26 01:33:57 -0500903 impl ToTokens for TypeTuple {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700904 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700905 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500906 self.elems.to_tokens(tokens);
David Tolnaydb402062018-03-31 22:23:30 +0200907 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700908 }
909 }
910
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800911 impl ToTokens for TypePath {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700912 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay12f3b6f2018-09-01 16:10:53 -0700913 private::print_path(tokens, &self.qself, &self.path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700914 }
915 }
916
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800917 impl ToTokens for TypeTraitObject {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700918 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500919 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700920 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700921 }
922 }
923
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800924 impl ToTokens for TypeImplTrait {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700925 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700926 self.impl_token.to_tokens(tokens);
927 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700928 }
929 }
930
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800931 impl ToTokens for TypeGroup {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700932 fn to_tokens(&self, tokens: &mut TokenStream) {
Michael Layzell93c36282017-06-04 20:43:14 -0400933 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500934 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -0400935 });
936 }
937 }
938
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800939 impl ToTokens for TypeParen {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700940 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700941 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500942 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700943 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700944 }
945 }
946
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800947 impl ToTokens for TypeInfer {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700948 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700949 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700950 }
951 }
952
David Tolnay323279a2017-12-29 11:26:32 -0500953 impl ToTokens for TypeMacro {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700954 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay323279a2017-12-29 11:26:32 -0500955 self.mac.to_tokens(tokens);
956 }
957 }
958
David Tolnay2ae520a2017-12-29 11:19:50 -0500959 impl ToTokens for TypeVerbatim {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700960 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay2ae520a2017-12-29 11:19:50 -0500961 self.tts.to_tokens(tokens);
962 }
963 }
964
David Tolnayf93b90d2017-11-11 19:21:26 -0800965 impl ToTokens for ReturnType {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700966 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700967 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -0800968 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -0500969 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700970 arrow.to_tokens(tokens);
971 ty.to_tokens(tokens);
972 }
David Tolnay87d0b442016-09-04 11:52:12 -0700973 }
974 }
975 }
976
David Tolnay62f374c2016-10-02 13:37:00 -0700977 impl ToTokens for BareFnArg {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700978 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700979 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -0700980 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700981 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -0700982 }
983 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700984 }
985 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700986
Alex Crichton23a15f62017-08-28 12:34:23 -0700987 impl ToTokens for BareFnArgName {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700988 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichton23a15f62017-08-28 12:34:23 -0700989 match *self {
990 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
991 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
992 }
993 }
994 }
995
David Tolnayb8d8ef52016-10-29 14:30:08 -0700996 impl ToTokens for Abi {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700997 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700998 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -0500999 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001000 }
1001 }
David Tolnay87d0b442016-09-04 11:52:12 -07001002}