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