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