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