| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492 |
- // SPDX-License-Identifier: Apache-2.0 OR MIT
- use crate::attr::Attribute;
- use crate::data::{Fields, FieldsNamed, Variant};
- use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput};
- use crate::expr::Expr;
- use crate::generics::{Generics, TypeParamBound};
- use crate::ident::Ident;
- use crate::lifetime::Lifetime;
- use crate::mac::Macro;
- use crate::pat::{Pat, PatType};
- use crate::path::Path;
- use crate::punctuated::Punctuated;
- use crate::restriction::Visibility;
- use crate::stmt::Block;
- use crate::token;
- use crate::ty::{Abi, ReturnType, Type};
- use proc_macro2::TokenStream;
- #[cfg(feature = "parsing")]
- use std::mem;
- ast_enum_of_structs! {
- /// Things that can appear directly inside of a module or scope.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum Item {
- /// A constant item: `const MAX: u16 = 65535`.
- Const(ItemConst),
- /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
- Enum(ItemEnum),
- /// An `extern crate` item: `extern crate serde`.
- ExternCrate(ItemExternCrate),
- /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
- /// }`.
- Fn(ItemFn),
- /// A block of foreign items: `extern "C" { ... }`.
- ForeignMod(ItemForeignMod),
- /// An impl block providing trait or associated items: `impl<A> Trait
- /// for Data<A> { ... }`.
- Impl(ItemImpl),
- /// A macro invocation, which includes `macro_rules!` definitions.
- Macro(ItemMacro),
- /// A module or module declaration: `mod m` or `mod m { ... }`.
- Mod(ItemMod),
- /// A static item: `static BIKE: Shed = Shed(42)`.
- Static(ItemStatic),
- /// A struct definition: `struct Foo<A> { x: A }`.
- Struct(ItemStruct),
- /// A trait definition: `pub trait Iterator { ... }`.
- Trait(ItemTrait),
- /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
- TraitAlias(ItemTraitAlias),
- /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
- Type(ItemType),
- /// A union definition: `union Foo<A, B> { x: A, y: B }`.
- Union(ItemUnion),
- /// A use declaration: `use std::collections::HashMap`.
- Use(ItemUse),
- /// Tokens forming an item not interpreted by Syn.
- Verbatim(TokenStream),
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match item {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // Item::Const(item) => {...}
- // Item::Enum(item) => {...}
- // ...
- // Item::Verbatim(item) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
- }
- ast_struct! {
- /// A constant item: `const MAX: u16 = 65535`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemConst {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub const_token: Token![const],
- pub ident: Ident,
- pub generics: Generics,
- pub colon_token: Token![:],
- pub ty: Box<Type>,
- pub eq_token: Token![=],
- pub expr: Box<Expr>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemEnum {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub enum_token: Token![enum],
- pub ident: Ident,
- pub generics: Generics,
- pub brace_token: token::Brace,
- pub variants: Punctuated<Variant, Token![,]>,
- }
- }
- ast_struct! {
- /// An `extern crate` item: `extern crate serde`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemExternCrate {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub extern_token: Token![extern],
- pub crate_token: Token![crate],
- pub ident: Ident,
- pub rename: Option<(Token![as], Ident)>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A free-standing function: `fn process(n: usize) -> Result<()> { ... }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemFn {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub sig: Signature,
- pub block: Box<Block>,
- }
- }
- ast_struct! {
- /// A block of foreign items: `extern "C" { ... }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemForeignMod {
- pub attrs: Vec<Attribute>,
- pub unsafety: Option<Token![unsafe]>,
- pub abi: Abi,
- pub brace_token: token::Brace,
- pub items: Vec<ForeignItem>,
- }
- }
- ast_struct! {
- /// An impl block providing trait or associated items: `impl<A> Trait
- /// for Data<A> { ... }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemImpl {
- pub attrs: Vec<Attribute>,
- pub defaultness: Option<Token![default]>,
- pub unsafety: Option<Token![unsafe]>,
- pub impl_token: Token![impl],
- pub generics: Generics,
- /// Trait this impl implements.
- pub trait_: Option<(Option<Token![!]>, Path, Token![for])>,
- /// The Self type of the impl.
- pub self_ty: Box<Type>,
- pub brace_token: token::Brace,
- pub items: Vec<ImplItem>,
- }
- }
- ast_struct! {
- /// A macro invocation, which includes `macro_rules!` definitions.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemMacro {
- pub attrs: Vec<Attribute>,
- /// The `example` in `macro_rules! example { ... }`.
- pub ident: Option<Ident>,
- pub mac: Macro,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_struct! {
- /// A module or module declaration: `mod m` or `mod m { ... }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemMod {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub unsafety: Option<Token![unsafe]>,
- pub mod_token: Token![mod],
- pub ident: Ident,
- pub content: Option<(token::Brace, Vec<Item>)>,
- pub semi: Option<Token![;]>,
- }
- }
- ast_struct! {
- /// A static item: `static BIKE: Shed = Shed(42)`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemStatic {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub static_token: Token![static],
- pub mutability: StaticMutability,
- pub ident: Ident,
- pub colon_token: Token![:],
- pub ty: Box<Type>,
- pub eq_token: Token![=],
- pub expr: Box<Expr>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A struct definition: `struct Foo<A> { x: A }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemStruct {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub struct_token: Token![struct],
- pub ident: Ident,
- pub generics: Generics,
- pub fields: Fields,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_struct! {
- /// A trait definition: `pub trait Iterator { ... }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemTrait {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub unsafety: Option<Token![unsafe]>,
- pub auto_token: Option<Token![auto]>,
- pub restriction: Option<ImplRestriction>,
- pub trait_token: Token![trait],
- pub ident: Ident,
- pub generics: Generics,
- pub colon_token: Option<Token![:]>,
- pub supertraits: Punctuated<TypeParamBound, Token![+]>,
- pub brace_token: token::Brace,
- pub items: Vec<TraitItem>,
- }
- }
- ast_struct! {
- /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemTraitAlias {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub trait_token: Token![trait],
- pub ident: Ident,
- pub generics: Generics,
- pub eq_token: Token![=],
- pub bounds: Punctuated<TypeParamBound, Token![+]>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemType {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub type_token: Token![type],
- pub ident: Ident,
- pub generics: Generics,
- pub eq_token: Token![=],
- pub ty: Box<Type>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A union definition: `union Foo<A, B> { x: A, y: B }`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemUnion {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub union_token: Token![union],
- pub ident: Ident,
- pub generics: Generics,
- pub fields: FieldsNamed,
- }
- }
- ast_struct! {
- /// A use declaration: `use std::collections::HashMap`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ItemUse {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub use_token: Token![use],
- pub leading_colon: Option<Token![::]>,
- pub tree: UseTree,
- pub semi_token: Token![;],
- }
- }
- impl Item {
- #[cfg(feature = "parsing")]
- pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
- match self {
- Item::Const(ItemConst { attrs, .. })
- | Item::Enum(ItemEnum { attrs, .. })
- | Item::ExternCrate(ItemExternCrate { attrs, .. })
- | Item::Fn(ItemFn { attrs, .. })
- | Item::ForeignMod(ItemForeignMod { attrs, .. })
- | Item::Impl(ItemImpl { attrs, .. })
- | Item::Macro(ItemMacro { attrs, .. })
- | Item::Mod(ItemMod { attrs, .. })
- | Item::Static(ItemStatic { attrs, .. })
- | Item::Struct(ItemStruct { attrs, .. })
- | Item::Trait(ItemTrait { attrs, .. })
- | Item::TraitAlias(ItemTraitAlias { attrs, .. })
- | Item::Type(ItemType { attrs, .. })
- | Item::Union(ItemUnion { attrs, .. })
- | Item::Use(ItemUse { attrs, .. }) => mem::replace(attrs, new),
- Item::Verbatim(_) => Vec::new(),
- }
- }
- }
- impl From<DeriveInput> for Item {
- fn from(input: DeriveInput) -> Item {
- match input.data {
- Data::Struct(data) => Item::Struct(ItemStruct {
- attrs: input.attrs,
- vis: input.vis,
- struct_token: data.struct_token,
- ident: input.ident,
- generics: input.generics,
- fields: data.fields,
- semi_token: data.semi_token,
- }),
- Data::Enum(data) => Item::Enum(ItemEnum {
- attrs: input.attrs,
- vis: input.vis,
- enum_token: data.enum_token,
- ident: input.ident,
- generics: input.generics,
- brace_token: data.brace_token,
- variants: data.variants,
- }),
- Data::Union(data) => Item::Union(ItemUnion {
- attrs: input.attrs,
- vis: input.vis,
- union_token: data.union_token,
- ident: input.ident,
- generics: input.generics,
- fields: data.fields,
- }),
- }
- }
- }
- impl From<ItemStruct> for DeriveInput {
- fn from(input: ItemStruct) -> DeriveInput {
- DeriveInput {
- attrs: input.attrs,
- vis: input.vis,
- ident: input.ident,
- generics: input.generics,
- data: Data::Struct(DataStruct {
- struct_token: input.struct_token,
- fields: input.fields,
- semi_token: input.semi_token,
- }),
- }
- }
- }
- impl From<ItemEnum> for DeriveInput {
- fn from(input: ItemEnum) -> DeriveInput {
- DeriveInput {
- attrs: input.attrs,
- vis: input.vis,
- ident: input.ident,
- generics: input.generics,
- data: Data::Enum(DataEnum {
- enum_token: input.enum_token,
- brace_token: input.brace_token,
- variants: input.variants,
- }),
- }
- }
- }
- impl From<ItemUnion> for DeriveInput {
- fn from(input: ItemUnion) -> DeriveInput {
- DeriveInput {
- attrs: input.attrs,
- vis: input.vis,
- ident: input.ident,
- generics: input.generics,
- data: Data::Union(DataUnion {
- union_token: input.union_token,
- fields: input.fields,
- }),
- }
- }
- }
- ast_enum_of_structs! {
- /// A suffix of an import tree in a `use` item: `Type as Renamed` or `*`.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub enum UseTree {
- /// A path prefix of imports in a `use` item: `std::...`.
- Path(UsePath),
- /// An identifier imported by a `use` item: `HashMap`.
- Name(UseName),
- /// An renamed identifier imported by a `use` item: `HashMap as Map`.
- Rename(UseRename),
- /// A glob import in a `use` item: `*`.
- Glob(UseGlob),
- /// A braced group of imports in a `use` item: `{A, B, C}`.
- Group(UseGroup),
- }
- }
- ast_struct! {
- /// A path prefix of imports in a `use` item: `std::...`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct UsePath {
- pub ident: Ident,
- pub colon2_token: Token![::],
- pub tree: Box<UseTree>,
- }
- }
- ast_struct! {
- /// An identifier imported by a `use` item: `HashMap`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct UseName {
- pub ident: Ident,
- }
- }
- ast_struct! {
- /// An renamed identifier imported by a `use` item: `HashMap as Map`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct UseRename {
- pub ident: Ident,
- pub as_token: Token![as],
- pub rename: Ident,
- }
- }
- ast_struct! {
- /// A glob import in a `use` item: `*`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct UseGlob {
- pub star_token: Token![*],
- }
- }
- ast_struct! {
- /// A braced group of imports in a `use` item: `{A, B, C}`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct UseGroup {
- pub brace_token: token::Brace,
- pub items: Punctuated<UseTree, Token![,]>,
- }
- }
- ast_enum_of_structs! {
- /// An item within an `extern` block.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum ForeignItem {
- /// A foreign function in an `extern` block.
- Fn(ForeignItemFn),
- /// A foreign static item in an `extern` block: `static ext: u8`.
- Static(ForeignItemStatic),
- /// A foreign type in an `extern` block: `type void`.
- Type(ForeignItemType),
- /// A macro invocation within an extern block.
- Macro(ForeignItemMacro),
- /// Tokens in an `extern` block not interpreted by Syn.
- Verbatim(TokenStream),
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match item {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // ForeignItem::Fn(item) => {...}
- // ForeignItem::Static(item) => {...}
- // ...
- // ForeignItem::Verbatim(item) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
- }
- ast_struct! {
- /// A foreign function in an `extern` block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ForeignItemFn {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub sig: Signature,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A foreign static item in an `extern` block: `static ext: u8`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ForeignItemStatic {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub static_token: Token![static],
- pub mutability: StaticMutability,
- pub ident: Ident,
- pub colon_token: Token![:],
- pub ty: Box<Type>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A foreign type in an `extern` block: `type void`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ForeignItemType {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub type_token: Token![type],
- pub ident: Ident,
- pub generics: Generics,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A macro invocation within an extern block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ForeignItemMacro {
- pub attrs: Vec<Attribute>,
- pub mac: Macro,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_enum_of_structs! {
- /// An item declaration within the definition of a trait.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum TraitItem {
- /// An associated constant within the definition of a trait.
- Const(TraitItemConst),
- /// An associated function within the definition of a trait.
- Fn(TraitItemFn),
- /// An associated type within the definition of a trait.
- Type(TraitItemType),
- /// A macro invocation within the definition of a trait.
- Macro(TraitItemMacro),
- /// Tokens within the definition of a trait not interpreted by Syn.
- Verbatim(TokenStream),
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match item {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // TraitItem::Const(item) => {...}
- // TraitItem::Fn(item) => {...}
- // ...
- // TraitItem::Verbatim(item) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
- }
- ast_struct! {
- /// An associated constant within the definition of a trait.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct TraitItemConst {
- pub attrs: Vec<Attribute>,
- pub const_token: Token![const],
- pub ident: Ident,
- pub generics: Generics,
- pub colon_token: Token![:],
- pub ty: Type,
- pub default: Option<(Token![=], Expr)>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// An associated function within the definition of a trait.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct TraitItemFn {
- pub attrs: Vec<Attribute>,
- pub sig: Signature,
- pub default: Option<Block>,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_struct! {
- /// An associated type within the definition of a trait.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct TraitItemType {
- pub attrs: Vec<Attribute>,
- pub type_token: Token![type],
- pub ident: Ident,
- pub generics: Generics,
- pub colon_token: Option<Token![:]>,
- pub bounds: Punctuated<TypeParamBound, Token![+]>,
- pub default: Option<(Token![=], Type)>,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A macro invocation within the definition of a trait.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct TraitItemMacro {
- pub attrs: Vec<Attribute>,
- pub mac: Macro,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_enum_of_structs! {
- /// An item within an impl block.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum ImplItem {
- /// An associated constant within an impl block.
- Const(ImplItemConst),
- /// An associated function within an impl block.
- Fn(ImplItemFn),
- /// An associated type within an impl block.
- Type(ImplItemType),
- /// A macro invocation within an impl block.
- Macro(ImplItemMacro),
- /// Tokens within an impl block not interpreted by Syn.
- Verbatim(TokenStream),
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match item {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // ImplItem::Const(item) => {...}
- // ImplItem::Fn(item) => {...}
- // ...
- // ImplItem::Verbatim(item) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
- }
- ast_struct! {
- /// An associated constant within an impl block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ImplItemConst {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub defaultness: Option<Token![default]>,
- pub const_token: Token![const],
- pub ident: Ident,
- pub generics: Generics,
- pub colon_token: Token![:],
- pub ty: Type,
- pub eq_token: Token![=],
- pub expr: Expr,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// An associated function within an impl block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ImplItemFn {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub defaultness: Option<Token![default]>,
- pub sig: Signature,
- pub block: Block,
- }
- }
- ast_struct! {
- /// An associated type within an impl block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ImplItemType {
- pub attrs: Vec<Attribute>,
- pub vis: Visibility,
- pub defaultness: Option<Token![default]>,
- pub type_token: Token![type],
- pub ident: Ident,
- pub generics: Generics,
- pub eq_token: Token![=],
- pub ty: Type,
- pub semi_token: Token![;],
- }
- }
- ast_struct! {
- /// A macro invocation within an impl block.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct ImplItemMacro {
- pub attrs: Vec<Attribute>,
- pub mac: Macro,
- pub semi_token: Option<Token![;]>,
- }
- }
- ast_struct! {
- /// A function signature in a trait or implementation: `unsafe fn
- /// initialize(&self)`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct Signature {
- pub constness: Option<Token![const]>,
- pub asyncness: Option<Token![async]>,
- pub unsafety: Option<Token![unsafe]>,
- pub abi: Option<Abi>,
- pub fn_token: Token![fn],
- pub ident: Ident,
- pub generics: Generics,
- pub paren_token: token::Paren,
- pub inputs: Punctuated<FnArg, Token![,]>,
- pub variadic: Option<Variadic>,
- pub output: ReturnType,
- }
- }
- impl Signature {
- /// A method's `self` receiver, such as `&self` or `self: Box<Self>`.
- pub fn receiver(&self) -> Option<&Receiver> {
- let arg = self.inputs.first()?;
- match arg {
- FnArg::Receiver(receiver) => Some(receiver),
- FnArg::Typed(_) => None,
- }
- }
- }
- ast_enum_of_structs! {
- /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub enum FnArg {
- /// The `self` argument of an associated method.
- Receiver(Receiver),
- /// A function argument accepted by pattern and type.
- Typed(PatType),
- }
- }
- ast_struct! {
- /// The `self` argument of an associated method.
- ///
- /// If `colon_token` is present, the receiver is written with an explicit
- /// type such as `self: Box<Self>`. If `colon_token` is absent, the receiver
- /// is written in shorthand such as `self` or `&self` or `&mut self`. In the
- /// shorthand case, the type in `ty` is reconstructed as one of `Self`,
- /// `&Self`, or `&mut Self`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct Receiver {
- pub attrs: Vec<Attribute>,
- pub reference: Option<(Token![&], Option<Lifetime>)>,
- pub mutability: Option<Token![mut]>,
- pub self_token: Token![self],
- pub colon_token: Option<Token![:]>,
- pub ty: Box<Type>,
- }
- }
- impl Receiver {
- pub fn lifetime(&self) -> Option<&Lifetime> {
- self.reference.as_ref()?.1.as_ref()
- }
- }
- ast_struct! {
- /// The variadic argument of a foreign function.
- ///
- /// ```rust
- /// # struct c_char;
- /// # struct c_int;
- /// #
- /// extern "C" {
- /// fn printf(format: *const c_char, ...) -> c_int;
- /// // ^^^
- /// }
- /// ```
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- pub struct Variadic {
- pub attrs: Vec<Attribute>,
- pub pat: Option<(Box<Pat>, Token![:])>,
- pub dots: Token![...],
- pub comma: Option<Token![,]>,
- }
- }
- ast_enum! {
- /// The mutability of an `Item::Static` or `ForeignItem::Static`.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum StaticMutability {
- Mut(Token![mut]),
- None,
- }
- }
- ast_enum! {
- /// Unused, but reserved for RFC 3323 restrictions.
- #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum ImplRestriction {}
- // TODO: https://rust-lang.github.io/rfcs/3323-restrictions.html
- //
- // pub struct ImplRestriction {
- // pub impl_token: Token![impl],
- // pub paren_token: token::Paren,
- // pub in_token: Option<Token![in]>,
- // pub path: Box<Path>,
- // }
- }
- #[cfg(feature = "parsing")]
- pub(crate) mod parsing {
- use crate::attr::{self, Attribute};
- use crate::derive;
- use crate::error::{Error, Result};
- use crate::expr::Expr;
- use crate::ext::IdentExt as _;
- use crate::generics::{self, Generics, TypeParamBound};
- use crate::ident::Ident;
- use crate::item::{
- FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType,
- ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, Item, ItemConst,
- ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod,
- ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver,
- Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro,
- TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,
- };
- use crate::lifetime::Lifetime;
- use crate::lit::LitStr;
- use crate::mac::{self, Macro};
- use crate::parse::discouraged::Speculative as _;
- use crate::parse::{Parse, ParseBuffer, ParseStream};
- use crate::pat::{Pat, PatType, PatWild};
- use crate::path::Path;
- use crate::punctuated::Punctuated;
- use crate::restriction::Visibility;
- use crate::stmt::Block;
- use crate::token;
- use crate::ty::{Abi, ReturnType, Type, TypePath, TypeReference};
- use crate::verbatim;
- use proc_macro2::TokenStream;
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for Item {
- fn parse(input: ParseStream) -> Result<Self> {
- let begin = input.fork();
- let attrs = input.call(Attribute::parse_outer)?;
- parse_rest_of_item(begin, attrs, input)
- }
- }
- pub(crate) fn parse_rest_of_item(
- begin: ParseBuffer,
- mut attrs: Vec<Attribute>,
- input: ParseStream,
- ) -> Result<Item> {
- let ahead = input.fork();
- let vis: Visibility = ahead.parse()?;
- let lookahead = ahead.lookahead1();
- let allow_safe = false;
- let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) {
- let vis: Visibility = input.parse()?;
- let sig: Signature = input.parse()?;
- if input.peek(Token![;]) {
- input.parse::<Token![;]>()?;
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- } else {
- parse_rest_of_fn(input, Vec::new(), vis, sig).map(Item::Fn)
- }
- } else if lookahead.peek(Token![extern]) {
- ahead.parse::<Token![extern]>()?;
- let lookahead = ahead.lookahead1();
- if lookahead.peek(Token![crate]) {
- input.parse().map(Item::ExternCrate)
- } else if lookahead.peek(token::Brace) {
- input.parse().map(Item::ForeignMod)
- } else if lookahead.peek(LitStr) {
- ahead.parse::<LitStr>()?;
- let lookahead = ahead.lookahead1();
- if lookahead.peek(token::Brace) {
- input.parse().map(Item::ForeignMod)
- } else {
- Err(lookahead.error())
- }
- } else {
- Err(lookahead.error())
- }
- } else if lookahead.peek(Token![use]) {
- let allow_crate_root_in_path = true;
- match parse_item_use(input, allow_crate_root_in_path)? {
- Some(item_use) => Ok(Item::Use(item_use)),
- None => Ok(Item::Verbatim(verbatim::between(&begin, input))),
- }
- } else if lookahead.peek(Token![static]) {
- let vis = input.parse()?;
- let static_token = input.parse()?;
- let mutability = input.parse()?;
- let ident = input.parse()?;
- if input.peek(Token![=]) {
- input.parse::<Token![=]>()?;
- input.parse::<Expr>()?;
- input.parse::<Token![;]>()?;
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- } else {
- let colon_token = input.parse()?;
- let ty = input.parse()?;
- if input.peek(Token![;]) {
- input.parse::<Token![;]>()?;
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(Item::Static(ItemStatic {
- attrs: Vec::new(),
- vis,
- static_token,
- mutability,
- ident,
- colon_token,
- ty,
- eq_token: input.parse()?,
- expr: input.parse()?,
- semi_token: input.parse()?,
- }))
- }
- }
- } else if lookahead.peek(Token![const]) {
- let vis = input.parse()?;
- let const_token: Token![const] = input.parse()?;
- let lookahead = input.lookahead1();
- let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.call(Ident::parse_any)?
- } else {
- return Err(lookahead.error());
- };
- let mut generics: Generics = input.parse()?;
- let colon_token = input.parse()?;
- let ty = input.parse()?;
- let value = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
- let expr: Expr = input.parse()?;
- Some((eq_token, expr))
- } else {
- None
- };
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- match value {
- Some((eq_token, expr))
- if generics.lt_token.is_none() && generics.where_clause.is_none() =>
- {
- Ok(Item::Const(ItemConst {
- attrs: Vec::new(),
- vis,
- const_token,
- ident,
- generics,
- colon_token,
- ty,
- eq_token,
- expr: Box::new(expr),
- semi_token,
- }))
- }
- _ => Ok(Item::Verbatim(verbatim::between(&begin, input))),
- }
- } else if lookahead.peek(Token![unsafe]) {
- ahead.parse::<Token![unsafe]>()?;
- let lookahead = ahead.lookahead1();
- if lookahead.peek(Token![trait])
- || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
- {
- input.parse().map(Item::Trait)
- } else if lookahead.peek(Token![impl]) {
- let allow_verbatim_impl = true;
- if let Some(item) = parse_impl(input, allow_verbatim_impl)? {
- Ok(Item::Impl(item))
- } else {
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- }
- } else if lookahead.peek(Token![extern]) {
- input.parse().map(Item::ForeignMod)
- } else if lookahead.peek(Token![mod]) {
- input.parse().map(Item::Mod)
- } else {
- Err(lookahead.error())
- }
- } else if lookahead.peek(Token![mod]) {
- input.parse().map(Item::Mod)
- } else if lookahead.peek(Token![type]) {
- parse_item_type(begin, input)
- } else if lookahead.peek(Token![struct]) {
- input.parse().map(Item::Struct)
- } else if lookahead.peek(Token![enum]) {
- input.parse().map(Item::Enum)
- } else if lookahead.peek(Token![union]) && ahead.peek2(Ident) {
- input.parse().map(Item::Union)
- } else if lookahead.peek(Token![trait]) {
- input.call(parse_trait_or_trait_alias)
- } else if lookahead.peek(Token![auto]) && ahead.peek2(Token![trait]) {
- input.parse().map(Item::Trait)
- } else if lookahead.peek(Token![impl])
- || lookahead.peek(Token![default]) && !ahead.peek2(Token![!])
- {
- let allow_verbatim_impl = true;
- if let Some(item) = parse_impl(input, allow_verbatim_impl)? {
- Ok(Item::Impl(item))
- } else {
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- }
- } else if lookahead.peek(Token![macro]) {
- input.advance_to(&ahead);
- parse_macro2(begin, vis, input)
- } else if vis.is_inherited()
- && (lookahead.peek(Ident)
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- || lookahead.peek(Token![::]))
- {
- input.parse().map(Item::Macro)
- } else {
- Err(lookahead.error())
- }?;
- attrs.extend(item.replace_attrs(Vec::new()));
- item.replace_attrs(attrs);
- Ok(item)
- }
- struct FlexibleItemType {
- vis: Visibility,
- defaultness: Option<Token![default]>,
- type_token: Token![type],
- ident: Ident,
- generics: Generics,
- colon_token: Option<Token![:]>,
- bounds: Punctuated<TypeParamBound, Token![+]>,
- ty: Option<(Token![=], Type)>,
- semi_token: Token![;],
- }
- enum TypeDefaultness {
- Optional,
- Disallowed,
- }
- enum WhereClauseLocation {
- // type Ty<T> where T: 'static = T;
- BeforeEq,
- // type Ty<T> = T where T: 'static;
- AfterEq,
- // TODO: goes away once the migration period on rust-lang/rust#89122 is over
- Both,
- }
- impl FlexibleItemType {
- fn parse(
- input: ParseStream,
- allow_defaultness: TypeDefaultness,
- where_clause_location: WhereClauseLocation,
- ) -> Result<Self> {
- let vis: Visibility = input.parse()?;
- let defaultness: Option<Token![default]> = match allow_defaultness {
- TypeDefaultness::Optional => input.parse()?,
- TypeDefaultness::Disallowed => None,
- };
- let type_token: Token![type] = input.parse()?;
- let ident: Ident = input.parse()?;
- let mut generics: Generics = input.parse()?;
- let (colon_token, bounds) = Self::parse_optional_bounds(input)?;
- match where_clause_location {
- WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => {
- generics.where_clause = input.parse()?;
- }
- WhereClauseLocation::AfterEq => {}
- }
- let ty = Self::parse_optional_definition(input)?;
- match where_clause_location {
- WhereClauseLocation::AfterEq | WhereClauseLocation::Both
- if generics.where_clause.is_none() =>
- {
- generics.where_clause = input.parse()?;
- }
- _ => {}
- }
- let semi_token: Token![;] = input.parse()?;
- Ok(FlexibleItemType {
- vis,
- defaultness,
- type_token,
- ident,
- generics,
- colon_token,
- bounds,
- ty,
- semi_token,
- })
- }
- fn parse_optional_bounds(
- input: ParseStream,
- ) -> Result<(Option<Token![:]>, Punctuated<TypeParamBound, Token![+]>)> {
- let colon_token: Option<Token![:]> = input.parse()?;
- let mut bounds = Punctuated::new();
- if colon_token.is_some() {
- loop {
- if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
- break;
- }
- bounds.push_value({
- let allow_precise_capture = false;
- let allow_const = true;
- TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
- });
- if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
- break;
- }
- bounds.push_punct(input.parse::<Token![+]>()?);
- }
- }
- Ok((colon_token, bounds))
- }
- fn parse_optional_definition(input: ParseStream) -> Result<Option<(Token![=], Type)>> {
- let eq_token: Option<Token![=]> = input.parse()?;
- if let Some(eq_token) = eq_token {
- let definition: Type = input.parse()?;
- Ok(Some((eq_token, definition)))
- } else {
- Ok(None)
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemMacro {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let path = input.call(Path::parse_mod_style)?;
- let bang_token: Token![!] = input.parse()?;
- let ident: Option<Ident> = if input.peek(Token![try]) {
- input.call(Ident::parse_any).map(Some)
- } else {
- input.parse()
- }?;
- let (delimiter, tokens) = input.call(mac::parse_delimiter)?;
- let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
- Some(input.parse()?)
- } else {
- None
- };
- Ok(ItemMacro {
- attrs,
- ident,
- mac: Macro {
- path,
- bang_token,
- delimiter,
- tokens,
- },
- semi_token,
- })
- }
- }
- fn parse_macro2(begin: ParseBuffer, _vis: Visibility, input: ParseStream) -> Result<Item> {
- input.parse::<Token![macro]>()?;
- input.parse::<Ident>()?;
- let mut lookahead = input.lookahead1();
- if lookahead.peek(token::Paren) {
- let paren_content;
- parenthesized!(paren_content in input);
- paren_content.parse::<TokenStream>()?;
- lookahead = input.lookahead1();
- }
- if lookahead.peek(token::Brace) {
- let brace_content;
- braced!(brace_content in input);
- brace_content.parse::<TokenStream>()?;
- } else {
- return Err(lookahead.error());
- }
- Ok(Item::Verbatim(verbatim::between(&begin, input)))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemExternCrate {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ItemExternCrate {
- attrs: input.call(Attribute::parse_outer)?,
- vis: input.parse()?,
- extern_token: input.parse()?,
- crate_token: input.parse()?,
- ident: {
- if input.peek(Token![self]) {
- input.call(Ident::parse_any)?
- } else {
- input.parse()?
- }
- },
- rename: {
- if input.peek(Token![as]) {
- let as_token: Token![as] = input.parse()?;
- let rename: Ident = if input.peek(Token![_]) {
- Ident::from(input.parse::<Token![_]>()?)
- } else {
- input.parse()?
- };
- Some((as_token, rename))
- } else {
- None
- }
- },
- semi_token: input.parse()?,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemUse {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_crate_root_in_path = false;
- parse_item_use(input, allow_crate_root_in_path).map(Option::unwrap)
- }
- }
- fn parse_item_use(
- input: ParseStream,
- allow_crate_root_in_path: bool,
- ) -> Result<Option<ItemUse>> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let use_token: Token![use] = input.parse()?;
- let leading_colon: Option<Token![::]> = input.parse()?;
- let tree = parse_use_tree(input, allow_crate_root_in_path && leading_colon.is_none())?;
- let semi_token: Token![;] = input.parse()?;
- let tree = match tree {
- Some(tree) => tree,
- None => return Ok(None),
- };
- Ok(Some(ItemUse {
- attrs,
- vis,
- use_token,
- leading_colon,
- tree,
- semi_token,
- }))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for UseTree {
- fn parse(input: ParseStream) -> Result<UseTree> {
- let allow_crate_root_in_path = false;
- parse_use_tree(input, allow_crate_root_in_path).map(Option::unwrap)
- }
- }
- fn parse_use_tree(
- input: ParseStream,
- allow_crate_root_in_path: bool,
- ) -> Result<Option<UseTree>> {
- let lookahead = input.lookahead1();
- if lookahead.peek(Ident)
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- || lookahead.peek(Token![try])
- {
- let ident = input.call(Ident::parse_any)?;
- if input.peek(Token![::]) {
- Ok(Some(UseTree::Path(UsePath {
- ident,
- colon2_token: input.parse()?,
- tree: Box::new(input.parse()?),
- })))
- } else if input.peek(Token![as]) {
- Ok(Some(UseTree::Rename(UseRename {
- ident,
- as_token: input.parse()?,
- rename: {
- if input.peek(Ident) {
- input.parse()?
- } else if input.peek(Token![_]) {
- Ident::from(input.parse::<Token![_]>()?)
- } else {
- return Err(input.error("expected identifier or underscore"));
- }
- },
- })))
- } else {
- Ok(Some(UseTree::Name(UseName { ident })))
- }
- } else if lookahead.peek(Token![*]) {
- Ok(Some(UseTree::Glob(UseGlob {
- star_token: input.parse()?,
- })))
- } else if lookahead.peek(token::Brace) {
- let content;
- let brace_token = braced!(content in input);
- let mut items = Punctuated::new();
- let mut has_any_crate_root_in_path = false;
- loop {
- if content.is_empty() {
- break;
- }
- let this_tree_starts_with_crate_root =
- allow_crate_root_in_path && content.parse::<Option<Token![::]>>()?.is_some();
- has_any_crate_root_in_path |= this_tree_starts_with_crate_root;
- match parse_use_tree(
- &content,
- allow_crate_root_in_path && !this_tree_starts_with_crate_root,
- )? {
- Some(tree) if !has_any_crate_root_in_path => items.push_value(tree),
- _ => has_any_crate_root_in_path = true,
- }
- if content.is_empty() {
- break;
- }
- let comma: Token![,] = content.parse()?;
- if !has_any_crate_root_in_path {
- items.push_punct(comma);
- }
- }
- if has_any_crate_root_in_path {
- Ok(None)
- } else {
- Ok(Some(UseTree::Group(UseGroup { brace_token, items })))
- }
- } else {
- Err(lookahead.error())
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemStatic {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ItemStatic {
- attrs: input.call(Attribute::parse_outer)?,
- vis: input.parse()?,
- static_token: input.parse()?,
- mutability: input.parse()?,
- ident: input.parse()?,
- colon_token: input.parse()?,
- ty: input.parse()?,
- eq_token: input.parse()?,
- expr: input.parse()?,
- semi_token: input.parse()?,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemConst {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let const_token: Token![const] = input.parse()?;
- let lookahead = input.lookahead1();
- let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.call(Ident::parse_any)?
- } else {
- return Err(lookahead.error());
- };
- let colon_token: Token![:] = input.parse()?;
- let ty: Type = input.parse()?;
- let eq_token: Token![=] = input.parse()?;
- let expr: Expr = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(ItemConst {
- attrs,
- vis,
- const_token,
- ident,
- generics: Generics::default(),
- colon_token,
- ty: Box::new(ty),
- eq_token,
- expr: Box::new(expr),
- semi_token,
- })
- }
- }
- fn peek_signature(input: ParseStream, allow_safe: bool) -> bool {
- let fork = input.fork();
- fork.parse::<Option<Token![const]>>().is_ok()
- && fork.parse::<Option<Token![async]>>().is_ok()
- && ((allow_safe
- && token::parsing::peek_keyword(fork.cursor(), "safe")
- && token::parsing::keyword(&fork, "safe").is_ok())
- || fork.parse::<Option<Token![unsafe]>>().is_ok())
- && fork.parse::<Option<Abi>>().is_ok()
- && fork.peek(Token![fn])
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for Signature {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_safe = false;
- parse_signature(input, allow_safe).map(Option::unwrap)
- }
- }
- fn parse_signature(input: ParseStream, allow_safe: bool) -> Result<Option<Signature>> {
- let constness: Option<Token![const]> = input.parse()?;
- let asyncness: Option<Token![async]> = input.parse()?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let safe = allow_safe
- && unsafety.is_none()
- && token::parsing::peek_keyword(input.cursor(), "safe");
- if safe {
- token::parsing::keyword(input, "safe")?;
- }
- let abi: Option<Abi> = input.parse()?;
- let fn_token: Token![fn] = input.parse()?;
- let ident: Ident = input.parse()?;
- let mut generics: Generics = input.parse()?;
- let content;
- let paren_token = parenthesized!(content in input);
- let (inputs, variadic) = parse_fn_args(&content)?;
- let output: ReturnType = input.parse()?;
- generics.where_clause = input.parse()?;
- Ok(if safe {
- None
- } else {
- Some(Signature {
- constness,
- asyncness,
- unsafety,
- abi,
- fn_token,
- ident,
- generics,
- paren_token,
- inputs,
- variadic,
- output,
- })
- })
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemFn {
- fn parse(input: ParseStream) -> Result<Self> {
- let outer_attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let sig: Signature = input.parse()?;
- parse_rest_of_fn(input, outer_attrs, vis, sig)
- }
- }
- fn parse_rest_of_fn(
- input: ParseStream,
- mut attrs: Vec<Attribute>,
- vis: Visibility,
- sig: Signature,
- ) -> Result<ItemFn> {
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
- Ok(ItemFn {
- attrs,
- vis,
- sig,
- block: Box::new(Block { brace_token, stmts }),
- })
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for FnArg {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_variadic = false;
- let attrs = input.call(Attribute::parse_outer)?;
- match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? {
- FnArgOrVariadic::FnArg(arg) => Ok(arg),
- FnArgOrVariadic::Variadic(_) => unreachable!(),
- }
- }
- }
- enum FnArgOrVariadic {
- FnArg(FnArg),
- Variadic(Variadic),
- }
- fn parse_fn_arg_or_variadic(
- input: ParseStream,
- attrs: Vec<Attribute>,
- allow_variadic: bool,
- ) -> Result<FnArgOrVariadic> {
- let ahead = input.fork();
- if let Ok(mut receiver) = ahead.parse::<Receiver>() {
- input.advance_to(&ahead);
- receiver.attrs = attrs;
- return Ok(FnArgOrVariadic::FnArg(FnArg::Receiver(receiver)));
- }
- // Hack to parse pre-2018 syntax in
- // test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
- // because the rest of the test case is valuable.
- if input.peek(Ident) && input.peek2(Token![<]) {
- let span = input.span();
- return Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType {
- attrs,
- pat: Box::new(Pat::Wild(PatWild {
- attrs: Vec::new(),
- underscore_token: Token,
- })),
- colon_token: Token,
- ty: input.parse()?,
- })));
- }
- let pat = Box::new(Pat::parse_single(input)?);
- let colon_token: Token![:] = input.parse()?;
- if allow_variadic {
- if let Some(dots) = input.parse::<Option<Token![...]>>()? {
- return Ok(FnArgOrVariadic::Variadic(Variadic {
- attrs,
- pat: Some((pat, colon_token)),
- dots,
- comma: None,
- }));
- }
- }
- Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType {
- attrs,
- pat,
- colon_token,
- ty: input.parse()?,
- })))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for Receiver {
- fn parse(input: ParseStream) -> Result<Self> {
- let reference = if input.peek(Token![&]) {
- let ampersand: Token![&] = input.parse()?;
- let lifetime: Option<Lifetime> = input.parse()?;
- Some((ampersand, lifetime))
- } else {
- None
- };
- let mutability: Option<Token![mut]> = input.parse()?;
- let self_token: Token![self] = input.parse()?;
- let colon_token: Option<Token![:]> = if reference.is_some() {
- None
- } else {
- input.parse()?
- };
- let ty: Type = if colon_token.is_some() {
- input.parse()?
- } else {
- let mut ty = Type::Path(TypePath {
- qself: None,
- path: Path::from(Ident::new("Self", self_token.span)),
- });
- if let Some((ampersand, lifetime)) = reference.as_ref() {
- ty = Type::Reference(TypeReference {
- and_token: Token,
- lifetime: lifetime.clone(),
- mutability: mutability.as_ref().map(|m| Token),
- elem: Box::new(ty),
- });
- }
- ty
- };
- Ok(Receiver {
- attrs: Vec::new(),
- reference,
- mutability,
- self_token,
- colon_token,
- ty: Box::new(ty),
- })
- }
- }
- fn parse_fn_args(
- input: ParseStream,
- ) -> Result<(Punctuated<FnArg, Token![,]>, Option<Variadic>)> {
- let mut args = Punctuated::new();
- let mut variadic = None;
- let mut has_receiver = false;
- while !input.is_empty() {
- let attrs = input.call(Attribute::parse_outer)?;
- if let Some(dots) = input.parse::<Option<Token![...]>>()? {
- variadic = Some(Variadic {
- attrs,
- pat: None,
- dots,
- comma: if input.is_empty() {
- None
- } else {
- Some(input.parse()?)
- },
- });
- break;
- }
- let allow_variadic = true;
- let arg = match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? {
- FnArgOrVariadic::FnArg(arg) => arg,
- FnArgOrVariadic::Variadic(arg) => {
- variadic = Some(Variadic {
- comma: if input.is_empty() {
- None
- } else {
- Some(input.parse()?)
- },
- ..arg
- });
- break;
- }
- };
- match &arg {
- FnArg::Receiver(receiver) if has_receiver => {
- return Err(Error::new(
- receiver.self_token.span,
- "unexpected second method receiver",
- ));
- }
- FnArg::Receiver(receiver) if !args.is_empty() => {
- return Err(Error::new(
- receiver.self_token.span,
- "unexpected method receiver",
- ));
- }
- FnArg::Receiver(_) => has_receiver = true,
- FnArg::Typed(_) => {}
- }
- args.push_value(arg);
- if input.is_empty() {
- break;
- }
- let comma: Token![,] = input.parse()?;
- args.push_punct(comma);
- }
- Ok((args, variadic))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemMod {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let mod_token: Token![mod] = input.parse()?;
- let ident: Ident = if input.peek(Token![try]) {
- input.call(Ident::parse_any)
- } else {
- input.parse()
- }?;
- let lookahead = input.lookahead1();
- if lookahead.peek(Token![;]) {
- Ok(ItemMod {
- attrs,
- vis,
- unsafety,
- mod_token,
- ident,
- content: None,
- semi: Some(input.parse()?),
- })
- } else if lookahead.peek(token::Brace) {
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let mut items = Vec::new();
- while !content.is_empty() {
- items.push(content.parse()?);
- }
- Ok(ItemMod {
- attrs,
- vis,
- unsafety,
- mod_token,
- ident,
- content: Some((brace_token, items)),
- semi: None,
- })
- } else {
- Err(lookahead.error())
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemForeignMod {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let abi: Abi = input.parse()?;
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let mut items = Vec::new();
- while !content.is_empty() {
- items.push(content.parse()?);
- }
- Ok(ItemForeignMod {
- attrs,
- unsafety,
- abi,
- brace_token,
- items,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ForeignItem {
- fn parse(input: ParseStream) -> Result<Self> {
- let begin = input.fork();
- let mut attrs = input.call(Attribute::parse_outer)?;
- let ahead = input.fork();
- let vis: Visibility = ahead.parse()?;
- let lookahead = ahead.lookahead1();
- let allow_safe = true;
- let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) {
- let vis: Visibility = input.parse()?;
- let sig = parse_signature(input, allow_safe)?;
- let has_safe = sig.is_none();
- let has_body = input.peek(token::Brace);
- let semi_token: Option<Token![;]> = if has_body {
- let content;
- braced!(content in input);
- content.call(Attribute::parse_inner)?;
- content.call(Block::parse_within)?;
- None
- } else {
- Some(input.parse()?)
- };
- if has_safe || has_body {
- Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(ForeignItem::Fn(ForeignItemFn {
- attrs: Vec::new(),
- vis,
- sig: sig.unwrap(),
- semi_token: semi_token.unwrap(),
- }))
- }
- } else if lookahead.peek(Token![static])
- || ((ahead.peek(Token![unsafe])
- || token::parsing::peek_keyword(ahead.cursor(), "safe"))
- && ahead.peek2(Token![static]))
- {
- let vis = input.parse()?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let safe =
- unsafety.is_none() && token::parsing::peek_keyword(input.cursor(), "safe");
- if safe {
- token::parsing::keyword(input, "safe")?;
- }
- let static_token = input.parse()?;
- let mutability = input.parse()?;
- let ident = input.parse()?;
- let colon_token = input.parse()?;
- let ty = input.parse()?;
- let has_value = input.peek(Token![=]);
- if has_value {
- input.parse::<Token![=]>()?;
- input.parse::<Expr>()?;
- }
- let semi_token: Token![;] = input.parse()?;
- if unsafety.is_some() || safe || has_value {
- Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(ForeignItem::Static(ForeignItemStatic {
- attrs: Vec::new(),
- vis,
- static_token,
- mutability,
- ident,
- colon_token,
- ty,
- semi_token,
- }))
- }
- } else if lookahead.peek(Token![type]) {
- parse_foreign_item_type(begin, input)
- } else if vis.is_inherited()
- && (lookahead.peek(Ident)
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- || lookahead.peek(Token![::]))
- {
- input.parse().map(ForeignItem::Macro)
- } else {
- Err(lookahead.error())
- }?;
- let item_attrs = match &mut item {
- ForeignItem::Fn(item) => &mut item.attrs,
- ForeignItem::Static(item) => &mut item.attrs,
- ForeignItem::Type(item) => &mut item.attrs,
- ForeignItem::Macro(item) => &mut item.attrs,
- ForeignItem::Verbatim(_) => return Ok(item),
- };
- attrs.append(item_attrs);
- *item_attrs = attrs;
- Ok(item)
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ForeignItemFn {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let sig: Signature = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(ForeignItemFn {
- attrs,
- vis,
- sig,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ForeignItemStatic {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ForeignItemStatic {
- attrs: input.call(Attribute::parse_outer)?,
- vis: input.parse()?,
- static_token: input.parse()?,
- mutability: input.parse()?,
- ident: input.parse()?,
- colon_token: input.parse()?,
- ty: input.parse()?,
- semi_token: input.parse()?,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ForeignItemType {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ForeignItemType {
- attrs: input.call(Attribute::parse_outer)?,
- vis: input.parse()?,
- type_token: input.parse()?,
- ident: input.parse()?,
- generics: {
- let mut generics: Generics = input.parse()?;
- generics.where_clause = input.parse()?;
- generics
- },
- semi_token: input.parse()?,
- })
- }
- }
- fn parse_foreign_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ForeignItem> {
- let FlexibleItemType {
- vis,
- defaultness: _,
- type_token,
- ident,
- generics,
- colon_token,
- bounds: _,
- ty,
- semi_token,
- } = FlexibleItemType::parse(
- input,
- TypeDefaultness::Disallowed,
- WhereClauseLocation::Both,
- )?;
- if colon_token.is_some() || ty.is_some() {
- Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(ForeignItem::Type(ForeignItemType {
- attrs: Vec::new(),
- vis,
- type_token,
- ident,
- generics,
- semi_token,
- }))
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ForeignItemMacro {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let mac: Macro = input.parse()?;
- let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
- None
- } else {
- Some(input.parse()?)
- };
- Ok(ForeignItemMacro {
- attrs,
- mac,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemType {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(ItemType {
- attrs: input.call(Attribute::parse_outer)?,
- vis: input.parse()?,
- type_token: input.parse()?,
- ident: input.parse()?,
- generics: {
- let mut generics: Generics = input.parse()?;
- generics.where_clause = input.parse()?;
- generics
- },
- eq_token: input.parse()?,
- ty: input.parse()?,
- semi_token: input.parse()?,
- })
- }
- }
- fn parse_item_type(begin: ParseBuffer, input: ParseStream) -> Result<Item> {
- let FlexibleItemType {
- vis,
- defaultness: _,
- type_token,
- ident,
- generics,
- colon_token,
- bounds: _,
- ty,
- semi_token,
- } = FlexibleItemType::parse(
- input,
- TypeDefaultness::Disallowed,
- WhereClauseLocation::BeforeEq,
- )?;
- let (eq_token, ty) = match ty {
- Some(ty) if colon_token.is_none() => ty,
- _ => return Ok(Item::Verbatim(verbatim::between(&begin, input))),
- };
- Ok(Item::Type(ItemType {
- attrs: Vec::new(),
- vis,
- type_token,
- ident,
- generics,
- eq_token,
- ty: Box::new(ty),
- semi_token,
- }))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemStruct {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis = input.parse::<Visibility>()?;
- let struct_token = input.parse::<Token![struct]>()?;
- let ident = input.parse::<Ident>()?;
- let generics = input.parse::<Generics>()?;
- let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?;
- Ok(ItemStruct {
- attrs,
- vis,
- struct_token,
- ident,
- generics: Generics {
- where_clause,
- ..generics
- },
- fields,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemEnum {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis = input.parse::<Visibility>()?;
- let enum_token = input.parse::<Token![enum]>()?;
- let ident = input.parse::<Ident>()?;
- let generics = input.parse::<Generics>()?;
- let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?;
- Ok(ItemEnum {
- attrs,
- vis,
- enum_token,
- ident,
- generics: Generics {
- where_clause,
- ..generics
- },
- brace_token,
- variants,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemUnion {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis = input.parse::<Visibility>()?;
- let union_token = input.parse::<Token![union]>()?;
- let ident = input.parse::<Ident>()?;
- let generics = input.parse::<Generics>()?;
- let (where_clause, fields) = derive::parsing::data_union(input)?;
- Ok(ItemUnion {
- attrs,
- vis,
- union_token,
- ident,
- generics: Generics {
- where_clause,
- ..generics
- },
- fields,
- })
- }
- }
- fn parse_trait_or_trait_alias(input: ParseStream) -> Result<Item> {
- let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
- let lookahead = input.lookahead1();
- if lookahead.peek(token::Brace)
- || lookahead.peek(Token![:])
- || lookahead.peek(Token![where])
- {
- let unsafety = None;
- let auto_token = None;
- parse_rest_of_trait(
- input,
- attrs,
- vis,
- unsafety,
- auto_token,
- trait_token,
- ident,
- generics,
- )
- .map(Item::Trait)
- } else if lookahead.peek(Token![=]) {
- parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
- .map(Item::TraitAlias)
- } else {
- Err(lookahead.error())
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemTrait {
- fn parse(input: ParseStream) -> Result<Self> {
- let outer_attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let auto_token: Option<Token![auto]> = input.parse()?;
- let trait_token: Token![trait] = input.parse()?;
- let ident: Ident = input.parse()?;
- let generics: Generics = input.parse()?;
- parse_rest_of_trait(
- input,
- outer_attrs,
- vis,
- unsafety,
- auto_token,
- trait_token,
- ident,
- generics,
- )
- }
- }
- fn parse_rest_of_trait(
- input: ParseStream,
- mut attrs: Vec<Attribute>,
- vis: Visibility,
- unsafety: Option<Token![unsafe]>,
- auto_token: Option<Token![auto]>,
- trait_token: Token![trait],
- ident: Ident,
- mut generics: Generics,
- ) -> Result<ItemTrait> {
- let colon_token: Option<Token![:]> = input.parse()?;
- let mut supertraits = Punctuated::new();
- if colon_token.is_some() {
- loop {
- if input.peek(Token![where]) || input.peek(token::Brace) {
- break;
- }
- supertraits.push_value({
- let allow_precise_capture = false;
- let allow_const = true;
- TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
- });
- if input.peek(Token![where]) || input.peek(token::Brace) {
- break;
- }
- supertraits.push_punct(input.parse()?);
- }
- }
- generics.where_clause = input.parse()?;
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let mut items = Vec::new();
- while !content.is_empty() {
- items.push(content.parse()?);
- }
- Ok(ItemTrait {
- attrs,
- vis,
- unsafety,
- auto_token,
- restriction: None,
- trait_token,
- ident,
- generics,
- colon_token,
- supertraits,
- brace_token,
- items,
- })
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemTraitAlias {
- fn parse(input: ParseStream) -> Result<Self> {
- let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
- parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
- }
- }
- fn parse_start_of_trait_alias(
- input: ParseStream,
- ) -> Result<(Vec<Attribute>, Visibility, Token![trait], Ident, Generics)> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let trait_token: Token![trait] = input.parse()?;
- let ident: Ident = input.parse()?;
- let generics: Generics = input.parse()?;
- Ok((attrs, vis, trait_token, ident, generics))
- }
- fn parse_rest_of_trait_alias(
- input: ParseStream,
- attrs: Vec<Attribute>,
- vis: Visibility,
- trait_token: Token![trait],
- ident: Ident,
- mut generics: Generics,
- ) -> Result<ItemTraitAlias> {
- let eq_token: Token![=] = input.parse()?;
- let mut bounds = Punctuated::new();
- loop {
- if input.peek(Token![where]) || input.peek(Token![;]) {
- break;
- }
- bounds.push_value({
- let allow_precise_capture = false;
- let allow_const = false;
- TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
- });
- if input.peek(Token![where]) || input.peek(Token![;]) {
- break;
- }
- bounds.push_punct(input.parse()?);
- }
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(ItemTraitAlias {
- attrs,
- vis,
- trait_token,
- ident,
- generics,
- eq_token,
- bounds,
- semi_token,
- })
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for TraitItem {
- fn parse(input: ParseStream) -> Result<Self> {
- let begin = input.fork();
- let mut attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let defaultness: Option<Token![default]> = input.parse()?;
- let ahead = input.fork();
- let lookahead = ahead.lookahead1();
- let allow_safe = false;
- let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) {
- input.parse().map(TraitItem::Fn)
- } else if lookahead.peek(Token![const]) {
- let const_token: Token![const] = ahead.parse()?;
- let lookahead = ahead.lookahead1();
- if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.advance_to(&ahead);
- let ident = input.call(Ident::parse_any)?;
- let mut generics: Generics = input.parse()?;
- let colon_token: Token![:] = input.parse()?;
- let ty: Type = input.parse()?;
- let default = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
- let expr: Expr = input.parse()?;
- Some((eq_token, expr))
- } else {
- None
- };
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- if generics.lt_token.is_none() && generics.where_clause.is_none() {
- Ok(TraitItem::Const(TraitItemConst {
- attrs: Vec::new(),
- const_token,
- ident,
- generics,
- colon_token,
- ty,
- default,
- semi_token,
- }))
- } else {
- return Ok(TraitItem::Verbatim(verbatim::between(&begin, input)));
- }
- } else if lookahead.peek(Token![async])
- || lookahead.peek(Token![unsafe])
- || lookahead.peek(Token![extern])
- || lookahead.peek(Token![fn])
- {
- input.parse().map(TraitItem::Fn)
- } else {
- Err(lookahead.error())
- }
- } else if lookahead.peek(Token![type]) {
- parse_trait_item_type(begin.fork(), input)
- } else if vis.is_inherited()
- && defaultness.is_none()
- && (lookahead.peek(Ident)
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- || lookahead.peek(Token![::]))
- {
- input.parse().map(TraitItem::Macro)
- } else {
- Err(lookahead.error())
- }?;
- match (vis, defaultness) {
- (Visibility::Inherited, None) => {}
- _ => return Ok(TraitItem::Verbatim(verbatim::between(&begin, input))),
- }
- let item_attrs = match &mut item {
- TraitItem::Const(item) => &mut item.attrs,
- TraitItem::Fn(item) => &mut item.attrs,
- TraitItem::Type(item) => &mut item.attrs,
- TraitItem::Macro(item) => &mut item.attrs,
- TraitItem::Verbatim(_) => unreachable!(),
- };
- attrs.append(item_attrs);
- *item_attrs = attrs;
- Ok(item)
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for TraitItemConst {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let const_token: Token![const] = input.parse()?;
- let lookahead = input.lookahead1();
- let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.call(Ident::parse_any)?
- } else {
- return Err(lookahead.error());
- };
- let colon_token: Token![:] = input.parse()?;
- let ty: Type = input.parse()?;
- let default = if input.peek(Token![=]) {
- let eq_token: Token![=] = input.parse()?;
- let default: Expr = input.parse()?;
- Some((eq_token, default))
- } else {
- None
- };
- let semi_token: Token![;] = input.parse()?;
- Ok(TraitItemConst {
- attrs,
- const_token,
- ident,
- generics: Generics::default(),
- colon_token,
- ty,
- default,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for TraitItemFn {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let sig: Signature = input.parse()?;
- let lookahead = input.lookahead1();
- let (brace_token, stmts, semi_token) = if lookahead.peek(token::Brace) {
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let stmts = content.call(Block::parse_within)?;
- (Some(brace_token), stmts, None)
- } else if lookahead.peek(Token![;]) {
- let semi_token: Token![;] = input.parse()?;
- (None, Vec::new(), Some(semi_token))
- } else {
- return Err(lookahead.error());
- };
- Ok(TraitItemFn {
- attrs,
- sig,
- default: brace_token.map(|brace_token| Block { brace_token, stmts }),
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for TraitItemType {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let type_token: Token![type] = input.parse()?;
- let ident: Ident = input.parse()?;
- let mut generics: Generics = input.parse()?;
- let (colon_token, bounds) = FlexibleItemType::parse_optional_bounds(input)?;
- let default = FlexibleItemType::parse_optional_definition(input)?;
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(TraitItemType {
- attrs,
- type_token,
- ident,
- generics,
- colon_token,
- bounds,
- default,
- semi_token,
- })
- }
- }
- fn parse_trait_item_type(begin: ParseBuffer, input: ParseStream) -> Result<TraitItem> {
- let FlexibleItemType {
- vis,
- defaultness: _,
- type_token,
- ident,
- generics,
- colon_token,
- bounds,
- ty,
- semi_token,
- } = FlexibleItemType::parse(
- input,
- TypeDefaultness::Disallowed,
- WhereClauseLocation::AfterEq,
- )?;
- if vis.is_some() {
- Ok(TraitItem::Verbatim(verbatim::between(&begin, input)))
- } else {
- Ok(TraitItem::Type(TraitItemType {
- attrs: Vec::new(),
- type_token,
- ident,
- generics,
- colon_token,
- bounds,
- default: ty,
- semi_token,
- }))
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for TraitItemMacro {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let mac: Macro = input.parse()?;
- let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
- None
- } else {
- Some(input.parse()?)
- };
- Ok(TraitItemMacro {
- attrs,
- mac,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ItemImpl {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_verbatim_impl = false;
- parse_impl(input, allow_verbatim_impl).map(Option::unwrap)
- }
- }
- fn parse_impl(input: ParseStream, allow_verbatim_impl: bool) -> Result<Option<ItemImpl>> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let has_visibility = allow_verbatim_impl && input.parse::<Visibility>()?.is_some();
- let defaultness: Option<Token![default]> = input.parse()?;
- let unsafety: Option<Token![unsafe]> = input.parse()?;
- let impl_token: Token![impl] = input.parse()?;
- let has_generics = generics::parsing::choose_generics_over_qpath(input);
- let mut generics: Generics = if has_generics {
- input.parse()?
- } else {
- Generics::default()
- };
- let is_const_impl = allow_verbatim_impl
- && (input.peek(Token![const]) || input.peek(Token![?]) && input.peek2(Token![const]));
- if is_const_impl {
- input.parse::<Option<Token![?]>>()?;
- input.parse::<Token![const]>()?;
- }
- let polarity = if input.peek(Token![!]) && !input.peek2(token::Brace) {
- Some(input.parse::<Token![!]>()?)
- } else {
- None
- };
- #[cfg(not(feature = "printing"))]
- let first_ty_span = input.span();
- let mut first_ty: Type = input.parse()?;
- let self_ty: Type;
- let trait_;
- let is_impl_for = input.peek(Token![for]);
- if is_impl_for {
- let for_token: Token![for] = input.parse()?;
- let mut first_ty_ref = &first_ty;
- while let Type::Group(ty) = first_ty_ref {
- first_ty_ref = &ty.elem;
- }
- if let Type::Path(TypePath { qself: None, .. }) = first_ty_ref {
- while let Type::Group(ty) = first_ty {
- first_ty = *ty.elem;
- }
- if let Type::Path(TypePath { qself: None, path }) = first_ty {
- trait_ = Some((polarity, path, for_token));
- } else {
- unreachable!();
- }
- } else if !allow_verbatim_impl {
- #[cfg(feature = "printing")]
- return Err(Error::new_spanned(first_ty_ref, "expected trait path"));
- #[cfg(not(feature = "printing"))]
- return Err(Error::new(first_ty_span, "expected trait path"));
- } else {
- trait_ = None;
- }
- self_ty = input.parse()?;
- } else if let Some(polarity) = polarity {
- return Err(Error::new(
- polarity.span,
- "inherent impls cannot be negative",
- ));
- } else {
- trait_ = None;
- self_ty = first_ty;
- }
- generics.where_clause = input.parse()?;
- let content;
- let brace_token = braced!(content in input);
- attr::parsing::parse_inner(&content, &mut attrs)?;
- let mut items = Vec::new();
- while !content.is_empty() {
- items.push(content.parse()?);
- }
- if has_visibility || is_const_impl || is_impl_for && trait_.is_none() {
- Ok(None)
- } else {
- Ok(Some(ItemImpl {
- attrs,
- defaultness,
- unsafety,
- impl_token,
- generics,
- trait_,
- self_ty: Box::new(self_ty),
- brace_token,
- items,
- }))
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ImplItem {
- fn parse(input: ParseStream) -> Result<Self> {
- let begin = input.fork();
- let mut attrs = input.call(Attribute::parse_outer)?;
- let ahead = input.fork();
- let vis: Visibility = ahead.parse()?;
- let mut lookahead = ahead.lookahead1();
- let defaultness = if lookahead.peek(Token![default]) && !ahead.peek2(Token![!]) {
- let defaultness: Token![default] = ahead.parse()?;
- lookahead = ahead.lookahead1();
- Some(defaultness)
- } else {
- None
- };
- let allow_safe = false;
- let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) {
- let allow_omitted_body = true;
- if let Some(item) = parse_impl_item_fn(input, allow_omitted_body)? {
- Ok(ImplItem::Fn(item))
- } else {
- Ok(ImplItem::Verbatim(verbatim::between(&begin, input)))
- }
- } else if lookahead.peek(Token![const]) {
- input.advance_to(&ahead);
- let const_token: Token![const] = input.parse()?;
- let lookahead = input.lookahead1();
- let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.call(Ident::parse_any)?
- } else {
- return Err(lookahead.error());
- };
- let mut generics: Generics = input.parse()?;
- let colon_token: Token![:] = input.parse()?;
- let ty: Type = input.parse()?;
- let value = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
- let expr: Expr = input.parse()?;
- Some((eq_token, expr))
- } else {
- None
- };
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- return match value {
- Some((eq_token, expr))
- if generics.lt_token.is_none() && generics.where_clause.is_none() =>
- {
- Ok(ImplItem::Const(ImplItemConst {
- attrs,
- vis,
- defaultness,
- const_token,
- ident,
- generics,
- colon_token,
- ty,
- eq_token,
- expr,
- semi_token,
- }))
- }
- _ => Ok(ImplItem::Verbatim(verbatim::between(&begin, input))),
- };
- } else if lookahead.peek(Token![type]) {
- parse_impl_item_type(begin, input)
- } else if vis.is_inherited()
- && defaultness.is_none()
- && (lookahead.peek(Ident)
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- || lookahead.peek(Token![::]))
- {
- input.parse().map(ImplItem::Macro)
- } else {
- Err(lookahead.error())
- }?;
- {
- let item_attrs = match &mut item {
- ImplItem::Const(item) => &mut item.attrs,
- ImplItem::Fn(item) => &mut item.attrs,
- ImplItem::Type(item) => &mut item.attrs,
- ImplItem::Macro(item) => &mut item.attrs,
- ImplItem::Verbatim(_) => return Ok(item),
- };
- attrs.append(item_attrs);
- *item_attrs = attrs;
- }
- Ok(item)
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ImplItemConst {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let defaultness: Option<Token![default]> = input.parse()?;
- let const_token: Token![const] = input.parse()?;
- let lookahead = input.lookahead1();
- let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
- input.call(Ident::parse_any)?
- } else {
- return Err(lookahead.error());
- };
- let colon_token: Token![:] = input.parse()?;
- let ty: Type = input.parse()?;
- let eq_token: Token![=] = input.parse()?;
- let expr: Expr = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(ImplItemConst {
- attrs,
- vis,
- defaultness,
- const_token,
- ident,
- generics: Generics::default(),
- colon_token,
- ty,
- eq_token,
- expr,
- semi_token,
- })
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ImplItemFn {
- fn parse(input: ParseStream) -> Result<Self> {
- let allow_omitted_body = false;
- parse_impl_item_fn(input, allow_omitted_body).map(Option::unwrap)
- }
- }
- fn parse_impl_item_fn(
- input: ParseStream,
- allow_omitted_body: bool,
- ) -> Result<Option<ImplItemFn>> {
- let mut attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let defaultness: Option<Token![default]> = input.parse()?;
- let sig: Signature = input.parse()?;
- // Accept functions without a body in an impl block because rustc's
- // *parser* does not reject them (the compilation error is emitted later
- // than parsing) and it can be useful for macro DSLs.
- if allow_omitted_body && input.parse::<Option<Token![;]>>()?.is_some() {
- return Ok(None);
- }
- let content;
- let brace_token = braced!(content in input);
- attrs.extend(content.call(Attribute::parse_inner)?);
- let block = Block {
- brace_token,
- stmts: content.call(Block::parse_within)?,
- };
- Ok(Some(ImplItemFn {
- attrs,
- vis,
- defaultness,
- sig,
- block,
- }))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ImplItemType {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let vis: Visibility = input.parse()?;
- let defaultness: Option<Token![default]> = input.parse()?;
- let type_token: Token![type] = input.parse()?;
- let ident: Ident = input.parse()?;
- let mut generics: Generics = input.parse()?;
- let eq_token: Token![=] = input.parse()?;
- let ty: Type = input.parse()?;
- generics.where_clause = input.parse()?;
- let semi_token: Token![;] = input.parse()?;
- Ok(ImplItemType {
- attrs,
- vis,
- defaultness,
- type_token,
- ident,
- generics,
- eq_token,
- ty,
- semi_token,
- })
- }
- }
- fn parse_impl_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ImplItem> {
- let FlexibleItemType {
- vis,
- defaultness,
- type_token,
- ident,
- generics,
- colon_token,
- bounds: _,
- ty,
- semi_token,
- } = FlexibleItemType::parse(
- input,
- TypeDefaultness::Optional,
- WhereClauseLocation::AfterEq,
- )?;
- let (eq_token, ty) = match ty {
- Some(ty) if colon_token.is_none() => ty,
- _ => return Ok(ImplItem::Verbatim(verbatim::between(&begin, input))),
- };
- Ok(ImplItem::Type(ImplItemType {
- attrs: Vec::new(),
- vis,
- defaultness,
- type_token,
- ident,
- generics,
- eq_token,
- ty,
- semi_token,
- }))
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for ImplItemMacro {
- fn parse(input: ParseStream) -> Result<Self> {
- let attrs = input.call(Attribute::parse_outer)?;
- let mac: Macro = input.parse()?;
- let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
- None
- } else {
- Some(input.parse()?)
- };
- Ok(ImplItemMacro {
- attrs,
- mac,
- semi_token,
- })
- }
- }
- impl Visibility {
- fn is_inherited(&self) -> bool {
- match self {
- Visibility::Inherited => true,
- _ => false,
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
- impl Parse for StaticMutability {
- fn parse(input: ParseStream) -> Result<Self> {
- let mut_token: Option<Token![mut]> = input.parse()?;
- Ok(mut_token.map_or(StaticMutability::None, StaticMutability::Mut))
- }
- }
- }
- #[cfg(feature = "printing")]
- mod printing {
- use crate::attr::FilterAttrs;
- use crate::data::Fields;
- use crate::item::{
- ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType, ImplItemConst,
- ImplItemFn, ImplItemMacro, ImplItemType, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
- ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait,
- ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability,
- TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName,
- UsePath, UseRename, Variadic,
- };
- use crate::mac::MacroDelimiter;
- use crate::path;
- use crate::path::printing::PathStyle;
- use crate::print::TokensOrDefault;
- use crate::ty::Type;
- use proc_macro2::TokenStream;
- use quote::{ToTokens, TokenStreamExt};
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemExternCrate {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.extern_token.to_tokens(tokens);
- self.crate_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- if let Some((as_token, rename)) = &self.rename {
- as_token.to_tokens(tokens);
- rename.to_tokens(tokens);
- }
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemUse {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.use_token.to_tokens(tokens);
- self.leading_colon.to_tokens(tokens);
- self.tree.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemStatic {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.static_token.to_tokens(tokens);
- self.mutability.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemConst {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemFn {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.sig.to_tokens(tokens);
- self.block.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&self.block.stmts);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemMod {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.unsafety.to_tokens(tokens);
- self.mod_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- if let Some((brace, items)) = &self.content {
- brace.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(items);
- });
- } else {
- TokensOrDefault(&self.semi).to_tokens(tokens);
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemForeignMod {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.unsafety.to_tokens(tokens);
- self.abi.to_tokens(tokens);
- self.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&self.items);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemType {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemEnum {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.enum_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.brace_token.surround(tokens, |tokens| {
- self.variants.to_tokens(tokens);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemStruct {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.struct_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- match &self.fields {
- Fields::Named(fields) => {
- self.generics.where_clause.to_tokens(tokens);
- fields.to_tokens(tokens);
- }
- Fields::Unnamed(fields) => {
- fields.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- TokensOrDefault(&self.semi_token).to_tokens(tokens);
- }
- Fields::Unit => {
- self.generics.where_clause.to_tokens(tokens);
- TokensOrDefault(&self.semi_token).to_tokens(tokens);
- }
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemUnion {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.union_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.fields.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemTrait {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.unsafety.to_tokens(tokens);
- self.auto_token.to_tokens(tokens);
- self.trait_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- if !self.supertraits.is_empty() {
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- self.supertraits.to_tokens(tokens);
- }
- self.generics.where_clause.to_tokens(tokens);
- self.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&self.items);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemTraitAlias {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.trait_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.bounds.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemImpl {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.defaultness.to_tokens(tokens);
- self.unsafety.to_tokens(tokens);
- self.impl_token.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- if let Some((polarity, path, for_token)) = &self.trait_ {
- polarity.to_tokens(tokens);
- path.to_tokens(tokens);
- for_token.to_tokens(tokens);
- }
- self.self_ty.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&self.items);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ItemMacro {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- path::printing::print_path(tokens, &self.mac.path, PathStyle::Mod);
- self.mac.bang_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- match &self.mac.delimiter {
- MacroDelimiter::Paren(paren) => {
- paren.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
- }
- MacroDelimiter::Brace(brace) => {
- brace.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
- }
- MacroDelimiter::Bracket(bracket) => {
- bracket.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
- }
- }
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for UsePath {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.ident.to_tokens(tokens);
- self.colon2_token.to_tokens(tokens);
- self.tree.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for UseName {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.ident.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for UseRename {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.ident.to_tokens(tokens);
- self.as_token.to_tokens(tokens);
- self.rename.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for UseGlob {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.star_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for UseGroup {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.brace_token.surround(tokens, |tokens| {
- self.items.to_tokens(tokens);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for TraitItemConst {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- if let Some((eq_token, default)) = &self.default {
- eq_token.to_tokens(tokens);
- default.to_tokens(tokens);
- }
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for TraitItemFn {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.sig.to_tokens(tokens);
- match &self.default {
- Some(block) => {
- block.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&block.stmts);
- });
- }
- None => {
- TokensOrDefault(&self.semi_token).to_tokens(tokens);
- }
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for TraitItemType {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- if !self.bounds.is_empty() {
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- self.bounds.to_tokens(tokens);
- }
- if let Some((eq_token, default)) = &self.default {
- eq_token.to_tokens(tokens);
- default.to_tokens(tokens);
- }
- self.generics.where_clause.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for TraitItemMacro {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.mac.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ImplItemConst {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- self.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.expr.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ImplItemFn {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- self.sig.to_tokens(tokens);
- self.block.brace_token.surround(tokens, |tokens| {
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&self.block.stmts);
- });
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ImplItemType {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- self.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.eq_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ImplItemMacro {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.mac.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ForeignItemFn {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.sig.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ForeignItemStatic {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.static_token.to_tokens(tokens);
- self.mutability.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ForeignItemType {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for ForeignItemMacro {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.mac.to_tokens(tokens);
- self.semi_token.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for Signature {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.constness.to_tokens(tokens);
- self.asyncness.to_tokens(tokens);
- self.unsafety.to_tokens(tokens);
- self.abi.to_tokens(tokens);
- self.fn_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- self.generics.to_tokens(tokens);
- self.paren_token.surround(tokens, |tokens| {
- self.inputs.to_tokens(tokens);
- if let Some(variadic) = &self.variadic {
- if !self.inputs.empty_or_trailing() {
- <Token![,]>::default().to_tokens(tokens);
- }
- variadic.to_tokens(tokens);
- }
- });
- self.output.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for Receiver {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- if let Some((ampersand, lifetime)) = &self.reference {
- ampersand.to_tokens(tokens);
- lifetime.to_tokens(tokens);
- }
- self.mutability.to_tokens(tokens);
- self.self_token.to_tokens(tokens);
- if let Some(colon_token) = &self.colon_token {
- colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- } else {
- let consistent = match (&self.reference, &self.mutability, &*self.ty) {
- (Some(_), mutability, Type::Reference(ty)) => {
- mutability.is_some() == ty.mutability.is_some()
- && match &*ty.elem {
- Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self"),
- _ => false,
- }
- }
- (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"),
- _ => false,
- };
- if !consistent {
- <Token![:]>::default().to_tokens(tokens);
- self.ty.to_tokens(tokens);
- }
- }
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for Variadic {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- if let Some((pat, colon)) = &self.pat {
- pat.to_tokens(tokens);
- colon.to_tokens(tokens);
- }
- self.dots.to_tokens(tokens);
- self.comma.to_tokens(tokens);
- }
- }
- #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
- impl ToTokens for StaticMutability {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- match self {
- StaticMutability::None => {}
- StaticMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
- }
- }
- }
- }
|