standalone_syn/
item.rs

1// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use super::*;
10use derive::{Data, DeriveInput};
11use punctuated::Punctuated;
12use proc_macro2::TokenStream;
13use token::{Brace, Paren};
14
15#[cfg(feature = "extra-traits")]
16use tt::TokenStreamHelper;
17#[cfg(feature = "extra-traits")]
18use std::hash::{Hash, Hasher};
19
20ast_enum_of_structs! {
21    /// Things that can appear directly inside of a module or scope.
22    ///
23    /// *This type is available if Syn is built with the `"full"` feature.*
24    ///
25    /// # Syntax tree enum
26    ///
27    /// This type is a [syntax tree enum].
28    ///
29    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
30    pub enum Item {
31        /// An `extern crate` item: `extern crate serde`.
32        ///
33        /// *This type is available if Syn is built with the `"full"` feature.*
34        pub ExternCrate(ItemExternCrate {
35            pub attrs: Vec<Attribute>,
36            pub vis: Visibility,
37            pub extern_token: Token![extern],
38            pub crate_token: Token![crate],
39            pub ident: Ident,
40            pub rename: Option<(Token![as], Ident)>,
41            pub semi_token: Token![;],
42        }),
43
44        /// A use declaration: `use std::collections::HashMap`.
45        ///
46        /// *This type is available if Syn is built with the `"full"` feature.*
47        pub Use(ItemUse {
48            pub attrs: Vec<Attribute>,
49            pub vis: Visibility,
50            pub use_token: Token![use],
51            pub leading_colon: Option<Token![::]>,
52            pub prefix: Punctuated<Ident, Token![::]>,
53            pub tree: UseTree,
54            pub semi_token: Token![;],
55        }),
56
57        /// A static item: `static BIKE: Shed = Shed(42)`.
58        ///
59        /// *This type is available if Syn is built with the `"full"` feature.*
60        pub Static(ItemStatic {
61            pub attrs: Vec<Attribute>,
62            pub vis: Visibility,
63            pub static_token: Token![static],
64            pub mutability: Option<Token![mut]>,
65            pub ident: Ident,
66            pub colon_token: Token![:],
67            pub ty: Box<Type>,
68            pub eq_token: Token![=],
69            pub expr: Box<Expr>,
70            pub semi_token: Token![;],
71        }),
72
73        /// A constant item: `const MAX: u16 = 65535`.
74        ///
75        /// *This type is available if Syn is built with the `"full"` feature.*
76        pub Const(ItemConst {
77            pub attrs: Vec<Attribute>,
78            pub vis: Visibility,
79            pub const_token: Token![const],
80            pub ident: Ident,
81            pub colon_token: Token![:],
82            pub ty: Box<Type>,
83            pub eq_token: Token![=],
84            pub expr: Box<Expr>,
85            pub semi_token: Token![;],
86        }),
87
88        /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
89        /// }`.
90        ///
91        /// *This type is available if Syn is built with the `"full"` feature.*
92        pub Fn(ItemFn {
93            pub attrs: Vec<Attribute>,
94            pub vis: Visibility,
95            pub constness: Option<Token![const]>,
96            pub unsafety: Option<Token![unsafe]>,
97            pub abi: Option<Abi>,
98            pub ident: Ident,
99            pub decl: Box<FnDecl>,
100            pub block: Box<Block>,
101        }),
102
103        /// A module or module declaration: `mod m` or `mod m { ... }`.
104        ///
105        /// *This type is available if Syn is built with the `"full"` feature.*
106        pub Mod(ItemMod {
107            pub attrs: Vec<Attribute>,
108            pub vis: Visibility,
109            pub mod_token: Token![mod],
110            pub ident: Ident,
111            pub content: Option<(token::Brace, Vec<Item>)>,
112            pub semi: Option<Token![;]>,
113        }),
114
115        /// A block of foreign items: `extern "C" { ... }`.
116        ///
117        /// *This type is available if Syn is built with the `"full"` feature.*
118        pub ForeignMod(ItemForeignMod {
119            pub attrs: Vec<Attribute>,
120            pub abi: Abi,
121            pub brace_token: token::Brace,
122            pub items: Vec<ForeignItem>,
123        }),
124
125        /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
126        ///
127        /// *This type is available if Syn is built with the `"full"` feature.*
128        pub Type(ItemType {
129            pub attrs: Vec<Attribute>,
130            pub vis: Visibility,
131            pub type_token: Token![type],
132            pub ident: Ident,
133            pub generics: Generics,
134            pub eq_token: Token![=],
135            pub ty: Box<Type>,
136            pub semi_token: Token![;],
137        }),
138
139        /// A struct definition: `struct Foo<A> { x: A }`.
140        ///
141        /// *This type is available if Syn is built with the `"full"` feature.*
142        pub Struct(ItemStruct {
143            pub attrs: Vec<Attribute>,
144            pub vis: Visibility,
145            pub struct_token: Token![struct],
146            pub ident: Ident,
147            pub generics: Generics,
148            pub fields: Fields,
149            pub semi_token: Option<Token![;]>,
150        }),
151
152        /// An enum definition: `enum Foo<A, B> { C<A>, D<B> }`.
153        ///
154        /// *This type is available if Syn is built with the `"full"` feature.*
155        pub Enum(ItemEnum {
156            pub attrs: Vec<Attribute>,
157            pub vis: Visibility,
158            pub enum_token: Token![enum],
159            pub ident: Ident,
160            pub generics: Generics,
161            pub brace_token: token::Brace,
162            pub variants: Punctuated<Variant, Token![,]>,
163        }),
164
165        /// A union definition: `union Foo<A, B> { x: A, y: B }`.
166        ///
167        /// *This type is available if Syn is built with the `"full"` feature.*
168        pub Union(ItemUnion {
169            pub attrs: Vec<Attribute>,
170            pub vis: Visibility,
171            pub union_token: Token![union],
172            pub ident: Ident,
173            pub generics: Generics,
174            pub fields: FieldsNamed,
175        }),
176
177        /// A trait definition: `pub trait Iterator { ... }`.
178        ///
179        /// *This type is available if Syn is built with the `"full"` feature.*
180        pub Trait(ItemTrait {
181            pub attrs: Vec<Attribute>,
182            pub vis: Visibility,
183            pub unsafety: Option<Token![unsafe]>,
184            pub auto_token: Option<Token![auto]>,
185            pub trait_token: Token![trait],
186            pub ident: Ident,
187            pub generics: Generics,
188            pub colon_token: Option<Token![:]>,
189            pub supertraits: Punctuated<TypeParamBound, Token![+]>,
190            pub brace_token: token::Brace,
191            pub items: Vec<TraitItem>,
192        }),
193
194        /// An impl block providing trait or associated items: `impl<A> Trait
195        /// for Data<A> { ... }`.
196        ///
197        /// *This type is available if Syn is built with the `"full"` feature.*
198        pub Impl(ItemImpl {
199            pub attrs: Vec<Attribute>,
200            pub defaultness: Option<Token![default]>,
201            pub unsafety: Option<Token![unsafe]>,
202            pub impl_token: Token![impl],
203            pub generics: Generics,
204            /// Trait this impl implements.
205            pub trait_: Option<(Option<Token![!]>, Path, Token![for])>,
206            /// The Self type of the impl.
207            pub self_ty: Box<Type>,
208            pub brace_token: token::Brace,
209            pub items: Vec<ImplItem>,
210        }),
211
212        /// A macro invocation, which includes `macro_rules!` definitions.
213        ///
214        /// *This type is available if Syn is built with the `"full"` feature.*
215        pub Macro(ItemMacro {
216            pub attrs: Vec<Attribute>,
217            /// The `example` in `macro_rules! example { ... }`.
218            pub ident: Option<Ident>,
219            pub mac: Macro,
220            pub semi_token: Option<Token![;]>,
221        }),
222
223        /// A 2.0-style declarative macro introduced by the `macro` keyword.
224        ///
225        /// *This type is available if Syn is built with the `"full"` feature.*
226        pub Macro2(ItemMacro2 #manual_extra_traits {
227            pub attrs: Vec<Attribute>,
228            pub vis: Visibility,
229            pub macro_token: Token![macro],
230            pub ident: Ident,
231            pub paren_token: Paren,
232            pub args: TokenStream,
233            pub brace_token: Brace,
234            pub body: TokenStream,
235        }),
236
237        /// Tokens forming an item not interpreted by Syn.
238        ///
239        /// *This type is available if Syn is built with the `"full"` feature.*
240        pub Verbatim(ItemVerbatim #manual_extra_traits {
241            pub tts: TokenStream,
242        }),
243    }
244}
245
246#[cfg(feature = "extra-traits")]
247impl Eq for ItemMacro2 {}
248
249#[cfg(feature = "extra-traits")]
250impl PartialEq for ItemMacro2 {
251    fn eq(&self, other: &Self) -> bool {
252        self.attrs == other.attrs && self.vis == other.vis && self.macro_token == other.macro_token
253            && self.ident == other.ident && self.paren_token == other.paren_token
254            && TokenStreamHelper(&self.args) == TokenStreamHelper(&other.args)
255            && self.brace_token == other.brace_token
256            && TokenStreamHelper(&self.body) == TokenStreamHelper(&other.body)
257    }
258}
259
260#[cfg(feature = "extra-traits")]
261impl Hash for ItemMacro2 {
262    fn hash<H>(&self, state: &mut H)
263    where
264        H: Hasher,
265    {
266        self.attrs.hash(state);
267        self.vis.hash(state);
268        self.macro_token.hash(state);
269        self.ident.hash(state);
270        self.paren_token.hash(state);
271        TokenStreamHelper(&self.args).hash(state);
272        self.brace_token.hash(state);
273        TokenStreamHelper(&self.body).hash(state);
274    }
275}
276
277#[cfg(feature = "extra-traits")]
278impl Eq for ItemVerbatim {}
279
280#[cfg(feature = "extra-traits")]
281impl PartialEq for ItemVerbatim {
282    fn eq(&self, other: &Self) -> bool {
283        TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
284    }
285}
286
287#[cfg(feature = "extra-traits")]
288impl Hash for ItemVerbatim {
289    fn hash<H>(&self, state: &mut H)
290    where
291        H: Hasher,
292    {
293        TokenStreamHelper(&self.tts).hash(state);
294    }
295}
296
297impl From<DeriveInput> for Item {
298    fn from(input: DeriveInput) -> Item {
299        match input.data {
300            Data::Struct(data) => Item::Struct(ItemStruct {
301                attrs: input.attrs,
302                vis: input.vis,
303                struct_token: data.struct_token,
304                ident: input.ident,
305                generics: input.generics,
306                fields: data.fields,
307                semi_token: data.semi_token,
308            }),
309            Data::Enum(data) => Item::Enum(ItemEnum {
310                attrs: input.attrs,
311                vis: input.vis,
312                enum_token: data.enum_token,
313                ident: input.ident,
314                generics: input.generics,
315                brace_token: data.brace_token,
316                variants: data.variants,
317            }),
318            Data::Union(data) => Item::Union(ItemUnion {
319                attrs: input.attrs,
320                vis: input.vis,
321                union_token: data.union_token,
322                ident: input.ident,
323                generics: input.generics,
324                fields: data.fields,
325            }),
326        }
327    }
328}
329
330ast_enum_of_structs! {
331    /// A suffix of an import tree in a `use` item: `Type as Renamed` or `*`.
332    ///
333    /// *This type is available if Syn is built with the `"full"` feature.*
334    ///
335    /// # Syntax tree enum
336    ///
337    /// This type is a [syntax tree enum].
338    ///
339    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
340    pub enum UseTree {
341        /// An identifier imported by a `use` item: `Type` or `Type as Renamed`.
342        ///
343        /// *This type is available if Syn is built with the `"full"` feature.*
344        pub Path(UsePath {
345            pub ident: Ident,
346            pub rename: Option<(Token![as], Ident)>,
347        }),
348
349        /// A glob import in a `use` item: `*`.
350        ///
351        /// *This type is available if Syn is built with the `"full"` feature.*
352        pub Glob(UseGlob {
353            pub star_token: Token![*],
354        }),
355
356        /// A braced list of imports in a `use` item: `{A, B, C}`.
357        ///
358        /// *This type is available if Syn is built with the `"full"` feature.*
359        pub List(UseList {
360            pub brace_token: token::Brace,
361            pub items: Punctuated<UseTree, Token![,]>,
362        }),
363    }
364}
365
366ast_enum_of_structs! {
367    /// An item within an `extern` block.
368    ///
369    /// *This type is available if Syn is built with the `"full"` feature.*
370    ///
371    /// # Syntax tree enum
372    ///
373    /// This type is a [syntax tree enum].
374    ///
375    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
376    pub enum ForeignItem {
377        /// A foreign function in an `extern` block.
378        ///
379        /// *This type is available if Syn is built with the `"full"` feature.*
380        pub Fn(ForeignItemFn {
381            pub attrs: Vec<Attribute>,
382            pub vis: Visibility,
383            pub ident: Ident,
384            pub decl: Box<FnDecl>,
385            pub semi_token: Token![;],
386        }),
387
388        /// A foreign static item in an `extern` block: `static ext: u8`.
389        ///
390        /// *This type is available if Syn is built with the `"full"` feature.*
391        pub Static(ForeignItemStatic {
392            pub attrs: Vec<Attribute>,
393            pub vis: Visibility,
394            pub static_token: Token![static],
395            pub mutability: Option<Token![mut]>,
396            pub ident: Ident,
397            pub colon_token: Token![:],
398            pub ty: Box<Type>,
399            pub semi_token: Token![;],
400        }),
401
402        /// A foreign type in an `extern` block: `type void`.
403        ///
404        /// *This type is available if Syn is built with the `"full"` feature.*
405        pub Type(ForeignItemType {
406            pub attrs: Vec<Attribute>,
407            pub vis: Visibility,
408            pub type_token: Token![type],
409            pub ident: Ident,
410            pub semi_token: Token![;],
411        }),
412
413        /// Tokens in an `extern` block not interpreted by Syn.
414        ///
415        /// *This type is available if Syn is built with the `"full"` feature.*
416        pub Verbatim(ForeignItemVerbatim #manual_extra_traits {
417            pub tts: TokenStream,
418        }),
419    }
420}
421
422#[cfg(feature = "extra-traits")]
423impl Eq for ForeignItemVerbatim {}
424
425#[cfg(feature = "extra-traits")]
426impl PartialEq for ForeignItemVerbatim {
427    fn eq(&self, other: &Self) -> bool {
428        TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
429    }
430}
431
432#[cfg(feature = "extra-traits")]
433impl Hash for ForeignItemVerbatim {
434    fn hash<H>(&self, state: &mut H)
435    where
436        H: Hasher,
437    {
438        TokenStreamHelper(&self.tts).hash(state);
439    }
440}
441
442ast_enum_of_structs! {
443    /// An item declaration within the definition of a trait.
444    ///
445    /// *This type is available if Syn is built with the `"full"` feature.*
446    ///
447    /// # Syntax tree enum
448    ///
449    /// This type is a [syntax tree enum].
450    ///
451    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
452    pub enum TraitItem {
453        /// An associated constant within the definition of a trait.
454        ///
455        /// *This type is available if Syn is built with the `"full"` feature.*
456        pub Const(TraitItemConst {
457            pub attrs: Vec<Attribute>,
458            pub const_token: Token![const],
459            pub ident: Ident,
460            pub colon_token: Token![:],
461            pub ty: Type,
462            pub default: Option<(Token![=], Expr)>,
463            pub semi_token: Token![;],
464        }),
465
466        /// A trait method within the definition of a trait.
467        ///
468        /// *This type is available if Syn is built with the `"full"` feature.*
469        pub Method(TraitItemMethod {
470            pub attrs: Vec<Attribute>,
471            pub sig: MethodSig,
472            pub default: Option<Block>,
473            pub semi_token: Option<Token![;]>,
474        }),
475
476        /// An associated type within the definition of a trait.
477        ///
478        /// *This type is available if Syn is built with the `"full"` feature.*
479        pub Type(TraitItemType {
480            pub attrs: Vec<Attribute>,
481            pub type_token: Token![type],
482            pub ident: Ident,
483            pub generics: Generics,
484            pub colon_token: Option<Token![:]>,
485            pub bounds: Punctuated<TypeParamBound, Token![+]>,
486            pub default: Option<(Token![=], Type)>,
487            pub semi_token: Token![;],
488        }),
489
490        /// A macro invocation within the definition of a trait.
491        ///
492        /// *This type is available if Syn is built with the `"full"` feature.*
493        pub Macro(TraitItemMacro {
494            pub attrs: Vec<Attribute>,
495            pub mac: Macro,
496            pub semi_token: Option<Token![;]>,
497        }),
498
499        /// Tokens within the definition of a trait not interpreted by Syn.
500        ///
501        /// *This type is available if Syn is built with the `"full"` feature.*
502        pub Verbatim(TraitItemVerbatim #manual_extra_traits {
503            pub tts: TokenStream,
504        }),
505    }
506}
507
508#[cfg(feature = "extra-traits")]
509impl Eq for TraitItemVerbatim {}
510
511#[cfg(feature = "extra-traits")]
512impl PartialEq for TraitItemVerbatim {
513    fn eq(&self, other: &Self) -> bool {
514        TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
515    }
516}
517
518#[cfg(feature = "extra-traits")]
519impl Hash for TraitItemVerbatim {
520    fn hash<H>(&self, state: &mut H)
521    where
522        H: Hasher,
523    {
524        TokenStreamHelper(&self.tts).hash(state);
525    }
526}
527
528ast_enum_of_structs! {
529    /// An item within an impl block.
530    ///
531    /// *This type is available if Syn is built with the `"full"` feature.*
532    ///
533    /// # Syntax tree enum
534    ///
535    /// This type is a [syntax tree enum].
536    ///
537    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
538    pub enum ImplItem {
539        /// An associated constant within an impl block.
540        ///
541        /// *This type is available if Syn is built with the `"full"` feature.*
542        pub Const(ImplItemConst {
543            pub attrs: Vec<Attribute>,
544            pub vis: Visibility,
545            pub defaultness: Option<Token![default]>,
546            pub const_token: Token![const],
547            pub ident: Ident,
548            pub colon_token: Token![:],
549            pub ty: Type,
550            pub eq_token: Token![=],
551            pub expr: Expr,
552            pub semi_token: Token![;],
553        }),
554
555        /// A method within an impl block.
556        ///
557        /// *This type is available if Syn is built with the `"full"` feature.*
558        pub Method(ImplItemMethod {
559            pub attrs: Vec<Attribute>,
560            pub vis: Visibility,
561            pub defaultness: Option<Token![default]>,
562            pub sig: MethodSig,
563            pub block: Block,
564        }),
565
566        /// An associated type within an impl block.
567        ///
568        /// *This type is available if Syn is built with the `"full"` feature.*
569        pub Type(ImplItemType {
570            pub attrs: Vec<Attribute>,
571            pub vis: Visibility,
572            pub defaultness: Option<Token![default]>,
573            pub type_token: Token![type],
574            pub ident: Ident,
575            pub generics: Generics,
576            pub eq_token: Token![=],
577            pub ty: Type,
578            pub semi_token: Token![;],
579        }),
580
581        /// A macro invocation within an impl block.
582        ///
583        /// *This type is available if Syn is built with the `"full"` feature.*
584        pub Macro(ImplItemMacro {
585            pub attrs: Vec<Attribute>,
586            pub mac: Macro,
587            pub semi_token: Option<Token![;]>,
588        }),
589
590        /// Tokens within an impl block not interpreted by Syn.
591        ///
592        /// *This type is available if Syn is built with the `"full"` feature.*
593        pub Verbatim(ImplItemVerbatim #manual_extra_traits {
594            pub tts: TokenStream,
595        }),
596    }
597}
598
599#[cfg(feature = "extra-traits")]
600impl Eq for ImplItemVerbatim {}
601
602#[cfg(feature = "extra-traits")]
603impl PartialEq for ImplItemVerbatim {
604    fn eq(&self, other: &Self) -> bool {
605        TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
606    }
607}
608
609#[cfg(feature = "extra-traits")]
610impl Hash for ImplItemVerbatim {
611    fn hash<H>(&self, state: &mut H)
612    where
613        H: Hasher,
614    {
615        TokenStreamHelper(&self.tts).hash(state);
616    }
617}
618
619ast_struct! {
620    /// A method's signature in a trait or implementation: `unsafe fn
621    /// initialize(&self)`.
622    ///
623    /// *This type is available if Syn is built with the `"full"` feature.*
624    pub struct MethodSig {
625        pub constness: Option<Token![const]>,
626        pub unsafety: Option<Token![unsafe]>,
627        pub abi: Option<Abi>,
628        pub ident: Ident,
629        pub decl: FnDecl,
630    }
631}
632
633ast_struct! {
634    /// Header of a function declaration, without including the body.
635    ///
636    /// *This type is available if Syn is built with the `"full"` feature.*
637    pub struct FnDecl {
638        pub fn_token: Token![fn],
639        pub generics: Generics,
640        pub paren_token: token::Paren,
641        pub inputs: Punctuated<FnArg, Token![,]>,
642        pub variadic: Option<Token![...]>,
643        pub output: ReturnType,
644    }
645}
646
647ast_enum_of_structs! {
648    /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`.
649    ///
650    /// *This type is available if Syn is built with the `"full"` feature.*
651    ///
652    /// # Syntax tree enum
653    ///
654    /// This type is a [syntax tree enum].
655    ///
656    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
657    pub enum FnArg {
658        /// Self captured by reference in a function signature: `&self` or `&mut
659        /// self`.
660        ///
661        /// *This type is available if Syn is built with the `"full"` feature.*
662        pub SelfRef(ArgSelfRef {
663            pub and_token: Token![&],
664            pub lifetime: Option<Lifetime>,
665            pub mutability: Option<Token![mut]>,
666            pub self_token: Token![self],
667        }),
668
669        /// Self captured by value in a function signature: `self` or `mut
670        /// self`.
671        ///
672        /// *This type is available if Syn is built with the `"full"` feature.*
673        pub SelfValue(ArgSelf {
674            pub mutability: Option<Token![mut]>,
675            pub self_token: Token![self],
676        }),
677
678        /// An explicitly typed pattern captured by a function signature.
679        ///
680        /// *This type is available if Syn is built with the `"full"` feature.*
681        pub Captured(ArgCaptured {
682            pub pat: Pat,
683            pub colon_token: Token![:],
684            pub ty: Type,
685        }),
686
687        /// A pattern whose type is inferred captured by a function signature.
688        pub Inferred(Pat),
689        /// A type not bound to any pattern in a function signature.
690        pub Ignored(Type),
691    }
692}
693
694#[cfg(feature = "parsing")]
695pub mod parsing {
696    use super::*;
697
698    use synom::Synom;
699
700    impl_synom!(Item "item" alt!(
701        syn!(ItemExternCrate) => { Item::ExternCrate }
702        |
703        syn!(ItemUse) => { Item::Use }
704        |
705        syn!(ItemStatic) => { Item::Static }
706        |
707        syn!(ItemConst) => { Item::Const }
708        |
709        syn!(ItemFn) => { Item::Fn }
710        |
711        syn!(ItemMod) => { Item::Mod }
712        |
713        syn!(ItemForeignMod) => { Item::ForeignMod }
714        |
715        syn!(ItemType) => { Item::Type }
716        |
717        syn!(ItemStruct) => { Item::Struct }
718        |
719        syn!(ItemEnum) => { Item::Enum }
720        |
721        syn!(ItemUnion) => { Item::Union }
722        |
723        syn!(ItemTrait) => { Item::Trait }
724        |
725        syn!(ItemImpl) => { Item::Impl }
726        |
727        syn!(ItemMacro) => { Item::Macro }
728        |
729        syn!(ItemMacro2) => { Item::Macro2 }
730    ));
731
732    impl_synom!(ItemMacro "macro item" do_parse!(
733        attrs: many0!(Attribute::parse_outer) >>
734        what: call!(Path::parse_mod_style) >>
735        bang: punct!(!) >>
736        ident: option!(syn!(Ident)) >>
737        body: call!(tt::delimited) >>
738        semi: cond!(!is_brace(&body.0), punct!(;)) >>
739        (ItemMacro {
740            attrs: attrs,
741            ident: ident,
742            mac: Macro {
743                path: what,
744                bang_token: bang,
745                delimiter: body.0,
746                tts: body.1,
747            },
748            semi_token: semi,
749        })
750    ));
751
752    // TODO: figure out the actual grammar; is body required to be braced?
753    impl_synom!(ItemMacro2 "macro2 item" do_parse!(
754        attrs: many0!(Attribute::parse_outer) >>
755        vis: syn!(Visibility) >>
756        macro_: keyword!(macro) >>
757        ident: syn!(Ident) >>
758        args: call!(tt::parenthesized) >>
759        body: call!(tt::braced) >>
760        (ItemMacro2 {
761            attrs: attrs,
762            vis: vis,
763            macro_token: macro_,
764            ident: ident,
765            paren_token: args.0,
766            args: args.1,
767            brace_token: body.0,
768            body: body.1,
769        })
770    ));
771
772    impl_synom!(ItemExternCrate "extern crate item" do_parse!(
773        attrs: many0!(Attribute::parse_outer) >>
774        vis: syn!(Visibility) >>
775        extern_: keyword!(extern) >>
776        crate_: keyword!(crate) >>
777        ident: syn!(Ident) >>
778        rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
779        semi: punct!(;) >>
780        (ItemExternCrate {
781            attrs: attrs,
782            vis: vis,
783            extern_token: extern_,
784            crate_token: crate_,
785            ident: ident,
786            rename: rename,
787            semi_token: semi,
788        })
789    ));
790
791    impl_synom!(ItemUse "use item" do_parse!(
792        attrs: many0!(Attribute::parse_outer) >>
793        vis: syn!(Visibility) >>
794        use_: keyword!(use) >>
795        leading_colon: option!(punct!(::)) >>
796        mut prefix: call!(Punctuated::parse_terminated_with, use_prefix) >>
797        tree: switch!(value!(prefix.empty_or_trailing()),
798            true => syn!(UseTree)
799            |
800            false => alt!(
801                tuple!(keyword!(as), syn!(Ident)) => {
802                    |rename| UseTree::Path(UsePath {
803                        ident: prefix.pop().unwrap().into_value(),
804                        rename: Some(rename),
805                    })
806                }
807                |
808                epsilon!() => {
809                    |_| UseTree::Path(UsePath {
810                        ident: prefix.pop().unwrap().into_value(),
811                        rename: None,
812                    })
813                }
814            )
815        ) >>
816        semi: punct!(;) >>
817        (ItemUse {
818            attrs: attrs,
819            vis: vis,
820            use_token: use_,
821            leading_colon: leading_colon,
822            prefix: prefix,
823            tree: tree,
824            semi_token: semi,
825        })
826    ));
827
828    named!(use_prefix -> Ident, alt!(
829        syn!(Ident)
830        |
831        keyword!(self) => { Into::into }
832        |
833        keyword!(super) => { Into::into }
834        |
835        keyword!(crate) => { Into::into }
836    ));
837
838    impl_synom!(UseTree "use tree" alt!(
839        syn!(UsePath) => { UseTree::Path }
840        |
841        syn!(UseGlob) => { UseTree::Glob }
842        |
843        syn!(UseList) => { UseTree::List }
844    ));
845
846    impl_synom!(UsePath "use path" do_parse!(
847        ident: alt!(
848            syn!(Ident)
849            |
850            keyword!(self) => { Into::into }
851        ) >>
852        rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
853        (UsePath {
854            ident: ident,
855            rename: rename,
856        })
857    ));
858
859    impl_synom!(UseGlob "use glob" do_parse!(
860        star: punct!(*) >>
861        (UseGlob {
862            star_token: star,
863        })
864    ));
865
866    impl_synom!(UseList "use list" do_parse!(
867        list: braces!(Punctuated::parse_terminated) >>
868        (UseList {
869            brace_token: list.0,
870            items: list.1,
871        })
872    ));
873
874    impl_synom!(ItemStatic "static item" do_parse!(
875        attrs: many0!(Attribute::parse_outer) >>
876        vis: syn!(Visibility) >>
877        static_: keyword!(static) >>
878        mutability: option!(keyword!(mut)) >>
879        ident: syn!(Ident) >>
880        colon: punct!(:) >>
881        ty: syn!(Type) >>
882        eq: punct!(=) >>
883        value: syn!(Expr) >>
884        semi: punct!(;) >>
885        (ItemStatic {
886            attrs: attrs,
887            vis: vis,
888            static_token: static_,
889            mutability: mutability,
890            ident: ident,
891            colon_token: colon,
892            ty: Box::new(ty),
893            eq_token: eq,
894            expr: Box::new(value),
895            semi_token: semi,
896        })
897    ));
898
899    impl_synom!(ItemConst "const item" do_parse!(
900        attrs: many0!(Attribute::parse_outer) >>
901        vis: syn!(Visibility) >>
902        const_: keyword!(const) >>
903        ident: syn!(Ident) >>
904        colon: punct!(:) >>
905        ty: syn!(Type) >>
906        eq: punct!(=) >>
907        value: syn!(Expr) >>
908        semi: punct!(;) >>
909        (ItemConst {
910            attrs: attrs,
911            vis: vis,
912            const_token: const_,
913            ident: ident,
914            colon_token: colon,
915            ty: Box::new(ty),
916            eq_token: eq,
917            expr: Box::new(value),
918            semi_token: semi,
919        })
920    ));
921
922    impl_synom!(ItemFn "fn item" do_parse!(
923        outer_attrs: many0!(Attribute::parse_outer) >>
924        vis: syn!(Visibility) >>
925        constness: option!(keyword!(const)) >>
926        unsafety: option!(keyword!(unsafe)) >>
927        abi: option!(syn!(Abi)) >>
928        fn_: keyword!(fn) >>
929        ident: syn!(Ident) >>
930        generics: syn!(Generics) >>
931        inputs: parens!(Punctuated::parse_terminated) >>
932        ret: syn!(ReturnType) >>
933        where_clause: option!(syn!(WhereClause)) >>
934        inner_attrs_stmts: braces!(tuple!(
935            many0!(Attribute::parse_inner),
936            call!(Block::parse_within)
937        )) >>
938        (ItemFn {
939            attrs: {
940                let mut attrs = outer_attrs;
941                attrs.extend((inner_attrs_stmts.1).0);
942                attrs
943            },
944            vis: vis,
945            constness: constness,
946            unsafety: unsafety,
947            abi: abi,
948            decl: Box::new(FnDecl {
949                fn_token: fn_,
950                paren_token: inputs.0,
951                inputs: inputs.1,
952                output: ret,
953                variadic: None,
954                generics: Generics {
955                    where_clause: where_clause,
956                    .. generics
957                },
958            }),
959            ident: ident,
960            block: Box::new(Block {
961                brace_token: inner_attrs_stmts.0,
962                stmts: (inner_attrs_stmts.1).1,
963            }),
964        })
965    ));
966
967    impl Synom for FnArg {
968        named!(parse -> Self, alt!(
969            do_parse!(
970                and: punct!(&) >>
971                lt: option!(syn!(Lifetime)) >>
972                mutability: option!(keyword!(mut)) >>
973                self_: keyword!(self) >>
974                not!(punct!(:)) >>
975                (ArgSelfRef {
976                    lifetime: lt,
977                    mutability: mutability,
978                    and_token: and,
979                    self_token: self_,
980                }.into())
981            )
982            |
983            do_parse!(
984                mutability: option!(keyword!(mut)) >>
985                self_: keyword!(self) >>
986                not!(punct!(:)) >>
987                (ArgSelf {
988                    mutability: mutability,
989                    self_token: self_,
990                }.into())
991            )
992            |
993            do_parse!(
994                pat: syn!(Pat) >>
995                colon: punct!(:) >>
996                ty: syn!(Type) >>
997                (ArgCaptured {
998                    pat: pat,
999                    ty: ty,
1000                    colon_token: colon,
1001                }.into())
1002            )
1003            |
1004            syn!(Type) => { FnArg::Ignored }
1005        ));
1006
1007        fn description() -> Option<&'static str> {
1008            Some("function argument")
1009        }
1010    }
1011
1012    impl_synom!(ItemMod "mod item" do_parse!(
1013        outer_attrs: many0!(Attribute::parse_outer) >>
1014        vis: syn!(Visibility) >>
1015        mod_: keyword!(mod) >>
1016        ident: syn!(Ident) >>
1017        content_semi: alt!(
1018            punct!(;) => {|semi| (
1019                Vec::new(),
1020                None,
1021                Some(semi),
1022            )}
1023            |
1024            braces!(
1025                tuple!(
1026                    many0!(Attribute::parse_inner),
1027                    many0!(Item::parse)
1028                )
1029            ) => {|(brace, (inner_attrs, items))| (
1030                inner_attrs,
1031                Some((brace, items)),
1032                None,
1033            )}
1034        ) >>
1035        (ItemMod {
1036            attrs: {
1037                let mut attrs = outer_attrs;
1038                attrs.extend(content_semi.0);
1039                attrs
1040            },
1041            vis: vis,
1042            mod_token: mod_,
1043            ident: ident,
1044            content: content_semi.1,
1045            semi: content_semi.2,
1046        })
1047    ));
1048
1049    impl_synom!(ItemForeignMod "foreign mod item" do_parse!(
1050        attrs: many0!(Attribute::parse_outer) >>
1051        abi: syn!(Abi) >>
1052        items: braces!(many0!(ForeignItem::parse)) >>
1053        (ItemForeignMod {
1054            attrs: attrs,
1055            abi: abi,
1056            brace_token: items.0,
1057            items: items.1,
1058        })
1059    ));
1060
1061    impl_synom!(ForeignItem "foreign item" alt!(
1062        syn!(ForeignItemFn) => { ForeignItem::Fn }
1063        |
1064        syn!(ForeignItemStatic) => { ForeignItem::Static }
1065        |
1066        syn!(ForeignItemType) => { ForeignItem::Type }
1067    ));
1068
1069    impl_synom!(ForeignItemFn "foreign function" do_parse!(
1070        attrs: many0!(Attribute::parse_outer) >>
1071        vis: syn!(Visibility) >>
1072        fn_: keyword!(fn) >>
1073        ident: syn!(Ident) >>
1074        generics: syn!(Generics) >>
1075        inputs: parens!(do_parse!(
1076            args: call!(Punctuated::parse_terminated) >>
1077            variadic: option!(cond_reduce!(args.empty_or_trailing(), punct!(...))) >>
1078            (args, variadic)
1079        )) >>
1080        ret: syn!(ReturnType) >>
1081        where_clause: option!(syn!(WhereClause)) >>
1082        semi: punct!(;) >>
1083        ({
1084            let (parens, (inputs, variadic)) = inputs;
1085            ForeignItemFn {
1086                ident: ident,
1087                attrs: attrs,
1088                semi_token: semi,
1089                decl: Box::new(FnDecl {
1090                    fn_token: fn_,
1091                    paren_token: parens,
1092                    inputs: inputs,
1093                    variadic: variadic,
1094                    output: ret,
1095                    generics: Generics {
1096                        where_clause: where_clause,
1097                        .. generics
1098                    },
1099                }),
1100                vis: vis,
1101            }
1102        })
1103    ));
1104
1105    impl_synom!(ForeignItemStatic "foreign static" do_parse!(
1106        attrs: many0!(Attribute::parse_outer) >>
1107        vis: syn!(Visibility) >>
1108        static_: keyword!(static) >>
1109        mutability: option!(keyword!(mut)) >>
1110        ident: syn!(Ident) >>
1111        colon: punct!(:) >>
1112        ty: syn!(Type) >>
1113        semi: punct!(;) >>
1114        (ForeignItemStatic {
1115            ident: ident,
1116            attrs: attrs,
1117            semi_token: semi,
1118            ty: Box::new(ty),
1119            mutability: mutability,
1120            static_token: static_,
1121            colon_token: colon,
1122            vis: vis,
1123        })
1124    ));
1125
1126    impl_synom!(ForeignItemType "foreign type" do_parse!(
1127        attrs: many0!(Attribute::parse_outer) >>
1128        vis: syn!(Visibility) >>
1129        type_: keyword!(type) >>
1130        ident: syn!(Ident) >>
1131        semi: punct!(;) >>
1132        (ForeignItemType {
1133            attrs: attrs,
1134            vis: vis,
1135            type_token: type_,
1136            ident: ident,
1137            semi_token: semi,
1138        })
1139    ));
1140
1141    impl_synom!(ItemType "type item" do_parse!(
1142        attrs: many0!(Attribute::parse_outer) >>
1143        vis: syn!(Visibility) >>
1144        type_: keyword!(type) >>
1145        ident: syn!(Ident) >>
1146        generics: syn!(Generics) >>
1147        where_clause: option!(syn!(WhereClause)) >>
1148        eq: punct!(=) >>
1149        ty: syn!(Type) >>
1150        semi: punct!(;) >>
1151        (ItemType {
1152            attrs: attrs,
1153            vis: vis,
1154            type_token: type_,
1155            ident: ident,
1156            generics: Generics {
1157                where_clause: where_clause,
1158                ..generics
1159            },
1160            eq_token: eq,
1161            ty: Box::new(ty),
1162            semi_token: semi,
1163        })
1164    ));
1165
1166    impl_synom!(ItemStruct "struct item" switch!(
1167        map!(syn!(DeriveInput), Into::into),
1168        Item::Struct(item) => value!(item)
1169        |
1170        _ => reject!()
1171    ));
1172
1173    impl_synom!(ItemEnum "enum item" switch!(
1174        map!(syn!(DeriveInput), Into::into),
1175        Item::Enum(item) => value!(item)
1176        |
1177        _ => reject!()
1178    ));
1179
1180    impl_synom!(ItemUnion "union item" do_parse!(
1181        attrs: many0!(Attribute::parse_outer) >>
1182        vis: syn!(Visibility) >>
1183        union_: keyword!(union) >>
1184        ident: syn!(Ident) >>
1185        generics: syn!(Generics) >>
1186        where_clause: option!(syn!(WhereClause)) >>
1187        fields: syn!(FieldsNamed) >>
1188        (ItemUnion {
1189            attrs: attrs,
1190            vis: vis,
1191            union_token: union_,
1192            ident: ident,
1193            generics: Generics {
1194                where_clause: where_clause,
1195                .. generics
1196            },
1197            fields: fields,
1198        })
1199    ));
1200
1201    impl_synom!(ItemTrait "trait item" do_parse!(
1202        attrs: many0!(Attribute::parse_outer) >>
1203        vis: syn!(Visibility) >>
1204        unsafety: option!(keyword!(unsafe)) >>
1205        auto_: option!(keyword!(auto)) >>
1206        trait_: keyword!(trait) >>
1207        ident: syn!(Ident) >>
1208        generics: syn!(Generics) >>
1209        colon: option!(punct!(:)) >>
1210        bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
1211        where_clause: option!(syn!(WhereClause)) >>
1212        body: braces!(many0!(TraitItem::parse)) >>
1213        (ItemTrait {
1214            attrs: attrs,
1215            vis: vis,
1216            unsafety: unsafety,
1217            auto_token: auto_,
1218            trait_token: trait_,
1219            ident: ident,
1220            generics: Generics {
1221                where_clause: where_clause,
1222                .. generics
1223            },
1224            colon_token: colon,
1225            supertraits: bounds.unwrap_or_default(),
1226            brace_token: body.0,
1227            items: body.1,
1228        })
1229    ));
1230
1231    impl_synom!(TraitItem "trait item" alt!(
1232        syn!(TraitItemConst) => { TraitItem::Const }
1233        |
1234        syn!(TraitItemMethod) => { TraitItem::Method }
1235        |
1236        syn!(TraitItemType) => { TraitItem::Type }
1237        |
1238        syn!(TraitItemMacro) => { TraitItem::Macro }
1239    ));
1240
1241    impl_synom!(TraitItemConst "const trait item" do_parse!(
1242        attrs: many0!(Attribute::parse_outer) >>
1243        const_: keyword!(const) >>
1244        ident: syn!(Ident) >>
1245        colon: punct!(:) >>
1246        ty: syn!(Type) >>
1247        default: option!(tuple!(punct!(=), syn!(Expr))) >>
1248        semi: punct!(;) >>
1249        (TraitItemConst {
1250            attrs: attrs,
1251            const_token: const_,
1252            ident: ident,
1253            colon_token: colon,
1254            ty: ty,
1255            default: default,
1256            semi_token: semi,
1257        })
1258    ));
1259
1260    impl_synom!(TraitItemMethod "method trait item" do_parse!(
1261        outer_attrs: many0!(Attribute::parse_outer) >>
1262        constness: option!(keyword!(const)) >>
1263        unsafety: option!(keyword!(unsafe)) >>
1264        abi: option!(syn!(Abi)) >>
1265        fn_: keyword!(fn) >>
1266        ident: syn!(Ident) >>
1267        generics: syn!(Generics) >>
1268        inputs: parens!(Punctuated::parse_terminated) >>
1269        ret: syn!(ReturnType) >>
1270        where_clause: option!(syn!(WhereClause)) >>
1271        body: option!(braces!(
1272            tuple!(many0!(Attribute::parse_inner),
1273                   call!(Block::parse_within))
1274        )) >>
1275        semi: cond!(body.is_none(), punct!(;)) >>
1276        ({
1277            let (inner_attrs, stmts) = match body {
1278                Some((b, (inner_attrs, stmts))) => (inner_attrs, Some((stmts, b))),
1279                None => (Vec::new(), None),
1280            };
1281            TraitItemMethod {
1282                attrs: {
1283                    let mut attrs = outer_attrs;
1284                    attrs.extend(inner_attrs);
1285                    attrs
1286                },
1287                sig: MethodSig {
1288                    constness: constness,
1289                    unsafety: unsafety,
1290                    abi: abi,
1291                    ident: ident,
1292                    decl: FnDecl {
1293                        inputs: inputs.1,
1294                        output: ret,
1295                        fn_token: fn_,
1296                        paren_token: inputs.0,
1297                        variadic: None,
1298                        generics: Generics {
1299                            where_clause: where_clause,
1300                            .. generics
1301                        },
1302                    },
1303                },
1304                default: stmts.map(|stmts| {
1305                    Block {
1306                        stmts: stmts.0,
1307                        brace_token: stmts.1,
1308                    }
1309                }),
1310                semi_token: semi,
1311            }
1312        })
1313    ));
1314
1315    impl_synom!(TraitItemType "trait item type" do_parse!(
1316        attrs: many0!(Attribute::parse_outer) >>
1317        type_: keyword!(type) >>
1318        ident: syn!(Ident) >>
1319        generics: syn!(Generics) >>
1320        colon: option!(punct!(:)) >>
1321        bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
1322        where_clause: option!(syn!(WhereClause)) >>
1323        default: option!(tuple!(punct!(=), syn!(Type))) >>
1324        semi: punct!(;) >>
1325        (TraitItemType {
1326            attrs: attrs,
1327            type_token: type_,
1328            ident: ident,
1329            generics: Generics {
1330                where_clause: where_clause,
1331                .. generics
1332            },
1333            colon_token: colon,
1334            bounds: bounds.unwrap_or_default(),
1335            default: default,
1336            semi_token: semi,
1337        })
1338    ));
1339
1340    impl_synom!(TraitItemMacro "trait item macro" do_parse!(
1341        attrs: many0!(Attribute::parse_outer) >>
1342        mac: syn!(Macro) >>
1343        semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
1344        (TraitItemMacro {
1345            attrs: attrs,
1346            mac: mac,
1347            semi_token: semi,
1348        })
1349    ));
1350
1351    impl_synom!(ItemImpl "impl item" do_parse!(
1352        attrs: many0!(Attribute::parse_outer) >>
1353        defaultness: option!(keyword!(default)) >>
1354        unsafety: option!(keyword!(unsafe)) >>
1355        impl_: keyword!(impl) >>
1356        generics: syn!(Generics) >>
1357        polarity_path: alt!(
1358            do_parse!(
1359                polarity: option!(punct!(!)) >>
1360                path: syn!(Path) >>
1361                for_: keyword!(for) >>
1362                (Some((polarity, path, for_)))
1363            )
1364            |
1365            epsilon!() => { |_| None }
1366        ) >>
1367        self_ty: syn!(Type) >>
1368        where_clause: option!(syn!(WhereClause)) >>
1369        body: braces!(many0!(ImplItem::parse)) >>
1370        (ItemImpl {
1371            attrs: attrs,
1372            defaultness: defaultness,
1373            unsafety: unsafety,
1374            impl_token: impl_,
1375            generics: Generics {
1376                where_clause: where_clause,
1377                .. generics
1378            },
1379            trait_: polarity_path,
1380            self_ty: Box::new(self_ty),
1381            brace_token: body.0,
1382            items: body.1,
1383        })
1384    ));
1385
1386    impl_synom!(ImplItem "item in impl block" alt!(
1387        syn!(ImplItemConst) => { ImplItem::Const }
1388        |
1389        syn!(ImplItemMethod) => { ImplItem::Method }
1390        |
1391        syn!(ImplItemType) => { ImplItem::Type }
1392        |
1393        syn!(ImplItemMacro) => { ImplItem::Macro }
1394    ));
1395
1396    impl_synom!(ImplItemConst "const item in impl block" do_parse!(
1397        attrs: many0!(Attribute::parse_outer) >>
1398        vis: syn!(Visibility) >>
1399        defaultness: option!(keyword!(default)) >>
1400        const_: keyword!(const) >>
1401        ident: syn!(Ident) >>
1402        colon: punct!(:) >>
1403        ty: syn!(Type) >>
1404        eq: punct!(=) >>
1405        value: syn!(Expr) >>
1406        semi: punct!(;) >>
1407        (ImplItemConst {
1408            attrs: attrs,
1409            vis: vis,
1410            defaultness: defaultness,
1411            const_token: const_,
1412            ident: ident,
1413            colon_token: colon,
1414            ty: ty,
1415            eq_token: eq,
1416            expr: value,
1417            semi_token: semi,
1418        })
1419    ));
1420
1421    impl_synom!(ImplItemMethod "method in impl block" do_parse!(
1422        outer_attrs: many0!(Attribute::parse_outer) >>
1423        vis: syn!(Visibility) >>
1424        defaultness: option!(keyword!(default)) >>
1425        constness: option!(keyword!(const)) >>
1426        unsafety: option!(keyword!(unsafe)) >>
1427        abi: option!(syn!(Abi)) >>
1428        fn_: keyword!(fn) >>
1429        ident: syn!(Ident) >>
1430        generics: syn!(Generics) >>
1431        inputs: parens!(Punctuated::parse_terminated) >>
1432        ret: syn!(ReturnType) >>
1433        where_clause: option!(syn!(WhereClause)) >>
1434        inner_attrs_stmts: braces!(tuple!(
1435            many0!(Attribute::parse_inner),
1436            call!(Block::parse_within)
1437        )) >>
1438        (ImplItemMethod {
1439            attrs: {
1440                let mut attrs = outer_attrs;
1441                attrs.extend((inner_attrs_stmts.1).0);
1442                attrs
1443            },
1444            vis: vis,
1445            defaultness: defaultness,
1446            sig: MethodSig {
1447                constness: constness,
1448                unsafety: unsafety,
1449                abi: abi,
1450                ident: ident,
1451                decl: FnDecl {
1452                    fn_token: fn_,
1453                    paren_token: inputs.0,
1454                    inputs: inputs.1,
1455                    output: ret,
1456                    generics: Generics {
1457                        where_clause: where_clause,
1458                        .. generics
1459                    },
1460                    variadic: None,
1461                },
1462            },
1463            block: Block {
1464                brace_token: inner_attrs_stmts.0,
1465                stmts: (inner_attrs_stmts.1).1,
1466            },
1467        })
1468    ));
1469
1470    impl_synom!(ImplItemType "type in impl block" do_parse!(
1471        attrs: many0!(Attribute::parse_outer) >>
1472        vis: syn!(Visibility) >>
1473        defaultness: option!(keyword!(default)) >>
1474        type_: keyword!(type) >>
1475        ident: syn!(Ident) >>
1476        generics: syn!(Generics) >>
1477        eq: punct!(=) >>
1478        ty: syn!(Type) >>
1479        semi: punct!(;) >>
1480        (ImplItemType {
1481            attrs: attrs,
1482            vis: vis,
1483            defaultness: defaultness,
1484            type_token: type_,
1485            ident: ident,
1486            generics: generics,
1487            eq_token: eq,
1488            ty: ty,
1489            semi_token: semi,
1490        })
1491    ));
1492
1493    impl_synom!(ImplItemMacro "macro in impl block" do_parse!(
1494        attrs: many0!(Attribute::parse_outer) >>
1495        mac: syn!(Macro) >>
1496        semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
1497        (ImplItemMacro {
1498            attrs: attrs,
1499            mac: mac,
1500            semi_token: semi,
1501        })
1502    ));
1503
1504    fn is_brace(delimiter: &MacroDelimiter) -> bool {
1505        match *delimiter {
1506            MacroDelimiter::Brace(_) => true,
1507            MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
1508        }
1509    }
1510}
1511
1512#[cfg(feature = "printing")]
1513mod printing {
1514    use super::*;
1515    use attr::FilterAttrs;
1516    use quote::{ToTokens, Tokens};
1517
1518    impl ToTokens for ItemExternCrate {
1519        fn to_tokens(&self, tokens: &mut Tokens) {
1520            tokens.append_all(self.attrs.outer());
1521            self.vis.to_tokens(tokens);
1522            self.extern_token.to_tokens(tokens);
1523            self.crate_token.to_tokens(tokens);
1524            self.ident.to_tokens(tokens);
1525            if let Some((ref as_token, ref rename)) = self.rename {
1526                as_token.to_tokens(tokens);
1527                rename.to_tokens(tokens);
1528            }
1529            self.semi_token.to_tokens(tokens);
1530        }
1531    }
1532
1533    impl ToTokens for ItemUse {
1534        fn to_tokens(&self, tokens: &mut Tokens) {
1535            tokens.append_all(self.attrs.outer());
1536            self.vis.to_tokens(tokens);
1537            self.use_token.to_tokens(tokens);
1538            self.leading_colon.to_tokens(tokens);
1539            self.prefix.to_tokens(tokens);
1540            self.tree.to_tokens(tokens);
1541            self.semi_token.to_tokens(tokens);
1542        }
1543    }
1544
1545    impl ToTokens for ItemStatic {
1546        fn to_tokens(&self, tokens: &mut Tokens) {
1547            tokens.append_all(self.attrs.outer());
1548            self.vis.to_tokens(tokens);
1549            self.static_token.to_tokens(tokens);
1550            self.mutability.to_tokens(tokens);
1551            self.ident.to_tokens(tokens);
1552            self.colon_token.to_tokens(tokens);
1553            self.ty.to_tokens(tokens);
1554            self.eq_token.to_tokens(tokens);
1555            self.expr.to_tokens(tokens);
1556            self.semi_token.to_tokens(tokens);
1557        }
1558    }
1559
1560    impl ToTokens for ItemConst {
1561        fn to_tokens(&self, tokens: &mut Tokens) {
1562            tokens.append_all(self.attrs.outer());
1563            self.vis.to_tokens(tokens);
1564            self.const_token.to_tokens(tokens);
1565            self.ident.to_tokens(tokens);
1566            self.colon_token.to_tokens(tokens);
1567            self.ty.to_tokens(tokens);
1568            self.eq_token.to_tokens(tokens);
1569            self.expr.to_tokens(tokens);
1570            self.semi_token.to_tokens(tokens);
1571        }
1572    }
1573
1574    impl ToTokens for ItemFn {
1575        fn to_tokens(&self, tokens: &mut Tokens) {
1576            tokens.append_all(self.attrs.outer());
1577            self.vis.to_tokens(tokens);
1578            self.constness.to_tokens(tokens);
1579            self.unsafety.to_tokens(tokens);
1580            self.abi.to_tokens(tokens);
1581            NamedDecl(&self.decl, self.ident).to_tokens(tokens);
1582            self.block.brace_token.surround(tokens, |tokens| {
1583                tokens.append_all(self.attrs.inner());
1584                tokens.append_all(&self.block.stmts);
1585            });
1586        }
1587    }
1588
1589    impl ToTokens for ItemMod {
1590        fn to_tokens(&self, tokens: &mut Tokens) {
1591            tokens.append_all(self.attrs.outer());
1592            self.vis.to_tokens(tokens);
1593            self.mod_token.to_tokens(tokens);
1594            self.ident.to_tokens(tokens);
1595            if let Some((ref brace, ref items)) = self.content {
1596                brace.surround(tokens, |tokens| {
1597                    tokens.append_all(self.attrs.inner());
1598                    tokens.append_all(items);
1599                });
1600            } else {
1601                TokensOrDefault(&self.semi).to_tokens(tokens);
1602            }
1603        }
1604    }
1605
1606    impl ToTokens for ItemForeignMod {
1607        fn to_tokens(&self, tokens: &mut Tokens) {
1608            tokens.append_all(self.attrs.outer());
1609            self.abi.to_tokens(tokens);
1610            self.brace_token.surround(tokens, |tokens| {
1611                tokens.append_all(&self.items);
1612            });
1613        }
1614    }
1615
1616    impl ToTokens for ItemType {
1617        fn to_tokens(&self, tokens: &mut Tokens) {
1618            tokens.append_all(self.attrs.outer());
1619            self.vis.to_tokens(tokens);
1620            self.type_token.to_tokens(tokens);
1621            self.ident.to_tokens(tokens);
1622            self.generics.to_tokens(tokens);
1623            self.generics.where_clause.to_tokens(tokens);
1624            self.eq_token.to_tokens(tokens);
1625            self.ty.to_tokens(tokens);
1626            self.semi_token.to_tokens(tokens);
1627        }
1628    }
1629
1630    impl ToTokens for ItemEnum {
1631        fn to_tokens(&self, tokens: &mut Tokens) {
1632            tokens.append_all(self.attrs.outer());
1633            self.vis.to_tokens(tokens);
1634            self.enum_token.to_tokens(tokens);
1635            self.ident.to_tokens(tokens);
1636            self.generics.to_tokens(tokens);
1637            self.generics.where_clause.to_tokens(tokens);
1638            self.brace_token.surround(tokens, |tokens| {
1639                self.variants.to_tokens(tokens);
1640            });
1641        }
1642    }
1643
1644    impl ToTokens for ItemStruct {
1645        fn to_tokens(&self, tokens: &mut Tokens) {
1646            tokens.append_all(self.attrs.outer());
1647            self.vis.to_tokens(tokens);
1648            self.struct_token.to_tokens(tokens);
1649            self.ident.to_tokens(tokens);
1650            self.generics.to_tokens(tokens);
1651            match self.fields {
1652                Fields::Named(ref fields) => {
1653                    self.generics.where_clause.to_tokens(tokens);
1654                    fields.to_tokens(tokens);
1655                }
1656                Fields::Unnamed(ref fields) => {
1657                    fields.to_tokens(tokens);
1658                    self.generics.where_clause.to_tokens(tokens);
1659                    TokensOrDefault(&self.semi_token).to_tokens(tokens);
1660                }
1661                Fields::Unit => {
1662                    self.generics.where_clause.to_tokens(tokens);
1663                    TokensOrDefault(&self.semi_token).to_tokens(tokens);
1664                }
1665            }
1666        }
1667    }
1668
1669    impl ToTokens for ItemUnion {
1670        fn to_tokens(&self, tokens: &mut Tokens) {
1671            tokens.append_all(self.attrs.outer());
1672            self.vis.to_tokens(tokens);
1673            self.union_token.to_tokens(tokens);
1674            self.ident.to_tokens(tokens);
1675            self.generics.to_tokens(tokens);
1676            self.generics.where_clause.to_tokens(tokens);
1677            self.fields.to_tokens(tokens);
1678        }
1679    }
1680
1681    impl ToTokens for ItemTrait {
1682        fn to_tokens(&self, tokens: &mut Tokens) {
1683            tokens.append_all(self.attrs.outer());
1684            self.vis.to_tokens(tokens);
1685            self.unsafety.to_tokens(tokens);
1686            self.auto_token.to_tokens(tokens);
1687            self.trait_token.to_tokens(tokens);
1688            self.ident.to_tokens(tokens);
1689            self.generics.to_tokens(tokens);
1690            if !self.supertraits.is_empty() {
1691                TokensOrDefault(&self.colon_token).to_tokens(tokens);
1692                self.supertraits.to_tokens(tokens);
1693            }
1694            self.generics.where_clause.to_tokens(tokens);
1695            self.brace_token.surround(tokens, |tokens| {
1696                tokens.append_all(&self.items);
1697            });
1698        }
1699    }
1700
1701    impl ToTokens for ItemImpl {
1702        fn to_tokens(&self, tokens: &mut Tokens) {
1703            tokens.append_all(self.attrs.outer());
1704            self.defaultness.to_tokens(tokens);
1705            self.unsafety.to_tokens(tokens);
1706            self.impl_token.to_tokens(tokens);
1707            self.generics.to_tokens(tokens);
1708            if let Some((ref polarity, ref path, ref for_token)) = self.trait_ {
1709                polarity.to_tokens(tokens);
1710                path.to_tokens(tokens);
1711                for_token.to_tokens(tokens);
1712            }
1713            self.self_ty.to_tokens(tokens);
1714            self.generics.where_clause.to_tokens(tokens);
1715            self.brace_token.surround(tokens, |tokens| {
1716                tokens.append_all(&self.items);
1717            });
1718        }
1719    }
1720
1721    impl ToTokens for ItemMacro {
1722        fn to_tokens(&self, tokens: &mut Tokens) {
1723            tokens.append_all(self.attrs.outer());
1724            self.mac.path.to_tokens(tokens);
1725            self.mac.bang_token.to_tokens(tokens);
1726            self.ident.to_tokens(tokens);
1727            match self.mac.delimiter {
1728                MacroDelimiter::Paren(ref paren) => {
1729                    paren.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
1730                }
1731                MacroDelimiter::Brace(ref brace) => {
1732                    brace.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
1733                }
1734                MacroDelimiter::Bracket(ref bracket) => {
1735                    bracket.surround(tokens, |tokens| self.mac.tts.to_tokens(tokens));
1736                }
1737            }
1738            self.semi_token.to_tokens(tokens);
1739        }
1740    }
1741
1742    impl ToTokens for ItemMacro2 {
1743        fn to_tokens(&self, tokens: &mut Tokens) {
1744            tokens.append_all(self.attrs.outer());
1745            self.vis.to_tokens(tokens);
1746            self.macro_token.to_tokens(tokens);
1747            self.ident.to_tokens(tokens);
1748            self.paren_token.surround(tokens, |tokens| {
1749                self.args.to_tokens(tokens);
1750            });
1751            self.brace_token.surround(tokens, |tokens| {
1752                self.body.to_tokens(tokens);
1753            });
1754        }
1755    }
1756
1757    impl ToTokens for ItemVerbatim {
1758        fn to_tokens(&self, tokens: &mut Tokens) {
1759            self.tts.to_tokens(tokens);
1760        }
1761    }
1762
1763    impl ToTokens for UsePath {
1764        fn to_tokens(&self, tokens: &mut Tokens) {
1765            self.ident.to_tokens(tokens);
1766            if let Some((ref as_token, ref rename)) = self.rename {
1767                as_token.to_tokens(tokens);
1768                rename.to_tokens(tokens);
1769            }
1770        }
1771    }
1772
1773    impl ToTokens for UseGlob {
1774        fn to_tokens(&self, tokens: &mut Tokens) {
1775            self.star_token.to_tokens(tokens);
1776        }
1777    }
1778
1779    impl ToTokens for UseList {
1780        fn to_tokens(&self, tokens: &mut Tokens) {
1781            self.brace_token.surround(tokens, |tokens| {
1782                self.items.to_tokens(tokens);
1783            });
1784        }
1785    }
1786
1787    impl ToTokens for TraitItemConst {
1788        fn to_tokens(&self, tokens: &mut Tokens) {
1789            tokens.append_all(self.attrs.outer());
1790            self.const_token.to_tokens(tokens);
1791            self.ident.to_tokens(tokens);
1792            self.colon_token.to_tokens(tokens);
1793            self.ty.to_tokens(tokens);
1794            if let Some((ref eq_token, ref default)) = self.default {
1795                eq_token.to_tokens(tokens);
1796                default.to_tokens(tokens);
1797            }
1798            self.semi_token.to_tokens(tokens);
1799        }
1800    }
1801
1802    impl ToTokens for TraitItemMethod {
1803        fn to_tokens(&self, tokens: &mut Tokens) {
1804            tokens.append_all(self.attrs.outer());
1805            self.sig.to_tokens(tokens);
1806            match self.default {
1807                Some(ref block) => {
1808                    block.brace_token.surround(tokens, |tokens| {
1809                        tokens.append_all(self.attrs.inner());
1810                        tokens.append_all(&block.stmts);
1811                    });
1812                }
1813                None => {
1814                    TokensOrDefault(&self.semi_token).to_tokens(tokens);
1815                }
1816            }
1817        }
1818    }
1819
1820    impl ToTokens for TraitItemType {
1821        fn to_tokens(&self, tokens: &mut Tokens) {
1822            tokens.append_all(self.attrs.outer());
1823            self.type_token.to_tokens(tokens);
1824            self.ident.to_tokens(tokens);
1825            self.generics.to_tokens(tokens);
1826            if !self.bounds.is_empty() {
1827                TokensOrDefault(&self.colon_token).to_tokens(tokens);
1828                self.bounds.to_tokens(tokens);
1829            }
1830            self.generics.where_clause.to_tokens(tokens);
1831            if let Some((ref eq_token, ref default)) = self.default {
1832                eq_token.to_tokens(tokens);
1833                default.to_tokens(tokens);
1834            }
1835            self.semi_token.to_tokens(tokens);
1836        }
1837    }
1838
1839    impl ToTokens for TraitItemMacro {
1840        fn to_tokens(&self, tokens: &mut Tokens) {
1841            tokens.append_all(self.attrs.outer());
1842            self.mac.to_tokens(tokens);
1843            self.semi_token.to_tokens(tokens);
1844        }
1845    }
1846
1847    impl ToTokens for TraitItemVerbatim {
1848        fn to_tokens(&self, tokens: &mut Tokens) {
1849            self.tts.to_tokens(tokens);
1850        }
1851    }
1852
1853    impl ToTokens for ImplItemConst {
1854        fn to_tokens(&self, tokens: &mut Tokens) {
1855            tokens.append_all(self.attrs.outer());
1856            self.vis.to_tokens(tokens);
1857            self.defaultness.to_tokens(tokens);
1858            self.const_token.to_tokens(tokens);
1859            self.ident.to_tokens(tokens);
1860            self.colon_token.to_tokens(tokens);
1861            self.ty.to_tokens(tokens);
1862            self.eq_token.to_tokens(tokens);
1863            self.expr.to_tokens(tokens);
1864            self.semi_token.to_tokens(tokens);
1865        }
1866    }
1867
1868    impl ToTokens for ImplItemMethod {
1869        fn to_tokens(&self, tokens: &mut Tokens) {
1870            tokens.append_all(self.attrs.outer());
1871            self.vis.to_tokens(tokens);
1872            self.defaultness.to_tokens(tokens);
1873            self.sig.to_tokens(tokens);
1874            self.block.brace_token.surround(tokens, |tokens| {
1875                tokens.append_all(self.attrs.inner());
1876                tokens.append_all(&self.block.stmts);
1877            });
1878        }
1879    }
1880
1881    impl ToTokens for ImplItemType {
1882        fn to_tokens(&self, tokens: &mut Tokens) {
1883            tokens.append_all(self.attrs.outer());
1884            self.vis.to_tokens(tokens);
1885            self.defaultness.to_tokens(tokens);
1886            self.type_token.to_tokens(tokens);
1887            self.ident.to_tokens(tokens);
1888            self.generics.to_tokens(tokens);
1889            self.eq_token.to_tokens(tokens);
1890            self.ty.to_tokens(tokens);
1891            self.semi_token.to_tokens(tokens);
1892        }
1893    }
1894
1895    impl ToTokens for ImplItemMacro {
1896        fn to_tokens(&self, tokens: &mut Tokens) {
1897            tokens.append_all(self.attrs.outer());
1898            self.mac.to_tokens(tokens);
1899            self.semi_token.to_tokens(tokens);
1900        }
1901    }
1902
1903    impl ToTokens for ImplItemVerbatim {
1904        fn to_tokens(&self, tokens: &mut Tokens) {
1905            self.tts.to_tokens(tokens);
1906        }
1907    }
1908
1909    impl ToTokens for ForeignItemFn {
1910        fn to_tokens(&self, tokens: &mut Tokens) {
1911            tokens.append_all(self.attrs.outer());
1912            self.vis.to_tokens(tokens);
1913            NamedDecl(&self.decl, self.ident).to_tokens(tokens);
1914            self.semi_token.to_tokens(tokens);
1915        }
1916    }
1917
1918    impl ToTokens for ForeignItemStatic {
1919        fn to_tokens(&self, tokens: &mut Tokens) {
1920            tokens.append_all(self.attrs.outer());
1921            self.vis.to_tokens(tokens);
1922            self.static_token.to_tokens(tokens);
1923            self.mutability.to_tokens(tokens);
1924            self.ident.to_tokens(tokens);
1925            self.colon_token.to_tokens(tokens);
1926            self.ty.to_tokens(tokens);
1927            self.semi_token.to_tokens(tokens);
1928        }
1929    }
1930
1931    impl ToTokens for ForeignItemType {
1932        fn to_tokens(&self, tokens: &mut Tokens) {
1933            tokens.append_all(self.attrs.outer());
1934            self.vis.to_tokens(tokens);
1935            self.type_token.to_tokens(tokens);
1936            self.ident.to_tokens(tokens);
1937            self.semi_token.to_tokens(tokens);
1938        }
1939    }
1940
1941    impl ToTokens for ForeignItemVerbatim {
1942        fn to_tokens(&self, tokens: &mut Tokens) {
1943            self.tts.to_tokens(tokens);
1944        }
1945    }
1946
1947    impl ToTokens for MethodSig {
1948        fn to_tokens(&self, tokens: &mut Tokens) {
1949            self.constness.to_tokens(tokens);
1950            self.unsafety.to_tokens(tokens);
1951            self.abi.to_tokens(tokens);
1952            NamedDecl(&self.decl, self.ident).to_tokens(tokens);
1953        }
1954    }
1955
1956    struct NamedDecl<'a>(&'a FnDecl, Ident);
1957
1958    impl<'a> ToTokens for NamedDecl<'a> {
1959        fn to_tokens(&self, tokens: &mut Tokens) {
1960            self.0.fn_token.to_tokens(tokens);
1961            self.1.to_tokens(tokens);
1962            self.0.generics.to_tokens(tokens);
1963            self.0.paren_token.surround(tokens, |tokens| {
1964                self.0.inputs.to_tokens(tokens);
1965                if self.0.variadic.is_some() && !self.0.inputs.empty_or_trailing() {
1966                    <Token![,]>::default().to_tokens(tokens);
1967                }
1968                self.0.variadic.to_tokens(tokens);
1969            });
1970            self.0.output.to_tokens(tokens);
1971            self.0.generics.where_clause.to_tokens(tokens);
1972        }
1973    }
1974
1975    impl ToTokens for ArgSelfRef {
1976        fn to_tokens(&self, tokens: &mut Tokens) {
1977            self.and_token.to_tokens(tokens);
1978            self.lifetime.to_tokens(tokens);
1979            self.mutability.to_tokens(tokens);
1980            self.self_token.to_tokens(tokens);
1981        }
1982    }
1983
1984    impl ToTokens for ArgSelf {
1985        fn to_tokens(&self, tokens: &mut Tokens) {
1986            self.mutability.to_tokens(tokens);
1987            self.self_token.to_tokens(tokens);
1988        }
1989    }
1990
1991    impl ToTokens for ArgCaptured {
1992        fn to_tokens(&self, tokens: &mut Tokens) {
1993            self.pat.to_tokens(tokens);
1994            self.colon_token.to_tokens(tokens);
1995            self.ty.to_tokens(tokens);
1996        }
1997    }
1998}