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