1use super::*;
2use crate::punctuated::Punctuated;
3use proc_macro2::TokenStream;
4
5ast_enum_of_structs! {
6 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
17 #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)]
18 pub enum Type {
19 Array(TypeArray),
21
22 BareFn(TypeBareFn),
24
25 Group(TypeGroup),
27
28 ImplTrait(TypeImplTrait),
31
32 Infer(TypeInfer),
34
35 Macro(TypeMacro),
37
38 Never(TypeNever),
40
41 Paren(TypeParen),
43
44 Path(TypePath),
47
48 Ptr(TypePtr),
50
51 Reference(TypeReference),
53
54 Slice(TypeSlice),
56
57 TraitObject(TypeTraitObject),
60
61 Tuple(TypeTuple),
63
64 Verbatim(TokenStream),
66
67 #[cfg(syn_no_non_exhaustive)]
86 #[doc(hidden)]
87 __NonExhaustive,
88 }
89}
90
91ast_struct! {
92 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
97 pub struct TypeArray {
98 pub bracket_token: token::Bracket,
99 pub elem: Box<Type>,
100 pub semi_token: Token![;],
101 pub len: Expr,
102 }
103}
104
105ast_struct! {
106 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
111 pub struct TypeBareFn {
112 pub lifetimes: Option<BoundLifetimes>,
113 pub unsafety: Option<Token![unsafe]>,
114 pub abi: Option<Abi>,
115 pub fn_token: Token![fn],
116 pub paren_token: token::Paren,
117 pub inputs: Punctuated<BareFnArg, Token![,]>,
118 pub variadic: Option<Variadic>,
119 pub output: ReturnType,
120 }
121}
122
123ast_struct! {
124 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
129 pub struct TypeGroup {
130 pub group_token: token::Group,
131 pub elem: Box<Type>,
132 }
133}
134
135ast_struct! {
136 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
142 pub struct TypeImplTrait {
143 pub impl_token: Token![impl],
144 pub bounds: Punctuated<TypeParamBound, Token![+]>,
145 }
146}
147
148ast_struct! {
149 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
154 pub struct TypeInfer {
155 pub underscore_token: Token![_],
156 }
157}
158
159ast_struct! {
160 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
165 pub struct TypeMacro {
166 pub mac: Macro,
167 }
168}
169
170ast_struct! {
171 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
176 pub struct TypeNever {
177 pub bang_token: Token![!],
178 }
179}
180
181ast_struct! {
182 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
187 pub struct TypeParen {
188 pub paren_token: token::Paren,
189 pub elem: Box<Type>,
190 }
191}
192
193ast_struct! {
194 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
200 pub struct TypePath {
201 pub qself: Option<QSelf>,
202 pub path: Path,
203 }
204}
205
206ast_struct! {
207 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
212 pub struct TypePtr {
213 pub star_token: Token![*],
214 pub const_token: Option<Token![const]>,
215 pub mutability: Option<Token![mut]>,
216 pub elem: Box<Type>,
217 }
218}
219
220ast_struct! {
221 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
226 pub struct TypeReference {
227 pub and_token: Token![&],
228 pub lifetime: Option<Lifetime>,
229 pub mutability: Option<Token![mut]>,
230 pub elem: Box<Type>,
231 }
232}
233
234ast_struct! {
235 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
240 pub struct TypeSlice {
241 pub bracket_token: token::Bracket,
242 pub elem: Box<Type>,
243 }
244}
245
246ast_struct! {
247 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
253 pub struct TypeTraitObject {
254 pub dyn_token: Option<Token![dyn]>,
255 pub bounds: Punctuated<TypeParamBound, Token![+]>,
256 }
257}
258
259ast_struct! {
260 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
265 pub struct TypeTuple {
266 pub paren_token: token::Paren,
267 pub elems: Punctuated<Type, Token![,]>,
268 }
269}
270
271ast_struct! {
272 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
277 pub struct Abi {
278 pub extern_token: Token![extern],
279 pub name: Option<LitStr>,
280 }
281}
282
283ast_struct! {
284 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
289 pub struct BareFnArg {
290 pub attrs: Vec<Attribute>,
291 pub name: Option<(Ident, Token![:])>,
292 pub ty: Type,
293 }
294}
295
296ast_struct! {
297 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
312 pub struct Variadic {
313 pub attrs: Vec<Attribute>,
314 pub dots: Token![...],
315 }
316}
317
318ast_enum! {
319 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
324 pub enum ReturnType {
325 Default,
329 Type(Token![->], Box<Type>),
331 }
332}
333
334#[cfg(feature = "parsing")]
335pub mod parsing {
336 use super::*;
337 use crate::ext::IdentExt;
338 use crate::parse::{Parse, ParseStream, Result};
339 use crate::path;
340 use proc_macro2::{Punct, Spacing, TokenTree};
341
342 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
343 impl Parse for Type {
344 fn parse(input: ParseStream) -> Result<Self> {
345 let allow_plus = true;
346 ambig_ty(input, allow_plus)
347 }
348 }
349
350 impl Type {
351 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
357 pub fn without_plus(input: ParseStream) -> Result<Self> {
358 let allow_plus = false;
359 ambig_ty(input, allow_plus)
360 }
361 }
362
363 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
364 let begin = input.fork();
365
366 if input.peek(token::Group) {
367 let mut group: TypeGroup = input.parse()?;
368 if input.peek(Token![::]) && input.peek3(Ident::peek_any) {
369 if let Type::Path(mut ty) = *group.elem {
370 Path::parse_rest(input, &mut ty.path, false)?;
371 return Ok(Type::Path(ty));
372 } else {
373 return Ok(Type::Path(TypePath {
374 qself: Some(QSelf {
375 lt_token: Token,
376 position: 0,
377 as_token: None,
378 gt_token: Token,
379 ty: group.elem,
380 }),
381 path: Path::parse_helper(input, false)?,
382 }));
383 }
384 } else if input.peek(Token![<]) || input.peek(Token![::]) && input.peek3(Token![<]) {
385 if let Type::Path(mut ty) = *group.elem {
386 let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
387 if let PathArguments::None = arguments {
388 *arguments = PathArguments::AngleBracketed(input.parse()?);
389 Path::parse_rest(input, &mut ty.path, false)?;
390 return Ok(Type::Path(ty));
391 } else {
392 group.elem = Box::new(Type::Path(ty));
393 }
394 }
395 }
396 return Ok(Type::Group(group));
397 }
398
399 let mut lifetimes = None::<BoundLifetimes>;
400 let mut lookahead = input.lookahead1();
401 if lookahead.peek(Token![for]) {
402 lifetimes = input.parse()?;
403 lookahead = input.lookahead1();
404 if !lookahead.peek(Ident)
405 && !lookahead.peek(Token![fn])
406 && !lookahead.peek(Token![unsafe])
407 && !lookahead.peek(Token![extern])
408 && !lookahead.peek(Token![super])
409 && !lookahead.peek(Token![self])
410 && !lookahead.peek(Token![Self])
411 && !lookahead.peek(Token![crate])
412 || input.peek(Token![dyn])
413 {
414 return Err(lookahead.error());
415 }
416 }
417
418 if lookahead.peek(token::Paren) {
419 let content;
420 let paren_token = parenthesized!(content in input);
421 if content.is_empty() {
422 return Ok(Type::Tuple(TypeTuple {
423 paren_token,
424 elems: Punctuated::new(),
425 }));
426 }
427 if content.peek(Lifetime) {
428 return Ok(Type::Paren(TypeParen {
429 paren_token,
430 elem: Box::new(Type::TraitObject(content.parse()?)),
431 }));
432 }
433 if content.peek(Token![?]) {
434 return Ok(Type::TraitObject(TypeTraitObject {
435 dyn_token: None,
436 bounds: {
437 let mut bounds = Punctuated::new();
438 bounds.push_value(TypeParamBound::Trait(TraitBound {
439 paren_token: Some(paren_token),
440 ..content.parse()?
441 }));
442 while let Some(plus) = input.parse()? {
443 bounds.push_punct(plus);
444 bounds.push_value(input.parse()?);
445 }
446 bounds
447 },
448 }));
449 }
450 let mut first: Type = content.parse()?;
451 if content.peek(Token![,]) {
452 return Ok(Type::Tuple(TypeTuple {
453 paren_token,
454 elems: {
455 let mut elems = Punctuated::new();
456 elems.push_value(first);
457 elems.push_punct(content.parse()?);
458 while !content.is_empty() {
459 elems.push_value(content.parse()?);
460 if content.is_empty() {
461 break;
462 }
463 elems.push_punct(content.parse()?);
464 }
465 elems
466 },
467 }));
468 }
469 if allow_plus && input.peek(Token![+]) {
470 loop {
471 let first = match first {
472 Type::Path(TypePath { qself: None, path }) => {
473 TypeParamBound::Trait(TraitBound {
474 paren_token: Some(paren_token),
475 modifier: TraitBoundModifier::None,
476 lifetimes: None,
477 path,
478 })
479 }
480 Type::TraitObject(TypeTraitObject {
481 dyn_token: None,
482 bounds,
483 }) => {
484 if bounds.len() > 1 || bounds.trailing_punct() {
485 first = Type::TraitObject(TypeTraitObject {
486 dyn_token: None,
487 bounds,
488 });
489 break;
490 }
491 match bounds.into_iter().next().unwrap() {
492 TypeParamBound::Trait(trait_bound) => {
493 TypeParamBound::Trait(TraitBound {
494 paren_token: Some(paren_token),
495 ..trait_bound
496 })
497 }
498 other @ TypeParamBound::Lifetime(_) => other,
499 }
500 }
501 _ => break,
502 };
503 return Ok(Type::TraitObject(TypeTraitObject {
504 dyn_token: None,
505 bounds: {
506 let mut bounds = Punctuated::new();
507 bounds.push_value(first);
508 while let Some(plus) = input.parse()? {
509 bounds.push_punct(plus);
510 bounds.push_value(input.parse()?);
511 }
512 bounds
513 },
514 }));
515 }
516 }
517 Ok(Type::Paren(TypeParen {
518 paren_token,
519 elem: Box::new(first),
520 }))
521 } else if lookahead.peek(Token![fn])
522 || lookahead.peek(Token![unsafe])
523 || lookahead.peek(Token![extern])
524 {
525 let allow_mut_self = true;
526 if let Some(mut bare_fn) = parse_bare_fn(input, allow_mut_self)? {
527 bare_fn.lifetimes = lifetimes;
528 Ok(Type::BareFn(bare_fn))
529 } else {
530 Ok(Type::Verbatim(verbatim::between(begin, input)))
531 }
532 } else if lookahead.peek(Ident)
533 || input.peek(Token![super])
534 || input.peek(Token![self])
535 || input.peek(Token![Self])
536 || input.peek(Token![crate])
537 || lookahead.peek(Token![::])
538 || lookahead.peek(Token![<])
539 {
540 let dyn_token: Option<Token![dyn]> = input.parse()?;
541 if dyn_token.is_some() {
542 let star_token: Option<Token![*]> = input.parse()?;
543 let bounds = TypeTraitObject::parse_bounds(input, allow_plus)?;
544 return Ok(if star_token.is_some() {
545 Type::Verbatim(verbatim::between(begin, input))
546 } else {
547 Type::TraitObject(TypeTraitObject { dyn_token, bounds })
548 });
549 }
550
551 let ty: TypePath = input.parse()?;
552 if ty.qself.is_some() {
553 return Ok(Type::Path(ty));
554 }
555
556 if input.peek(Token![!]) && !input.peek(Token![!=]) {
557 let mut contains_arguments = false;
558 for segment in &ty.path.segments {
559 match segment.arguments {
560 PathArguments::None => {}
561 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
562 contains_arguments = true;
563 }
564 }
565 }
566
567 if !contains_arguments {
568 let bang_token: Token![!] = input.parse()?;
569 let (delimiter, tokens) = mac::parse_delimiter(input)?;
570 return Ok(Type::Macro(TypeMacro {
571 mac: Macro {
572 path: ty.path,
573 bang_token,
574 delimiter,
575 tokens,
576 },
577 }));
578 }
579 }
580
581 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
582 let mut bounds = Punctuated::new();
583 bounds.push_value(TypeParamBound::Trait(TraitBound {
584 paren_token: None,
585 modifier: TraitBoundModifier::None,
586 lifetimes,
587 path: ty.path,
588 }));
589 if allow_plus {
590 while input.peek(Token![+]) {
591 bounds.push_punct(input.parse()?);
592 if !(input.peek(Ident::peek_any)
593 || input.peek(Token![::])
594 || input.peek(Token![?])
595 || input.peek(Lifetime)
596 || input.peek(token::Paren))
597 {
598 break;
599 }
600 bounds.push_value(input.parse()?);
601 }
602 }
603 return Ok(Type::TraitObject(TypeTraitObject {
604 dyn_token: None,
605 bounds,
606 }));
607 }
608
609 Ok(Type::Path(ty))
610 } else if lookahead.peek(token::Bracket) {
611 let content;
612 let bracket_token = bracketed!(content in input);
613 let elem: Type = content.parse()?;
614 if content.peek(Token![;]) {
615 Ok(Type::Array(TypeArray {
616 bracket_token,
617 elem: Box::new(elem),
618 semi_token: content.parse()?,
619 len: content.parse()?,
620 }))
621 } else {
622 Ok(Type::Slice(TypeSlice {
623 bracket_token,
624 elem: Box::new(elem),
625 }))
626 }
627 } else if lookahead.peek(Token![*]) {
628 input.parse().map(Type::Ptr)
629 } else if lookahead.peek(Token![&]) {
630 input.parse().map(Type::Reference)
631 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
632 input.parse().map(Type::Never)
633 } else if lookahead.peek(Token![impl]) {
634 TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
635 } else if lookahead.peek(Token![_]) {
636 input.parse().map(Type::Infer)
637 } else if lookahead.peek(Lifetime) {
638 input.parse().map(Type::TraitObject)
639 } else {
640 Err(lookahead.error())
641 }
642 }
643
644 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
645 impl Parse for TypeSlice {
646 fn parse(input: ParseStream) -> Result<Self> {
647 let content;
648 Ok(TypeSlice {
649 bracket_token: bracketed!(content in input),
650 elem: content.parse()?,
651 })
652 }
653 }
654
655 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
656 impl Parse for TypeArray {
657 fn parse(input: ParseStream) -> Result<Self> {
658 let content;
659 Ok(TypeArray {
660 bracket_token: bracketed!(content in input),
661 elem: content.parse()?,
662 semi_token: content.parse()?,
663 len: content.parse()?,
664 })
665 }
666 }
667
668 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
669 impl Parse for TypePtr {
670 fn parse(input: ParseStream) -> Result<Self> {
671 let star_token: Token![*] = input.parse()?;
672
673 let lookahead = input.lookahead1();
674 let (const_token, mutability) = if lookahead.peek(Token![const]) {
675 (Some(input.parse()?), None)
676 } else if lookahead.peek(Token![mut]) {
677 (None, Some(input.parse()?))
678 } else {
679 return Err(lookahead.error());
680 };
681
682 Ok(TypePtr {
683 star_token,
684 const_token,
685 mutability,
686 elem: Box::new(input.call(Type::without_plus)?),
687 })
688 }
689 }
690
691 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
692 impl Parse for TypeReference {
693 fn parse(input: ParseStream) -> Result<Self> {
694 Ok(TypeReference {
695 and_token: input.parse()?,
696 lifetime: input.parse()?,
697 mutability: input.parse()?,
698 elem: Box::new(input.call(Type::without_plus)?),
700 })
701 }
702 }
703
704 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
705 impl Parse for TypeBareFn {
706 fn parse(input: ParseStream) -> Result<Self> {
707 let allow_mut_self = false;
708 parse_bare_fn(input, allow_mut_self).map(Option::unwrap)
709 }
710 }
711
712 fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> {
713 let args;
714 let mut variadic = None;
715 let mut has_mut_self = false;
716
717 let bare_fn = TypeBareFn {
718 lifetimes: input.parse()?,
719 unsafety: input.parse()?,
720 abi: input.parse()?,
721 fn_token: input.parse()?,
722 paren_token: parenthesized!(args in input),
723 inputs: {
724 let mut inputs = Punctuated::new();
725
726 while !args.is_empty() {
727 let attrs = args.call(Attribute::parse_outer)?;
728
729 if inputs.empty_or_trailing() && args.peek(Token![...]) {
730 variadic = Some(Variadic {
731 attrs,
732 dots: args.parse()?,
733 });
734 break;
735 }
736
737 if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? {
738 inputs.push_value(BareFnArg { attrs, ..arg });
739 } else {
740 has_mut_self = true;
741 }
742 if args.is_empty() {
743 break;
744 }
745
746 let comma = args.parse()?;
747 if !has_mut_self {
748 inputs.push_punct(comma);
749 }
750 }
751
752 inputs
753 },
754 variadic,
755 output: input.call(ReturnType::without_plus)?,
756 };
757
758 if has_mut_self {
759 Ok(None)
760 } else {
761 Ok(Some(bare_fn))
762 }
763 }
764
765 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
766 impl Parse for TypeNever {
767 fn parse(input: ParseStream) -> Result<Self> {
768 Ok(TypeNever {
769 bang_token: input.parse()?,
770 })
771 }
772 }
773
774 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
775 impl Parse for TypeInfer {
776 fn parse(input: ParseStream) -> Result<Self> {
777 Ok(TypeInfer {
778 underscore_token: input.parse()?,
779 })
780 }
781 }
782
783 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
784 impl Parse for TypeTuple {
785 fn parse(input: ParseStream) -> Result<Self> {
786 let content;
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()?;
797 Ok(TypeTuple {
798 paren_token,
799 elems: {
800 let mut elems = Punctuated::new();
801 elems.push_value(first);
802 elems.push_punct(content.parse()?);
803 while !content.is_empty() {
804 elems.push_value(content.parse()?);
805 if content.is_empty() {
806 break;
807 }
808 elems.push_punct(content.parse()?);
809 }
810 elems
811 },
812 })
813 }
814 }
815
816 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
817 impl Parse for TypeMacro {
818 fn parse(input: ParseStream) -> Result<Self> {
819 Ok(TypeMacro {
820 mac: input.parse()?,
821 })
822 }
823 }
824
825 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
826 impl Parse for TypePath {
827 fn parse(input: ParseStream) -> Result<Self> {
828 let expr_style = false;
829 let (qself, mut path) = path::parsing::qpath(input, expr_style)?;
830
831 while path.segments.last().unwrap().arguments.is_empty()
832 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
833 {
834 input.parse::<Option<Token![::]>>()?;
835 let args: ParenthesizedGenericArguments = input.parse()?;
836 let allow_associated_type = cfg!(feature = "full")
837 && match &args.output {
838 ReturnType::Default => true,
839 ReturnType::Type(_, ty) => match **ty {
840 Type::Paren(_) => true,
842 _ => false,
843 },
844 };
845 let parenthesized = PathArguments::Parenthesized(args);
846 path.segments.last_mut().unwrap().arguments = parenthesized;
847 if allow_associated_type {
848 Path::parse_rest(input, &mut path, expr_style)?;
849 }
850 }
851
852 Ok(TypePath { qself, path })
853 }
854 }
855
856 impl ReturnType {
857 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
858 pub fn without_plus(input: ParseStream) -> Result<Self> {
859 let allow_plus = false;
860 Self::parse(input, allow_plus)
861 }
862
863 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
864 if input.peek(Token![->]) {
865 let arrow = input.parse()?;
866 let ty = ambig_ty(input, allow_plus)?;
867 Ok(ReturnType::Type(arrow, Box::new(ty)))
868 } else {
869 Ok(ReturnType::Default)
870 }
871 }
872 }
873
874 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
875 impl Parse for ReturnType {
876 fn parse(input: ParseStream) -> Result<Self> {
877 let allow_plus = true;
878 Self::parse(input, allow_plus)
879 }
880 }
881
882 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
883 impl Parse for TypeTraitObject {
884 fn parse(input: ParseStream) -> Result<Self> {
885 let allow_plus = true;
886 Self::parse(input, allow_plus)
887 }
888 }
889
890 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
891 for bound in bounds {
892 if let TypeParamBound::Trait(_) = *bound {
893 return true;
894 }
895 }
896 false
897 }
898
899 impl TypeTraitObject {
900 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
901 pub fn without_plus(input: ParseStream) -> Result<Self> {
902 let allow_plus = false;
903 Self::parse(input, allow_plus)
904 }
905
906 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
908 Ok(TypeTraitObject {
909 dyn_token: input.parse()?,
910 bounds: Self::parse_bounds(input, allow_plus)?,
911 })
912 }
913
914 fn parse_bounds(
915 input: ParseStream,
916 allow_plus: bool,
917 ) -> Result<Punctuated<TypeParamBound, Token![+]>> {
918 let mut bounds = Punctuated::new();
919 loop {
920 bounds.push_value(input.parse()?);
921 if !(allow_plus && input.peek(Token![+])) {
922 break;
923 }
924 bounds.push_punct(input.parse()?);
925 if !(input.peek(Ident::peek_any)
926 || input.peek(Token![::])
927 || input.peek(Token![?])
928 || input.peek(Lifetime)
929 || input.peek(token::Paren))
930 {
931 break;
932 }
933 }
934 if !at_least_one_type(&bounds) {
936 return Err(input.error("expected at least one type"));
937 }
938 Ok(bounds)
939 }
940 }
941
942 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
943 impl Parse for TypeImplTrait {
944 fn parse(input: ParseStream) -> Result<Self> {
945 let allow_plus = true;
946 Self::parse(input, allow_plus)
947 }
948 }
949
950 impl TypeImplTrait {
951 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
952 pub fn without_plus(input: ParseStream) -> Result<Self> {
953 let allow_plus = false;
954 Self::parse(input, allow_plus)
955 }
956
957 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
958 Ok(TypeImplTrait {
959 impl_token: input.parse()?,
960 bounds: TypeTraitObject::parse_bounds(input, allow_plus)?,
961 })
962 }
963 }
964
965 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
966 impl Parse for TypeGroup {
967 fn parse(input: ParseStream) -> Result<Self> {
968 let group = crate::group::parse_group(input)?;
969 Ok(TypeGroup {
970 group_token: group.token,
971 elem: group.content.parse()?,
972 })
973 }
974 }
975
976 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
977 impl Parse for TypeParen {
978 fn parse(input: ParseStream) -> Result<Self> {
979 let allow_plus = false;
980 Self::parse(input, allow_plus)
981 }
982 }
983
984 impl TypeParen {
985 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
986 let content;
987 Ok(TypeParen {
988 paren_token: parenthesized!(content in input),
989 elem: Box::new(ambig_ty(&content, allow_plus)?),
990 })
991 }
992 }
993
994 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
995 impl Parse for BareFnArg {
996 fn parse(input: ParseStream) -> Result<Self> {
997 let allow_mut_self = false;
998 parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap)
999 }
1000 }
1001
1002 fn parse_bare_fn_arg(
1003 input: ParseStream,
1004 mut allow_mut_self: bool,
1005 ) -> Result<Option<BareFnArg>> {
1006 let mut has_mut_self = false;
1007 let arg = BareFnArg {
1008 attrs: input.call(Attribute::parse_outer)?,
1009 name: {
1010 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self]))
1011 && input.peek2(Token![:])
1012 && !input.peek2(Token![::])
1013 {
1014 let name = input.call(Ident::parse_any)?;
1015 let colon: Token![:] = input.parse()?;
1016 Some((name, colon))
1017 } else if allow_mut_self
1018 && input.peek(Token![mut])
1019 && input.peek2(Token![self])
1020 && input.peek3(Token![:])
1021 && !input.peek3(Token![::])
1022 {
1023 has_mut_self = true;
1024 allow_mut_self = false;
1025 input.parse::<Token![mut]>()?;
1026 input.parse::<Token![self]>()?;
1027 input.parse::<Token![:]>()?;
1028 None
1029 } else {
1030 None
1031 }
1032 },
1033 ty: if !has_mut_self && input.peek(Token![...]) {
1034 let dot3 = input.parse::<Token![...]>()?;
1035 let args = vec![
1036 TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1037 TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1038 TokenTree::Punct(Punct::new('.', Spacing::Alone)),
1039 ];
1040 let tokens: TokenStream = args
1041 .into_iter()
1042 .zip(&dot3.spans)
1043 .map(|(mut arg, span)| {
1044 arg.set_span(*span);
1045 arg
1046 })
1047 .collect();
1048 Type::Verbatim(tokens)
1049 } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) {
1050 has_mut_self = true;
1051 input.parse::<Token![mut]>()?;
1052 Type::Path(TypePath {
1053 qself: None,
1054 path: input.parse::<Token![self]>()?.into(),
1055 })
1056 } else {
1057 input.parse()?
1058 },
1059 };
1060
1061 if has_mut_self {
1062 Ok(None)
1063 } else {
1064 Ok(Some(arg))
1065 }
1066 }
1067
1068 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1069 impl Parse for Abi {
1070 fn parse(input: ParseStream) -> Result<Self> {
1071 Ok(Abi {
1072 extern_token: input.parse()?,
1073 name: input.parse()?,
1074 })
1075 }
1076 }
1077
1078 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1079 impl Parse for Option<Abi> {
1080 fn parse(input: ParseStream) -> Result<Self> {
1081 if input.peek(Token![extern]) {
1082 input.parse().map(Some)
1083 } else {
1084 Ok(None)
1085 }
1086 }
1087 }
1088}
1089
1090#[cfg(feature = "printing")]
1091mod printing {
1092 use super::*;
1093 use crate::attr::FilterAttrs;
1094 use crate::print::TokensOrDefault;
1095 use proc_macro2::TokenStream;
1096 use quote::{ToTokens, TokenStreamExt};
1097
1098 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1099 impl ToTokens for TypeSlice {
1100 fn to_tokens(&self, tokens: &mut TokenStream) {
1101 self.bracket_token.surround(tokens, |tokens| {
1102 self.elem.to_tokens(tokens);
1103 });
1104 }
1105 }
1106
1107 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1108 impl ToTokens for TypeArray {
1109 fn to_tokens(&self, tokens: &mut TokenStream) {
1110 self.bracket_token.surround(tokens, |tokens| {
1111 self.elem.to_tokens(tokens);
1112 self.semi_token.to_tokens(tokens);
1113 self.len.to_tokens(tokens);
1114 });
1115 }
1116 }
1117
1118 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1119 impl ToTokens for TypePtr {
1120 fn to_tokens(&self, tokens: &mut TokenStream) {
1121 self.star_token.to_tokens(tokens);
1122 match &self.mutability {
1123 Some(tok) => tok.to_tokens(tokens),
1124 None => {
1125 TokensOrDefault(&self.const_token).to_tokens(tokens);
1126 }
1127 }
1128 self.elem.to_tokens(tokens);
1129 }
1130 }
1131
1132 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1133 impl ToTokens for TypeReference {
1134 fn to_tokens(&self, tokens: &mut TokenStream) {
1135 self.and_token.to_tokens(tokens);
1136 self.lifetime.to_tokens(tokens);
1137 self.mutability.to_tokens(tokens);
1138 self.elem.to_tokens(tokens);
1139 }
1140 }
1141
1142 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1143 impl ToTokens for TypeBareFn {
1144 fn to_tokens(&self, tokens: &mut TokenStream) {
1145 self.lifetimes.to_tokens(tokens);
1146 self.unsafety.to_tokens(tokens);
1147 self.abi.to_tokens(tokens);
1148 self.fn_token.to_tokens(tokens);
1149 self.paren_token.surround(tokens, |tokens| {
1150 self.inputs.to_tokens(tokens);
1151 if let Some(variadic) = &self.variadic {
1152 if !self.inputs.empty_or_trailing() {
1153 let span = variadic.dots.spans[0];
1154 Token.to_tokens(tokens);
1155 }
1156 variadic.to_tokens(tokens);
1157 }
1158 });
1159 self.output.to_tokens(tokens);
1160 }
1161 }
1162
1163 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1164 impl ToTokens for TypeNever {
1165 fn to_tokens(&self, tokens: &mut TokenStream) {
1166 self.bang_token.to_tokens(tokens);
1167 }
1168 }
1169
1170 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1171 impl ToTokens for TypeTuple {
1172 fn to_tokens(&self, tokens: &mut TokenStream) {
1173 self.paren_token.surround(tokens, |tokens| {
1174 self.elems.to_tokens(tokens);
1175 });
1176 }
1177 }
1178
1179 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1180 impl ToTokens for TypePath {
1181 fn to_tokens(&self, tokens: &mut TokenStream) {
1182 path::printing::print_path(tokens, &self.qself, &self.path);
1183 }
1184 }
1185
1186 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1187 impl ToTokens for TypeTraitObject {
1188 fn to_tokens(&self, tokens: &mut TokenStream) {
1189 self.dyn_token.to_tokens(tokens);
1190 self.bounds.to_tokens(tokens);
1191 }
1192 }
1193
1194 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1195 impl ToTokens for TypeImplTrait {
1196 fn to_tokens(&self, tokens: &mut TokenStream) {
1197 self.impl_token.to_tokens(tokens);
1198 self.bounds.to_tokens(tokens);
1199 }
1200 }
1201
1202 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1203 impl ToTokens for TypeGroup {
1204 fn to_tokens(&self, tokens: &mut TokenStream) {
1205 self.group_token.surround(tokens, |tokens| {
1206 self.elem.to_tokens(tokens);
1207 });
1208 }
1209 }
1210
1211 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1212 impl ToTokens for TypeParen {
1213 fn to_tokens(&self, tokens: &mut TokenStream) {
1214 self.paren_token.surround(tokens, |tokens| {
1215 self.elem.to_tokens(tokens);
1216 });
1217 }
1218 }
1219
1220 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1221 impl ToTokens for TypeInfer {
1222 fn to_tokens(&self, tokens: &mut TokenStream) {
1223 self.underscore_token.to_tokens(tokens);
1224 }
1225 }
1226
1227 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1228 impl ToTokens for TypeMacro {
1229 fn to_tokens(&self, tokens: &mut TokenStream) {
1230 self.mac.to_tokens(tokens);
1231 }
1232 }
1233
1234 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1235 impl ToTokens for ReturnType {
1236 fn to_tokens(&self, tokens: &mut TokenStream) {
1237 match self {
1238 ReturnType::Default => {}
1239 ReturnType::Type(arrow, ty) => {
1240 arrow.to_tokens(tokens);
1241 ty.to_tokens(tokens);
1242 }
1243 }
1244 }
1245 }
1246
1247 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1248 impl ToTokens for BareFnArg {
1249 fn to_tokens(&self, tokens: &mut TokenStream) {
1250 tokens.append_all(self.attrs.outer());
1251 if let Some((name, colon)) = &self.name {
1252 name.to_tokens(tokens);
1253 colon.to_tokens(tokens);
1254 }
1255 self.ty.to_tokens(tokens);
1256 }
1257 }
1258
1259 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1260 impl ToTokens for Variadic {
1261 fn to_tokens(&self, tokens: &mut TokenStream) {
1262 tokens.append_all(self.attrs.outer());
1263 self.dots.to_tokens(tokens);
1264 }
1265 }
1266
1267 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1268 impl ToTokens for Abi {
1269 fn to_tokens(&self, tokens: &mut TokenStream) {
1270 self.extern_token.to_tokens(tokens);
1271 self.name.to_tokens(tokens);
1272 }
1273 }
1274}