Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493// 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), } } }}