]> git.proxmox.com Git - rustc.git/blame - vendor/syn/src/ty.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / vendor / syn / src / ty.rs
CommitLineData
e74abb32
XL
1use super::*;
2use crate::punctuated::Punctuated;
3#[cfg(feature = "extra-traits")]
4use crate::tt::TokenStreamHelper;
5use proc_macro2::TokenStream;
6#[cfg(feature = "extra-traits")]
7use std::hash::{Hash, Hasher};
8
9ast_enum_of_structs! {
10 /// The possible types that a Rust value could have.
11 ///
12 /// *This type is available if Syn is built with the `"derive"` or `"full"`
13 /// feature.*
14 ///
15 /// # Syntax tree enum
16 ///
17 /// This type is a [syntax tree enum].
18 ///
19 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
20 //
21 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
22 // blocked on https://github.com/rust-lang/rust/issues/62833
23 pub enum Type #manual_extra_traits {
24 /// A fixed size array type: `[T; n]`.
25 Array(TypeArray),
26
27 /// A bare function type: `fn(usize) -> bool`.
28 BareFn(TypeBareFn),
29
30 /// A type contained within invisible delimiters.
31 Group(TypeGroup),
32
33 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
34 /// a lifetime.
35 ImplTrait(TypeImplTrait),
36
37 /// Indication that a type should be inferred by the compiler: `_`.
38 Infer(TypeInfer),
39
40 /// A macro in the type position.
41 Macro(TypeMacro),
42
43 /// The never type: `!`.
44 Never(TypeNever),
45
46 /// A parenthesized type equivalent to the inner type.
47 Paren(TypeParen),
48
49 /// A path like `std::slice::Iter`, optionally qualified with a
50 /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
51 Path(TypePath),
52
53 /// A raw pointer type: `*const T` or `*mut T`.
54 Ptr(TypePtr),
55
56 /// A reference type: `&'a T` or `&'a mut T`.
57 Reference(TypeReference),
58
59 /// A dynamically sized slice type: `[T]`.
60 Slice(TypeSlice),
61
62 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
63 /// trait or a lifetime.
64 TraitObject(TypeTraitObject),
65
66 /// A tuple type: `(A, B, C, String)`.
67 Tuple(TypeTuple),
68
69 /// Tokens in type position not interpreted by Syn.
70 Verbatim(TokenStream),
71
72 #[doc(hidden)]
73 __Nonexhaustive,
74 }
75}
76
77ast_struct! {
78 /// A fixed size array type: `[T; n]`.
79 ///
80 /// *This type is available if Syn is built with the `"derive"` or
81 /// `"full"` feature.*
82 pub struct TypeArray {
83 pub bracket_token: token::Bracket,
84 pub elem: Box<Type>,
85 pub semi_token: Token![;],
86 pub len: Expr,
87 }
88}
89
90ast_struct! {
91 /// A bare function type: `fn(usize) -> bool`.
92 ///
93 /// *This type is available if Syn is built with the `"derive"` or
94 /// `"full"` feature.*
95 pub struct TypeBareFn {
96 pub lifetimes: Option<BoundLifetimes>,
97 pub unsafety: Option<Token![unsafe]>,
98 pub abi: Option<Abi>,
99 pub fn_token: Token![fn],
100 pub paren_token: token::Paren,
101 pub inputs: Punctuated<BareFnArg, Token![,]>,
102 pub variadic: Option<Variadic>,
103 pub output: ReturnType,
104 }
105}
106
107ast_struct! {
108 /// A type contained within invisible delimiters.
109 ///
110 /// *This type is available if Syn is built with the `"derive"` or
111 /// `"full"` feature.*
112 pub struct TypeGroup {
113 pub group_token: token::Group,
114 pub elem: Box<Type>,
115 }
116}
117
118ast_struct! {
119 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
120 /// a lifetime.
121 ///
122 /// *This type is available if Syn is built with the `"derive"` or
123 /// `"full"` feature.*
124 pub struct TypeImplTrait {
125 pub impl_token: Token![impl],
126 pub bounds: Punctuated<TypeParamBound, Token![+]>,
127 }
128}
129
130ast_struct! {
131 /// Indication that a type should be inferred by the compiler: `_`.
132 ///
133 /// *This type is available if Syn is built with the `"derive"` or
134 /// `"full"` feature.*
135 pub struct TypeInfer {
136 pub underscore_token: Token![_],
137 }
138}
139
140ast_struct! {
141 /// A macro in the type position.
142 ///
143 /// *This type is available if Syn is built with the `"derive"` or
144 /// `"full"` feature.*
145 pub struct TypeMacro {
146 pub mac: Macro,
147 }
148}
149
150ast_struct! {
151 /// The never type: `!`.
152 ///
153 /// *This type is available if Syn is built with the `"derive"` or
154 /// `"full"` feature.*
155 pub struct TypeNever {
156 pub bang_token: Token![!],
157 }
158}
159
160ast_struct! {
161 /// A parenthesized type equivalent to the inner type.
162 ///
163 /// *This type is available if Syn is built with the `"derive"` or
164 /// `"full"` feature.*
165 pub struct TypeParen {
166 pub paren_token: token::Paren,
167 pub elem: Box<Type>,
168 }
169}
170
171ast_struct! {
172 /// A path like `std::slice::Iter`, optionally qualified with a
173 /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
174 ///
175 /// *This type is available if Syn is built with the `"derive"` or
176 /// `"full"` feature.*
177 pub struct TypePath {
178 pub qself: Option<QSelf>,
179 pub path: Path,
180 }
181}
182
183ast_struct! {
184 /// A raw pointer type: `*const T` or `*mut T`.
185 ///
186 /// *This type is available if Syn is built with the `"derive"` or
187 /// `"full"` feature.*
188 pub struct TypePtr {
189 pub star_token: Token![*],
190 pub const_token: Option<Token![const]>,
191 pub mutability: Option<Token![mut]>,
192 pub elem: Box<Type>,
193 }
194}
195
196ast_struct! {
197 /// A reference type: `&'a T` or `&'a mut T`.
198 ///
199 /// *This type is available if Syn is built with the `"derive"` or
200 /// `"full"` feature.*
201 pub struct TypeReference {
202 pub and_token: Token![&],
203 pub lifetime: Option<Lifetime>,
204 pub mutability: Option<Token![mut]>,
205 pub elem: Box<Type>,
206 }
207}
208
209ast_struct! {
210 /// A dynamically sized slice type: `[T]`.
211 ///
212 /// *This type is available if Syn is built with the `"derive"` or
213 /// `"full"` feature.*
214 pub struct TypeSlice {
215 pub bracket_token: token::Bracket,
216 pub elem: Box<Type>,
217 }
218}
219
220ast_struct! {
221 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
222 /// trait or a lifetime.
223 ///
224 /// *This type is available if Syn is built with the `"derive"` or
225 /// `"full"` feature.*
226 pub struct TypeTraitObject {
227 pub dyn_token: Option<Token![dyn]>,
228 pub bounds: Punctuated<TypeParamBound, Token![+]>,
229 }
230}
231
232ast_struct! {
233 /// A tuple type: `(A, B, C, String)`.
234 ///
235 /// *This type is available if Syn is built with the `"derive"` or
236 /// `"full"` feature.*
237 pub struct TypeTuple {
238 pub paren_token: token::Paren,
239 pub elems: Punctuated<Type, Token![,]>,
240 }
241}
242
243#[cfg(feature = "extra-traits")]
244impl Eq for Type {}
245
246#[cfg(feature = "extra-traits")]
247impl PartialEq for Type {
248 fn eq(&self, other: &Self) -> bool {
249 match (self, other) {
250 (Type::Array(this), Type::Array(other)) => this == other,
251 (Type::BareFn(this), Type::BareFn(other)) => this == other,
252 (Type::Group(this), Type::Group(other)) => this == other,
253 (Type::ImplTrait(this), Type::ImplTrait(other)) => this == other,
254 (Type::Infer(this), Type::Infer(other)) => this == other,
255 (Type::Macro(this), Type::Macro(other)) => this == other,
256 (Type::Never(this), Type::Never(other)) => this == other,
257 (Type::Paren(this), Type::Paren(other)) => this == other,
258 (Type::Path(this), Type::Path(other)) => this == other,
259 (Type::Ptr(this), Type::Ptr(other)) => this == other,
260 (Type::Reference(this), Type::Reference(other)) => this == other,
261 (Type::Slice(this), Type::Slice(other)) => this == other,
262 (Type::TraitObject(this), Type::TraitObject(other)) => this == other,
263 (Type::Tuple(this), Type::Tuple(other)) => this == other,
264 (Type::Verbatim(this), Type::Verbatim(other)) => {
265 TokenStreamHelper(this) == TokenStreamHelper(other)
266 }
267 _ => false,
268 }
269 }
270}
271
272#[cfg(feature = "extra-traits")]
273impl Hash for Type {
274 fn hash<H>(&self, hash: &mut H)
275 where
276 H: Hasher,
277 {
278 match self {
279 Type::Array(ty) => {
280 hash.write_u8(0);
281 ty.hash(hash);
282 }
283 Type::BareFn(ty) => {
284 hash.write_u8(1);
285 ty.hash(hash);
286 }
287 Type::Group(ty) => {
288 hash.write_u8(2);
289 ty.hash(hash);
290 }
291 Type::ImplTrait(ty) => {
292 hash.write_u8(3);
293 ty.hash(hash);
294 }
295 Type::Infer(ty) => {
296 hash.write_u8(4);
297 ty.hash(hash);
298 }
299 Type::Macro(ty) => {
300 hash.write_u8(5);
301 ty.hash(hash);
302 }
303 Type::Never(ty) => {
304 hash.write_u8(6);
305 ty.hash(hash);
306 }
307 Type::Paren(ty) => {
308 hash.write_u8(7);
309 ty.hash(hash);
310 }
311 Type::Path(ty) => {
312 hash.write_u8(8);
313 ty.hash(hash);
314 }
315 Type::Ptr(ty) => {
316 hash.write_u8(9);
317 ty.hash(hash);
318 }
319 Type::Reference(ty) => {
320 hash.write_u8(10);
321 ty.hash(hash);
322 }
323 Type::Slice(ty) => {
324 hash.write_u8(11);
325 ty.hash(hash);
326 }
327 Type::TraitObject(ty) => {
328 hash.write_u8(12);
329 ty.hash(hash);
330 }
331 Type::Tuple(ty) => {
332 hash.write_u8(13);
333 ty.hash(hash);
334 }
335 Type::Verbatim(ty) => {
336 hash.write_u8(14);
337 TokenStreamHelper(ty).hash(hash);
338 }
339 Type::__Nonexhaustive => unreachable!(),
340 }
341 }
342}
343
344ast_struct! {
345 /// The binary interface of a function: `extern "C"`.
346 ///
347 /// *This type is available if Syn is built with the `"derive"` or `"full"`
348 /// feature.*
349 pub struct Abi {
350 pub extern_token: Token![extern],
351 pub name: Option<LitStr>,
352 }
353}
354
355ast_struct! {
356 /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
357 ///
358 /// *This type is available if Syn is built with the `"derive"` or `"full"`
359 /// feature.*
360 pub struct BareFnArg {
361 pub attrs: Vec<Attribute>,
362 pub name: Option<(Ident, Token![:])>,
363 pub ty: Type,
364 }
365}
366
367ast_struct! {
368 /// The variadic argument of a foreign function.
369 ///
370 /// ```rust
371 /// # struct c_char;
372 /// # struct c_int;
373 /// #
374 /// extern "C" {
375 /// fn printf(format: *const c_char, ...) -> c_int;
376 /// // ^^^
377 /// }
378 /// ```
379 ///
380 /// *This type is available if Syn is built with the `"derive"` or `"full"`
381 /// feature.*
382 pub struct Variadic {
383 pub attrs: Vec<Attribute>,
384 pub dots: Token![...],
385 }
386}
387
388ast_enum! {
389 /// Return type of a function signature.
390 ///
391 /// *This type is available if Syn is built with the `"derive"` or `"full"`
392 /// feature.*
393 pub enum ReturnType {
394 /// Return type is not specified.
395 ///
396 /// Functions default to `()` and closures default to type inference.
397 Default,
398 /// A particular type is returned.
399 Type(Token![->], Box<Type>),
400 }
401}
402
403#[cfg(feature = "parsing")]
404pub mod parsing {
405 use super::*;
406
407 use crate::ext::IdentExt;
408 use crate::parse::{Parse, ParseStream, Result};
409 use crate::path;
60c5eb7d
XL
410 use proc_macro2::{Punct, Spacing, TokenTree};
411 use std::iter::FromIterator;
e74abb32
XL
412
413 impl Parse for Type {
414 fn parse(input: ParseStream) -> Result<Self> {
415 ambig_ty(input, true)
416 }
417 }
418
419 impl Type {
420 /// In some positions, types may not contain the `+` character, to
421 /// disambiguate them. For example in the expression `1 as T`, T may not
422 /// contain a `+` character.
423 ///
424 /// This parser does not allow a `+`, while the default parser does.
425 pub fn without_plus(input: ParseStream) -> Result<Self> {
426 ambig_ty(input, false)
427 }
428 }
429
430 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
431 if input.peek(token::Group) {
432 return input.parse().map(Type::Group);
433 }
434
435 let mut lifetimes = None::<BoundLifetimes>;
436 let mut lookahead = input.lookahead1();
437 if lookahead.peek(Token![for]) {
438 lifetimes = input.parse()?;
439 lookahead = input.lookahead1();
440 if !lookahead.peek(Ident)
441 && !lookahead.peek(Token![fn])
442 && !lookahead.peek(Token![unsafe])
443 && !lookahead.peek(Token![extern])
444 && !lookahead.peek(Token![super])
445 && !lookahead.peek(Token![self])
446 && !lookahead.peek(Token![Self])
447 && !lookahead.peek(Token![crate])
448 {
449 return Err(lookahead.error());
450 }
451 }
452
453 if lookahead.peek(token::Paren) {
454 let content;
455 let paren_token = parenthesized!(content in input);
456 if content.is_empty() {
457 return Ok(Type::Tuple(TypeTuple {
458 paren_token,
459 elems: Punctuated::new(),
460 }));
461 }
462 if content.peek(Lifetime) {
463 return Ok(Type::Paren(TypeParen {
464 paren_token,
465 elem: Box::new(Type::TraitObject(content.parse()?)),
466 }));
467 }
468 if content.peek(Token![?]) {
469 return Ok(Type::TraitObject(TypeTraitObject {
470 dyn_token: None,
471 bounds: {
472 let mut bounds = Punctuated::new();
473 bounds.push_value(TypeParamBound::Trait(TraitBound {
474 paren_token: Some(paren_token),
475 ..content.parse()?
476 }));
477 while let Some(plus) = input.parse()? {
478 bounds.push_punct(plus);
479 bounds.push_value(input.parse()?);
480 }
481 bounds
482 },
483 }));
484 }
485 let mut first: Type = content.parse()?;
486 if content.peek(Token![,]) {
487 return Ok(Type::Tuple(TypeTuple {
488 paren_token,
489 elems: {
490 let mut elems = Punctuated::new();
491 elems.push_value(first);
492 elems.push_punct(content.parse()?);
493 let rest: Punctuated<Type, Token![,]> =
494 content.parse_terminated(Parse::parse)?;
495 elems.extend(rest);
496 elems
497 },
498 }));
499 }
500 if allow_plus && input.peek(Token![+]) {
501 loop {
502 let first = match first {
503 Type::Path(TypePath { qself: None, path }) => {
504 TypeParamBound::Trait(TraitBound {
505 paren_token: Some(paren_token),
506 modifier: TraitBoundModifier::None,
507 lifetimes: None,
508 path,
509 })
510 }
511 Type::TraitObject(TypeTraitObject {
512 dyn_token: None,
513 bounds,
514 }) => {
515 if bounds.len() > 1 || bounds.trailing_punct() {
516 first = Type::TraitObject(TypeTraitObject {
517 dyn_token: None,
518 bounds,
519 });
520 break;
521 }
522 match bounds.into_iter().next().unwrap() {
523 TypeParamBound::Trait(trait_bound) => {
524 TypeParamBound::Trait(TraitBound {
525 paren_token: Some(paren_token),
526 ..trait_bound
527 })
528 }
529 other => other,
530 }
531 }
532 _ => break,
533 };
534 return Ok(Type::TraitObject(TypeTraitObject {
535 dyn_token: None,
536 bounds: {
537 let mut bounds = Punctuated::new();
538 bounds.push_value(first);
539 while let Some(plus) = input.parse()? {
540 bounds.push_punct(plus);
541 bounds.push_value(input.parse()?);
542 }
543 bounds
544 },
545 }));
546 }
547 }
548 Ok(Type::Paren(TypeParen {
549 paren_token,
550 elem: Box::new(first),
551 }))
552 } else if lookahead.peek(Token![fn])
553 || lookahead.peek(Token![unsafe])
554 || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
555 {
556 let mut bare_fn: TypeBareFn = input.parse()?;
557 bare_fn.lifetimes = lifetimes;
558 Ok(Type::BareFn(bare_fn))
559 } else if lookahead.peek(Ident)
560 || input.peek(Token![super])
561 || input.peek(Token![self])
562 || input.peek(Token![Self])
563 || input.peek(Token![crate])
564 || input.peek(Token![extern])
565 || lookahead.peek(Token![::])
566 || lookahead.peek(Token![<])
567 {
568 if input.peek(Token![dyn]) {
569 let mut trait_object: TypeTraitObject = input.parse()?;
570 if lifetimes.is_some() {
571 match trait_object.bounds.iter_mut().next().unwrap() {
572 TypeParamBound::Trait(trait_bound) => {
573 trait_bound.lifetimes = lifetimes;
574 }
575 TypeParamBound::Lifetime(_) => unreachable!(),
576 }
577 }
578 return Ok(Type::TraitObject(trait_object));
579 }
580
581 let ty: TypePath = input.parse()?;
582 if ty.qself.is_some() {
583 return Ok(Type::Path(ty));
584 }
585
586 if input.peek(Token![!]) && !input.peek(Token![!=]) {
587 let mut contains_arguments = false;
588 for segment in &ty.path.segments {
589 match segment.arguments {
590 PathArguments::None => {}
591 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
592 contains_arguments = true;
593 }
594 }
595 }
596
597 if !contains_arguments {
598 let bang_token: Token![!] = input.parse()?;
599 let (delimiter, tokens) = mac::parse_delimiter(input)?;
600 return Ok(Type::Macro(TypeMacro {
601 mac: Macro {
602 path: ty.path,
603 bang_token,
604 delimiter,
605 tokens,
606 },
607 }));
608 }
609 }
610
611 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
612 let mut bounds = Punctuated::new();
613 bounds.push_value(TypeParamBound::Trait(TraitBound {
614 paren_token: None,
615 modifier: TraitBoundModifier::None,
616 lifetimes,
617 path: ty.path,
618 }));
619 if allow_plus {
620 while input.peek(Token![+]) {
621 bounds.push_punct(input.parse()?);
622 if input.peek(Token![>]) {
623 break;
624 }
625 bounds.push_value(input.parse()?);
626 }
627 }
628 return Ok(Type::TraitObject(TypeTraitObject {
629 dyn_token: None,
630 bounds,
631 }));
632 }
633
634 Ok(Type::Path(ty))
635 } else if lookahead.peek(token::Bracket) {
636 let content;
637 let bracket_token = bracketed!(content in input);
638 let elem: Type = content.parse()?;
639 if content.peek(Token![;]) {
640 Ok(Type::Array(TypeArray {
641 bracket_token,
642 elem: Box::new(elem),
643 semi_token: content.parse()?,
644 len: content.parse()?,
645 }))
646 } else {
647 Ok(Type::Slice(TypeSlice {
648 bracket_token,
649 elem: Box::new(elem),
650 }))
651 }
652 } else if lookahead.peek(Token![*]) {
653 input.parse().map(Type::Ptr)
654 } else if lookahead.peek(Token![&]) {
655 input.parse().map(Type::Reference)
656 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
657 input.parse().map(Type::Never)
658 } else if lookahead.peek(Token![impl]) {
659 input.parse().map(Type::ImplTrait)
660 } else if lookahead.peek(Token![_]) {
661 input.parse().map(Type::Infer)
662 } else if lookahead.peek(Lifetime) {
663 input.parse().map(Type::TraitObject)
664 } else {
665 Err(lookahead.error())
666 }
667 }
668
669 impl Parse for TypeSlice {
670 fn parse(input: ParseStream) -> Result<Self> {
671 let content;
672 Ok(TypeSlice {
673 bracket_token: bracketed!(content in input),
674 elem: content.parse()?,
675 })
676 }
677 }
678
679 impl Parse for TypeArray {
680 fn parse(input: ParseStream) -> Result<Self> {
681 let content;
682 Ok(TypeArray {
683 bracket_token: bracketed!(content in input),
684 elem: content.parse()?,
685 semi_token: content.parse()?,
686 len: content.parse()?,
687 })
688 }
689 }
690
691 impl Parse for TypePtr {
692 fn parse(input: ParseStream) -> Result<Self> {
693 let star_token: Token![*] = input.parse()?;
694
695 let lookahead = input.lookahead1();
696 let (const_token, mutability) = if lookahead.peek(Token![const]) {
697 (Some(input.parse()?), None)
698 } else if lookahead.peek(Token![mut]) {
699 (None, Some(input.parse()?))
700 } else {
701 return Err(lookahead.error());
702 };
703
704 Ok(TypePtr {
705 star_token,
706 const_token,
707 mutability,
708 elem: Box::new(input.call(Type::without_plus)?),
709 })
710 }
711 }
712
713 impl Parse for TypeReference {
714 fn parse(input: ParseStream) -> Result<Self> {
715 Ok(TypeReference {
716 and_token: input.parse()?,
717 lifetime: input.parse()?,
718 mutability: input.parse()?,
719 // & binds tighter than +, so we don't allow + here.
720 elem: Box::new(input.call(Type::without_plus)?),
721 })
722 }
723 }
724
725 impl Parse for TypeBareFn {
726 fn parse(input: ParseStream) -> Result<Self> {
727 let args;
60c5eb7d 728 let mut variadic = None;
e74abb32
XL
729 Ok(TypeBareFn {
730 lifetimes: input.parse()?,
731 unsafety: input.parse()?,
732 abi: input.parse()?,
733 fn_token: input.parse()?,
734 paren_token: parenthesized!(args in input),
735 inputs: {
736 let mut inputs = Punctuated::new();
60c5eb7d
XL
737
738 while !args.is_empty() {
739 let attrs = args.call(Attribute::parse_outer)?;
740
741 if inputs.empty_or_trailing() && args.peek(Token![...]) {
742 variadic = Some(Variadic {
743 attrs,
744 dots: args.parse()?,
745 });
746 break;
747 }
748
749 inputs.push_value(BareFnArg {
750 attrs,
751 ..args.parse()?
752 });
e74abb32
XL
753 if args.is_empty() {
754 break;
755 }
60c5eb7d 756
e74abb32
XL
757 inputs.push_punct(args.parse()?);
758 }
60c5eb7d 759
e74abb32
XL
760 inputs
761 },
60c5eb7d 762 variadic,
e74abb32
XL
763 output: input.call(ReturnType::without_plus)?,
764 })
765 }
766 }
767
768 impl Parse for TypeNever {
769 fn parse(input: ParseStream) -> Result<Self> {
770 Ok(TypeNever {
771 bang_token: input.parse()?,
772 })
773 }
774 }
775
776 impl Parse for TypeInfer {
777 fn parse(input: ParseStream) -> Result<Self> {
778 Ok(TypeInfer {
779 underscore_token: input.parse()?,
780 })
781 }
782 }
783
784 impl Parse for TypeTuple {
785 fn parse(input: ParseStream) -> Result<Self> {
786 let content;
60c5eb7d
XL
787 let paren_token = parenthesized!(content in input);
788
789 if content.is_empty() {
790 return Ok(TypeTuple {
791 paren_token,
792 elems: Punctuated::new(),
793 });
794 }
795
796 let first: Type = content.parse()?;
e74abb32 797 Ok(TypeTuple {
60c5eb7d
XL
798 paren_token,
799 elems: {
800 let mut elems = Punctuated::new();
801 elems.push_value(first);
802 elems.push_punct(content.parse()?);
803 let rest: Punctuated<Type, Token![,]> =
804 content.parse_terminated(Parse::parse)?;
805 elems.extend(rest);
806 elems
807 },
e74abb32
XL
808 })
809 }
810 }
811
812 impl Parse for TypeMacro {
813 fn parse(input: ParseStream) -> Result<Self> {
814 Ok(TypeMacro {
815 mac: input.parse()?,
816 })
817 }
818 }
819
820 impl Parse for TypePath {
821 fn parse(input: ParseStream) -> Result<Self> {
822 let (qself, mut path) = path::parsing::qpath(input, false)?;
823
824 if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) {
825 let args: ParenthesizedGenericArguments = input.parse()?;
826 let parenthesized = PathArguments::Parenthesized(args);
827 path.segments.last_mut().unwrap().arguments = parenthesized;
828 }
829
830 Ok(TypePath { qself, path })
831 }
832 }
833
834 impl ReturnType {
835 pub fn without_plus(input: ParseStream) -> Result<Self> {
836 Self::parse(input, false)
837 }
838
839 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
840 if input.peek(Token![->]) {
841 let arrow = input.parse()?;
842 let ty = ambig_ty(input, allow_plus)?;
843 Ok(ReturnType::Type(arrow, Box::new(ty)))
844 } else {
845 Ok(ReturnType::Default)
846 }
847 }
848 }
849
850 impl Parse for ReturnType {
851 fn parse(input: ParseStream) -> Result<Self> {
852 Self::parse(input, true)
853 }
854 }
855
856 impl Parse for TypeTraitObject {
857 fn parse(input: ParseStream) -> Result<Self> {
858 Self::parse(input, true)
859 }
860 }
861
862 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
863 for bound in bounds {
864 if let TypeParamBound::Trait(_) = *bound {
865 return true;
866 }
867 }
868 false
869 }
870
871 impl TypeTraitObject {
872 pub fn without_plus(input: ParseStream) -> Result<Self> {
873 Self::parse(input, false)
874 }
875
876 // Only allow multiple trait references if allow_plus is true.
877 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
878 Ok(TypeTraitObject {
879 dyn_token: input.parse()?,
880 bounds: {
881 let mut bounds = Punctuated::new();
882 if allow_plus {
883 loop {
884 bounds.push_value(input.parse()?);
885 if !input.peek(Token![+]) {
886 break;
887 }
888 bounds.push_punct(input.parse()?);
889 if input.peek(Token![>]) {
890 break;
891 }
892 }
893 } else {
894 bounds.push_value(input.parse()?);
895 }
896 // Just lifetimes like `'a + 'b` is not a TraitObject.
897 if !at_least_one_type(&bounds) {
898 return Err(input.error("expected at least one type"));
899 }
900 bounds
901 },
902 })
903 }
904 }
905
906 impl Parse for TypeImplTrait {
907 fn parse(input: ParseStream) -> Result<Self> {
908 Ok(TypeImplTrait {
909 impl_token: input.parse()?,
910 // NOTE: rust-lang/rust#34511 includes discussion about whether
911 // or not + should be allowed in ImplTrait directly without ().
912 bounds: {
913 let mut bounds = Punctuated::new();
914 loop {
915 bounds.push_value(input.parse()?);
916 if !input.peek(Token![+]) {
917 break;
918 }
919 bounds.push_punct(input.parse()?);
920 }
921 bounds
922 },
923 })
924 }
925 }
926
927 impl Parse for TypeGroup {
928 fn parse(input: ParseStream) -> Result<Self> {
929 let group = crate::group::parse_group(input)?;
930 Ok(TypeGroup {
931 group_token: group.token,
932 elem: group.content.parse()?,
933 })
934 }
935 }
936
937 impl Parse for TypeParen {
938 fn parse(input: ParseStream) -> Result<Self> {
939 Self::parse(input, false)
940 }
941 }
942
943 impl TypeParen {
944 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
945 let content;
946 Ok(TypeParen {
947 paren_token: parenthesized!(content in input),
948 elem: Box::new(ambig_ty(&content, allow_plus)?),
949 })
950 }
951 }
952
953 impl Parse for BareFnArg {
954 fn parse(input: ParseStream) -> Result<Self> {
955 Ok(BareFnArg {
956 attrs: input.call(Attribute::parse_outer)?,
957 name: {
958 if (input.peek(Ident) || input.peek(Token![_]))
959 && input.peek2(Token![:])
960 && !input.peek2(Token![::])
961 {
962 let name = input.call(Ident::parse_any)?;
963 let colon: Token![:] = input.parse()?;
964 Some((name, colon))
965 } else {
966 None
967 }
968 },
60c5eb7d
XL
969 ty: match input.parse::<Option<Token![...]>>()? {
970 Some(dot3) => {
971 let args = vec![
972 TokenTree::Punct(Punct::new('.', Spacing::Joint)),
973 TokenTree::Punct(Punct::new('.', Spacing::Joint)),
974 TokenTree::Punct(Punct::new('.', Spacing::Alone)),
975 ];
976 let tokens = TokenStream::from_iter(args.into_iter().zip(&dot3.spans).map(
977 |(mut arg, span)| {
978 arg.set_span(*span);
979 arg
980 },
981 ));
982 Type::Verbatim(tokens)
983 }
984 None => input.parse()?,
985 },
e74abb32
XL
986 })
987 }
988 }
989
990 impl Parse for Abi {
991 fn parse(input: ParseStream) -> Result<Self> {
992 Ok(Abi {
993 extern_token: input.parse()?,
994 name: input.parse()?,
995 })
996 }
997 }
998
999 impl Parse for Option<Abi> {
1000 fn parse(input: ParseStream) -> Result<Self> {
1001 if input.peek(Token![extern]) {
1002 input.parse().map(Some)
1003 } else {
1004 Ok(None)
1005 }
1006 }
1007 }
1008}
1009
1010#[cfg(feature = "printing")]
1011mod printing {
1012 use super::*;
1013
1014 use proc_macro2::TokenStream;
1015 use quote::{ToTokens, TokenStreamExt};
1016
1017 use crate::attr::FilterAttrs;
1018 use crate::print::TokensOrDefault;
1019
1020 impl ToTokens for TypeSlice {
1021 fn to_tokens(&self, tokens: &mut TokenStream) {
1022 self.bracket_token.surround(tokens, |tokens| {
1023 self.elem.to_tokens(tokens);
1024 });
1025 }
1026 }
1027
1028 impl ToTokens for TypeArray {
1029 fn to_tokens(&self, tokens: &mut TokenStream) {
1030 self.bracket_token.surround(tokens, |tokens| {
1031 self.elem.to_tokens(tokens);
1032 self.semi_token.to_tokens(tokens);
1033 self.len.to_tokens(tokens);
1034 });
1035 }
1036 }
1037
1038 impl ToTokens for TypePtr {
1039 fn to_tokens(&self, tokens: &mut TokenStream) {
1040 self.star_token.to_tokens(tokens);
1041 match &self.mutability {
1042 Some(tok) => tok.to_tokens(tokens),
1043 None => {
1044 TokensOrDefault(&self.const_token).to_tokens(tokens);
1045 }
1046 }
1047 self.elem.to_tokens(tokens);
1048 }
1049 }
1050
1051 impl ToTokens for TypeReference {
1052 fn to_tokens(&self, tokens: &mut TokenStream) {
1053 self.and_token.to_tokens(tokens);
1054 self.lifetime.to_tokens(tokens);
1055 self.mutability.to_tokens(tokens);
1056 self.elem.to_tokens(tokens);
1057 }
1058 }
1059
1060 impl ToTokens for TypeBareFn {
1061 fn to_tokens(&self, tokens: &mut TokenStream) {
1062 self.lifetimes.to_tokens(tokens);
1063 self.unsafety.to_tokens(tokens);
1064 self.abi.to_tokens(tokens);
1065 self.fn_token.to_tokens(tokens);
1066 self.paren_token.surround(tokens, |tokens| {
1067 self.inputs.to_tokens(tokens);
1068 if let Some(variadic) = &self.variadic {
1069 if !self.inputs.empty_or_trailing() {
1070 let span = variadic.dots.spans[0];
1071 Token![,](span).to_tokens(tokens);
1072 }
1073 variadic.to_tokens(tokens);
1074 }
1075 });
1076 self.output.to_tokens(tokens);
1077 }
1078 }
1079
1080 impl ToTokens for TypeNever {
1081 fn to_tokens(&self, tokens: &mut TokenStream) {
1082 self.bang_token.to_tokens(tokens);
1083 }
1084 }
1085
1086 impl ToTokens for TypeTuple {
1087 fn to_tokens(&self, tokens: &mut TokenStream) {
1088 self.paren_token.surround(tokens, |tokens| {
1089 self.elems.to_tokens(tokens);
1090 });
1091 }
1092 }
1093
1094 impl ToTokens for TypePath {
1095 fn to_tokens(&self, tokens: &mut TokenStream) {
1096 private::print_path(tokens, &self.qself, &self.path);
1097 }
1098 }
1099
1100 impl ToTokens for TypeTraitObject {
1101 fn to_tokens(&self, tokens: &mut TokenStream) {
1102 self.dyn_token.to_tokens(tokens);
1103 self.bounds.to_tokens(tokens);
1104 }
1105 }
1106
1107 impl ToTokens for TypeImplTrait {
1108 fn to_tokens(&self, tokens: &mut TokenStream) {
1109 self.impl_token.to_tokens(tokens);
1110 self.bounds.to_tokens(tokens);
1111 }
1112 }
1113
1114 impl ToTokens for TypeGroup {
1115 fn to_tokens(&self, tokens: &mut TokenStream) {
1116 self.group_token.surround(tokens, |tokens| {
1117 self.elem.to_tokens(tokens);
1118 });
1119 }
1120 }
1121
1122 impl ToTokens for TypeParen {
1123 fn to_tokens(&self, tokens: &mut TokenStream) {
1124 self.paren_token.surround(tokens, |tokens| {
1125 self.elem.to_tokens(tokens);
1126 });
1127 }
1128 }
1129
1130 impl ToTokens for TypeInfer {
1131 fn to_tokens(&self, tokens: &mut TokenStream) {
1132 self.underscore_token.to_tokens(tokens);
1133 }
1134 }
1135
1136 impl ToTokens for TypeMacro {
1137 fn to_tokens(&self, tokens: &mut TokenStream) {
1138 self.mac.to_tokens(tokens);
1139 }
1140 }
1141
1142 impl ToTokens for ReturnType {
1143 fn to_tokens(&self, tokens: &mut TokenStream) {
1144 match self {
1145 ReturnType::Default => {}
1146 ReturnType::Type(arrow, ty) => {
1147 arrow.to_tokens(tokens);
1148 ty.to_tokens(tokens);
1149 }
1150 }
1151 }
1152 }
1153
1154 impl ToTokens for BareFnArg {
1155 fn to_tokens(&self, tokens: &mut TokenStream) {
1156 tokens.append_all(self.attrs.outer());
1157 if let Some((name, colon)) = &self.name {
1158 name.to_tokens(tokens);
1159 colon.to_tokens(tokens);
1160 }
1161 self.ty.to_tokens(tokens);
1162 }
1163 }
1164
1165 impl ToTokens for Variadic {
1166 fn to_tokens(&self, tokens: &mut TokenStream) {
1167 tokens.append_all(self.attrs.outer());
1168 self.dots.to_tokens(tokens);
1169 }
1170 }
1171
1172 impl ToTokens for Abi {
1173 fn to_tokens(&self, tokens: &mut TokenStream) {
1174 self.extern_token.to_tokens(tokens);
1175 self.name.to_tokens(tokens);
1176 }
1177 }
1178}