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 alloc::boxed::Box;
12use alloc::vec::Vec;
13use proc_macro2::TokenStream;
14
15#[doc = r" The possible types that a Rust value could have."]
#[doc = r""]
#[doc = r" # Syntax tree enum"]
#[doc = r""]
#[doc = r" This type is a [syntax tree enum]."]
#[doc = r""]
#[doc = r" [syntax tree enum]: crate::expr::Expr#syntax-tree-enums"]
#[non_exhaustive]
pub enum Type {
#[doc = r" A fixed size array type: `[T; n]`."]
Array(TypeArray),
#[doc = r" A function pointer type: `fn(usize) -> bool`."]
FnPtr(TypeFnPtr),
#[doc = r" A type contained within invisible delimiters."]
Group(TypeGroup),
#[doc =
r" An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or"]
#[doc = r" a lifetime."]
ImplTrait(TypeImplTrait),
#[doc =
r" Indication that a type should be inferred by the compiler: `_`."]
Infer(TypeInfer),
#[doc = r" A macro in the type position."]
Macro(TypeMacro),
#[doc = r" The never type: `!`."]
Never(TypeNever),
#[doc = r" A parenthesized type equivalent to the inner type."]
Paren(TypeParen),
#[doc = r" A path like `core::slice::Iter`, optionally qualified with a"]
#[doc = r" self-type as in `<Vec<T> as SomeTrait>::Associated`."]
Path(TypePath),
#[doc = r" A raw pointer type: `*const T` or `*mut T`."]
Ptr(TypePtr),
#[doc = r" A reference type: `&'a T` or `&'a mut T`."]
Reference(TypeReference),
#[doc = r" A dynamically sized slice type: `[T]`."]
Slice(TypeSlice),
#[doc =
r" A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a"]
#[doc = r" trait or a lifetime."]
TraitObject(TypeTraitObject),
#[doc = r" A tuple type: `(A, B, C, String)`."]
Tuple(TypeTuple),
#[doc = r" Tokens in type position not interpreted by Syn."]
#[doc = r""]
#[doc = r#" <div class="warning">"#]
#[doc = r""]
#[doc =
r" Important: see [Compatibility notes][crate#verbatim-variants]."]
#[doc = r""]
#[doc = r" </div>"]
Verbatim(TokenStream),
}
impl ::quote::ToTokens for Type {
fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
match self {
Type::Array(_e) => _e.to_tokens(tokens),
Type::FnPtr(_e) => _e.to_tokens(tokens),
Type::Group(_e) => _e.to_tokens(tokens),
Type::ImplTrait(_e) => _e.to_tokens(tokens),
Type::Infer(_e) => _e.to_tokens(tokens),
Type::Macro(_e) => _e.to_tokens(tokens),
Type::Never(_e) => _e.to_tokens(tokens),
Type::Paren(_e) => _e.to_tokens(tokens),
Type::Path(_e) => _e.to_tokens(tokens),
Type::Ptr(_e) => _e.to_tokens(tokens),
Type::Reference(_e) => _e.to_tokens(tokens),
Type::Slice(_e) => _e.to_tokens(tokens),
Type::TraitObject(_e) => _e.to_tokens(tokens),
Type::Tuple(_e) => _e.to_tokens(tokens),
Type::Verbatim(_e) => _e.to_tokens(tokens),
}
}
}ast_enum_of_structs! {
16 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
24 #[non_exhaustive]
25 pub enum Type {
26 Array(TypeArray),
28
29 FnPtr(TypeFnPtr),
31
32 Group(TypeGroup),
34
35 ImplTrait(TypeImplTrait),
38
39 Infer(TypeInfer),
41
42 Macro(TypeMacro),
44
45 Never(TypeNever),
47
48 Paren(TypeParen),
50
51 Path(TypePath),
54
55 Ptr(TypePtr),
57
58 Reference(TypeReference),
60
61 Slice(TypeSlice),
63
64 TraitObject(TypeTraitObject),
67
68 Tuple(TypeTuple),
70
71 Verbatim(TokenStream),
79 }
80}
81
82#[doc = r" A fixed size array type: `[T; n]`."]
pub struct TypeArray {
pub attrs: Vec<Attribute>,
pub bracket_token: token::Bracket,
pub elem: Box<Type>,
pub semi_token: crate::token::Semi,
pub len: Expr,
}ast_struct! {
83 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
85 pub struct TypeArray {
86 pub attrs: Vec<Attribute>,
87 pub bracket_token: token::Bracket,
88 pub elem: Box<Type>,
89 pub semi_token: Token![;],
90 pub len: Expr,
91 }
92}
93
94#[doc = r" A function pointer type: `fn(usize) -> bool`."]
pub struct TypeFnPtr {
pub attrs: Vec<Attribute>,
pub lifetimes: Option<BoundLifetimes>,
pub unsafety: Option<crate::token::Unsafe>,
pub abi: Option<Abi>,
pub fn_token: crate::token::Fn,
pub paren_token: token::Paren,
pub inputs: Punctuated<NamedArg, crate::token::Comma>,
pub variadic: Option<FnPtrVariadic>,
pub output: ReturnType,
}ast_struct! {
95 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
97 pub struct TypeFnPtr {
98 pub attrs: Vec<Attribute>,
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<NamedArg, Token![,]>,
105 pub variadic: Option<FnPtrVariadic>,
106 pub output: ReturnType,
107 }
108}
109
110#[doc = r" A type contained within invisible delimiters."]
pub struct TypeGroup {
pub attrs: Vec<Attribute>,
pub group_token: token::Group,
pub elem: Box<Type>,
}ast_struct! {
111 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
113 pub struct TypeGroup {
114 pub attrs: Vec<Attribute>,
115 pub group_token: token::Group,
116 pub elem: Box<Type>,
117 }
118}
119
120#[doc =
r" An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or"]
#[doc = r" a lifetime."]
pub struct TypeImplTrait {
pub attrs: Vec<Attribute>,
pub impl_token: crate::token::Impl,
pub bounds: Punctuated<TypeParamBound, crate::token::Plus>,
}ast_struct! {
121 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
124 pub struct TypeImplTrait {
125 pub attrs: Vec<Attribute>,
126 pub impl_token: Token![impl],
127 pub bounds: Punctuated<TypeParamBound, Token![+]>,
128 }
129}
130
131#[doc = r" Indication that a type should be inferred by the compiler: `_`."]
pub struct TypeInfer {
pub attrs: Vec<Attribute>,
pub underscore_token: crate::token::Underscore,
}ast_struct! {
132 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
134 pub struct TypeInfer {
135 pub attrs: Vec<Attribute>,
136 pub underscore_token: Token![_],
137 }
138}
139
140#[doc = r" A macro in the type position."]
pub struct TypeMacro {
pub attrs: Vec<Attribute>,
pub mac: Macro,
}ast_struct! {
141 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
143 pub struct TypeMacro {
144 pub attrs: Vec<Attribute>,
145 pub mac: Macro,
146 }
147}
148
149#[doc = r" The never type: `!`."]
pub struct TypeNever {
pub attrs: Vec<Attribute>,
pub bang_token: crate::token::Not,
}ast_struct! {
150 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
152 pub struct TypeNever {
153 pub attrs: Vec<Attribute>,
154 pub bang_token: Token![!],
155 }
156}
157
158#[doc = r" A parenthesized type equivalent to the inner type."]
pub struct TypeParen {
pub attrs: Vec<Attribute>,
pub paren_token: token::Paren,
pub elem: Box<Type>,
}ast_struct! {
159 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
161 pub struct TypeParen {
162 pub attrs: Vec<Attribute>,
163 pub paren_token: token::Paren,
164 pub elem: Box<Type>,
165 }
166}
167
168#[doc = r" A path like `core::slice::Iter`, optionally qualified with a"]
#[doc = r" self-type as in `<Vec<T> as SomeTrait>::Associated`."]
pub struct TypePath {
pub attrs: Vec<Attribute>,
pub qself: Option<QSelf>,
pub path: Path,
}ast_struct! {
169 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
172 pub struct TypePath {
173 pub attrs: Vec<Attribute>,
174 pub qself: Option<QSelf>,
175 pub path: Path,
176 }
177}
178
179#[doc = r" A raw pointer type: `*const T` or `*mut T`."]
pub struct TypePtr {
pub attrs: Vec<Attribute>,
pub star_token: crate::token::Star,
pub mutability: PointerMutability,
pub elem: Box<Type>,
}ast_struct! {
180 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
182 pub struct TypePtr {
183 pub attrs: Vec<Attribute>,
184 pub star_token: Token![*],
185 pub mutability: PointerMutability,
186 pub elem: Box<Type>,
187 }
188}
189
190#[doc = r" A reference type: `&'a T` or `&'a mut T`."]
pub struct TypeReference {
pub attrs: Vec<Attribute>,
pub and_token: crate::token::And,
pub lifetime: Option<Lifetime>,
pub mutability: Option<crate::token::Mut>,
pub elem: Box<Type>,
}ast_struct! {
191 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
193 pub struct TypeReference {
194 pub attrs: Vec<Attribute>,
195 pub and_token: Token![&],
196 pub lifetime: Option<Lifetime>,
197 pub mutability: Option<Token![mut]>,
198 pub elem: Box<Type>,
199 }
200}
201
202#[doc = r" A dynamically sized slice type: `[T]`."]
pub struct TypeSlice {
pub attrs: Vec<Attribute>,
pub bracket_token: token::Bracket,
pub elem: Box<Type>,
}ast_struct! {
203 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
205 pub struct TypeSlice {
206 pub attrs: Vec<Attribute>,
207 pub bracket_token: token::Bracket,
208 pub elem: Box<Type>,
209 }
210}
211
212#[doc =
r" A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a"]
#[doc = r" trait or a lifetime."]
pub struct TypeTraitObject {
pub attrs: Vec<Attribute>,
#[doc =
r" The `dyn` keyword is required since Rust 2021 edition. In editions"]
#[doc =
r" 2015–2018, trait objects without a `dyn` keyword are allowed"]
#[doc = r" but deprecated."]
pub dyn_token: Option<crate::token::Dyn>,
pub bounds: Punctuated<TypeParamBound, crate::token::Plus>,
}ast_struct! {
213 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
216 pub struct TypeTraitObject {
217 pub attrs: Vec<Attribute>,
218 pub dyn_token: Option<Token![dyn]>,
222 pub bounds: Punctuated<TypeParamBound, Token![+]>,
223 }
224}
225
226#[doc = r" A tuple type: `(A, B, C, String)`."]
pub struct TypeTuple {
pub attrs: Vec<Attribute>,
pub paren_token: token::Paren,
pub elems: Punctuated<Type, crate::token::Comma>,
}ast_struct! {
227 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
229 pub struct TypeTuple {
230 pub attrs: Vec<Attribute>,
231 pub paren_token: token::Paren,
232 pub elems: Punctuated<Type, Token![,]>,
233 }
234}
235
236#[doc = r#" The binary interface of a function: `extern "C"`."#]
pub struct Abi {
pub extern_token: crate::token::Extern,
#[doc =
r" ABI name is optional, but note that extern blocks and functions with"]
#[doc =
r" an omitted ABI name are [deprecated since Rust 1.86.0][deprecated]."]
#[doc =
r" Omitting the ABI after the extern keyword has always implicitly"]
#[doc =
r#" resulted in the "C" ABI. It is now recommended to explicitly specify"#]
#[doc = r#" the "C" ABI (`extern "C" {}` and `extern "C" fn`)."#]
#[doc = r""]
#[doc =
r" [deprecated]: https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/#make-missing-abi-lint-warn-by-default"]
pub name: Option<LitStr>,
}ast_struct! {
237 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
239 pub struct Abi {
240 pub extern_token: Token![extern],
241
242 pub name: Option<LitStr>,
250 }
251}
252
253#[doc =
r" Mutability of a raw pointer (`*const T`, `*mut T`), in which non-mutable"]
#[doc = r" isn't the implicit default."]
pub enum PointerMutability {
Const(crate::token::Const),
Mut(crate::token::Mut),
}ast_enum! {
254 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
257 pub enum PointerMutability {
258 Const(Token![const]),
259 Mut(Token![mut]),
260 }
261}
262
263#[doc =
r" An argument in a function type: the `usize` in `fn(usize) -> bool`."]
pub struct NamedArg {
pub attrs: Vec<Attribute>,
pub name: Option<(Ident, crate::token::Colon)>,
pub ty: Type,
}ast_struct! {
264 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
266 pub struct NamedArg {
267 pub attrs: Vec<Attribute>,
268 pub name: Option<(Ident, Token![:])>,
269 pub ty: Type,
270 }
271}
272
273#[doc =
r" The variadic argument of a function pointer like `fn(usize, ...)`."]
pub struct FnPtrVariadic {
pub attrs: Vec<Attribute>,
pub name: Option<(Ident, crate::token::Colon)>,
pub dots: crate::token::DotDotDot,
pub comma: Option<crate::token::Comma>,
}ast_struct! {
274 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
276 pub struct FnPtrVariadic {
277 pub attrs: Vec<Attribute>,
278 pub name: Option<(Ident, Token![:])>,
279 pub dots: Token![...],
280 pub comma: Option<Token![,]>,
281 }
282}
283
284#[doc = r" Return type of a function signature."]
pub enum ReturnType {
#[doc = r" Return type is not specified."]
#[doc = r""]
#[doc =
r" Functions default to `()` and closures default to type inference."]
Default,
#[doc = r" A particular type is returned."]
Type(crate::token::RArrow, Box<Type>),
}ast_enum! {
285 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
287 pub enum ReturnType {
288 Default,
292 Type(Token![->], Box<Type>),
294 }
295}
296
297#[cfg(feature = "parsing")]
298pub(crate) mod parsing {
299 use crate::attr::Attribute;
300 use crate::buffer::Cursor;
301 use crate::error::{Error, Result};
302 use crate::ext::IdentExt as _;
303 use crate::generics::{BoundLifetimes, TraitBound, TraitBoundModifiers, TypeParamBound};
304 use crate::ident::Ident;
305 use crate::lifetime::Lifetime;
306 use crate::mac::{self, Macro};
307 use crate::parse::{Parse, ParseStream};
308 use crate::path;
309 use crate::path::{Path, PathArguments, QSelf};
310 use crate::punctuated::Punctuated;
311 use crate::token;
312 use crate::ty::{
313 Abi, FnPtrVariadic, NamedArg, PointerMutability, ReturnType, Type, TypeArray, TypeFnPtr,
314 TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr,
315 TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
316 };
317 use crate::verbatim;
318 use alloc::boxed::Box;
319 use alloc::vec::Vec;
320 use proc_macro2::TokenStream;
321
322 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
323 impl Parse for Type {
324 fn parse(input: ParseStream) -> Result<Self> {
325 let allow_plus = true;
326 let allow_group_generic = true;
327 ambig_ty(input, allow_plus, allow_group_generic)
328 }
329 }
330
331 impl Type {
332 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
338 pub fn without_plus(input: ParseStream) -> Result<Self> {
339 let allow_plus = false;
340 let allow_group_generic = true;
341 ambig_ty(input, allow_plus, allow_group_generic)
342 }
343 }
344
345 pub(crate) fn ambig_ty(
346 input: ParseStream,
347 allow_plus: bool,
348 allow_group_generic: bool,
349 ) -> Result<Type> {
350 let begin = input.cursor();
351
352 if input.peek(token::Group) {
353 let mut group: TypeGroup = input.parse()?;
354 if input.peek(crate::token::PathSepToken![::]) && input.peek3(Ident::peek_any) {
355 if let Type::Path(mut ty) = *group.elem {
356 Path::parse_rest(input, &mut ty.path, false)?;
357 return Ok(Type::Path(ty));
358 } else {
359 return Ok(Type::Path(TypePath {
360 attrs: Vec::new(),
361 qself: Some(QSelf {
362 lt_token: crate::token::LtToken,
363 position: 0,
364 as_token: None,
365 gt_token: crate::token::GtToken,
366 ty: group.elem,
367 }),
368 path: Path::parse_helper(input, false)?,
369 }));
370 }
371 } else if input.peek(crate::token::LtToken![<]) && allow_group_generic
372 || input.peek(crate::token::PathSepToken![::]) && input.peek3(crate::token::LtToken![<])
373 {
374 if let Type::Path(mut ty) = *group.elem {
375 let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
376 if arguments.is_none() {
377 *arguments = PathArguments::AngleBracketed(input.parse()?);
378 Path::parse_rest(input, &mut ty.path, false)?;
379 return Ok(Type::Path(ty));
380 } else {
381 *group.elem = Type::Path(ty);
382 }
383 }
384 }
385 return Ok(Type::Group(group));
386 }
387
388 let mut lifetimes = None::<BoundLifetimes>;
389 let mut lookahead = input.lookahead1();
390 if lookahead.peek(crate::token::ForToken![for]) {
391 lifetimes = input.parse()?;
392 lookahead = input.lookahead1();
393 if !lookahead.peek(Ident)
394 && !lookahead.peek(crate::token::FnToken![fn])
395 && !lookahead.peek(crate::token::UnsafeToken![unsafe])
396 && !lookahead.peek(crate::token::ExternToken![extern])
397 && !lookahead.peek(crate::token::SuperToken![super])
398 && !lookahead.peek(crate::token::SelfValueToken![self])
399 && !lookahead.peek(crate::token::SelfTypeToken![Self])
400 && !lookahead.peek(crate::token::CrateToken![crate])
401 || input.peek(crate::token::DynToken![dyn])
402 {
403 return Err(lookahead.error());
404 }
405 }
406
407 if lookahead.peek(token::Paren) {
408 let content;
409 let paren_token = match crate::__private::parse_parens(&input) {
crate::__private::Ok(parens) => {
content = parens.content;
_ = content;
parens.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input);
410 if content.is_empty() {
411 return Ok(Type::Tuple(TypeTuple {
412 attrs: Vec::new(),
413 paren_token,
414 elems: Punctuated::new(),
415 }));
416 }
417 if content.peek(Lifetime) {
418 return Ok(Type::Paren(TypeParen {
419 attrs: Vec::new(),
420 paren_token,
421 elem: Box::new(Type::TraitObject(content.parse()?)),
422 }));
423 }
424 if content.peek(crate::token::QuestionToken![?]) {
425 return Ok(Type::TraitObject(TypeTraitObject {
426 attrs: Vec::new(),
427 dyn_token: None,
428 bounds: {
429 let mut bounds = Punctuated::new();
430 bounds.push_value(TypeParamBound::Trait(TraitBound {
431 paren_token: Some(paren_token),
432 ..content.parse()?
433 }));
434 while let Some(plus) = input.parse()? {
435 bounds.push_punct(plus);
436 bounds.push_value({
437 let allow_precise_capture = false;
438 let allow_const = false;
439 TypeParamBound::parse_single(
440 input,
441 allow_precise_capture,
442 allow_const,
443 )?
444 });
445 }
446 bounds
447 },
448 }));
449 }
450 let mut first: Type = content.parse()?;
451 if content.peek(crate::token::CommaToken![,]) {
452 return Ok(Type::Tuple(TypeTuple {
453 attrs: Vec::new(),
454 paren_token,
455 elems: {
456 let mut elems = Punctuated::new();
457 elems.push_value(first);
458 elems.push_punct(content.parse()?);
459 while !content.is_empty() {
460 elems.push_value(content.parse()?);
461 if content.is_empty() {
462 break;
463 }
464 elems.push_punct(content.parse()?);
465 }
466 elems
467 },
468 }));
469 }
470 if allow_plus && input.peek(crate::token::PlusToken![+]) {
471 loop {
472 let first = match first {
473 Type::Path(TypePath {
474 attrs: _,
475 qself: None,
476 path,
477 }) => TypeParamBound::Trait(TraitBound {
478 paren_token: Some(paren_token),
479 lifetimes: None,
480 modifiers: TraitBoundModifiers {},
481 maybe: None,
482 path,
483 }),
484 Type::TraitObject(TypeTraitObject {
485 attrs: _,
486 dyn_token: None,
487 bounds,
488 }) => {
489 if bounds.len() > 1 || bounds.trailing_punct() {
490 first = Type::TraitObject(TypeTraitObject {
491 attrs: Vec::new(),
492 dyn_token: None,
493 bounds,
494 });
495 break;
496 }
497 match bounds.into_iter().next().unwrap() {
498 TypeParamBound::Trait(trait_bound) => {
499 TypeParamBound::Trait(TraitBound {
500 paren_token: Some(paren_token),
501 ..trait_bound
502 })
503 }
504 other @ (TypeParamBound::Lifetime(_)
505 | TypeParamBound::PreciseCapture(_)
506 | TypeParamBound::Verbatim(_)) => other,
507 }
508 }
509 _ => break,
510 };
511 return Ok(Type::TraitObject(TypeTraitObject {
512 attrs: Vec::new(),
513 dyn_token: None,
514 bounds: {
515 let mut bounds = Punctuated::new();
516 bounds.push_value(first);
517 while let Some(plus) = input.parse()? {
518 bounds.push_punct(plus);
519 bounds.push_value({
520 let allow_precise_capture = false;
521 let allow_const = false;
522 TypeParamBound::parse_single(
523 input,
524 allow_precise_capture,
525 allow_const,
526 )?
527 });
528 }
529 bounds
530 },
531 }));
532 }
533 }
534 Ok(Type::Paren(TypeParen {
535 attrs: Vec::new(),
536 paren_token,
537 elem: Box::new(first),
538 }))
539 } else if lookahead.peek(crate::token::UnsafeToken![unsafe]) && input.peek2(crate::token::LtToken![<]) {
540 input.parse::<crate::token::UnsafeToken![unsafe]>()?;
541 input.parse::<crate::token::LtToken![<]>()?;
542 while !input.peek(crate::token::GtToken![>]) {
543 Lifetime::parse_any(input)?;
544 if input.peek(crate::token::GtToken![>]) {
545 break;
546 }
547 input.parse::<crate::token::CommaToken![,]>()?;
548 }
549 input.parse::<crate::token::GtToken![>]>()?;
550 ambig_ty(input, allow_plus, allow_group_generic)?;
551 Ok(Type::Verbatim(verbatim::between(begin, input.cursor())))
552 } else if lookahead.peek(crate::token::FnToken![fn])
553 || input.peek(crate::token::UnsafeToken![unsafe])
554 || lookahead.peek(crate::token::ExternToken![extern])
555 {
556 let mut fn_ptr: TypeFnPtr = input.parse()?;
557 fn_ptr.lifetimes = lifetimes;
558 Ok(Type::FnPtr(fn_ptr))
559 } else if truecfg!(feature = "full")
560 && input.cursor().peek_keyword("builtin")
561 && input.peek2(crate::token::PoundToken![#])
562 {
563 token::parsing::keyword(input, "builtin")?;
564 input.parse::<crate::token::PoundToken![#]>()?;
565 input.parse::<Ident>()?;
566 let args;
567 match crate::__private::parse_parens(&input) {
crate::__private::Ok(parens) => {
args = parens.content;
_ = args;
parens.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
};parenthesized!(args in input);
568 args.parse::<TokenStream>()?;
569 Ok(Type::Verbatim(verbatim::between(begin, input.cursor())))
570 } else if lookahead.peek(Ident)
571 || input.peek(crate::token::SuperToken![super])
572 || input.peek(crate::token::SelfValueToken![self])
573 || input.peek(crate::token::SelfTypeToken![Self])
574 || input.peek(crate::token::CrateToken![crate])
575 || lookahead.peek(crate::token::PathSepToken![::])
576 || lookahead.peek(crate::token::LtToken![<])
577 {
578 let ty: TypePath = input.parse()?;
579 if ty.qself.is_some() {
580 return Ok(Type::Path(ty));
581 }
582
583 if input.peek(crate::token::NotToken![!]) && !input.peek(crate::token::NeToken![!=]) && ty.path.is_mod_style() {
584 let bang_token: crate::token::NotToken![!] = input.parse()?;
585 let (delimiter, tokens) = mac::parse_delimiter(input)?;
586 return Ok(Type::Macro(TypeMacro {
587 attrs: Vec::new(),
588 mac: Macro {
589 path: ty.path,
590 bang_token,
591 delimiter,
592 tokens,
593 },
594 }));
595 }
596
597 if lifetimes.is_some() || allow_plus && input.peek(crate::token::PlusToken![+]) {
598 let mut bounds = Punctuated::new();
599 bounds.push_value(TypeParamBound::Trait(TraitBound {
600 paren_token: None,
601 lifetimes,
602 modifiers: TraitBoundModifiers {},
603 maybe: None,
604 path: ty.path,
605 }));
606 if allow_plus {
607 while input.peek(crate::token::PlusToken![+]) {
608 bounds.push_punct(input.parse()?);
609 if !(input.peek(Ident::peek_any)
610 || input.peek(crate::token::PathSepToken![::])
611 || input.peek(crate::token::QuestionToken![?])
612 || input.peek(Lifetime)
613 || input.peek(token::Paren))
614 {
615 break;
616 }
617 bounds.push_value({
618 let allow_precise_capture = false;
619 let allow_const = false;
620 TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
621 });
622 }
623 }
624 return Ok(Type::TraitObject(TypeTraitObject {
625 attrs: Vec::new(),
626 dyn_token: None,
627 bounds,
628 }));
629 }
630
631 Ok(Type::Path(ty))
632 } else if lookahead.peek(crate::token::DynToken![dyn]) {
633 let dyn_begin = input.cursor();
634 let dyn_token: crate::token::DynToken![dyn] = input.parse()?;
635 let star_token: Option<crate::token::StarToken![*]> = input.parse()?;
636 let bounds = TypeTraitObject::parse_bounds(dyn_begin, input, allow_plus)?;
637 Ok(if star_token.is_some() {
638 Type::Verbatim(verbatim::between(begin, input.cursor()))
639 } else {
640 Type::TraitObject(TypeTraitObject {
641 attrs: Vec::new(),
642 dyn_token: Some(dyn_token),
643 bounds,
644 })
645 })
646 } else if lookahead.peek(token::Bracket) {
647 let content;
648 let bracket_token = match crate::__private::parse_brackets(&input) {
crate::__private::Ok(brackets) => {
content = brackets.content;
_ = content;
brackets.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input);
649 let elem: Type = content.parse()?;
650 if content.peek(crate::token::SemiToken![;]) {
651 Ok(Type::Array(TypeArray {
652 attrs: Vec::new(),
653 bracket_token,
654 elem: Box::new(elem),
655 semi_token: content.parse()?,
656 len: content.parse()?,
657 }))
658 } else {
659 Ok(Type::Slice(TypeSlice {
660 attrs: Vec::new(),
661 bracket_token,
662 elem: Box::new(elem),
663 }))
664 }
665 } else if lookahead.peek(crate::token::StarToken![*]) {
666 input.parse().map(Type::Ptr)
667 } else if lookahead.peek(crate::token::AndToken![&]) {
668 input.parse().map(Type::Reference)
669 } else if lookahead.peek(crate::token::NotToken![!]) && !input.peek(crate::token::EqToken![=]) {
670 input.parse().map(Type::Never)
671 } else if lookahead.peek(crate::token::ImplToken![impl]) {
672 TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
673 } else if lookahead.peek(crate::token::UnderscoreToken![_]) {
674 input.parse().map(Type::Infer)
675 } else if lookahead.peek(Lifetime) {
676 input.parse().map(Type::TraitObject)
677 } else {
678 Err(lookahead.error())
679 }
680 }
681
682 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
683 impl Parse for TypeSlice {
684 fn parse(input: ParseStream) -> Result<Self> {
685 let content;
686 Ok(TypeSlice {
687 attrs: Vec::new(),
688 bracket_token: match crate::__private::parse_brackets(&input) {
crate::__private::Ok(brackets) => {
content = brackets.content;
_ = content;
brackets.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input),
689 elem: content.parse()?,
690 })
691 }
692 }
693
694 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
695 impl Parse for TypeArray {
696 fn parse(input: ParseStream) -> Result<Self> {
697 let content;
698 Ok(TypeArray {
699 attrs: Vec::new(),
700 bracket_token: match crate::__private::parse_brackets(&input) {
crate::__private::Ok(brackets) => {
content = brackets.content;
_ = content;
brackets.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input),
701 elem: content.parse()?,
702 semi_token: content.parse()?,
703 len: content.parse()?,
704 })
705 }
706 }
707
708 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
709 impl Parse for TypePtr {
710 fn parse(input: ParseStream) -> Result<Self> {
711 Ok(TypePtr {
712 attrs: Vec::new(),
713 star_token: input.parse()?,
714 mutability: input.parse()?,
715 elem: Box::new(input.call(Type::without_plus)?),
716 })
717 }
718 }
719
720 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
721 impl Parse for TypeReference {
722 fn parse(input: ParseStream) -> Result<Self> {
723 Ok(TypeReference {
724 attrs: Vec::new(),
725 and_token: input.parse()?,
726 lifetime: Lifetime::parse_optional_any(input),
727 mutability: input.parse()?,
728 elem: Box::new(input.call(Type::without_plus)?),
730 })
731 }
732 }
733
734 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
735 impl Parse for TypeFnPtr {
736 fn parse(input: ParseStream) -> Result<Self> {
737 let args;
738 let mut variadic = None;
739
740 Ok(TypeFnPtr {
741 attrs: Vec::new(),
742 lifetimes: input.parse()?,
743 unsafety: input.parse()?,
744 abi: input.parse()?,
745 fn_token: input.parse()?,
746 paren_token: match crate::__private::parse_parens(&input) {
crate::__private::Ok(parens) => {
args = parens.content;
_ = args;
parens.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(args in input),
747 inputs: {
748 let mut inputs = Punctuated::new();
749
750 while !args.is_empty() {
751 let attrs = args.call(Attribute::parse_outer)?;
752
753 if inputs.empty_or_trailing()
754 && (args.peek(crate::token::DotDotDotToken![...])
755 || (args.peek(Ident) || args.peek(crate::token::UnderscoreToken![_]))
756 && args.peek2(crate::token::ColonToken![:])
757 && args.peek3(crate::token::DotDotDotToken![...]))
758 {
759 variadic = Some(parse_fn_ptr_variadic(&args, attrs)?);
760 break;
761 }
762
763 let allow_self = inputs.is_empty();
764 let arg = parse_fn_ptr_arg(&args, allow_self)?;
765 inputs.push_value(NamedArg { attrs, ..arg });
766 if args.is_empty() {
767 break;
768 }
769
770 let comma = args.parse()?;
771 inputs.push_punct(comma);
772 }
773
774 inputs
775 },
776 variadic,
777 output: input.call(ReturnType::without_plus)?,
778 })
779 }
780 }
781
782 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
783 impl Parse for TypeNever {
784 fn parse(input: ParseStream) -> Result<Self> {
785 Ok(TypeNever {
786 attrs: Vec::new(),
787 bang_token: input.parse()?,
788 })
789 }
790 }
791
792 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
793 impl Parse for TypeInfer {
794 fn parse(input: ParseStream) -> Result<Self> {
795 Ok(TypeInfer {
796 attrs: Vec::new(),
797 underscore_token: input.parse()?,
798 })
799 }
800 }
801
802 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
803 impl Parse for TypeTuple {
804 fn parse(input: ParseStream) -> Result<Self> {
805 let content;
806 let paren_token = match crate::__private::parse_parens(&input) {
crate::__private::Ok(parens) => {
content = parens.content;
_ = content;
parens.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input);
807
808 if content.is_empty() {
809 return Ok(TypeTuple {
810 attrs: Vec::new(),
811 paren_token,
812 elems: Punctuated::new(),
813 });
814 }
815
816 let first: Type = content.parse()?;
817 Ok(TypeTuple {
818 attrs: Vec::new(),
819 paren_token,
820 elems: {
821 let mut elems = Punctuated::new();
822 elems.push_value(first);
823 elems.push_punct(content.parse()?);
824 while !content.is_empty() {
825 elems.push_value(content.parse()?);
826 if content.is_empty() {
827 break;
828 }
829 elems.push_punct(content.parse()?);
830 }
831 elems
832 },
833 })
834 }
835 }
836
837 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
838 impl Parse for TypeMacro {
839 fn parse(input: ParseStream) -> Result<Self> {
840 Ok(TypeMacro {
841 attrs: Vec::new(),
842 mac: input.parse()?,
843 })
844 }
845 }
846
847 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
848 impl Parse for TypePath {
849 fn parse(input: ParseStream) -> Result<Self> {
850 let expr_style = false;
851 let (qself, path) = path::parsing::qpath(input, expr_style)?;
852 Ok(TypePath {
853 attrs: Vec::new(),
854 qself,
855 path,
856 })
857 }
858 }
859
860 impl ReturnType {
861 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
862 pub fn without_plus(input: ParseStream) -> Result<Self> {
863 let allow_plus = false;
864 Self::parse(input, allow_plus)
865 }
866
867 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
868 if input.peek(crate::token::RArrowToken![->]) {
869 let arrow = input.parse()?;
870 let allow_group_generic = true;
871 let ty = ambig_ty(input, allow_plus, allow_group_generic)?;
872 Ok(ReturnType::Type(arrow, Box::new(ty)))
873 } else {
874 Ok(ReturnType::Default)
875 }
876 }
877 }
878
879 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
880 impl Parse for ReturnType {
881 fn parse(input: ParseStream) -> Result<Self> {
882 let allow_plus = true;
883 Self::parse(input, allow_plus)
884 }
885 }
886
887 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
888 impl Parse for TypeTraitObject {
889 fn parse(input: ParseStream) -> Result<Self> {
890 let allow_plus = true;
891 Self::parse(input, allow_plus)
892 }
893 }
894
895 impl TypeTraitObject {
896 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
897 pub fn without_plus(input: ParseStream) -> Result<Self> {
898 let allow_plus = false;
899 Self::parse(input, allow_plus)
900 }
901
902 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
904 let dyn_begin = input.cursor();
905 let dyn_token: Option<crate::token::DynToken![dyn]> = input.parse()?;
906 let bounds = Self::parse_bounds(dyn_begin, input, allow_plus)?;
907 Ok(TypeTraitObject {
908 attrs: Vec::new(),
909 dyn_token,
910 bounds,
911 })
912 }
913
914 fn parse_bounds(
915 dyn_begin: Cursor,
916 input: ParseStream,
917 allow_plus: bool,
918 ) -> Result<Punctuated<TypeParamBound, crate::token::PlusToken![+]>> {
919 let allow_precise_capture = false;
920 let allow_const = false;
921 let bounds = TypeParamBound::parse_multiple(
922 input,
923 allow_plus,
924 allow_precise_capture,
925 allow_const,
926 )?;
927 let mut at_least_one_trait = false;
928 for bound in &bounds {
929 match bound {
930 TypeParamBound::Trait(_) => {
931 at_least_one_trait = true;
932 break;
933 }
934 TypeParamBound::Lifetime(_) => {}
935 TypeParamBound::PreciseCapture(_) | TypeParamBound::Verbatim(_) => {
936 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
937 }
938 }
939 }
940 if !at_least_one_trait {
942 let msg = "at least one trait is required for an object type";
943 return Err(Error::new_range(dyn_begin..input.cursor(), msg));
944 }
945 Ok(bounds)
946 }
947 }
948
949 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
950 impl Parse for TypeImplTrait {
951 fn parse(input: ParseStream) -> Result<Self> {
952 let allow_plus = true;
953 Self::parse(input, allow_plus)
954 }
955 }
956
957 impl TypeImplTrait {
958 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
959 pub fn without_plus(input: ParseStream) -> Result<Self> {
960 let allow_plus = false;
961 Self::parse(input, allow_plus)
962 }
963
964 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
965 let impl_begin = input.cursor();
966 let impl_token: crate::token::ImplToken![impl] = input.parse()?;
967 let allow_precise_capture = true;
968 let allow_const = true;
969 let bounds = TypeParamBound::parse_multiple(
970 input,
971 allow_plus,
972 allow_precise_capture,
973 allow_const,
974 )?;
975 let mut at_least_one_trait = false;
976 for bound in &bounds {
977 match bound {
978 TypeParamBound::Trait(_) => {
979 at_least_one_trait = true;
980 break;
981 }
982 TypeParamBound::Lifetime(_) | TypeParamBound::PreciseCapture(_) => {}
983 TypeParamBound::Verbatim(_) => {
984 at_least_one_trait = true;
986 break;
987 }
988 }
989 }
990 if !at_least_one_trait {
991 let msg = "at least one trait must be specified";
992 return Err(Error::new_range(impl_begin..input.cursor(), msg));
993 }
994 Ok(TypeImplTrait {
995 attrs: Vec::new(),
996 impl_token,
997 bounds,
998 })
999 }
1000 }
1001
1002 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1003 impl Parse for TypeGroup {
1004 fn parse(input: ParseStream) -> Result<Self> {
1005 let group = crate::group::parse_group(input)?;
1006 Ok(TypeGroup {
1007 attrs: Vec::new(),
1008 group_token: group.token,
1009 elem: group.content.parse()?,
1010 })
1011 }
1012 }
1013
1014 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1015 impl Parse for TypeParen {
1016 fn parse(input: ParseStream) -> Result<Self> {
1017 let allow_plus = false;
1018 Self::parse(input, allow_plus)
1019 }
1020 }
1021
1022 impl TypeParen {
1023 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
1024 let content;
1025 Ok(TypeParen {
1026 attrs: Vec::new(),
1027 paren_token: match crate::__private::parse_parens(&input) {
crate::__private::Ok(parens) => {
content = parens.content;
_ = content;
parens.token
}
crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input),
1028 elem: Box::new({
1029 let allow_group_generic = true;
1030 ambig_ty(&content, allow_plus, allow_group_generic)?
1031 }),
1032 })
1033 }
1034 }
1035
1036 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1037 impl Parse for NamedArg {
1038 fn parse(input: ParseStream) -> Result<Self> {
1039 let allow_self = false;
1040 parse_fn_ptr_arg(input, allow_self)
1041 }
1042 }
1043
1044 fn parse_fn_ptr_arg(input: ParseStream, allow_self: bool) -> Result<NamedArg> {
1045 let attrs = input.call(Attribute::parse_outer)?;
1046
1047 let begin = input.cursor();
1048
1049 let has_mut_self = allow_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self]);
1050 if has_mut_self {
1051 input.parse::<crate::token::MutToken![mut]>()?;
1052 }
1053
1054 let mut has_self = false;
1055 let mut name = if (input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) || {
1056 has_self = allow_self && input.peek(crate::token::SelfValueToken![self]);
1057 has_self
1058 }) && input.peek2(crate::token::ColonToken![:])
1059 && !input.peek2(crate::token::PathSepToken![::])
1060 {
1061 let name = input.call(Ident::parse_any)?;
1062 let colon: crate::token::ColonToken![:] = input.parse()?;
1063 Some((name, colon))
1064 } else {
1065 has_self = false;
1066 None
1067 };
1068
1069 let ty = if allow_self && !has_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self])
1070 {
1071 input.parse::<crate::token::MutToken![mut]>()?;
1072 input.parse::<crate::token::SelfValueToken![self]>()?;
1073 None
1074 } else if has_mut_self && name.is_none() {
1075 input.parse::<crate::token::SelfValueToken![self]>()?;
1076 None
1077 } else {
1078 Some(input.parse()?)
1079 };
1080
1081 let ty = match ty {
1082 Some(ty) if !has_mut_self => ty,
1083 _ => {
1084 name = None;
1085 Type::Verbatim(verbatim::between(begin, input.cursor()))
1086 }
1087 };
1088
1089 Ok(NamedArg { attrs, name, ty })
1090 }
1091
1092 fn parse_fn_ptr_variadic(input: ParseStream, attrs: Vec<Attribute>) -> Result<FnPtrVariadic> {
1093 Ok(FnPtrVariadic {
1094 attrs,
1095 name: if input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) {
1096 let name = input.call(Ident::parse_any)?;
1097 let colon: crate::token::ColonToken![:] = input.parse()?;
1098 Some((name, colon))
1099 } else {
1100 None
1101 },
1102 dots: input.parse()?,
1103 comma: input.parse()?,
1104 })
1105 }
1106
1107 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1108 impl Parse for Abi {
1109 fn parse(input: ParseStream) -> Result<Self> {
1110 Ok(Abi {
1111 extern_token: input.parse()?,
1112 name: input.parse()?,
1113 })
1114 }
1115 }
1116
1117 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1118 impl Parse for Option<Abi> {
1119 fn parse(input: ParseStream) -> Result<Self> {
1120 if input.peek(crate::token::ExternToken![extern]) {
1121 input.parse().map(Some)
1122 } else {
1123 Ok(None)
1124 }
1125 }
1126 }
1127
1128 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1129 impl Parse for PointerMutability {
1130 fn parse(input: ParseStream) -> Result<Self> {
1131 let lookahead = input.lookahead1();
1132 if lookahead.peek(crate::token::ConstToken![const]) {
1133 Ok(PointerMutability::Const(input.parse()?))
1134 } else if lookahead.peek(crate::token::MutToken![mut]) {
1135 Ok(PointerMutability::Mut(input.parse()?))
1136 } else {
1137 Err(lookahead.error())
1138 }
1139 }
1140 }
1141}
1142
1143#[cfg(feature = "printing")]
1144mod printing {
1145 use crate::attr::FilterAttrs;
1146 use crate::path;
1147 use crate::path::printing::PathStyle;
1148 use crate::ty::{
1149 Abi, FnPtrVariadic, NamedArg, PointerMutability, ReturnType, TypeArray, TypeFnPtr,
1150 TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr,
1151 TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
1152 };
1153 use proc_macro2::TokenStream;
1154 use quote::{ToTokens, TokenStreamExt as _};
1155
1156 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1157 impl ToTokens for TypeSlice {
1158 fn to_tokens(&self, tokens: &mut TokenStream) {
1159 self.bracket_token.surround(tokens, |tokens| {
1160 self.elem.to_tokens(tokens);
1161 });
1162 }
1163 }
1164
1165 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1166 impl ToTokens for TypeArray {
1167 fn to_tokens(&self, tokens: &mut TokenStream) {
1168 self.bracket_token.surround(tokens, |tokens| {
1169 self.elem.to_tokens(tokens);
1170 self.semi_token.to_tokens(tokens);
1171 self.len.to_tokens(tokens);
1172 });
1173 }
1174 }
1175
1176 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1177 impl ToTokens for TypePtr {
1178 fn to_tokens(&self, tokens: &mut TokenStream) {
1179 self.star_token.to_tokens(tokens);
1180 self.mutability.to_tokens(tokens);
1181 self.elem.to_tokens(tokens);
1182 }
1183 }
1184
1185 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1186 impl ToTokens for TypeReference {
1187 fn to_tokens(&self, tokens: &mut TokenStream) {
1188 self.and_token.to_tokens(tokens);
1189 self.lifetime.to_tokens(tokens);
1190 self.mutability.to_tokens(tokens);
1191 self.elem.to_tokens(tokens);
1192 }
1193 }
1194
1195 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1196 impl ToTokens for TypeFnPtr {
1197 fn to_tokens(&self, tokens: &mut TokenStream) {
1198 self.lifetimes.to_tokens(tokens);
1199 self.unsafety.to_tokens(tokens);
1200 self.abi.to_tokens(tokens);
1201 self.fn_token.to_tokens(tokens);
1202 self.paren_token.surround(tokens, |tokens| {
1203 self.inputs.to_tokens(tokens);
1204 if let Some(variadic) = &self.variadic {
1205 if !self.inputs.empty_or_trailing() {
1206 let span = variadic.dots.spans[0];
1207 crate::token::CommaToken.to_tokens(tokens);
1208 }
1209 variadic.to_tokens(tokens);
1210 }
1211 });
1212 self.output.to_tokens(tokens);
1213 }
1214 }
1215
1216 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1217 impl ToTokens for TypeNever {
1218 fn to_tokens(&self, tokens: &mut TokenStream) {
1219 self.bang_token.to_tokens(tokens);
1220 }
1221 }
1222
1223 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1224 impl ToTokens for TypeTuple {
1225 fn to_tokens(&self, tokens: &mut TokenStream) {
1226 self.paren_token.surround(tokens, |tokens| {
1227 self.elems.to_tokens(tokens);
1228 if self.elems.len() == 1 && !self.elems.trailing_punct() {
1231 <crate::token::CommaToken![,]>::default().to_tokens(tokens);
1232 }
1233 });
1234 }
1235 }
1236
1237 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1238 impl ToTokens for TypePath {
1239 fn to_tokens(&self, tokens: &mut TokenStream) {
1240 path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::AsWritten);
1241 }
1242 }
1243
1244 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1245 impl ToTokens for TypeTraitObject {
1246 fn to_tokens(&self, tokens: &mut TokenStream) {
1247 self.dyn_token.to_tokens(tokens);
1248 self.bounds.to_tokens(tokens);
1249 }
1250 }
1251
1252 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1253 impl ToTokens for TypeImplTrait {
1254 fn to_tokens(&self, tokens: &mut TokenStream) {
1255 self.impl_token.to_tokens(tokens);
1256 self.bounds.to_tokens(tokens);
1257 }
1258 }
1259
1260 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1261 impl ToTokens for TypeGroup {
1262 fn to_tokens(&self, tokens: &mut TokenStream) {
1263 self.group_token.surround(tokens, |tokens| {
1264 self.elem.to_tokens(tokens);
1265 });
1266 }
1267 }
1268
1269 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1270 impl ToTokens for TypeParen {
1271 fn to_tokens(&self, tokens: &mut TokenStream) {
1272 self.paren_token.surround(tokens, |tokens| {
1273 self.elem.to_tokens(tokens);
1274 });
1275 }
1276 }
1277
1278 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1279 impl ToTokens for TypeInfer {
1280 fn to_tokens(&self, tokens: &mut TokenStream) {
1281 self.underscore_token.to_tokens(tokens);
1282 }
1283 }
1284
1285 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1286 impl ToTokens for TypeMacro {
1287 fn to_tokens(&self, tokens: &mut TokenStream) {
1288 self.mac.to_tokens(tokens);
1289 }
1290 }
1291
1292 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1293 impl ToTokens for ReturnType {
1294 fn to_tokens(&self, tokens: &mut TokenStream) {
1295 match self {
1296 ReturnType::Default => {}
1297 ReturnType::Type(arrow, ty) => {
1298 arrow.to_tokens(tokens);
1299 ty.to_tokens(tokens);
1300 }
1301 }
1302 }
1303 }
1304
1305 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1306 impl ToTokens for NamedArg {
1307 fn to_tokens(&self, tokens: &mut TokenStream) {
1308 tokens.append_all(self.attrs.outer());
1309 if let Some((name, colon)) = &self.name {
1310 name.to_tokens(tokens);
1311 colon.to_tokens(tokens);
1312 }
1313 self.ty.to_tokens(tokens);
1314 }
1315 }
1316
1317 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1318 impl ToTokens for FnPtrVariadic {
1319 fn to_tokens(&self, tokens: &mut TokenStream) {
1320 tokens.append_all(self.attrs.outer());
1321 if let Some((name, colon)) = &self.name {
1322 name.to_tokens(tokens);
1323 colon.to_tokens(tokens);
1324 }
1325 self.dots.to_tokens(tokens);
1326 self.comma.to_tokens(tokens);
1327 }
1328 }
1329
1330 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1331 impl ToTokens for Abi {
1332 fn to_tokens(&self, tokens: &mut TokenStream) {
1333 self.extern_token.to_tokens(tokens);
1334 self.name.to_tokens(tokens);
1335 }
1336 }
1337
1338 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1339 impl ToTokens for PointerMutability {
1340 fn to_tokens(&self, tokens: &mut TokenStream) {
1341 match self {
1342 PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
1343 PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
1344 }
1345 }
1346 }
1347}