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