]>
Commit | Line | Data |
---|---|---|
0531ce1d XL |
1 | // 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 | ||
3b2f2976 | 9 | use super::*; |
0531ce1d | 10 | use proc_macro2::TokenStream; |
8faf50e0 | 11 | use punctuated::Punctuated; |
0531ce1d XL |
12 | #[cfg(feature = "extra-traits")] |
13 | use std::hash::{Hash, Hasher}; | |
14 | #[cfg(feature = "extra-traits")] | |
15 | use tt::TokenStreamHelper; | |
16 | ||
17 | ast_enum_of_structs! { | |
18 | /// The possible types that a Rust value could have. | |
3b2f2976 | 19 | /// |
0531ce1d XL |
20 | /// *This type is available if Syn is built with the `"derive"` or `"full"` |
21 | /// feature.* | |
22 | /// | |
23 | /// # Syntax tree enum | |
24 | /// | |
25 | /// This type is a [syntax tree enum]. | |
26 | /// | |
27 | /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums | |
28 | pub enum Type { | |
29 | /// A dynamically sized slice type: `[T]`. | |
30 | /// | |
31 | /// *This type is available if Syn is built with the `"derive"` or | |
32 | /// `"full"` feature.* | |
33 | pub Slice(TypeSlice { | |
34 | pub bracket_token: token::Bracket, | |
35 | pub elem: Box<Type>, | |
36 | }), | |
37 | ||
38 | /// A fixed size array type: `[T; n]`. | |
39 | /// | |
40 | /// *This type is available if Syn is built with the `"derive"` or | |
41 | /// `"full"` feature.* | |
42 | pub Array(TypeArray { | |
43 | pub bracket_token: token::Bracket, | |
44 | pub elem: Box<Type>, | |
45 | pub semi_token: Token![;], | |
46 | pub len: Expr, | |
47 | }), | |
48 | ||
49 | /// A raw pointer type: `*const T` or `*mut T`. | |
50 | /// | |
51 | /// *This type is available if Syn is built with the `"derive"` or | |
52 | /// `"full"` feature.* | |
53 | pub Ptr(TypePtr { | |
54 | pub star_token: Token![*], | |
55 | pub const_token: Option<Token![const]>, | |
56 | pub mutability: Option<Token![mut]>, | |
57 | pub elem: Box<Type>, | |
58 | }), | |
59 | ||
60 | /// A reference type: `&'a T` or `&'a mut T`. | |
61 | /// | |
62 | /// *This type is available if Syn is built with the `"derive"` or | |
63 | /// `"full"` feature.* | |
64 | pub Reference(TypeReference { | |
65 | pub and_token: Token![&], | |
66 | pub lifetime: Option<Lifetime>, | |
67 | pub mutability: Option<Token![mut]>, | |
68 | pub elem: Box<Type>, | |
69 | }), | |
70 | ||
71 | /// A bare function type: `fn(usize) -> bool`. | |
72 | /// | |
73 | /// *This type is available if Syn is built with the `"derive"` or | |
74 | /// `"full"` feature.* | |
75 | pub BareFn(TypeBareFn { | |
76 | pub unsafety: Option<Token![unsafe]>, | |
77 | pub abi: Option<Abi>, | |
78 | pub fn_token: Token![fn], | |
79 | pub lifetimes: Option<BoundLifetimes>, | |
80 | pub paren_token: token::Paren, | |
81 | pub inputs: Punctuated<BareFnArg, Token![,]>, | |
82 | pub variadic: Option<Token![...]>, | |
83 | pub output: ReturnType, | |
84 | }), | |
85 | ||
86 | /// The never type: `!`. | |
87 | /// | |
88 | /// *This type is available if Syn is built with the `"derive"` or | |
89 | /// `"full"` feature.* | |
90 | pub Never(TypeNever { | |
91 | pub bang_token: Token![!], | |
92 | }), | |
93 | ||
94 | /// A tuple type: `(A, B, C, String)`. | |
95 | /// | |
96 | /// *This type is available if Syn is built with the `"derive"` or | |
97 | /// `"full"` feature.* | |
98 | pub Tuple(TypeTuple { | |
99 | pub paren_token: token::Paren, | |
100 | pub elems: Punctuated<Type, Token![,]>, | |
101 | }), | |
102 | ||
103 | /// A path like `std::slice::Iter`, optionally qualified with a | |
104 | /// self-type as in `<Vec<T> as SomeTrait>::Associated`. | |
105 | /// | |
106 | /// Type arguments are stored in the Path itself. | |
107 | /// | |
108 | /// *This type is available if Syn is built with the `"derive"` or | |
109 | /// `"full"` feature.* | |
110 | pub Path(TypePath { | |
111 | pub qself: Option<QSelf>, | |
112 | pub path: Path, | |
113 | }), | |
114 | ||
115 | /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a | |
116 | /// trait or a lifetime. | |
117 | /// | |
118 | /// *This type is available if Syn is built with the `"derive"` or | |
119 | /// `"full"` feature.* | |
120 | pub TraitObject(TypeTraitObject { | |
121 | pub dyn_token: Option<Token![dyn]>, | |
122 | pub bounds: Punctuated<TypeParamBound, Token![+]>, | |
123 | }), | |
124 | ||
125 | /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or | |
126 | /// a lifetime. | |
127 | /// | |
128 | /// *This type is available if Syn is built with the `"derive"` or | |
129 | /// `"full"` feature.* | |
130 | pub ImplTrait(TypeImplTrait { | |
131 | pub impl_token: Token![impl], | |
132 | pub bounds: Punctuated<TypeParamBound, Token![+]>, | |
133 | }), | |
134 | ||
135 | /// A parenthesized type equivalent to the inner type. | |
136 | /// | |
137 | /// *This type is available if Syn is built with the `"derive"` or | |
138 | /// `"full"` feature.* | |
139 | pub Paren(TypeParen { | |
140 | pub paren_token: token::Paren, | |
141 | pub elem: Box<Type>, | |
142 | }), | |
143 | ||
144 | /// A type contained within invisible delimiters. | |
145 | /// | |
146 | /// *This type is available if Syn is built with the `"derive"` or | |
147 | /// `"full"` feature.* | |
148 | pub Group(TypeGroup { | |
149 | pub group_token: token::Group, | |
150 | pub elem: Box<Type>, | |
151 | }), | |
152 | ||
153 | /// Indication that a type should be inferred by the compiler: `_`. | |
154 | /// | |
155 | /// *This type is available if Syn is built with the `"derive"` or | |
156 | /// `"full"` feature.* | |
157 | pub Infer(TypeInfer { | |
158 | pub underscore_token: Token![_], | |
159 | }), | |
160 | ||
161 | /// A macro in the type position. | |
162 | /// | |
163 | /// *This type is available if Syn is built with the `"derive"` or | |
164 | /// `"full"` feature.* | |
165 | pub Macro(TypeMacro { | |
166 | pub mac: Macro, | |
167 | }), | |
168 | ||
169 | /// Tokens in type position not interpreted by Syn. | |
170 | /// | |
171 | /// *This type is available if Syn is built with the `"derive"` or | |
172 | /// `"full"` feature.* | |
173 | pub Verbatim(TypeVerbatim #manual_extra_traits { | |
174 | pub tts: TokenStream, | |
175 | }), | |
3b2f2976 XL |
176 | } |
177 | } | |
178 | ||
0531ce1d XL |
179 | #[cfg(feature = "extra-traits")] |
180 | impl Eq for TypeVerbatim {} | |
3b2f2976 | 181 | |
0531ce1d XL |
182 | #[cfg(feature = "extra-traits")] |
183 | impl PartialEq for TypeVerbatim { | |
184 | fn eq(&self, other: &Self) -> bool { | |
185 | TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts) | |
3b2f2976 XL |
186 | } |
187 | } | |
188 | ||
0531ce1d XL |
189 | #[cfg(feature = "extra-traits")] |
190 | impl Hash for TypeVerbatim { | |
191 | fn hash<H>(&self, state: &mut H) | |
192 | where | |
193 | H: Hasher, | |
194 | { | |
195 | TokenStreamHelper(&self.tts).hash(state); | |
3b2f2976 XL |
196 | } |
197 | } | |
198 | ||
0531ce1d XL |
199 | ast_struct! { |
200 | /// The binary interface of a function: `extern "C"`. | |
3b2f2976 | 201 | /// |
0531ce1d XL |
202 | /// *This type is available if Syn is built with the `"derive"` or `"full"` |
203 | /// feature.* | |
204 | pub struct Abi { | |
205 | pub extern_token: Token![extern], | |
206 | pub name: Option<LitStr>, | |
207 | } | |
3b2f2976 XL |
208 | } |
209 | ||
0531ce1d XL |
210 | ast_struct! { |
211 | /// An argument in a function type: the `usize` in `fn(usize) -> bool`. | |
212 | /// | |
213 | /// *This type is available if Syn is built with the `"derive"` or `"full"` | |
214 | /// feature.* | |
215 | pub struct BareFnArg { | |
216 | pub name: Option<(BareFnArgName, Token![:])>, | |
217 | pub ty: Type, | |
218 | } | |
3b2f2976 XL |
219 | } |
220 | ||
0531ce1d XL |
221 | ast_enum! { |
222 | /// Name of an argument in a function type: the `n` in `fn(n: usize)`. | |
223 | /// | |
224 | /// *This type is available if Syn is built with the `"derive"` or `"full"` | |
225 | /// feature.* | |
226 | pub enum BareFnArgName { | |
227 | /// Argument given a name. | |
228 | Named(Ident), | |
229 | /// Argument not given a name, matched with `_`. | |
230 | Wild(Token![_]), | |
231 | } | |
3b2f2976 XL |
232 | } |
233 | ||
0531ce1d XL |
234 | ast_enum! { |
235 | /// Return type of a function signature. | |
3b2f2976 | 236 | /// |
0531ce1d XL |
237 | /// *This type is available if Syn is built with the `"derive"` or `"full"` |
238 | /// feature.* | |
239 | pub enum ReturnType { | |
240 | /// Return type is not specified. | |
241 | /// | |
242 | /// Functions default to `()` and closures default to type inference. | |
243 | Default, | |
244 | /// A particular type is returned. | |
245 | Type(Token![->], Box<Type>), | |
246 | } | |
3b2f2976 XL |
247 | } |
248 | ||
249 | #[cfg(feature = "parsing")] | |
250 | pub mod parsing { | |
251 | use super::*; | |
0531ce1d | 252 | use path::parsing::qpath; |
8faf50e0 | 253 | use synom::Synom; |
0531ce1d XL |
254 | |
255 | impl Synom for Type { | |
256 | named!(parse -> Self, call!(ambig_ty, true)); | |
257 | ||
258 | fn description() -> Option<&'static str> { | |
259 | Some("type") | |
260 | } | |
261 | } | |
262 | ||
263 | impl Type { | |
264 | /// In some positions, types may not contain the `+` character, to | |
265 | /// disambiguate them. For example in the expression `1 as T`, T may not | |
266 | /// contain a `+` character. | |
267 | /// | |
268 | /// This parser does not allow a `+`, while the default parser does. | |
269 | named!(pub without_plus -> Self, call!(ambig_ty, false)); | |
270 | } | |
271 | ||
272 | named!(ambig_ty(allow_plus: bool) -> Type, alt!( | |
273 | syn!(TypeGroup) => { Type::Group } | |
274 | | | |
275 | // must be before TypeTuple | |
276 | call!(TypeParen::parse, allow_plus) => { Type::Paren } | |
3b2f2976 | 277 | | |
0531ce1d XL |
278 | // must be before TypePath |
279 | syn!(TypeMacro) => { Type::Macro } | |
3b2f2976 | 280 | | |
b7449926 XL |
281 | // must be before TypePath |
282 | syn!(TypeBareFn) => { Type::BareFn } | |
283 | | | |
0531ce1d XL |
284 | // must be before TypeTraitObject |
285 | call!(TypePath::parse, allow_plus) => { Type::Path } | |
3b2f2976 | 286 | | |
0531ce1d XL |
287 | // Don't try parsing more than one trait bound if we aren't allowing it. |
288 | // must be before TypeTuple | |
289 | call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject } | |
3b2f2976 | 290 | | |
0531ce1d | 291 | syn!(TypeSlice) => { Type::Slice } |
3b2f2976 | 292 | | |
0531ce1d | 293 | syn!(TypeArray) => { Type::Array } |
3b2f2976 | 294 | | |
0531ce1d | 295 | syn!(TypePtr) => { Type::Ptr } |
3b2f2976 | 296 | | |
0531ce1d | 297 | syn!(TypeReference) => { Type::Reference } |
3b2f2976 | 298 | | |
0531ce1d | 299 | syn!(TypeNever) => { Type::Never } |
3b2f2976 | 300 | | |
0531ce1d | 301 | syn!(TypeTuple) => { Type::Tuple } |
3b2f2976 | 302 | | |
0531ce1d XL |
303 | syn!(TypeImplTrait) => { Type::ImplTrait } |
304 | | | |
305 | syn!(TypeInfer) => { Type::Infer } | |
3b2f2976 XL |
306 | )); |
307 | ||
0531ce1d XL |
308 | impl Synom for TypeSlice { |
309 | named!(parse -> Self, map!( | |
310 | brackets!(syn!(Type)), | |
311 | |(b, ty)| TypeSlice { | |
312 | elem: Box::new(ty), | |
313 | bracket_token: b, | |
314 | } | |
315 | )); | |
3b2f2976 | 316 | |
0531ce1d XL |
317 | fn description() -> Option<&'static str> { |
318 | Some("slice type") | |
319 | } | |
320 | } | |
3b2f2976 | 321 | |
0531ce1d XL |
322 | impl Synom for TypeArray { |
323 | named!(parse -> Self, map!( | |
324 | brackets!(do_parse!( | |
325 | elem: syn!(Type) >> | |
326 | semi: punct!(;) >> | |
327 | len: syn!(Expr) >> | |
328 | (elem, semi, len) | |
329 | )), | |
330 | |(brackets, (elem, semi, len))| { | |
331 | TypeArray { | |
332 | elem: Box::new(elem), | |
333 | len: len, | |
334 | bracket_token: brackets, | |
335 | semi_token: semi, | |
336 | } | |
337 | } | |
338 | )); | |
339 | ||
340 | fn description() -> Option<&'static str> { | |
341 | Some("array type") | |
342 | } | |
343 | } | |
3b2f2976 | 344 | |
0531ce1d XL |
345 | impl Synom for TypePtr { |
346 | named!(parse -> Self, do_parse!( | |
347 | star: punct!(*) >> | |
348 | mutability: alt!( | |
349 | keyword!(const) => { |c| (None, Some(c)) } | |
350 | | | |
351 | keyword!(mut) => { |m| (Some(m), None) } | |
352 | ) >> | |
353 | target: call!(Type::without_plus) >> | |
354 | (TypePtr { | |
355 | const_token: mutability.1, | |
356 | star_token: star, | |
357 | mutability: mutability.0, | |
358 | elem: Box::new(target), | |
359 | }) | |
360 | )); | |
3b2f2976 | 361 | |
0531ce1d XL |
362 | fn description() -> Option<&'static str> { |
363 | Some("raw pointer type") | |
364 | } | |
365 | } | |
3b2f2976 | 366 | |
0531ce1d XL |
367 | impl Synom for TypeReference { |
368 | named!(parse -> Self, do_parse!( | |
369 | amp: punct!(&) >> | |
370 | life: option!(syn!(Lifetime)) >> | |
371 | mutability: option!(keyword!(mut)) >> | |
372 | // & binds tighter than +, so we don't allow + here. | |
373 | target: call!(Type::without_plus) >> | |
374 | (TypeReference { | |
375 | lifetime: life, | |
376 | mutability: mutability, | |
377 | elem: Box::new(target), | |
378 | and_token: amp, | |
379 | }) | |
380 | )); | |
3b2f2976 | 381 | |
0531ce1d XL |
382 | fn description() -> Option<&'static str> { |
383 | Some("reference type") | |
384 | } | |
385 | } | |
3b2f2976 | 386 | |
0531ce1d XL |
387 | impl Synom for TypeBareFn { |
388 | named!(parse -> Self, do_parse!( | |
389 | lifetimes: option!(syn!(BoundLifetimes)) >> | |
390 | unsafety: option!(keyword!(unsafe)) >> | |
391 | abi: option!(syn!(Abi)) >> | |
392 | fn_: keyword!(fn) >> | |
393 | parens: parens!(do_parse!( | |
394 | inputs: call!(Punctuated::parse_terminated) >> | |
395 | variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >> | |
396 | (inputs, variadic) | |
397 | )) >> | |
8faf50e0 | 398 | output: call!(ReturnType::without_plus) >> |
0531ce1d XL |
399 | (TypeBareFn { |
400 | unsafety: unsafety, | |
401 | abi: abi, | |
402 | lifetimes: lifetimes, | |
403 | output: output, | |
404 | variadic: (parens.1).1, | |
405 | fn_token: fn_, | |
406 | paren_token: parens.0, | |
407 | inputs: (parens.1).0, | |
408 | }) | |
409 | )); | |
3b2f2976 | 410 | |
0531ce1d XL |
411 | fn description() -> Option<&'static str> { |
412 | Some("`fn` type") | |
413 | } | |
414 | } | |
3b2f2976 | 415 | |
0531ce1d XL |
416 | impl Synom for TypeNever { |
417 | named!(parse -> Self, map!( | |
418 | punct!(!), | |
419 | |b| TypeNever { bang_token: b } | |
420 | )); | |
3b2f2976 | 421 | |
0531ce1d XL |
422 | fn description() -> Option<&'static str> { |
423 | Some("never type: `!`") | |
424 | } | |
425 | } | |
3b2f2976 | 426 | |
0531ce1d XL |
427 | impl Synom for TypeInfer { |
428 | named!(parse -> Self, map!( | |
429 | punct!(_), | |
430 | |u| TypeInfer { underscore_token: u } | |
431 | )); | |
3b2f2976 | 432 | |
0531ce1d XL |
433 | fn description() -> Option<&'static str> { |
434 | Some("inferred type: `_`") | |
435 | } | |
436 | } | |
3b2f2976 | 437 | |
0531ce1d XL |
438 | impl Synom for TypeTuple { |
439 | named!(parse -> Self, do_parse!( | |
440 | data: parens!(Punctuated::parse_terminated) >> | |
441 | (TypeTuple { | |
442 | paren_token: data.0, | |
443 | elems: data.1, | |
444 | }) | |
445 | )); | |
446 | ||
447 | fn description() -> Option<&'static str> { | |
448 | Some("tuple type") | |
449 | } | |
450 | } | |
451 | ||
452 | impl Synom for TypeMacro { | |
453 | named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac })); | |
454 | ||
455 | fn description() -> Option<&'static str> { | |
456 | Some("macro invocation") | |
457 | } | |
458 | } | |
459 | ||
460 | impl Synom for TypePath { | |
461 | named!(parse -> Self, call!(Self::parse, false)); | |
462 | ||
463 | fn description() -> Option<&'static str> { | |
464 | Some("type path") | |
465 | } | |
466 | } | |
467 | ||
468 | impl TypePath { | |
469 | named!(parse(allow_plus: bool) -> Self, do_parse!( | |
470 | qpath: qpath >> | |
471 | parenthesized: option!(cond_reduce!( | |
472 | qpath.1.segments.last().unwrap().value().arguments.is_empty(), | |
473 | syn!(ParenthesizedGenericArguments) | |
3b2f2976 | 474 | )) >> |
0531ce1d | 475 | cond!(allow_plus, not!(punct!(+))) >> |
3b2f2976 | 476 | ({ |
0531ce1d XL |
477 | let (qself, mut path) = qpath; |
478 | if let Some(parenthesized) = parenthesized { | |
479 | let parenthesized = PathArguments::Parenthesized(parenthesized); | |
480 | path.segments.last_mut().unwrap().value_mut().arguments = parenthesized; | |
3b2f2976 | 481 | } |
0531ce1d | 482 | TypePath { qself: qself, path: path } |
3b2f2976 | 483 | }) |
0531ce1d XL |
484 | )); |
485 | } | |
3b2f2976 | 486 | |
8faf50e0 XL |
487 | impl ReturnType { |
488 | named!(pub without_plus -> Self, call!(Self::parse, false)); | |
489 | named!(parse(allow_plus: bool) -> Self, alt!( | |
0531ce1d XL |
490 | do_parse!( |
491 | arrow: punct!(->) >> | |
8faf50e0 | 492 | ty: call!(ambig_ty, allow_plus) >> |
0531ce1d XL |
493 | (ReturnType::Type(arrow, Box::new(ty))) |
494 | ) | |
495 | | | |
496 | epsilon!() => { |_| ReturnType::Default } | |
497 | )); | |
8faf50e0 XL |
498 | } |
499 | ||
500 | impl Synom for ReturnType { | |
501 | named!(parse -> Self, call!(Self::parse, true)); | |
3b2f2976 | 502 | |
0531ce1d XL |
503 | fn description() -> Option<&'static str> { |
504 | Some("return type") | |
505 | } | |
506 | } | |
3b2f2976 | 507 | |
0531ce1d XL |
508 | impl Synom for TypeTraitObject { |
509 | named!(parse -> Self, call!(Self::parse, true)); | |
3b2f2976 | 510 | |
0531ce1d XL |
511 | fn description() -> Option<&'static str> { |
512 | Some("trait object type") | |
513 | } | |
514 | } | |
3b2f2976 | 515 | |
0531ce1d XL |
516 | fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { |
517 | for bound in bounds { | |
518 | if let TypeParamBound::Trait(_) = *bound { | |
519 | return true; | |
520 | } | |
521 | } | |
522 | false | |
523 | } | |
3b2f2976 | 524 | |
0531ce1d XL |
525 | impl TypeTraitObject { |
526 | named!(pub without_plus -> Self, call!(Self::parse, false)); | |
527 | ||
528 | // Only allow multiple trait references if allow_plus is true. | |
529 | named!(parse(allow_plus: bool) -> Self, do_parse!( | |
530 | dyn_token: option!(keyword!(dyn)) >> | |
531 | bounds: alt!( | |
532 | cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty) | |
533 | | | |
534 | syn!(TypeParamBound) => {|x| { | |
535 | let mut bounds = Punctuated::new(); | |
536 | bounds.push_value(x); | |
537 | bounds | |
538 | }} | |
539 | ) >> | |
540 | // Just lifetimes like `'a + 'b` is not a TraitObject. | |
541 | cond_reduce!(at_least_one_type(&bounds)) >> | |
542 | (TypeTraitObject { | |
543 | dyn_token: dyn_token, | |
544 | bounds: bounds, | |
545 | }) | |
546 | )); | |
547 | } | |
548 | ||
549 | impl Synom for TypeImplTrait { | |
550 | named!(parse -> Self, do_parse!( | |
551 | impl_: keyword!(impl) >> | |
552 | // NOTE: rust-lang/rust#34511 includes discussion about whether or | |
553 | // not + should be allowed in ImplTrait directly without (). | |
554 | elem: call!(Punctuated::parse_terminated_nonempty) >> | |
555 | (TypeImplTrait { | |
556 | impl_token: impl_, | |
557 | bounds: elem, | |
558 | }) | |
559 | )); | |
560 | ||
561 | fn description() -> Option<&'static str> { | |
562 | Some("`impl Trait` type") | |
563 | } | |
564 | } | |
565 | ||
566 | impl Synom for TypeGroup { | |
567 | named!(parse -> Self, do_parse!( | |
568 | data: grouped!(syn!(Type)) >> | |
569 | (TypeGroup { | |
570 | group_token: data.0, | |
571 | elem: Box::new(data.1), | |
572 | }) | |
573 | )); | |
574 | ||
575 | fn description() -> Option<&'static str> { | |
576 | Some("type surrounded by invisible delimiters") | |
577 | } | |
578 | } | |
579 | ||
580 | impl Synom for TypeParen { | |
581 | named!(parse -> Self, call!(Self::parse, false)); | |
582 | ||
583 | fn description() -> Option<&'static str> { | |
584 | Some("parenthesized type") | |
585 | } | |
586 | } | |
587 | ||
588 | impl TypeParen { | |
589 | named!(parse(allow_plus: bool) -> Self, do_parse!( | |
590 | data: parens!(syn!(Type)) >> | |
591 | cond!(allow_plus, not!(punct!(+))) >> | |
592 | (TypeParen { | |
593 | paren_token: data.0, | |
594 | elem: Box::new(data.1), | |
595 | }) | |
596 | )); | |
597 | } | |
598 | ||
599 | impl Synom for BareFnArg { | |
600 | named!(parse -> Self, do_parse!( | |
601 | name: option!(do_parse!( | |
602 | name: syn!(BareFnArgName) >> | |
603 | not!(punct!(::)) >> | |
604 | colon: punct!(:) >> | |
605 | (name, colon) | |
3b2f2976 | 606 | )) >> |
0531ce1d XL |
607 | ty: syn!(Type) >> |
608 | (BareFnArg { | |
609 | name: name, | |
610 | ty: ty, | |
3b2f2976 | 611 | }) |
0531ce1d | 612 | )); |
3b2f2976 | 613 | |
0531ce1d XL |
614 | fn description() -> Option<&'static str> { |
615 | Some("function type argument") | |
616 | } | |
617 | } | |
3b2f2976 | 618 | |
0531ce1d XL |
619 | impl Synom for BareFnArgName { |
620 | named!(parse -> Self, alt!( | |
621 | map!(syn!(Ident), BareFnArgName::Named) | |
622 | | | |
623 | map!(punct!(_), BareFnArgName::Wild) | |
624 | )); | |
3b2f2976 | 625 | |
0531ce1d XL |
626 | fn description() -> Option<&'static str> { |
627 | Some("function argument name") | |
628 | } | |
629 | } | |
3b2f2976 | 630 | |
0531ce1d XL |
631 | impl Synom for Abi { |
632 | named!(parse -> Self, do_parse!( | |
633 | extern_: keyword!(extern) >> | |
634 | name: option!(syn!(LitStr)) >> | |
635 | (Abi { | |
636 | extern_token: extern_, | |
637 | name: name, | |
638 | }) | |
639 | )); | |
3b2f2976 | 640 | |
0531ce1d XL |
641 | fn description() -> Option<&'static str> { |
642 | Some("`extern` ABI qualifier") | |
643 | } | |
644 | } | |
3b2f2976 XL |
645 | } |
646 | ||
647 | #[cfg(feature = "printing")] | |
648 | mod printing { | |
649 | use super::*; | |
8faf50e0 XL |
650 | use proc_macro2::TokenStream; |
651 | use quote::ToTokens; | |
3b2f2976 | 652 | |
0531ce1d | 653 | impl ToTokens for TypeSlice { |
8faf50e0 | 654 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
655 | self.bracket_token.surround(tokens, |tokens| { |
656 | self.elem.to_tokens(tokens); | |
657 | }); | |
3b2f2976 XL |
658 | } |
659 | } | |
660 | ||
0531ce1d | 661 | impl ToTokens for TypeArray { |
8faf50e0 | 662 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
663 | self.bracket_token.surround(tokens, |tokens| { |
664 | self.elem.to_tokens(tokens); | |
665 | self.semi_token.to_tokens(tokens); | |
666 | self.len.to_tokens(tokens); | |
667 | }); | |
3b2f2976 XL |
668 | } |
669 | } | |
670 | ||
0531ce1d | 671 | impl ToTokens for TypePtr { |
8faf50e0 | 672 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
673 | self.star_token.to_tokens(tokens); |
674 | match self.mutability { | |
675 | Some(ref tok) => tok.to_tokens(tokens), | |
676 | None => { | |
677 | TokensOrDefault(&self.const_token).to_tokens(tokens); | |
3b2f2976 | 678 | } |
3b2f2976 | 679 | } |
0531ce1d | 680 | self.elem.to_tokens(tokens); |
3b2f2976 XL |
681 | } |
682 | } | |
683 | ||
0531ce1d | 684 | impl ToTokens for TypeReference { |
8faf50e0 | 685 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
686 | self.and_token.to_tokens(tokens); |
687 | self.lifetime.to_tokens(tokens); | |
688 | self.mutability.to_tokens(tokens); | |
689 | self.elem.to_tokens(tokens); | |
3b2f2976 XL |
690 | } |
691 | } | |
692 | ||
0531ce1d | 693 | impl ToTokens for TypeBareFn { |
8faf50e0 | 694 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
695 | self.lifetimes.to_tokens(tokens); |
696 | self.unsafety.to_tokens(tokens); | |
697 | self.abi.to_tokens(tokens); | |
698 | self.fn_token.to_tokens(tokens); | |
699 | self.paren_token.surround(tokens, |tokens| { | |
700 | self.inputs.to_tokens(tokens); | |
701 | if let Some(ref variadic) = self.variadic { | |
702 | if !self.inputs.empty_or_trailing() { | |
703 | let span = variadic.0[0]; | |
704 | <Token![,]>::new(span).to_tokens(tokens); | |
705 | } | |
706 | variadic.to_tokens(tokens); | |
3b2f2976 | 707 | } |
0531ce1d XL |
708 | }); |
709 | self.output.to_tokens(tokens); | |
3b2f2976 XL |
710 | } |
711 | } | |
712 | ||
0531ce1d | 713 | impl ToTokens for TypeNever { |
8faf50e0 | 714 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
715 | self.bang_token.to_tokens(tokens); |
716 | } | |
717 | } | |
3b2f2976 | 718 | |
0531ce1d | 719 | impl ToTokens for TypeTuple { |
8faf50e0 | 720 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
721 | self.paren_token.surround(tokens, |tokens| { |
722 | self.elems.to_tokens(tokens); | |
83c7162d | 723 | }); |
0531ce1d XL |
724 | } |
725 | } | |
3b2f2976 | 726 | |
0531ce1d | 727 | impl ToTokens for TypePath { |
8faf50e0 | 728 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
729 | PathTokens(&self.qself, &self.path).to_tokens(tokens); |
730 | } | |
731 | } | |
3b2f2976 | 732 | |
0531ce1d | 733 | impl ToTokens for TypeTraitObject { |
8faf50e0 | 734 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
735 | self.dyn_token.to_tokens(tokens); |
736 | self.bounds.to_tokens(tokens); | |
3b2f2976 XL |
737 | } |
738 | } | |
739 | ||
0531ce1d | 740 | impl ToTokens for TypeImplTrait { |
8faf50e0 | 741 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
742 | self.impl_token.to_tokens(tokens); |
743 | self.bounds.to_tokens(tokens); | |
3b2f2976 XL |
744 | } |
745 | } | |
746 | ||
0531ce1d | 747 | impl ToTokens for TypeGroup { |
8faf50e0 | 748 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
749 | self.group_token.surround(tokens, |tokens| { |
750 | self.elem.to_tokens(tokens); | |
751 | }); | |
3b2f2976 XL |
752 | } |
753 | } | |
754 | ||
0531ce1d | 755 | impl ToTokens for TypeParen { |
8faf50e0 | 756 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
757 | self.paren_token.surround(tokens, |tokens| { |
758 | self.elem.to_tokens(tokens); | |
759 | }); | |
3b2f2976 XL |
760 | } |
761 | } | |
762 | ||
0531ce1d | 763 | impl ToTokens for TypeInfer { |
8faf50e0 | 764 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
765 | self.underscore_token.to_tokens(tokens); |
766 | } | |
767 | } | |
768 | ||
769 | impl ToTokens for TypeMacro { | |
8faf50e0 | 770 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
771 | self.mac.to_tokens(tokens); |
772 | } | |
773 | } | |
774 | ||
775 | impl ToTokens for TypeVerbatim { | |
8faf50e0 | 776 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
777 | self.tts.to_tokens(tokens); |
778 | } | |
779 | } | |
780 | ||
781 | impl ToTokens for ReturnType { | |
8faf50e0 | 782 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
783 | match *self { |
784 | ReturnType::Default => {} | |
785 | ReturnType::Type(ref arrow, ref ty) => { | |
786 | arrow.to_tokens(tokens); | |
787 | ty.to_tokens(tokens); | |
3b2f2976 | 788 | } |
3b2f2976 XL |
789 | } |
790 | } | |
791 | } | |
792 | ||
793 | impl ToTokens for BareFnArg { | |
8faf50e0 | 794 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d | 795 | if let Some((ref name, ref colon)) = self.name { |
3b2f2976 | 796 | name.to_tokens(tokens); |
0531ce1d | 797 | colon.to_tokens(tokens); |
3b2f2976 XL |
798 | } |
799 | self.ty.to_tokens(tokens); | |
800 | } | |
801 | } | |
802 | ||
0531ce1d | 803 | impl ToTokens for BareFnArgName { |
8faf50e0 | 804 | fn to_tokens(&self, tokens: &mut TokenStream) { |
3b2f2976 | 805 | match *self { |
0531ce1d XL |
806 | BareFnArgName::Named(ref t) => t.to_tokens(tokens), |
807 | BareFnArgName::Wild(ref t) => t.to_tokens(tokens), | |
3b2f2976 XL |
808 | } |
809 | } | |
810 | } | |
811 | ||
812 | impl ToTokens for Abi { | |
8faf50e0 | 813 | fn to_tokens(&self, tokens: &mut TokenStream) { |
0531ce1d XL |
814 | self.extern_token.to_tokens(tokens); |
815 | self.name.to_tokens(tokens); | |
3b2f2976 XL |
816 | } |
817 | } | |
818 | } |