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_const = false;
408 TypeParamBound::parse_single(
409 input,
410 allow_precise_capture,
411 allow_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_const = false;
484 TypeParamBound::parse_single(
485 input,
486 allow_precise_capture,
487 allow_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_const = false;
555 TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
556 });
557 }
558 }
559 return Ok(Type::TraitObject(TypeTraitObject {
560 dyn_token: None,
561 bounds,
562 }));
563 }
564
565 Ok(Type::Path(ty))
566 } else if lookahead.peek(Token![dyn]) {
567 let dyn_token: Token![dyn] = input.parse()?;
568 let dyn_span = dyn_token.span;
569 let star_token: Option<Token![*]> = input.parse()?;
570 let bounds = TypeTraitObject::parse_bounds(dyn_span, input, allow_plus)?;
571 Ok(if star_token.is_some() {
572 Type::Verbatim(verbatim::between(&begin, input))
573 } else {
574 Type::TraitObject(TypeTraitObject {
575 dyn_token: Some(dyn_token),
576 bounds,
577 })
578 })
579 } else if lookahead.peek(token::Bracket) {
580 let content;
581 let bracket_token = bracketed!(content in input);
582 let elem: Type = content.parse()?;
583 if content.peek(Token![;]) {
584 Ok(Type::Array(TypeArray {
585 bracket_token,
586 elem: Box::new(elem),
587 semi_token: content.parse()?,
588 len: content.parse()?,
589 }))
590 } else {
591 Ok(Type::Slice(TypeSlice {
592 bracket_token,
593 elem: Box::new(elem),
594 }))
595 }
596 } else if lookahead.peek(Token![*]) {
597 input.parse().map(Type::Ptr)
598 } else if lookahead.peek(Token![&]) {
599 input.parse().map(Type::Reference)
600 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
601 input.parse().map(Type::Never)
602 } else if lookahead.peek(Token![impl]) {
603 TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
604 } else if lookahead.peek(Token![_]) {
605 input.parse().map(Type::Infer)
606 } else if lookahead.peek(Lifetime) {
607 input.parse().map(Type::TraitObject)
608 } else {
609 Err(lookahead.error())
610 }
611 }
612
613 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
614 impl Parse for TypeSlice {
615 fn parse(input: ParseStream) -> Result<Self> {
616 let content;
617 Ok(TypeSlice {
618 bracket_token: bracketed!(content in input),
619 elem: content.parse()?,
620 })
621 }
622 }
623
624 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
625 impl Parse for TypeArray {
626 fn parse(input: ParseStream) -> Result<Self> {
627 let content;
628 Ok(TypeArray {
629 bracket_token: bracketed!(content in input),
630 elem: content.parse()?,
631 semi_token: content.parse()?,
632 len: content.parse()?,
633 })
634 }
635 }
636
637 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
638 impl Parse for TypePtr {
639 fn parse(input: ParseStream) -> Result<Self> {
640 let star_token: Token![*] = input.parse()?;
641
642 let lookahead = input.lookahead1();
643 let (const_token, mutability) = if lookahead.peek(Token![const]) {
644 (Some(input.parse()?), None)
645 } else if lookahead.peek(Token![mut]) {
646 (None, Some(input.parse()?))
647 } else {
648 return Err(lookahead.error());
649 };
650
651 Ok(TypePtr {
652 star_token,
653 const_token,
654 mutability,
655 elem: Box::new(input.call(Type::without_plus)?),
656 })
657 }
658 }
659
660 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
661 impl Parse for TypeReference {
662 fn parse(input: ParseStream) -> Result<Self> {
663 Ok(TypeReference {
664 and_token: input.parse()?,
665 lifetime: input.parse()?,
666 mutability: input.parse()?,
667 elem: Box::new(input.call(Type::without_plus)?),
669 })
670 }
671 }
672
673 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
674 impl Parse for TypeBareFn {
675 fn parse(input: ParseStream) -> Result<Self> {
676 let args;
677 let mut variadic = None;
678
679 Ok(TypeBareFn {
680 lifetimes: input.parse()?,
681 unsafety: input.parse()?,
682 abi: input.parse()?,
683 fn_token: input.parse()?,
684 paren_token: parenthesized!(args in input),
685 inputs: {
686 let mut inputs = Punctuated::new();
687
688 while !args.is_empty() {
689 let attrs = args.call(Attribute::parse_outer)?;
690
691 if inputs.empty_or_trailing()
692 && (args.peek(Token![...])
693 || (args.peek(Ident) || args.peek(Token![_]))
694 && args.peek2(Token![:])
695 && args.peek3(Token![...]))
696 {
697 variadic = Some(parse_bare_variadic(&args, attrs)?);
698 break;
699 }
700
701 let allow_self = inputs.is_empty();
702 let arg = parse_bare_fn_arg(&args, allow_self)?;
703 inputs.push_value(BareFnArg { attrs, ..arg });
704 if args.is_empty() {
705 break;
706 }
707
708 let comma = args.parse()?;
709 inputs.push_punct(comma);
710 }
711
712 inputs
713 },
714 variadic,
715 output: input.call(ReturnType::without_plus)?,
716 })
717 }
718 }
719
720 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
721 impl Parse for TypeNever {
722 fn parse(input: ParseStream) -> Result<Self> {
723 Ok(TypeNever {
724 bang_token: input.parse()?,
725 })
726 }
727 }
728
729 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
730 impl Parse for TypeInfer {
731 fn parse(input: ParseStream) -> Result<Self> {
732 Ok(TypeInfer {
733 underscore_token: input.parse()?,
734 })
735 }
736 }
737
738 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
739 impl Parse for TypeTuple {
740 fn parse(input: ParseStream) -> Result<Self> {
741 let content;
742 let paren_token = parenthesized!(content in input);
743
744 if content.is_empty() {
745 return Ok(TypeTuple {
746 paren_token,
747 elems: Punctuated::new(),
748 });
749 }
750
751 let first: Type = content.parse()?;
752 Ok(TypeTuple {
753 paren_token,
754 elems: {
755 let mut elems = Punctuated::new();
756 elems.push_value(first);
757 elems.push_punct(content.parse()?);
758 while !content.is_empty() {
759 elems.push_value(content.parse()?);
760 if content.is_empty() {
761 break;
762 }
763 elems.push_punct(content.parse()?);
764 }
765 elems
766 },
767 })
768 }
769 }
770
771 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
772 impl Parse for TypeMacro {
773 fn parse(input: ParseStream) -> Result<Self> {
774 Ok(TypeMacro {
775 mac: input.parse()?,
776 })
777 }
778 }
779
780 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
781 impl Parse for TypePath {
782 fn parse(input: ParseStream) -> Result<Self> {
783 let expr_style = false;
784 let (qself, path) = path::parsing::qpath(input, expr_style)?;
785 Ok(TypePath { qself, path })
786 }
787 }
788
789 impl ReturnType {
790 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
791 pub fn without_plus(input: ParseStream) -> Result<Self> {
792 let allow_plus = false;
793 Self::parse(input, allow_plus)
794 }
795
796 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
797 if input.peek(Token![->]) {
798 let arrow = input.parse()?;
799 let allow_group_generic = true;
800 let ty = ambig_ty(input, allow_plus, allow_group_generic)?;
801 Ok(ReturnType::Type(arrow, Box::new(ty)))
802 } else {
803 Ok(ReturnType::Default)
804 }
805 }
806 }
807
808 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
809 impl Parse for ReturnType {
810 fn parse(input: ParseStream) -> Result<Self> {
811 let allow_plus = true;
812 Self::parse(input, allow_plus)
813 }
814 }
815
816 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
817 impl Parse for TypeTraitObject {
818 fn parse(input: ParseStream) -> Result<Self> {
819 let allow_plus = true;
820 Self::parse(input, allow_plus)
821 }
822 }
823
824 impl TypeTraitObject {
825 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
826 pub fn without_plus(input: ParseStream) -> Result<Self> {
827 let allow_plus = false;
828 Self::parse(input, allow_plus)
829 }
830
831 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
833 let dyn_token: Option<Token![dyn]> = input.parse()?;
834 let dyn_span = match &dyn_token {
835 Some(token) => token.span,
836 None => input.span(),
837 };
838 let bounds = Self::parse_bounds(dyn_span, input, allow_plus)?;
839 Ok(TypeTraitObject { dyn_token, bounds })
840 }
841
842 fn parse_bounds(
843 dyn_span: Span,
844 input: ParseStream,
845 allow_plus: bool,
846 ) -> Result<Punctuated<TypeParamBound, Token![+]>> {
847 let allow_precise_capture = false;
848 let allow_const = false;
849 let bounds = TypeParamBound::parse_multiple(
850 input,
851 allow_plus,
852 allow_precise_capture,
853 allow_const,
854 )?;
855 let mut last_lifetime_span = None;
856 let mut at_least_one_trait = false;
857 for bound in &bounds {
858 match bound {
859 TypeParamBound::Trait(_) => {
860 at_least_one_trait = true;
861 break;
862 }
863 TypeParamBound::Lifetime(lifetime) => {
864 last_lifetime_span = Some(lifetime.ident.span());
865 }
866 TypeParamBound::PreciseCapture(_) | TypeParamBound::Verbatim(_) => {
867 unreachable!()
868 }
869 }
870 }
871 if !at_least_one_trait {
873 let msg = "at least one trait is required for an object type";
874 return Err(error::new2(dyn_span, last_lifetime_span.unwrap(), msg));
875 }
876 Ok(bounds)
877 }
878 }
879
880 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
881 impl Parse for TypeImplTrait {
882 fn parse(input: ParseStream) -> Result<Self> {
883 let allow_plus = true;
884 Self::parse(input, allow_plus)
885 }
886 }
887
888 impl TypeImplTrait {
889 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
890 pub fn without_plus(input: ParseStream) -> Result<Self> {
891 let allow_plus = false;
892 Self::parse(input, allow_plus)
893 }
894
895 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
896 let impl_token: Token![impl] = input.parse()?;
897 let allow_precise_capture = true;
898 let allow_const = true;
899 let bounds = TypeParamBound::parse_multiple(
900 input,
901 allow_plus,
902 allow_precise_capture,
903 allow_const,
904 )?;
905 let mut last_nontrait_span = None;
906 let mut at_least_one_trait = false;
907 for bound in &bounds {
908 match bound {
909 TypeParamBound::Trait(_) => {
910 at_least_one_trait = true;
911 break;
912 }
913 TypeParamBound::Lifetime(lifetime) => {
914 last_nontrait_span = Some(lifetime.ident.span());
915 }
916 TypeParamBound::PreciseCapture(precise_capture) => {
917 #[cfg(feature = "full")]
918 {
919 last_nontrait_span = Some(precise_capture.gt_token.span);
920 }
921 #[cfg(not(feature = "full"))]
922 {
923 _ = precise_capture;
924 unreachable!();
925 }
926 }
927 TypeParamBound::Verbatim(_) => {
928 at_least_one_trait = true;
930 break;
931 }
932 }
933 }
934 if !at_least_one_trait {
935 let msg = "at least one trait must be specified";
936 return Err(error::new2(
937 impl_token.span,
938 last_nontrait_span.unwrap(),
939 msg,
940 ));
941 }
942 Ok(TypeImplTrait { impl_token, bounds })
943 }
944 }
945
946 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
947 impl Parse for TypeGroup {
948 fn parse(input: ParseStream) -> Result<Self> {
949 let group = crate::group::parse_group(input)?;
950 Ok(TypeGroup {
951 group_token: group.token,
952 elem: group.content.parse()?,
953 })
954 }
955 }
956
957 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
958 impl Parse for TypeParen {
959 fn parse(input: ParseStream) -> Result<Self> {
960 let allow_plus = false;
961 Self::parse(input, allow_plus)
962 }
963 }
964
965 impl TypeParen {
966 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
967 let content;
968 Ok(TypeParen {
969 paren_token: parenthesized!(content in input),
970 elem: Box::new({
971 let allow_group_generic = true;
972 ambig_ty(&content, allow_plus, allow_group_generic)?
973 }),
974 })
975 }
976 }
977
978 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
979 impl Parse for BareFnArg {
980 fn parse(input: ParseStream) -> Result<Self> {
981 let allow_self = false;
982 parse_bare_fn_arg(input, allow_self)
983 }
984 }
985
986 fn parse_bare_fn_arg(input: ParseStream, allow_self: bool) -> Result<BareFnArg> {
987 let attrs = input.call(Attribute::parse_outer)?;
988
989 let begin = input.fork();
990
991 let has_mut_self = allow_self && input.peek(Token![mut]) && input.peek2(Token![self]);
992 if has_mut_self {
993 input.parse::<Token![mut]>()?;
994 }
995
996 let mut has_self = false;
997 let mut name = if (input.peek(Ident) || input.peek(Token![_]) || {
998 has_self = allow_self && input.peek(Token![self]);
999 has_self
1000 }) && input.peek2(Token![:])
1001 && !input.peek2(Token![::])
1002 {
1003 let name = input.call(Ident::parse_any)?;
1004 let colon: Token![:] = input.parse()?;
1005 Some((name, colon))
1006 } else {
1007 has_self = false;
1008 None
1009 };
1010
1011 let ty = if allow_self && !has_self && input.peek(Token![mut]) && input.peek2(Token![self])
1012 {
1013 input.parse::<Token![mut]>()?;
1014 input.parse::<Token![self]>()?;
1015 None
1016 } else if has_mut_self && name.is_none() {
1017 input.parse::<Token![self]>()?;
1018 None
1019 } else {
1020 Some(input.parse()?)
1021 };
1022
1023 let ty = match ty {
1024 Some(ty) if !has_mut_self => ty,
1025 _ => {
1026 name = None;
1027 Type::Verbatim(verbatim::between(&begin, input))
1028 }
1029 };
1030
1031 Ok(BareFnArg { attrs, name, ty })
1032 }
1033
1034 fn parse_bare_variadic(input: ParseStream, attrs: Vec<Attribute>) -> Result<BareVariadic> {
1035 Ok(BareVariadic {
1036 attrs,
1037 name: if input.peek(Ident) || input.peek(Token![_]) {
1038 let name = input.call(Ident::parse_any)?;
1039 let colon: Token![:] = input.parse()?;
1040 Some((name, colon))
1041 } else {
1042 None
1043 },
1044 dots: input.parse()?,
1045 comma: input.parse()?,
1046 })
1047 }
1048
1049 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1050 impl Parse for Abi {
1051 fn parse(input: ParseStream) -> Result<Self> {
1052 Ok(Abi {
1053 extern_token: input.parse()?,
1054 name: input.parse()?,
1055 })
1056 }
1057 }
1058
1059 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1060 impl Parse for Option<Abi> {
1061 fn parse(input: ParseStream) -> Result<Self> {
1062 if input.peek(Token![extern]) {
1063 input.parse().map(Some)
1064 } else {
1065 Ok(None)
1066 }
1067 }
1068 }
1069}
1070
1071#[cfg(feature = "printing")]
1072mod printing {
1073 use crate::attr::FilterAttrs;
1074 use crate::path;
1075 use crate::path::printing::PathStyle;
1076 use crate::print::TokensOrDefault;
1077 use crate::ty::{
1078 Abi, BareFnArg, BareVariadic, ReturnType, TypeArray, TypeBareFn, TypeGroup, TypeImplTrait,
1079 TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice,
1080 TypeTraitObject, TypeTuple,
1081 };
1082 use proc_macro2::TokenStream;
1083 use quote::{ToTokens, TokenStreamExt};
1084
1085 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1086 impl ToTokens for TypeSlice {
1087 fn to_tokens(&self, tokens: &mut TokenStream) {
1088 self.bracket_token.surround(tokens, |tokens| {
1089 self.elem.to_tokens(tokens);
1090 });
1091 }
1092 }
1093
1094 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1095 impl ToTokens for TypeArray {
1096 fn to_tokens(&self, tokens: &mut TokenStream) {
1097 self.bracket_token.surround(tokens, |tokens| {
1098 self.elem.to_tokens(tokens);
1099 self.semi_token.to_tokens(tokens);
1100 self.len.to_tokens(tokens);
1101 });
1102 }
1103 }
1104
1105 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1106 impl ToTokens for TypePtr {
1107 fn to_tokens(&self, tokens: &mut TokenStream) {
1108 self.star_token.to_tokens(tokens);
1109 match &self.mutability {
1110 Some(tok) => tok.to_tokens(tokens),
1111 None => {
1112 TokensOrDefault(&self.const_token).to_tokens(tokens);
1113 }
1114 }
1115 self.elem.to_tokens(tokens);
1116 }
1117 }
1118
1119 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1120 impl ToTokens for TypeReference {
1121 fn to_tokens(&self, tokens: &mut TokenStream) {
1122 self.and_token.to_tokens(tokens);
1123 self.lifetime.to_tokens(tokens);
1124 self.mutability.to_tokens(tokens);
1125 self.elem.to_tokens(tokens);
1126 }
1127 }
1128
1129 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1130 impl ToTokens for TypeBareFn {
1131 fn to_tokens(&self, tokens: &mut TokenStream) {
1132 self.lifetimes.to_tokens(tokens);
1133 self.unsafety.to_tokens(tokens);
1134 self.abi.to_tokens(tokens);
1135 self.fn_token.to_tokens(tokens);
1136 self.paren_token.surround(tokens, |tokens| {
1137 self.inputs.to_tokens(tokens);
1138 if let Some(variadic) = &self.variadic {
1139 if !self.inputs.empty_or_trailing() {
1140 let span = variadic.dots.spans[0];
1141 Token.to_tokens(tokens);
1142 }
1143 variadic.to_tokens(tokens);
1144 }
1145 });
1146 self.output.to_tokens(tokens);
1147 }
1148 }
1149
1150 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1151 impl ToTokens for TypeNever {
1152 fn to_tokens(&self, tokens: &mut TokenStream) {
1153 self.bang_token.to_tokens(tokens);
1154 }
1155 }
1156
1157 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1158 impl ToTokens for TypeTuple {
1159 fn to_tokens(&self, tokens: &mut TokenStream) {
1160 self.paren_token.surround(tokens, |tokens| {
1161 self.elems.to_tokens(tokens);
1162 if self.elems.len() == 1 && !self.elems.trailing_punct() {
1165 <Token![,]>::default().to_tokens(tokens);
1166 }
1167 });
1168 }
1169 }
1170
1171 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1172 impl ToTokens for TypePath {
1173 fn to_tokens(&self, tokens: &mut TokenStream) {
1174 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::AsWritten);
1175 }
1176 }
1177
1178 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1179 impl ToTokens for TypeTraitObject {
1180 fn to_tokens(&self, tokens: &mut TokenStream) {
1181 self.dyn_token.to_tokens(tokens);
1182 self.bounds.to_tokens(tokens);
1183 }
1184 }
1185
1186 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1187 impl ToTokens for TypeImplTrait {
1188 fn to_tokens(&self, tokens: &mut TokenStream) {
1189 self.impl_token.to_tokens(tokens);
1190 self.bounds.to_tokens(tokens);
1191 }
1192 }
1193
1194 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1195 impl ToTokens for TypeGroup {
1196 fn to_tokens(&self, tokens: &mut TokenStream) {
1197 self.group_token.surround(tokens, |tokens| {
1198 self.elem.to_tokens(tokens);
1199 });
1200 }
1201 }
1202
1203 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1204 impl ToTokens for TypeParen {
1205 fn to_tokens(&self, tokens: &mut TokenStream) {
1206 self.paren_token.surround(tokens, |tokens| {
1207 self.elem.to_tokens(tokens);
1208 });
1209 }
1210 }
1211
1212 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1213 impl ToTokens for TypeInfer {
1214 fn to_tokens(&self, tokens: &mut TokenStream) {
1215 self.underscore_token.to_tokens(tokens);
1216 }
1217 }
1218
1219 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1220 impl ToTokens for TypeMacro {
1221 fn to_tokens(&self, tokens: &mut TokenStream) {
1222 self.mac.to_tokens(tokens);
1223 }
1224 }
1225
1226 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1227 impl ToTokens for ReturnType {
1228 fn to_tokens(&self, tokens: &mut TokenStream) {
1229 match self {
1230 ReturnType::Default => {}
1231 ReturnType::Type(arrow, ty) => {
1232 arrow.to_tokens(tokens);
1233 ty.to_tokens(tokens);
1234 }
1235 }
1236 }
1237 }
1238
1239 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1240 impl ToTokens for BareFnArg {
1241 fn to_tokens(&self, tokens: &mut TokenStream) {
1242 tokens.append_all(self.attrs.outer());
1243 if let Some((name, colon)) = &self.name {
1244 name.to_tokens(tokens);
1245 colon.to_tokens(tokens);
1246 }
1247 self.ty.to_tokens(tokens);
1248 }
1249 }
1250
1251 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1252 impl ToTokens for BareVariadic {
1253 fn to_tokens(&self, tokens: &mut TokenStream) {
1254 tokens.append_all(self.attrs.outer());
1255 if let Some((name, colon)) = &self.name {
1256 name.to_tokens(tokens);
1257 colon.to_tokens(tokens);
1258 }
1259 self.dots.to_tokens(tokens);
1260 self.comma.to_tokens(tokens);
1261 }
1262 }
1263
1264 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1265 impl ToTokens for Abi {
1266 fn to_tokens(&self, tokens: &mut TokenStream) {
1267 self.extern_token.to_tokens(tokens);
1268 self.name.to_tokens(tokens);
1269 }
1270 }
1271}