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