use super::*;
use derive::{Data, DeriveInput};
use proc_macro2::TokenStream;
use punctuated::Punctuated;
use token::{Brace, Paren};
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
#[cfg(feature = "extra-traits")]
use tt::TokenStreamHelper;
ast_enum_of_structs! {
pub enum Item {
pub ExternCrate(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![;],
}),
pub Use(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![;],
}),
pub Static(ItemStatic {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub static_token: Token![static],
pub mutability: Option<Token![mut]>,
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Box<Type>,
pub eq_token: Token![=],
pub expr: Box<Expr>,
pub semi_token: Token![;],
}),
pub Const(ItemConst {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub const_token: Token![const],
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Box<Type>,
pub eq_token: Token![=],
pub expr: Box<Expr>,
pub semi_token: Token![;],
}),
pub Fn(ItemFn {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub constness: Option<Token![const]>,
pub asyncness: Option<Token![async]>,
pub unsafety: Option<Token![unsafe]>,
pub abi: Option<Abi>,
pub ident: Ident,
pub decl: Box<FnDecl>,
pub block: Box<Block>,
}),
pub Mod(ItemMod {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub mod_token: Token![mod],
pub ident: Ident,
pub content: Option<(token::Brace, Vec<Item>)>,
pub semi: Option<Token![;]>,
}),
pub ForeignMod(ItemForeignMod {
pub attrs: Vec<Attribute>,
pub abi: Abi,
pub brace_token: token::Brace,
pub items: Vec<ForeignItem>,
}),
pub Type(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![;],
}),
pub Existential(ItemExistential {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub existential_token: Token![existential],
pub type_token: Token![type],
pub ident: Ident,
pub generics: Generics,
pub colon_token: Option<Token![:]>,
pub bounds: Punctuated<TypeParamBound, Token![+]>,
pub semi_token: Token![;],
}),
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![;]>,
}),
pub Enum(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![,]>,
}),
pub Union(ItemUnion {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub union_token: Token![union],
pub ident: Ident,
pub generics: Generics,
pub fields: FieldsNamed,
}),
pub Trait(ItemTrait {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub unsafety: Option<Token![unsafe]>,
pub auto_token: Option<Token![auto]>,
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>,
}),
pub TraitAlias(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![;],
}),
pub Impl(ItemImpl {
pub attrs: Vec<Attribute>,
pub defaultness: Option<Token![default]>,
pub unsafety: Option<Token![unsafe]>,
pub impl_token: Token![impl],
pub generics: Generics,
pub trait_: Option<(Option<Token![!]>, Path, Token![for])>,
pub self_ty: Box<Type>,
pub brace_token: token::Brace,
pub items: Vec<ImplItem>,
}),
pub Macro(ItemMacro {
pub attrs: Vec<Attribute>,
pub ident: Option<Ident>,
pub mac: Macro,
pub semi_token: Option<Token![;]>,
}),
pub Macro2(ItemMacro2 #manual_extra_traits {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub macro_token: Token![macro],
pub ident: Ident,
pub paren_token: Paren,
pub args: TokenStream,
pub brace_token: Brace,
pub body: TokenStream,
}),
pub Verbatim(ItemVerbatim #manual_extra_traits {
pub tts: TokenStream,
}),
}
}
#[cfg(feature = "extra-traits")]
impl Eq for ItemMacro2 {}
#[cfg(feature = "extra-traits")]
impl PartialEq for ItemMacro2 {
fn eq(&self, other: &Self) -> bool {
self.attrs == other.attrs
&& self.vis == other.vis
&& self.macro_token == other.macro_token
&& self.ident == other.ident
&& self.paren_token == other.paren_token
&& TokenStreamHelper(&self.args) == TokenStreamHelper(&other.args)
&& self.brace_token == other.brace_token
&& TokenStreamHelper(&self.body) == TokenStreamHelper(&other.body)
}
}
#[cfg(feature = "extra-traits")]
impl Hash for ItemMacro2 {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.attrs.hash(state);
self.vis.hash(state);
self.macro_token.hash(state);
self.ident.hash(state);
self.paren_token.hash(state);
TokenStreamHelper(&self.args).hash(state);
self.brace_token.hash(state);
TokenStreamHelper(&self.body).hash(state);
}
}
#[cfg(feature = "extra-traits")]
impl Eq for ItemVerbatim {}
#[cfg(feature = "extra-traits")]
impl PartialEq for ItemVerbatim {
fn eq(&self, other: &Self) -> bool {
TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
}
}
#[cfg(feature = "extra-traits")]
impl Hash for ItemVerbatim {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
TokenStreamHelper(&self.tts).hash(state);
}
}
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,
}),
}
}
}
ast_enum_of_structs! {
pub enum UseTree {
pub Path(UsePath {
pub ident: Ident,
pub colon2_token: Token![::],
pub tree: Box<UseTree>,
}),
pub Name(UseName {
pub ident: Ident,
}),
pub Rename(UseRename {
pub ident: Ident,
pub as_token: Token![as],
pub rename: Ident,
}),
pub Glob(UseGlob {
pub star_token: Token![*],
}),
pub Group(UseGroup {
pub brace_token: token::Brace,
pub items: Punctuated<UseTree, Token![,]>,
}),
}
}
ast_enum_of_structs! {
pub enum ForeignItem {
pub Fn(ForeignItemFn {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub ident: Ident,
pub decl: Box<FnDecl>,
pub semi_token: Token![;],
}),
pub Static(ForeignItemStatic {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub static_token: Token![static],
pub mutability: Option<Token![mut]>,
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Box<Type>,
pub semi_token: Token![;],
}),
pub Type(ForeignItemType {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub type_token: Token![type],
pub ident: Ident,
pub semi_token: Token![;],
}),
pub Macro(ForeignItemMacro {
pub attrs: Vec<Attribute>,
pub mac: Macro,
pub semi_token: Option<Token![;]>,
}),
pub Verbatim(ForeignItemVerbatim #manual_extra_traits {
pub tts: TokenStream,
}),
}
}
#[cfg(feature = "extra-traits")]
impl Eq for ForeignItemVerbatim {}
#[cfg(feature = "extra-traits")]
impl PartialEq for ForeignItemVerbatim {
fn eq(&self, other: &Self) -> bool {
TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
}
}
#[cfg(feature = "extra-traits")]
impl Hash for ForeignItemVerbatim {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
TokenStreamHelper(&self.tts).hash(state);
}
}
ast_enum_of_structs! {
pub enum TraitItem {
pub Const(TraitItemConst {
pub attrs: Vec<Attribute>,
pub const_token: Token![const],
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Type,
pub default: Option<(Token![=], Expr)>,
pub semi_token: Token![;],
}),
pub Method(TraitItemMethod {
pub attrs: Vec<Attribute>,
pub sig: MethodSig,
pub default: Option<Block>,
pub semi_token: Option<Token![;]>,
}),
pub Type(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![;],
}),
pub Macro(TraitItemMacro {
pub attrs: Vec<Attribute>,
pub mac: Macro,
pub semi_token: Option<Token![;]>,
}),
pub Verbatim(TraitItemVerbatim #manual_extra_traits {
pub tts: TokenStream,
}),
}
}
#[cfg(feature = "extra-traits")]
impl Eq for TraitItemVerbatim {}
#[cfg(feature = "extra-traits")]
impl PartialEq for TraitItemVerbatim {
fn eq(&self, other: &Self) -> bool {
TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
}
}
#[cfg(feature = "extra-traits")]
impl Hash for TraitItemVerbatim {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
TokenStreamHelper(&self.tts).hash(state);
}
}
ast_enum_of_structs! {
pub enum ImplItem {
pub Const(ImplItemConst {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub defaultness: Option<Token![default]>,
pub const_token: Token![const],
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Type,
pub eq_token: Token![=],
pub expr: Expr,
pub semi_token: Token![;],
}),
pub Method(ImplItemMethod {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub defaultness: Option<Token![default]>,
pub sig: MethodSig,
pub block: Block,
}),
pub Type(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![;],
}),
pub Existential(ImplItemExistential {
pub attrs: Vec<Attribute>,
pub existential_token: Token![existential],
pub type_token: Token![type],
pub ident: Ident,
pub generics: Generics,
pub colon_token: Option<Token![:]>,
pub bounds: Punctuated<TypeParamBound, Token![+]>,
pub semi_token: Token![;],
}),
pub Macro(ImplItemMacro {
pub attrs: Vec<Attribute>,
pub mac: Macro,
pub semi_token: Option<Token![;]>,
}),
pub Verbatim(ImplItemVerbatim #manual_extra_traits {
pub tts: TokenStream,
}),
}
}
#[cfg(feature = "extra-traits")]
impl Eq for ImplItemVerbatim {}
#[cfg(feature = "extra-traits")]
impl PartialEq for ImplItemVerbatim {
fn eq(&self, other: &Self) -> bool {
TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
}
}
#[cfg(feature = "extra-traits")]
impl Hash for ImplItemVerbatim {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
TokenStreamHelper(&self.tts).hash(state);
}
}
ast_struct! {
pub struct MethodSig {
pub constness: Option<Token![const]>,
pub asyncness: Option<Token![async]>,
pub unsafety: Option<Token![unsafe]>,
pub abi: Option<Abi>,
pub ident: Ident,
pub decl: FnDecl,
}
}
ast_struct! {
pub struct FnDecl {
pub fn_token: Token![fn],
pub generics: Generics,
pub paren_token: token::Paren,
pub inputs: Punctuated<FnArg, Token![,]>,
pub variadic: Option<Token![...]>,
pub output: ReturnType,
}
}
ast_enum_of_structs! {
pub enum FnArg {
pub SelfRef(ArgSelfRef {
pub and_token: Token![&],
pub lifetime: Option<Lifetime>,
pub mutability: Option<Token![mut]>,
pub self_token: Token![self],
}),
pub SelfValue(ArgSelf {
pub mutability: Option<Token![mut]>,
pub self_token: Token![self],
}),
pub Captured(ArgCaptured {
pub pat: Pat,
pub colon_token: Token![:],
pub ty: Type,
}),
pub Inferred(Pat),
pub Ignored(Type),
}
}
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
use ext::IdentExt;
use parse::{Parse, ParseStream, Result};
use proc_macro2::{Punct, Spacing, TokenTree};
use std::iter::FromIterator;
impl Parse for Item {
fn parse(input: ParseStream) -> Result<Self> {
let mut attrs = input.call(Attribute::parse_outer)?;
let ahead = input.fork();
let vis: Visibility = ahead.parse()?;
let lookahead = ahead.lookahead1();
let mut item = 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![fn]) {
input.parse().map(Item::Fn)
} 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 if lookahead.peek(Token![fn]) {
input.parse().map(Item::Fn)
} else {
Err(lookahead.error())
}
} else {
Err(lookahead.error())
}
} else if lookahead.peek(Token![use]) {
input.parse().map(Item::Use)
} else if lookahead.peek(Token![static]) {
input.parse().map(Item::Static)
} else if lookahead.peek(Token![const]) {
ahead.parse::<Token![const]>()?;
let lookahead = ahead.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.parse().map(Item::Const)
} else if lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![async])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(Item::Fn)
} else {
Err(lookahead.error())
}
} 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]) {
input.parse().map(Item::Impl)
} else if lookahead.peek(Token![async])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(Item::Fn)
} else {
Err(lookahead.error())
}
} else if lookahead.peek(Token![async]) || lookahead.peek(Token![fn]) {
input.parse().map(Item::Fn)
} else if lookahead.peek(Token![mod]) {
input.parse().map(Item::Mod)
} else if lookahead.peek(Token![type]) {
input.parse().map(Item::Type)
} else if lookahead.peek(Token![existential]) {
input.parse().map(Item::Existential)
} 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![!])
{
input.parse().map(Item::Impl)
} else if lookahead.peek(Token![macro]) {
input.parse().map(Item::Macro2)
} else if vis.is_inherited()
&& (lookahead.peek(Ident)
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![crate])
|| lookahead.peek(Token![::]))
{
input.parse().map(Item::Macro)
} else {
Err(lookahead.error())
}?;
{
let item_attrs = match item {
Item::ExternCrate(ref mut item) => &mut item.attrs,
Item::Use(ref mut item) => &mut item.attrs,
Item::Static(ref mut item) => &mut item.attrs,
Item::Const(ref mut item) => &mut item.attrs,
Item::Fn(ref mut item) => &mut item.attrs,
Item::Mod(ref mut item) => &mut item.attrs,
Item::ForeignMod(ref mut item) => &mut item.attrs,
Item::Type(ref mut item) => &mut item.attrs,
Item::Existential(ref mut item) => &mut item.attrs,
Item::Struct(ref mut item) => &mut item.attrs,
Item::Enum(ref mut item) => &mut item.attrs,
Item::Union(ref mut item) => &mut item.attrs,
Item::Trait(ref mut item) => &mut item.attrs,
Item::TraitAlias(ref mut item) => &mut item.attrs,
Item::Impl(ref mut item) => &mut item.attrs,
Item::Macro(ref mut item) => &mut item.attrs,
Item::Macro2(ref mut item) => &mut item.attrs,
Item::Verbatim(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
}
Ok(item)
}
}
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> = input.parse()?;
let (delimiter, tts) = input.call(mac::parse_delimiter)?;
let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
Some(input.parse()?)
} else {
None
};
Ok(ItemMacro {
attrs: attrs,
ident: ident,
mac: Macro {
path: path,
bang_token: bang_token,
delimiter: delimiter,
tts: tts,
},
semi_token: semi_token,
})
}
}
impl Parse for ItemMacro2 {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let macro_token: Token![macro] = input.parse()?;
let ident: Ident = input.parse()?;
let paren_token;
let args;
let brace_token;
let body;
let lookahead = input.lookahead1();
if lookahead.peek(token::Paren) {
let paren_content;
paren_token = parenthesized!(paren_content in input);
args = paren_content.parse()?;
let brace_content;
brace_token = braced!(brace_content in input);
body = brace_content.parse()?;
} else if lookahead.peek(token::Brace) {
paren_token = token::Paren::default();
args = TokenStream::from_iter(vec![
TokenTree::Punct(Punct::new('$', Spacing::Alone)),
TokenTree::Punct(Punct::new('$', Spacing::Alone)),
]);
let brace_content;
brace_token = braced!(brace_content in input);
body = brace_content.parse()?;
} else {
return Err(lookahead.error());
}
Ok(ItemMacro2 {
attrs: attrs,
vis: vis,
macro_token: macro_token,
ident: ident,
paren_token: paren_token,
args: args,
brace_token: brace_token,
body: body,
})
}
}
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 = input.parse()?;
Some((as_token, rename))
} else {
None
}
},
semi_token: input.parse()?,
})
}
}
impl Parse for ItemUse {
fn parse(input: ParseStream) -> Result<Self> {
Ok(ItemUse {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
use_token: input.parse()?,
leading_colon: input.parse()?,
tree: input.parse()?,
semi_token: input.parse()?,
})
}
}
impl Parse for UseTree {
fn parse(input: ParseStream) -> Result<UseTree> {
let lookahead = input.lookahead1();
if lookahead.peek(Ident)
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Token![crate])
|| lookahead.peek(Token![extern])
{
let ident = input.call(Ident::parse_any)?;
if input.peek(Token![::]) {
Ok(UseTree::Path(UsePath {
ident: ident,
colon2_token: input.parse()?,
tree: Box::new(input.parse()?),
}))
} else if input.peek(Token![as]) {
Ok(UseTree::Rename(UseRename {
ident: 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(UseTree::Name(UseName { ident: ident }))
}
} else if lookahead.peek(Token![*]) {
Ok(UseTree::Glob(UseGlob {
star_token: input.parse()?,
}))
} else if lookahead.peek(token::Brace) {
let content;
Ok(UseTree::Group(UseGroup {
brace_token: braced!(content in input),
items: content.parse_terminated(UseTree::parse)?,
}))
} else {
Err(lookahead.error())
}
}
}
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()?,
})
}
}
impl Parse for ItemConst {
fn parse(input: ParseStream) -> Result<Self> {
Ok(ItemConst {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
const_token: input.parse()?,
ident: {
let lookahead = input.lookahead1();
if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
input.call(Ident::parse_any)?
} else {
return Err(lookahead.error());
}
},
colon_token: input.parse()?,
ty: input.parse()?,
eq_token: input.parse()?,
expr: input.parse()?,
semi_token: input.parse()?,
})
}
}
impl Parse for ItemFn {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let constness: Option<Token![const]> = input.parse()?;
let asyncness: Option<Token![async]> = input.parse()?;
let unsafety: Option<Token![unsafe]> = input.parse()?;
let abi: Option<Abi> = input.parse()?;
let fn_token: Token![fn] = input.parse()?;
let ident: Ident = input.parse()?;
let generics: Generics = input.parse()?;
let content;
let paren_token = parenthesized!(content in input);
let inputs = content.parse_terminated(FnArg::parse)?;
let variadic: Option<Token![...]> = match inputs.last() {
Some(punctuated::Pair::End(&FnArg::Captured(ArgCaptured {
ty: Type::Verbatim(TypeVerbatim { ref tts }),
..
}))) => parse2(tts.clone()).ok(),
_ => None,
};
let output: ReturnType = input.parse()?;
let where_clause: Option<WhereClause> = input.parse()?;
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let stmts = content.call(Block::parse_within)?;
Ok(ItemFn {
attrs: private::attrs(outer_attrs, inner_attrs),
vis: vis,
constness: constness,
asyncness: asyncness,
unsafety: unsafety,
abi: abi,
ident: ident,
decl: Box::new(FnDecl {
fn_token: fn_token,
paren_token: paren_token,
inputs: inputs,
output: output,
variadic: variadic,
generics: Generics {
where_clause: where_clause,
..generics
},
}),
block: Box::new(Block {
brace_token: brace_token,
stmts: stmts,
}),
})
}
}
impl Parse for FnArg {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Token![&]) {
let ahead = input.fork();
if ahead.call(arg_self_ref).is_ok() && !ahead.peek(Token![:]) {
return input.call(arg_self_ref).map(FnArg::SelfRef);
}
}
if input.peek(Token![mut]) || input.peek(Token![self]) {
let ahead = input.fork();
if ahead.call(arg_self).is_ok() && !ahead.peek(Token![:]) {
return input.call(arg_self).map(FnArg::SelfValue);
}
}
let ahead = input.fork();
let err = match ahead.call(arg_captured) {
Ok(_) => return input.call(arg_captured).map(FnArg::Captured),
Err(err) => err,
};
let ahead = input.fork();
if ahead.parse::<Type>().is_ok() {
return input.parse().map(FnArg::Ignored);
}
Err(err)
}
}
fn arg_self_ref(input: ParseStream) -> Result<ArgSelfRef> {
Ok(ArgSelfRef {
and_token: input.parse()?,
lifetime: input.parse()?,
mutability: input.parse()?,
self_token: input.parse()?,
})
}
fn arg_self(input: ParseStream) -> Result<ArgSelf> {
Ok(ArgSelf {
mutability: input.parse()?,
self_token: input.parse()?,
})
}
fn arg_captured(input: ParseStream) -> Result<ArgCaptured> {
Ok(ArgCaptured {
pat: input.parse()?,
colon_token: input.parse()?,
ty: match input.parse::<Token![...]>() {
Ok(dot3) => {
let args = vec![
TokenTree::Punct(Punct::new('.', Spacing::Joint)),
TokenTree::Punct(Punct::new('.', Spacing::Joint)),
TokenTree::Punct(Punct::new('.', Spacing::Alone)),
];
let tokens = TokenStream::from_iter(args.into_iter().zip(&dot3.spans).map(
|(mut arg, span)| {
arg.set_span(*span);
arg
},
));
Type::Verbatim(TypeVerbatim { tts: tokens })
}
Err(_) => input.parse()?,
},
})
}
impl Parse for ItemMod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let mod_token: Token![mod] = input.parse()?;
let ident: Ident = input.parse()?;
let lookahead = input.lookahead1();
if lookahead.peek(Token![;]) {
Ok(ItemMod {
attrs: outer_attrs,
vis: vis,
mod_token: mod_token,
ident: ident,
content: None,
semi: Some(input.parse()?),
})
} else if lookahead.peek(token::Brace) {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}
Ok(ItemMod {
attrs: private::attrs(outer_attrs, inner_attrs),
vis: vis,
mod_token: mod_token,
ident: ident,
content: Some((brace_token, items)),
semi: None,
})
} else {
Err(lookahead.error())
}
}
}
impl Parse for ItemForeignMod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let abi: Abi = input.parse()?;
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}
Ok(ItemForeignMod {
attrs: private::attrs(outer_attrs, inner_attrs),
abi: abi,
brace_token: brace_token,
items: items,
})
}
}
impl Parse for ForeignItem {
fn parse(input: ParseStream) -> Result<Self> {
let mut attrs = input.call(Attribute::parse_outer)?;
let ahead = input.fork();
let vis: Visibility = ahead.parse()?;
let lookahead = ahead.lookahead1();
let mut item = if lookahead.peek(Token![fn]) {
input.parse().map(ForeignItem::Fn)
} else if lookahead.peek(Token![static]) {
input.parse().map(ForeignItem::Static)
} else if lookahead.peek(Token![type]) {
input.parse().map(ForeignItem::Type)
} else if vis.is_inherited()
&& (lookahead.peek(Ident)
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![crate])
|| lookahead.peek(Token![::]))
{
input.parse().map(ForeignItem::Macro)
} else {
Err(lookahead.error())
}?;
{
let item_attrs = match item {
ForeignItem::Fn(ref mut item) => &mut item.attrs,
ForeignItem::Static(ref mut item) => &mut item.attrs,
ForeignItem::Type(ref mut item) => &mut item.attrs,
ForeignItem::Macro(ref mut item) => &mut item.attrs,
ForeignItem::Verbatim(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
}
Ok(item)
}
}
impl Parse for ForeignItemFn {
fn parse(input: ParseStream) -> Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let fn_token: Token![fn] = input.parse()?;
let ident: Ident = input.parse()?;
let generics: Generics = input.parse()?;
let content;
let paren_token = parenthesized!(content in input);
let mut inputs = Punctuated::new();
while !content.is_empty() && !content.peek(Token![...]) {
inputs.push_value(content.parse()?);
if content.is_empty() {
break;
}
inputs.push_punct(content.parse()?);
}
let variadic: Option<Token![...]> = if inputs.empty_or_trailing() {
content.parse()?
} else {
None
};
let output: ReturnType = input.parse()?;
let where_clause: Option<WhereClause> = input.parse()?;
let semi_token: Token![;] = input.parse()?;
Ok(ForeignItemFn {
attrs: attrs,
vis: vis,
ident: ident,
decl: Box::new(FnDecl {
fn_token: fn_token,
paren_token: paren_token,
inputs: inputs,
output: output,
variadic: variadic,
generics: Generics {
where_clause: where_clause,
..generics
},
}),
semi_token: semi_token,
})
}
}
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()?,
})
}
}
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()?,
semi_token: input.parse()?,
})
}
}
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: attrs,
mac: mac,
semi_token: semi_token,
})
}
}
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()?,
})
}
}
impl Parse for ItemExistential {
fn parse(input: ParseStream) -> Result<Self> {
Ok(ItemExistential {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
existential_token: input.parse()?,
type_token: input.parse()?,
ident: input.parse()?,
generics: {
let mut generics: Generics = input.parse()?;
generics.where_clause = input.parse()?;
generics
},
colon_token: Some(input.parse()?),
bounds: {
let mut bounds = Punctuated::new();
while !input.peek(Token![;]) {
if !bounds.is_empty() {
bounds.push_punct(input.parse()?);
}
bounds.push_value(input.parse()?);
}
bounds
},
semi_token: input.parse()?,
})
}
}
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: attrs,
vis: vis,
struct_token: struct_token,
ident: ident,
generics: Generics {
where_clause: where_clause,
..generics
},
fields: fields,
semi_token: semi_token,
})
}
}
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: attrs,
vis: vis,
enum_token: enum_token,
ident: ident,
generics: Generics {
where_clause: where_clause,
..generics
},
brace_token: brace_token,
variants: variants,
})
}
}
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: attrs,
vis: vis,
union_token: union_token,
ident: ident,
generics: Generics {
where_clause: where_clause,
..generics
},
fields: 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())
}
}
impl Parse for ItemTrait {
fn parse(input: ParseStream) -> Result<Self> {
let 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,
attrs,
vis,
unsafety,
auto_token,
trait_token,
ident,
generics,
)
}
}
fn parse_rest_of_trait(
input: ParseStream,
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 {
supertraits.push_value(input.parse()?);
if input.peek(Token![where]) || input.peek(token::Brace) {
break;
}
supertraits.push_punct(input.parse()?);
if input.peek(Token![where]) || input.peek(token::Brace) {
break;
}
}
}
generics.where_clause = input.parse()?;
let content;
let brace_token = braced!(content in input);
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}
Ok(ItemTrait {
attrs: attrs,
vis: vis,
unsafety: unsafety,
auto_token: auto_token,
trait_token: trait_token,
ident: ident,
generics: generics,
colon_token: colon_token,
supertraits: supertraits,
brace_token: brace_token,
items: items,
})
}
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(input.parse()?);
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: attrs,
vis: vis,
trait_token: trait_token,
ident: ident,
generics: generics,
eq_token: eq_token,
bounds: bounds,
semi_token: semi_token,
})
}
impl Parse for TraitItem {
fn parse(input: ParseStream) -> Result<Self> {
let mut attrs = input.call(Attribute::parse_outer)?;
let ahead = input.fork();
let lookahead = ahead.lookahead1();
let mut item = if lookahead.peek(Token![const]) {
ahead.parse::<Token![const]>()?;
let lookahead = ahead.lookahead1();
if lookahead.peek(Ident) {
input.parse().map(TraitItem::Const)
} else if lookahead.peek(Token![async])
|| lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(TraitItem::Method)
} else {
Err(lookahead.error())
}
} else if lookahead.peek(Token![async])
|| lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(TraitItem::Method)
} else if lookahead.peek(Token![type]) {
input.parse().map(TraitItem::Type)
} else if lookahead.peek(Ident)
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![crate])
|| lookahead.peek(Token![::])
{
input.parse().map(TraitItem::Macro)
} else {
Err(lookahead.error())
}?;
{
let item_attrs = match item {
TraitItem::Const(ref mut item) => &mut item.attrs,
TraitItem::Method(ref mut item) => &mut item.attrs,
TraitItem::Type(ref mut item) => &mut item.attrs,
TraitItem::Macro(ref mut item) => &mut item.attrs,
TraitItem::Verbatim(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
}
Ok(item)
}
}
impl Parse for TraitItemConst {
fn parse(input: ParseStream) -> Result<Self> {
Ok(TraitItemConst {
attrs: input.call(Attribute::parse_outer)?,
const_token: input.parse()?,
ident: input.parse()?,
colon_token: input.parse()?,
ty: input.parse()?,
default: {
if input.peek(Token![=]) {
let eq_token: Token![=] = input.parse()?;
let default: Expr = input.parse()?;
Some((eq_token, default))
} else {
None
}
},
semi_token: input.parse()?,
})
}
}
impl Parse for TraitItemMethod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let constness: Option<Token![const]> = input.parse()?;
let asyncness: Option<Token![async]> = input.parse()?;
let unsafety: Option<Token![unsafe]> = input.parse()?;
let abi: Option<Abi> = input.parse()?;
let fn_token: Token![fn] = input.parse()?;
let ident: Ident = input.parse()?;
let generics: Generics = input.parse()?;
let content;
let paren_token = parenthesized!(content in input);
let inputs = content.parse_terminated(FnArg::parse)?;
let output: ReturnType = input.parse()?;
let where_clause: Option<WhereClause> = input.parse()?;
let lookahead = input.lookahead1();
let (brace_token, inner_attrs, stmts, semi_token) = if lookahead.peek(token::Brace) {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let stmts = content.call(Block::parse_within)?;
(Some(brace_token), inner_attrs, stmts, None)
} else if lookahead.peek(Token![;]) {
let semi_token: Token![;] = input.parse()?;
(None, Vec::new(), Vec::new(), Some(semi_token))
} else {
return Err(lookahead.error());
};
Ok(TraitItemMethod {
attrs: private::attrs(outer_attrs, inner_attrs),
sig: MethodSig {
constness: constness,
asyncness: asyncness,
unsafety: unsafety,
abi: abi,
ident: ident,
decl: FnDecl {
fn_token: fn_token,
paren_token: paren_token,
inputs: inputs,
output: output,
variadic: None,
generics: Generics {
where_clause: where_clause,
..generics
},
},
},
default: brace_token.map(|brace_token| Block {
brace_token: brace_token,
stmts: stmts,
}),
semi_token: semi_token,
})
}
}
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: Option<Token![:]> = input.parse()?;
let mut bounds = Punctuated::new();
if colon_token.is_some() {
while !input.peek(Token![where]) && !input.peek(Token![=]) && !input.peek(Token![;])
{
if !bounds.is_empty() {
bounds.push_punct(input.parse()?);
}
bounds.push_value(input.parse()?);
}
}
generics.where_clause = input.parse()?;
let default = if input.peek(Token![=]) {
let eq_token: Token![=] = input.parse()?;
let default: Type = input.parse()?;
Some((eq_token, default))
} else {
None
};
let semi_token: Token![;] = input.parse()?;
Ok(TraitItemType {
attrs: attrs,
type_token: type_token,
ident: ident,
generics: generics,
colon_token: colon_token,
bounds: bounds,
default: default,
semi_token: semi_token,
})
}
}
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: attrs,
mac: mac,
semi_token: semi_token,
})
}
}
impl Parse for ItemImpl {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let defaultness: Option<Token![default]> = input.parse()?;
let unsafety: Option<Token![unsafe]> = input.parse()?;
let impl_token: Token![impl] = input.parse()?;
let has_generics = input.peek(Token![<])
&& (input.peek2(Token![>])
|| input.peek2(Token![#])
|| (input.peek2(Ident) || input.peek2(Lifetime))
&& (input.peek3(Token![:])
|| input.peek3(Token![,])
|| input.peek3(Token![>])));
let generics: Generics = if has_generics {
input.parse()?
} else {
Generics::default()
};
let trait_ = {
let ahead = input.fork();
if ahead.parse::<Option<Token![!]>>().is_ok()
&& ahead.parse::<Path>().is_ok()
&& ahead.parse::<Token![for]>().is_ok()
{
let polarity: Option<Token![!]> = input.parse()?;
let path: Path = input.parse()?;
let for_token: Token![for] = input.parse()?;
Some((polarity, path, for_token))
} else {
None
}
};
let self_ty: Type = input.parse()?;
let where_clause: Option<WhereClause> = input.parse()?;
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}
Ok(ItemImpl {
attrs: private::attrs(outer_attrs, inner_attrs),
defaultness: defaultness,
unsafety: unsafety,
impl_token: impl_token,
generics: Generics {
where_clause: where_clause,
..generics
},
trait_: trait_,
self_ty: Box::new(self_ty),
brace_token: brace_token,
items: items,
})
}
}
impl Parse for ImplItem {
fn parse(input: ParseStream) -> Result<Self> {
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 mut item = if lookahead.peek(Token![const]) {
ahead.parse::<Token![const]>()?;
let lookahead = ahead.lookahead1();
if lookahead.peek(Ident) {
input.parse().map(ImplItem::Const)
} else if lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![async])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(ImplItem::Method)
} else {
Err(lookahead.error())
}
} else if lookahead.peek(Token![unsafe])
|| lookahead.peek(Token![async])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![fn])
{
input.parse().map(ImplItem::Method)
} else if lookahead.peek(Token![type]) {
input.parse().map(ImplItem::Type)
} else if vis.is_inherited()
&& defaultness.is_none()
&& lookahead.peek(Token![existential])
{
input.parse().map(ImplItem::Existential)
} else if vis.is_inherited()
&& defaultness.is_none()
&& (lookahead.peek(Ident)
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Token![extern])
|| lookahead.peek(Token![crate])
|| lookahead.peek(Token![::]))
{
input.parse().map(ImplItem::Macro)
} else {
Err(lookahead.error())
}?;
{
let item_attrs = match item {
ImplItem::Const(ref mut item) => &mut item.attrs,
ImplItem::Method(ref mut item) => &mut item.attrs,
ImplItem::Type(ref mut item) => &mut item.attrs,
ImplItem::Existential(ref mut item) => &mut item.attrs,
ImplItem::Macro(ref mut item) => &mut item.attrs,
ImplItem::Verbatim(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
}
Ok(item)
}
}
impl Parse for ImplItemConst {
fn parse(input: ParseStream) -> Result<Self> {
Ok(ImplItemConst {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
defaultness: input.parse()?,
const_token: input.parse()?,
ident: input.parse()?,
colon_token: input.parse()?,
ty: input.parse()?,
eq_token: input.parse()?,
expr: input.parse()?,
semi_token: input.parse()?,
})
}
}
impl Parse for ImplItemMethod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let defaultness: Option<Token![default]> = input.parse()?;
let constness: Option<Token![const]> = input.parse()?;
let asyncness: Option<Token![async]> = input.parse()?;
let unsafety: Option<Token![unsafe]> = input.parse()?;
let abi: Option<Abi> = input.parse()?;
let fn_token: Token![fn] = input.parse()?;
let ident: Ident = input.parse()?;
let generics: Generics = input.parse()?;
let content;
let paren_token = parenthesized!(content in input);
let inputs = content.parse_terminated(FnArg::parse)?;
let output: ReturnType = input.parse()?;
let where_clause: Option<WhereClause> = input.parse()?;
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let stmts = content.call(Block::parse_within)?;
Ok(ImplItemMethod {
attrs: private::attrs(outer_attrs, inner_attrs),
vis: vis,
defaultness: defaultness,
sig: MethodSig {
constness: constness,
asyncness: asyncness,
unsafety: unsafety,
abi: abi,
ident: ident,
decl: FnDecl {
fn_token: fn_token,
paren_token: paren_token,
inputs: inputs,
output: output,
variadic: None,
generics: Generics {
where_clause: where_clause,
..generics
},
},
},
block: Block {
brace_token: brace_token,
stmts: stmts,
},
})
}
}
impl Parse for ImplItemType {
fn parse(input: ParseStream) -> Result<Self> {
Ok(ImplItemType {
attrs: input.call(Attribute::parse_outer)?,
vis: input.parse()?,
defaultness: 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()?,
})
}
}
impl Parse for ImplItemExistential {
fn parse(input: ParseStream) -> Result<Self> {
let ety: ItemExistential = input.parse()?;
Ok(ImplItemExistential {
attrs: ety.attrs,
existential_token: ety.existential_token,
type_token: ety.type_token,
ident: ety.ident,
generics: ety.generics,
colon_token: ety.colon_token,
bounds: ety.bounds,
semi_token: ety.semi_token,
})
}
}
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: attrs,
mac: mac,
semi_token: semi_token,
})
}
}
impl Visibility {
fn is_inherited(&self) -> bool {
match *self {
Visibility::Inherited => true,
_ => false,
}
}
}
impl MacroDelimiter {
fn is_brace(&self) -> bool {
match *self {
MacroDelimiter::Brace(_) => true,
MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
}
}
}
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
use proc_macro2::TokenStream;
use quote::{ToTokens, TokenStreamExt};
use attr::FilterAttrs;
use print::TokensOrDefault;
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((ref as_token, ref rename)) = self.rename {
as_token.to_tokens(tokens);
rename.to_tokens(tokens);
}
self.semi_token.to_tokens(tokens);
}
}
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);
}
}
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);
}
}
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);
}
}
impl ToTokens for ItemFn {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.vis.to_tokens(tokens);
self.constness.to_tokens(tokens);
self.asyncness.to_tokens(tokens);
self.unsafety.to_tokens(tokens);
self.abi.to_tokens(tokens);
NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
self.block.brace_token.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(&self.block.stmts);
});
}
}
impl ToTokens for ItemMod {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.vis.to_tokens(tokens);
self.mod_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
if let Some((ref brace, ref items)) = self.content {
brace.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(items);
});
} else {
TokensOrDefault(&self.semi).to_tokens(tokens);
}
}
}
impl ToTokens for ItemForeignMod {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.abi.to_tokens(tokens);
self.brace_token.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(&self.items);
});
}
}
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);
}
}
impl ToTokens for ItemExistential {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.vis.to_tokens(tokens);
self.existential_token.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);
if !self.bounds.is_empty() {
TokensOrDefault(&self.colon_token).to_tokens(tokens);
self.bounds.to_tokens(tokens);
}
self.semi_token.to_tokens(tokens);
}
}
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);
});
}
}
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(ref fields) => {
self.generics.where_clause.to_tokens(tokens);
fields.to_tokens(tokens);
}
Fields::Unnamed(ref 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);
}
}
}
}
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);
}
}
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.items);
});
}
}
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);
}
}
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((ref polarity, ref path, ref 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);
});
}
}
impl ToTokens for ItemMacro {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.mac.path.to_tokens(tokens);
self.mac.bang_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
match self.mac.delimiter {
MacroDelimiter::Paren(ref paren) => {
paren.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
}
MacroDelimiter::Brace(ref brace) => {
brace.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
}
MacroDelimiter::Bracket(ref bracket) => {
bracket.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
}
}
self.semi_token.to_tokens(tokens);
}
}
impl ToTokens for ItemMacro2 {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.vis.to_tokens(tokens);
self.macro_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
if self.args.to_string() != "$ $" {
self.paren_token.surround(tokens, |tokens| {
self.args.to_tokens(tokens);
});
}
self.brace_token.surround(tokens, |tokens| {
self.body.to_tokens(tokens);
});
}
}
impl ToTokens for ItemVerbatim {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.tts.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for UseName {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.ident.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for UseGlob {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.star_token.to_tokens(tokens);
}
}
impl ToTokens for UseGroup {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.brace_token.surround(tokens, |tokens| {
self.items.to_tokens(tokens);
});
}
}
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((ref eq_token, ref default)) = self.default {
eq_token.to_tokens(tokens);
default.to_tokens(tokens);
}
self.semi_token.to_tokens(tokens);
}
}
impl ToTokens for TraitItemMethod {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.sig.to_tokens(tokens);
match self.default {
Some(ref 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);
}
}
}
}
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);
}
self.generics.where_clause.to_tokens(tokens);
if let Some((ref eq_token, ref default)) = self.default {
eq_token.to_tokens(tokens);
default.to_tokens(tokens);
}
self.semi_token.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for TraitItemVerbatim {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.tts.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for ImplItemMethod {
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);
});
}
}
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.generics.where_clause.to_tokens(tokens);
self.eq_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}
impl ToTokens for ImplItemExistential {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.existential_token.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);
if !self.bounds.is_empty() {
TokensOrDefault(&self.colon_token).to_tokens(tokens);
self.bounds.to_tokens(tokens);
}
self.semi_token.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for ImplItemVerbatim {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.tts.to_tokens(tokens);
}
}
impl ToTokens for ForeignItemFn {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.vis.to_tokens(tokens);
NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
}
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);
}
}
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.semi_token.to_tokens(tokens);
}
}
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);
}
}
impl ToTokens for ForeignItemVerbatim {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.tts.to_tokens(tokens);
}
}
impl ToTokens for MethodSig {
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);
NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
}
}
struct NamedDecl<'a>(&'a FnDecl, &'a Ident);
impl<'a> ToTokens for NamedDecl<'a> {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.0.fn_token.to_tokens(tokens);
self.1.to_tokens(tokens);
self.0.generics.to_tokens(tokens);
self.0.paren_token.surround(tokens, |tokens| {
self.0.inputs.to_tokens(tokens);
if self.0.variadic.is_some() && !self.0.inputs.empty_or_trailing() {
<Token![,]>::default().to_tokens(tokens);
}
self.0.variadic.to_tokens(tokens);
});
self.0.output.to_tokens(tokens);
self.0.generics.where_clause.to_tokens(tokens);
}
}
impl ToTokens for ArgSelfRef {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.and_token.to_tokens(tokens);
self.lifetime.to_tokens(tokens);
self.mutability.to_tokens(tokens);
self.self_token.to_tokens(tokens);
}
}
impl ToTokens for ArgSelf {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.mutability.to_tokens(tokens);
self.self_token.to_tokens(tokens);
}
}
impl ToTokens for ArgCaptured {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.pat.to_tokens(tokens);
self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
}