1 use super::*;
2 
3 /// An item
4 ///
5 /// The name might be a dummy name in case of anonymous items
6 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
7 pub struct Item {
8     pub ident: Ident,
9     pub vis: Visibility,
10     pub attrs: Vec<Attribute>,
11     pub node: ItemKind,
12 }
13 
14 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
15 pub enum ItemKind {
16     /// An`extern crate` item, with optional original crate name.
17     ///
18     /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
19     ExternCrate(Option<Ident>),
20     /// A use declaration (`use` or `pub use`) item.
21     ///
22     /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
23     Use(Box<ViewPath>),
24     /// A static item (`static` or `pub static`).
25     ///
26     /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
27     Static(Box<Ty>, Mutability, Box<Expr>),
28     /// A constant item (`const` or `pub const`).
29     ///
30     /// E.g. `const FOO: i32 = 42;`
31     Const(Box<Ty>, Box<Expr>),
32     /// A function declaration (`fn` or `pub fn`).
33     ///
34     /// E.g. `fn foo(bar: usize) -> usize { .. }`
35     Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
36     /// A module declaration (`mod` or `pub mod`).
37     ///
38     /// E.g. `mod foo;` or `mod foo { .. }`
39     Mod(Option<Vec<Item>>),
40     /// An external module (`extern` or `pub extern`).
41     ///
42     /// E.g. `extern {}` or `extern "C" {}`
43     ForeignMod(ForeignMod),
44     /// A type alias (`type` or `pub type`).
45     ///
46     /// E.g. `type Foo = Bar<u8>;`
47     Ty(Box<Ty>, Generics),
48     /// An enum definition (`enum` or `pub enum`).
49     ///
50     /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
51     Enum(Vec<Variant>, Generics),
52     /// A struct definition (`struct` or `pub struct`).
53     ///
54     /// E.g. `struct Foo<A> { x: A }`
55     Struct(VariantData, Generics),
56     /// A union definition (`union` or `pub union`).
57     ///
58     /// E.g. `union Foo<A, B> { x: A, y: B }`
59     Union(VariantData, Generics),
60     /// A Trait declaration (`trait` or `pub trait`).
61     ///
62     /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
63     Trait(Unsafety, Generics, Vec<TyParamBound>, Vec<TraitItem>),
64     /// Default trait implementation.
65     ///
66     /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
67     DefaultImpl(Unsafety, Path),
68     /// An implementation.
69     ///
70     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
71     Impl(Unsafety,
72          ImplPolarity,
73          Generics,
74          Option<Path>, // (optional) trait this impl implements
75          Box<Ty>, // self
76          Vec<ImplItem>),
77     /// A macro invocation (which includes macro definition).
78     ///
79     /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
80     Mac(Mac),
81 }
82 
83 impl From<DeriveInput> for Item {
from(input: DeriveInput) -> Item84     fn from(input: DeriveInput) -> Item {
85         Item {
86             ident: input.ident,
87             vis: input.vis,
88             attrs: input.attrs,
89             node: match input.body {
90                 Body::Enum(variants) => ItemKind::Enum(variants, input.generics),
91                 Body::Struct(variant_data) => ItemKind::Struct(variant_data, input.generics),
92             },
93         }
94     }
95 }
96 
97 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
98 pub enum ViewPath {
99     /// `foo::bar::baz as quux`
100     ///
101     /// or just
102     ///
103     /// `foo::bar::baz` (with `as baz` implicitly on the right)
104     Simple(Path, Option<Ident>),
105 
106     /// `foo::bar::*`
107     Glob(Path),
108 
109     /// `foo::bar::{a, b, c}`
110     List(Path, Vec<PathListItem>),
111 }
112 
113 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
114 pub struct PathListItem {
115     pub name: Ident,
116     /// renamed in list, e.g. `use foo::{bar as baz};`
117     pub rename: Option<Ident>,
118 }
119 
120 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
121 pub enum Constness {
122     Const,
123     NotConst,
124 }
125 
126 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
127 pub enum Defaultness {
128     Default,
129     Final,
130 }
131 
132 /// Foreign module declaration.
133 ///
134 /// E.g. `extern { .. }` or `extern "C" { .. }`
135 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
136 pub struct ForeignMod {
137     pub abi: Abi,
138     pub items: Vec<ForeignItem>,
139 }
140 
141 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
142 pub struct ForeignItem {
143     pub ident: Ident,
144     pub attrs: Vec<Attribute>,
145     pub node: ForeignItemKind,
146     pub vis: Visibility,
147 }
148 
149 /// An item within an `extern` block
150 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
151 pub enum ForeignItemKind {
152     /// A foreign function
153     Fn(Box<FnDecl>, Generics),
154     /// A foreign static item (`static ext: u8`)
155     Static(Box<Ty>, Mutability),
156 }
157 
158 /// Represents an item declaration within a trait declaration,
159 /// possibly including a default implementation. A trait item is
160 /// either required (meaning it doesn't have an implementation, just a
161 /// signature) or provided (meaning it has a default implementation).
162 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
163 pub struct TraitItem {
164     pub ident: Ident,
165     pub attrs: Vec<Attribute>,
166     pub node: TraitItemKind,
167 }
168 
169 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
170 pub enum TraitItemKind {
171     Const(Ty, Option<Expr>),
172     Method(MethodSig, Option<Block>),
173     Type(Vec<TyParamBound>, Option<Ty>),
174     Macro(Mac),
175 }
176 
177 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
178 pub enum ImplPolarity {
179     /// `impl Trait for Type`
180     Positive,
181     /// `impl !Trait for Type`
182     Negative,
183 }
184 
185 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
186 pub struct ImplItem {
187     pub ident: Ident,
188     pub vis: Visibility,
189     pub defaultness: Defaultness,
190     pub attrs: Vec<Attribute>,
191     pub node: ImplItemKind,
192 }
193 
194 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
195 pub enum ImplItemKind {
196     Const(Ty, Expr),
197     Method(MethodSig, Block),
198     Type(Ty),
199     Macro(Mac),
200 }
201 
202 /// Represents a method's signature in a trait declaration,
203 /// or in an implementation.
204 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
205 pub struct MethodSig {
206     pub unsafety: Unsafety,
207     pub constness: Constness,
208     pub abi: Option<Abi>,
209     pub decl: FnDecl,
210     pub generics: Generics,
211 }
212 
213 /// Header (not the body) of a function declaration.
214 ///
215 /// E.g. `fn foo(bar: baz)`
216 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
217 pub struct FnDecl {
218     pub inputs: Vec<FnArg>,
219     pub output: FunctionRetTy,
220     pub variadic: bool,
221 }
222 
223 /// An argument in a function header.
224 ///
225 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
226 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
227 pub enum FnArg {
228     SelfRef(Option<Lifetime>, Mutability),
229     SelfValue(Mutability),
230     Captured(Pat, Ty),
231     Ignored(Ty),
232 }
233 
234 #[cfg(feature = "parsing")]
235 pub mod parsing {
236     use super::*;
237     use {Block, DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData,
238          Visibility};
239     use attr::parsing::{inner_attr, outer_attr};
240     use data::parsing::{struct_like_body, visibility};
241     use expr::parsing::{expr, pat, within_block};
242     use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
243     use ident::parsing::ident;
244     use mac::parsing::delimited;
245     use derive::{Body, DeriveInput};
246     use derive::parsing::derive_input;
247     use ty::parsing::{abi, mutability, path, ty, unsafety};
248 
249     named!(pub item -> Item, alt!(
250         item_extern_crate
251         |
252         item_use
253         |
254         item_static
255         |
256         item_const
257         |
258         item_fn
259         |
260         item_mod
261         |
262         item_foreign_mod
263         |
264         item_ty
265         |
266         item_struct_or_enum
267         |
268         item_union
269         |
270         item_trait
271         |
272         item_default_impl
273         |
274         item_impl
275         |
276         item_mac
277     ));
278 
279     named!(pub items -> Vec<Item>, many0!(item));
280 
281     named!(item_mac -> Item, do_parse!(
282         attrs: many0!(outer_attr) >>
283         what: path >>
284         punct!("!") >>
285         name: option!(ident) >>
286         body: delimited >>
287         cond!(match body.delim {
288             DelimToken::Paren | DelimToken::Bracket => true,
289             DelimToken::Brace => false,
290         }, punct!(";")) >>
291         (Item {
292             ident: name.unwrap_or_else(|| Ident::new("")),
293             vis: Visibility::Inherited,
294             attrs: attrs,
295             node: ItemKind::Mac(Mac {
296                 path: what,
297                 tts: vec![TokenTree::Delimited(body)],
298             }),
299         })
300     ));
301 
302     named!(item_extern_crate -> Item, do_parse!(
303         attrs: many0!(outer_attr) >>
304         vis: visibility >>
305         keyword!("extern") >>
306         keyword!("crate") >>
307         id: ident >>
308         rename: option!(preceded!(
309             keyword!("as"),
310             ident
311         )) >>
312         punct!(";") >>
313         ({
314             let (name, original_name) = match rename {
315                 Some(rename) => (rename, Some(id)),
316                 None => (id, None),
317             };
318             Item {
319                 ident: name,
320                 vis: vis,
321                 attrs: attrs,
322                 node: ItemKind::ExternCrate(original_name),
323             }
324         })
325     ));
326 
327     named!(item_use -> Item, do_parse!(
328         attrs: many0!(outer_attr) >>
329         vis: visibility >>
330         keyword!("use") >>
331         what: view_path >>
332         punct!(";") >>
333         (Item {
334             ident: "".into(),
335             vis: vis,
336             attrs: attrs,
337             node: ItemKind::Use(Box::new(what)),
338         })
339     ));
340 
341     named!(view_path -> ViewPath, alt!(
342         view_path_glob
343         |
344         view_path_list
345         |
346         view_path_list_root
347         |
348         view_path_simple // must be last
349     ));
350 
351 
352     named!(view_path_simple -> ViewPath, do_parse!(
353         path: path >>
354         rename: option!(preceded!(keyword!("as"), ident)) >>
355         (ViewPath::Simple(path, rename))
356     ));
357 
358     named!(view_path_glob -> ViewPath, do_parse!(
359         path: path >>
360         punct!("::") >>
361         punct!("*") >>
362         (ViewPath::Glob(path))
363     ));
364 
365     named!(view_path_list -> ViewPath, do_parse!(
366         path: path >>
367         punct!("::") >>
368         punct!("{") >>
369         items: terminated_list!(punct!(","), path_list_item) >>
370         punct!("}") >>
371         (ViewPath::List(path, items))
372     ));
373 
374     named!(view_path_list_root -> ViewPath, do_parse!(
375         global: option!(punct!("::")) >>
376         punct!("{") >>
377         items: terminated_list!(punct!(","), path_list_item) >>
378         punct!("}") >>
379         (ViewPath::List(Path {
380             global: global.is_some(),
381             segments: Vec::new(),
382         }, items))
383     ));
384 
385     named!(path_list_item -> PathListItem, do_parse!(
386         name: alt!(
387             ident
388             |
389             map!(keyword!("self"), Into::into)
390         ) >>
391         rename: option!(preceded!(keyword!("as"), ident)) >>
392         (PathListItem {
393             name: name,
394             rename: rename,
395         })
396     ));
397 
398     named!(item_static -> Item, do_parse!(
399         attrs: many0!(outer_attr) >>
400         vis: visibility >>
401         keyword!("static") >>
402         mutability: mutability >>
403         id: ident >>
404         punct!(":") >>
405         ty: ty >>
406         punct!("=") >>
407         value: expr >>
408         punct!(";") >>
409         (Item {
410             ident: id,
411             vis: vis,
412             attrs: attrs,
413             node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
414         })
415     ));
416 
417     named!(item_const -> Item, do_parse!(
418         attrs: many0!(outer_attr) >>
419         vis: visibility >>
420         keyword!("const") >>
421         id: ident >>
422         punct!(":") >>
423         ty: ty >>
424         punct!("=") >>
425         value: expr >>
426         punct!(";") >>
427         (Item {
428             ident: id,
429             vis: vis,
430             attrs: attrs,
431             node: ItemKind::Const(Box::new(ty), Box::new(value)),
432         })
433     ));
434 
435     named!(item_fn -> Item, do_parse!(
436         outer_attrs: many0!(outer_attr) >>
437         vis: visibility >>
438         constness: constness >>
439         unsafety: unsafety >>
440         abi: option!(abi) >>
441         keyword!("fn") >>
442         name: ident >>
443         generics: generics >>
444         punct!("(") >>
445         inputs: terminated_list!(punct!(","), fn_arg) >>
446         punct!(")") >>
447         ret: option!(preceded!(punct!("->"), ty)) >>
448         where_clause: where_clause >>
449         punct!("{") >>
450         inner_attrs: many0!(inner_attr) >>
451         stmts: within_block >>
452         punct!("}") >>
453         (Item {
454             ident: name,
455             vis: vis,
456             attrs: {
457                 let mut attrs = outer_attrs;
458                 attrs.extend(inner_attrs);
459                 attrs
460             },
461             node: ItemKind::Fn(
462                 Box::new(FnDecl {
463                     inputs: inputs,
464                     output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
465                     variadic: false,
466                 }),
467                 unsafety,
468                 constness,
469                 abi,
470                 Generics {
471                     where_clause: where_clause,
472                     .. generics
473                 },
474                 Box::new(Block {
475                     stmts: stmts,
476                 }),
477             ),
478         })
479     ));
480 
481     named!(fn_arg -> FnArg, alt!(
482         do_parse!(
483             punct!("&") >>
484             lt: option!(lifetime) >>
485             mutability: mutability >>
486             keyword!("self") >>
487             not!(punct!(":")) >>
488             (FnArg::SelfRef(lt, mutability))
489         )
490         |
491         do_parse!(
492             mutability: mutability >>
493             keyword!("self") >>
494             not!(punct!(":")) >>
495             (FnArg::SelfValue(mutability))
496         )
497         |
498         do_parse!(
499             pat: pat >>
500             punct!(":") >>
501             ty: ty >>
502             (FnArg::Captured(pat, ty))
503         )
504         |
505         ty => { FnArg::Ignored }
506     ));
507 
508     named!(item_mod -> Item, do_parse!(
509         outer_attrs: many0!(outer_attr) >>
510         vis: visibility >>
511         keyword!("mod") >>
512         id: ident >>
513         content: alt!(
514             punct!(";") => { |_| None }
515             |
516             delimited!(
517                 punct!("{"),
518                 tuple!(
519                     many0!(inner_attr),
520                     items
521                 ),
522                 punct!("}")
523             ) => { Some }
524         ) >>
525         (match content {
526             Some((inner_attrs, items)) => Item {
527                 ident: id,
528                 vis: vis,
529                 attrs: {
530                     let mut attrs = outer_attrs;
531                     attrs.extend(inner_attrs);
532                     attrs
533                 },
534                 node: ItemKind::Mod(Some(items)),
535             },
536             None => Item {
537                 ident: id,
538                 vis: vis,
539                 attrs: outer_attrs,
540                 node: ItemKind::Mod(None),
541             },
542         })
543     ));
544 
545     named!(item_foreign_mod -> Item, do_parse!(
546         attrs: many0!(outer_attr) >>
547         abi: abi >>
548         punct!("{") >>
549         items: many0!(foreign_item) >>
550         punct!("}") >>
551         (Item {
552             ident: "".into(),
553             vis: Visibility::Inherited,
554             attrs: attrs,
555             node: ItemKind::ForeignMod(ForeignMod {
556                 abi: abi,
557                 items: items,
558             }),
559         })
560     ));
561 
562     named!(foreign_item -> ForeignItem, alt!(
563         foreign_fn
564         |
565         foreign_static
566     ));
567 
568     named!(foreign_fn -> ForeignItem, do_parse!(
569         attrs: many0!(outer_attr) >>
570         vis: visibility >>
571         keyword!("fn") >>
572         name: ident >>
573         generics: generics >>
574         punct!("(") >>
575         inputs: separated_list!(punct!(","), fn_arg) >>
576         trailing_comma: option!(punct!(",")) >>
577         variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
578         punct!(")") >>
579         ret: option!(preceded!(punct!("->"), ty)) >>
580         where_clause: where_clause >>
581         punct!(";") >>
582         (ForeignItem {
583             ident: name,
584             attrs: attrs,
585             node: ForeignItemKind::Fn(
586                 Box::new(FnDecl {
587                     inputs: inputs,
588                     output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
589                     variadic: variadic.is_some(),
590                 }),
591                 Generics {
592                     where_clause: where_clause,
593                     .. generics
594                 },
595             ),
596             vis: vis,
597         })
598     ));
599 
600     named!(foreign_static -> ForeignItem, do_parse!(
601         attrs: many0!(outer_attr) >>
602         vis: visibility >>
603         keyword!("static") >>
604         mutability: mutability >>
605         id: ident >>
606         punct!(":") >>
607         ty: ty >>
608         punct!(";") >>
609         (ForeignItem {
610             ident: id,
611             attrs: attrs,
612             node: ForeignItemKind::Static(Box::new(ty), mutability),
613             vis: vis,
614         })
615     ));
616 
617     named!(item_ty -> Item, do_parse!(
618         attrs: many0!(outer_attr) >>
619         vis: visibility >>
620         keyword!("type") >>
621         id: ident >>
622         generics: generics >>
623         where_clause: where_clause >>
624         punct!("=") >>
625         ty: ty >>
626         punct!(";") >>
627         (Item {
628             ident: id,
629             vis: vis,
630             attrs: attrs,
631             node: ItemKind::Ty(
632                 Box::new(ty),
633                 Generics {
634                     where_clause: where_clause,
635                     ..generics
636                 },
637             ),
638         })
639     ));
640 
641     named!(item_struct_or_enum -> Item, map!(
642         derive_input,
643         |def: DeriveInput| Item {
644             ident: def.ident,
645             vis: def.vis,
646             attrs: def.attrs,
647             node: match def.body {
648                 Body::Enum(variants) => {
649                     ItemKind::Enum(variants, def.generics)
650                 }
651                 Body::Struct(variant_data) => {
652                     ItemKind::Struct(variant_data, def.generics)
653                 }
654             }
655         }
656     ));
657 
658     named!(item_union -> Item, do_parse!(
659         attrs: many0!(outer_attr) >>
660         vis: visibility >>
661         keyword!("union") >>
662         id: ident >>
663         generics: generics >>
664         where_clause: where_clause >>
665         fields: struct_like_body >>
666         (Item {
667             ident: id,
668             vis: vis,
669             attrs: attrs,
670             node: ItemKind::Union(
671                 VariantData::Struct(fields),
672                 Generics {
673                     where_clause: where_clause,
674                     .. generics
675                 },
676             ),
677         })
678     ));
679 
680     named!(item_trait -> Item, do_parse!(
681         attrs: many0!(outer_attr) >>
682         vis: visibility >>
683         unsafety: unsafety >>
684         keyword!("trait") >>
685         id: ident >>
686         generics: generics >>
687         bounds: opt_vec!(preceded!(
688             punct!(":"),
689             separated_nonempty_list!(punct!("+"), ty_param_bound)
690         )) >>
691         where_clause: where_clause >>
692         punct!("{") >>
693         body: many0!(trait_item) >>
694         punct!("}") >>
695         (Item {
696             ident: id,
697             vis: vis,
698             attrs: attrs,
699             node: ItemKind::Trait(
700                 unsafety,
701                 Generics {
702                     where_clause: where_clause,
703                     .. generics
704                 },
705                 bounds,
706                 body,
707             ),
708         })
709     ));
710 
711     named!(item_default_impl -> Item, do_parse!(
712         attrs: many0!(outer_attr) >>
713         unsafety: unsafety >>
714         keyword!("impl") >>
715         path: path >>
716         keyword!("for") >>
717         punct!("..") >>
718         punct!("{") >>
719         punct!("}") >>
720         (Item {
721             ident: "".into(),
722             vis: Visibility::Inherited,
723             attrs: attrs,
724             node: ItemKind::DefaultImpl(unsafety, path),
725         })
726     ));
727 
728     named!(trait_item -> TraitItem, alt!(
729         trait_item_const
730         |
731         trait_item_method
732         |
733         trait_item_type
734         |
735         trait_item_mac
736     ));
737 
738     named!(trait_item_const -> TraitItem, do_parse!(
739         attrs: many0!(outer_attr) >>
740         keyword!("const") >>
741         id: ident >>
742         punct!(":") >>
743         ty: ty >>
744         value: option!(preceded!(punct!("="), expr)) >>
745         punct!(";") >>
746         (TraitItem {
747             ident: id,
748             attrs: attrs,
749             node: TraitItemKind::Const(ty, value),
750         })
751     ));
752 
753     named!(trait_item_method -> TraitItem, do_parse!(
754         outer_attrs: many0!(outer_attr) >>
755         constness: constness >>
756         unsafety: unsafety >>
757         abi: option!(abi) >>
758         keyword!("fn") >>
759         name: ident >>
760         generics: generics >>
761         punct!("(") >>
762         inputs: terminated_list!(punct!(","), fn_arg) >>
763         punct!(")") >>
764         ret: option!(preceded!(punct!("->"), ty)) >>
765         where_clause: where_clause >>
766         body: option!(delimited!(
767             punct!("{"),
768             tuple!(many0!(inner_attr), within_block),
769             punct!("}")
770         )) >>
771         cond!(body.is_none(), punct!(";")) >>
772         ({
773             let (inner_attrs, stmts) = match body {
774                 Some((inner_attrs, stmts)) => (inner_attrs, Some(stmts)),
775                 None => (Vec::new(), None),
776             };
777             TraitItem {
778                 ident: name,
779                 attrs: {
780                     let mut attrs = outer_attrs;
781                     attrs.extend(inner_attrs);
782                     attrs
783                 },
784                 node: TraitItemKind::Method(
785                     MethodSig {
786                         unsafety: unsafety,
787                         constness: constness,
788                         abi: abi,
789                         decl: FnDecl {
790                             inputs: inputs,
791                             output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
792                             variadic: false,
793                         },
794                         generics: Generics {
795                             where_clause: where_clause,
796                             .. generics
797                         },
798                     },
799                     stmts.map(|stmts| Block { stmts: stmts }),
800                 ),
801             }
802         })
803     ));
804 
805     named!(trait_item_type -> TraitItem, do_parse!(
806         attrs: many0!(outer_attr) >>
807         keyword!("type") >>
808         id: ident >>
809         bounds: opt_vec!(preceded!(
810             punct!(":"),
811             separated_nonempty_list!(punct!("+"), ty_param_bound)
812         )) >>
813         default: option!(preceded!(punct!("="), ty)) >>
814         punct!(";") >>
815         (TraitItem {
816             ident: id,
817             attrs: attrs,
818             node: TraitItemKind::Type(bounds, default),
819         })
820     ));
821 
822     named!(trait_item_mac -> TraitItem, do_parse!(
823         attrs: many0!(outer_attr) >>
824         what: path >>
825         punct!("!") >>
826         body: delimited >>
827         cond!(match body.delim {
828             DelimToken::Paren | DelimToken::Bracket => true,
829             DelimToken::Brace => false,
830         }, punct!(";")) >>
831         (TraitItem {
832             ident: Ident::new(""),
833             attrs: attrs,
834             node: TraitItemKind::Macro(Mac {
835                 path: what,
836                 tts: vec![TokenTree::Delimited(body)],
837             }),
838         })
839     ));
840 
841     named!(item_impl -> Item, do_parse!(
842         attrs: many0!(outer_attr) >>
843         unsafety: unsafety >>
844         keyword!("impl") >>
845         generics: generics >>
846         polarity_path: alt!(
847             do_parse!(
848                 polarity: impl_polarity >>
849                 path: path >>
850                 keyword!("for") >>
851                 (polarity, Some(path))
852             )
853             |
854             epsilon!() => { |_| (ImplPolarity::Positive, None) }
855         ) >>
856         self_ty: ty >>
857         where_clause: where_clause >>
858         punct!("{") >>
859         body: many0!(impl_item) >>
860         punct!("}") >>
861         (Item {
862             ident: "".into(),
863             vis: Visibility::Inherited,
864             attrs: attrs,
865             node: ItemKind::Impl(
866                 unsafety,
867                 polarity_path.0,
868                 Generics {
869                     where_clause: where_clause,
870                     .. generics
871                 },
872                 polarity_path.1,
873                 Box::new(self_ty),
874                 body,
875             ),
876         })
877     ));
878 
879     named!(impl_item -> ImplItem, alt!(
880         impl_item_const
881         |
882         impl_item_method
883         |
884         impl_item_type
885         |
886         impl_item_macro
887     ));
888 
889     named!(impl_item_const -> ImplItem, do_parse!(
890         attrs: many0!(outer_attr) >>
891         vis: visibility >>
892         defaultness: defaultness >>
893         keyword!("const") >>
894         id: ident >>
895         punct!(":") >>
896         ty: ty >>
897         punct!("=") >>
898         value: expr >>
899         punct!(";") >>
900         (ImplItem {
901             ident: id,
902             vis: vis,
903             defaultness: defaultness,
904             attrs: attrs,
905             node: ImplItemKind::Const(ty, value),
906         })
907     ));
908 
909     named!(impl_item_method -> ImplItem, do_parse!(
910         outer_attrs: many0!(outer_attr) >>
911         vis: visibility >>
912         defaultness: defaultness >>
913         constness: constness >>
914         unsafety: unsafety >>
915         abi: option!(abi) >>
916         keyword!("fn") >>
917         name: ident >>
918         generics: generics >>
919         punct!("(") >>
920         inputs: terminated_list!(punct!(","), fn_arg) >>
921         punct!(")") >>
922         ret: option!(preceded!(punct!("->"), ty)) >>
923         where_clause: where_clause >>
924         punct!("{") >>
925         inner_attrs: many0!(inner_attr) >>
926         stmts: within_block >>
927         punct!("}") >>
928         (ImplItem {
929             ident: name,
930             vis: vis,
931             defaultness: defaultness,
932             attrs: {
933                 let mut attrs = outer_attrs;
934                 attrs.extend(inner_attrs);
935                 attrs
936             },
937             node: ImplItemKind::Method(
938                 MethodSig {
939                     unsafety: unsafety,
940                     constness: constness,
941                     abi: abi,
942                     decl: FnDecl {
943                         inputs: inputs,
944                         output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
945                         variadic: false,
946                     },
947                     generics: Generics {
948                         where_clause: where_clause,
949                         .. generics
950                     },
951                 },
952                 Block {
953                     stmts: stmts,
954                 },
955             ),
956         })
957     ));
958 
959     named!(impl_item_type -> ImplItem, do_parse!(
960         attrs: many0!(outer_attr) >>
961         vis: visibility >>
962         defaultness: defaultness >>
963         keyword!("type") >>
964         id: ident >>
965         punct!("=") >>
966         ty: ty >>
967         punct!(";") >>
968         (ImplItem {
969             ident: id,
970             vis: vis,
971             defaultness: defaultness,
972             attrs: attrs,
973             node: ImplItemKind::Type(ty),
974         })
975     ));
976 
977     named!(impl_item_macro -> ImplItem, do_parse!(
978         attrs: many0!(outer_attr) >>
979         what: path >>
980         punct!("!") >>
981         body: delimited >>
982         cond!(match body.delim {
983             DelimToken::Paren | DelimToken::Bracket => true,
984             DelimToken::Brace => false,
985         }, punct!(";")) >>
986         (ImplItem {
987             ident: Ident::new(""),
988             vis: Visibility::Inherited,
989             defaultness: Defaultness::Final,
990             attrs: attrs,
991             node: ImplItemKind::Macro(Mac {
992                 path: what,
993                 tts: vec![TokenTree::Delimited(body)],
994             }),
995         })
996     ));
997 
998     named!(impl_polarity -> ImplPolarity, alt!(
999         punct!("!") => { |_| ImplPolarity::Negative }
1000         |
1001         epsilon!() => { |_| ImplPolarity::Positive }
1002     ));
1003 
1004     named!(constness -> Constness, alt!(
1005         keyword!("const") => { |_| Constness::Const }
1006         |
1007         epsilon!() => { |_| Constness::NotConst }
1008     ));
1009 
1010     named!(defaultness -> Defaultness, alt!(
1011         keyword!("default") => { |_| Defaultness::Default }
1012         |
1013         epsilon!() => { |_| Defaultness::Final }
1014     ));
1015 }
1016 
1017 #[cfg(feature = "printing")]
1018 mod printing {
1019     use super::*;
1020     use {Delimited, DelimToken, FunctionRetTy, TokenTree};
1021     use attr::FilterAttrs;
1022     use data::VariantData;
1023     use quote::{Tokens, ToTokens};
1024 
1025     impl ToTokens for Item {
to_tokens(&self, tokens: &mut Tokens)1026         fn to_tokens(&self, tokens: &mut Tokens) {
1027             tokens.append_all(self.attrs.outer());
1028             match self.node {
1029                 ItemKind::ExternCrate(ref original) => {
1030                     self.vis.to_tokens(tokens);
1031                     tokens.append("extern");
1032                     tokens.append("crate");
1033                     if let Some(ref original) = *original {
1034                         original.to_tokens(tokens);
1035                         tokens.append("as");
1036                     }
1037                     self.ident.to_tokens(tokens);
1038                     tokens.append(";");
1039                 }
1040                 ItemKind::Use(ref view_path) => {
1041                     self.vis.to_tokens(tokens);
1042                     tokens.append("use");
1043                     view_path.to_tokens(tokens);
1044                     tokens.append(";");
1045                 }
1046                 ItemKind::Static(ref ty, ref mutability, ref expr) => {
1047                     self.vis.to_tokens(tokens);
1048                     tokens.append("static");
1049                     mutability.to_tokens(tokens);
1050                     self.ident.to_tokens(tokens);
1051                     tokens.append(":");
1052                     ty.to_tokens(tokens);
1053                     tokens.append("=");
1054                     expr.to_tokens(tokens);
1055                     tokens.append(";");
1056                 }
1057                 ItemKind::Const(ref ty, ref expr) => {
1058                     self.vis.to_tokens(tokens);
1059                     tokens.append("const");
1060                     self.ident.to_tokens(tokens);
1061                     tokens.append(":");
1062                     ty.to_tokens(tokens);
1063                     tokens.append("=");
1064                     expr.to_tokens(tokens);
1065                     tokens.append(";");
1066                 }
1067                 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
1068                     self.vis.to_tokens(tokens);
1069                     constness.to_tokens(tokens);
1070                     unsafety.to_tokens(tokens);
1071                     abi.to_tokens(tokens);
1072                     tokens.append("fn");
1073                     self.ident.to_tokens(tokens);
1074                     generics.to_tokens(tokens);
1075                     tokens.append("(");
1076                     tokens.append_separated(&decl.inputs, ",");
1077                     tokens.append(")");
1078                     if let FunctionRetTy::Ty(ref ty) = decl.output {
1079                         tokens.append("->");
1080                         ty.to_tokens(tokens);
1081                     }
1082                     generics.where_clause.to_tokens(tokens);
1083                     tokens.append("{");
1084                     tokens.append_all(self.attrs.inner());
1085                     tokens.append_all(&block.stmts);
1086                     tokens.append("}");
1087                 }
1088                 ItemKind::Mod(ref items) => {
1089                     self.vis.to_tokens(tokens);
1090                     tokens.append("mod");
1091                     self.ident.to_tokens(tokens);
1092                     match *items {
1093                         Some(ref items) => {
1094                             tokens.append("{");
1095                             tokens.append_all(self.attrs.inner());
1096                             tokens.append_all(items);
1097                             tokens.append("}");
1098                         }
1099                         None => tokens.append(";"),
1100                     }
1101                 }
1102                 ItemKind::ForeignMod(ref foreign_mod) => {
1103                     self.vis.to_tokens(tokens);
1104                     foreign_mod.abi.to_tokens(tokens);
1105                     tokens.append("{");
1106                     tokens.append_all(&foreign_mod.items);
1107                     tokens.append("}");
1108                 }
1109                 ItemKind::Ty(ref ty, ref generics) => {
1110                     self.vis.to_tokens(tokens);
1111                     tokens.append("type");
1112                     self.ident.to_tokens(tokens);
1113                     generics.to_tokens(tokens);
1114                     generics.where_clause.to_tokens(tokens);
1115                     tokens.append("=");
1116                     ty.to_tokens(tokens);
1117                     tokens.append(";");
1118                 }
1119                 ItemKind::Enum(ref variants, ref generics) => {
1120                     self.vis.to_tokens(tokens);
1121                     tokens.append("enum");
1122                     self.ident.to_tokens(tokens);
1123                     generics.to_tokens(tokens);
1124                     generics.where_clause.to_tokens(tokens);
1125                     tokens.append("{");
1126                     for variant in variants {
1127                         variant.to_tokens(tokens);
1128                         tokens.append(",");
1129                     }
1130                     tokens.append("}");
1131                 }
1132                 ItemKind::Struct(ref variant_data, ref generics) => {
1133                     self.vis.to_tokens(tokens);
1134                     tokens.append("struct");
1135                     self.ident.to_tokens(tokens);
1136                     generics.to_tokens(tokens);
1137                     match *variant_data {
1138                         VariantData::Struct(_) => {
1139                             generics.where_clause.to_tokens(tokens);
1140                             variant_data.to_tokens(tokens);
1141                             // no semicolon
1142                         }
1143                         VariantData::Tuple(_) => {
1144                             variant_data.to_tokens(tokens);
1145                             generics.where_clause.to_tokens(tokens);
1146                             tokens.append(";");
1147                         }
1148                         VariantData::Unit => {
1149                             generics.where_clause.to_tokens(tokens);
1150                             tokens.append(";");
1151                         }
1152                     }
1153                 }
1154                 ItemKind::Union(ref variant_data, ref generics) => {
1155                     self.vis.to_tokens(tokens);
1156                     tokens.append("union");
1157                     self.ident.to_tokens(tokens);
1158                     generics.to_tokens(tokens);
1159                     generics.where_clause.to_tokens(tokens);
1160                     variant_data.to_tokens(tokens);
1161                 }
1162                 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
1163                     self.vis.to_tokens(tokens);
1164                     unsafety.to_tokens(tokens);
1165                     tokens.append("trait");
1166                     self.ident.to_tokens(tokens);
1167                     generics.to_tokens(tokens);
1168                     if !bound.is_empty() {
1169                         tokens.append(":");
1170                         tokens.append_separated(bound, "+");
1171                     }
1172                     generics.where_clause.to_tokens(tokens);
1173                     tokens.append("{");
1174                     tokens.append_all(items);
1175                     tokens.append("}");
1176                 }
1177                 ItemKind::DefaultImpl(unsafety, ref path) => {
1178                     unsafety.to_tokens(tokens);
1179                     tokens.append("impl");
1180                     path.to_tokens(tokens);
1181                     tokens.append("for");
1182                     tokens.append("..");
1183                     tokens.append("{");
1184                     tokens.append("}");
1185                 }
1186                 ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => {
1187                     unsafety.to_tokens(tokens);
1188                     tokens.append("impl");
1189                     generics.to_tokens(tokens);
1190                     if let Some(ref path) = *path {
1191                         polarity.to_tokens(tokens);
1192                         path.to_tokens(tokens);
1193                         tokens.append("for");
1194                     }
1195                     ty.to_tokens(tokens);
1196                     generics.where_clause.to_tokens(tokens);
1197                     tokens.append("{");
1198                     tokens.append_all(items);
1199                     tokens.append("}");
1200                 }
1201                 ItemKind::Mac(ref mac) => {
1202                     mac.path.to_tokens(tokens);
1203                     tokens.append("!");
1204                     self.ident.to_tokens(tokens);
1205                     for tt in &mac.tts {
1206                         tt.to_tokens(tokens);
1207                     }
1208                     match mac.tts.last() {
1209                         Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1210                             // no semicolon
1211                         }
1212                         _ => tokens.append(";"),
1213                     }
1214                 }
1215             }
1216         }
1217     }
1218 
1219     impl ToTokens for ViewPath {
to_tokens(&self, tokens: &mut Tokens)1220         fn to_tokens(&self, tokens: &mut Tokens) {
1221             match *self {
1222                 ViewPath::Simple(ref path, ref rename) => {
1223                     path.to_tokens(tokens);
1224                     if let Some(ref rename) = *rename {
1225                         tokens.append("as");
1226                         rename.to_tokens(tokens);
1227                     }
1228                 }
1229                 ViewPath::Glob(ref path) => {
1230                     path.to_tokens(tokens);
1231                     tokens.append("::");
1232                     tokens.append("*");
1233                 }
1234                 ViewPath::List(ref path, ref items) => {
1235                     path.to_tokens(tokens);
1236                     if path.global || !path.segments.is_empty() {
1237                         tokens.append("::");
1238                     }
1239                     tokens.append("{");
1240                     tokens.append_separated(items, ",");
1241                     tokens.append("}");
1242                 }
1243             }
1244         }
1245     }
1246 
1247     impl ToTokens for PathListItem {
to_tokens(&self, tokens: &mut Tokens)1248         fn to_tokens(&self, tokens: &mut Tokens) {
1249             self.name.to_tokens(tokens);
1250             if let Some(ref rename) = self.rename {
1251                 tokens.append("as");
1252                 rename.to_tokens(tokens);
1253             }
1254         }
1255     }
1256 
1257     impl ToTokens for TraitItem {
to_tokens(&self, tokens: &mut Tokens)1258         fn to_tokens(&self, tokens: &mut Tokens) {
1259             tokens.append_all(self.attrs.outer());
1260             match self.node {
1261                 TraitItemKind::Const(ref ty, ref expr) => {
1262                     tokens.append("const");
1263                     self.ident.to_tokens(tokens);
1264                     tokens.append(":");
1265                     ty.to_tokens(tokens);
1266                     if let Some(ref expr) = *expr {
1267                         tokens.append("=");
1268                         expr.to_tokens(tokens);
1269                     }
1270                     tokens.append(";");
1271                 }
1272                 TraitItemKind::Method(ref sig, ref block) => {
1273                     sig.constness.to_tokens(tokens);
1274                     sig.unsafety.to_tokens(tokens);
1275                     sig.abi.to_tokens(tokens);
1276                     tokens.append("fn");
1277                     self.ident.to_tokens(tokens);
1278                     sig.generics.to_tokens(tokens);
1279                     tokens.append("(");
1280                     tokens.append_separated(&sig.decl.inputs, ",");
1281                     tokens.append(")");
1282                     if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1283                         tokens.append("->");
1284                         ty.to_tokens(tokens);
1285                     }
1286                     sig.generics.where_clause.to_tokens(tokens);
1287                     match *block {
1288                         Some(ref block) => {
1289                             tokens.append("{");
1290                             tokens.append_all(self.attrs.inner());
1291                             tokens.append_all(&block.stmts);
1292                             tokens.append("}");
1293                         }
1294                         None => tokens.append(";"),
1295                     }
1296                 }
1297                 TraitItemKind::Type(ref bound, ref default) => {
1298                     tokens.append("type");
1299                     self.ident.to_tokens(tokens);
1300                     if !bound.is_empty() {
1301                         tokens.append(":");
1302                         tokens.append_separated(bound, "+");
1303                     }
1304                     if let Some(ref default) = *default {
1305                         tokens.append("=");
1306                         default.to_tokens(tokens);
1307                     }
1308                     tokens.append(";");
1309                 }
1310                 TraitItemKind::Macro(ref mac) => {
1311                     mac.to_tokens(tokens);
1312                     match mac.tts.last() {
1313                         Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1314                             // no semicolon
1315                         }
1316                         _ => tokens.append(";"),
1317                     }
1318                 }
1319             }
1320         }
1321     }
1322 
1323     impl ToTokens for ImplItem {
to_tokens(&self, tokens: &mut Tokens)1324         fn to_tokens(&self, tokens: &mut Tokens) {
1325             tokens.append_all(self.attrs.outer());
1326             match self.node {
1327                 ImplItemKind::Const(ref ty, ref expr) => {
1328                     self.vis.to_tokens(tokens);
1329                     self.defaultness.to_tokens(tokens);
1330                     tokens.append("const");
1331                     self.ident.to_tokens(tokens);
1332                     tokens.append(":");
1333                     ty.to_tokens(tokens);
1334                     tokens.append("=");
1335                     expr.to_tokens(tokens);
1336                     tokens.append(";");
1337                 }
1338                 ImplItemKind::Method(ref sig, ref block) => {
1339                     self.vis.to_tokens(tokens);
1340                     self.defaultness.to_tokens(tokens);
1341                     sig.constness.to_tokens(tokens);
1342                     sig.unsafety.to_tokens(tokens);
1343                     sig.abi.to_tokens(tokens);
1344                     tokens.append("fn");
1345                     self.ident.to_tokens(tokens);
1346                     sig.generics.to_tokens(tokens);
1347                     tokens.append("(");
1348                     tokens.append_separated(&sig.decl.inputs, ",");
1349                     tokens.append(")");
1350                     if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1351                         tokens.append("->");
1352                         ty.to_tokens(tokens);
1353                     }
1354                     sig.generics.where_clause.to_tokens(tokens);
1355                     tokens.append("{");
1356                     tokens.append_all(self.attrs.inner());
1357                     tokens.append_all(&block.stmts);
1358                     tokens.append("}");
1359                 }
1360                 ImplItemKind::Type(ref ty) => {
1361                     self.vis.to_tokens(tokens);
1362                     self.defaultness.to_tokens(tokens);
1363                     tokens.append("type");
1364                     self.ident.to_tokens(tokens);
1365                     tokens.append("=");
1366                     ty.to_tokens(tokens);
1367                     tokens.append(";");
1368                 }
1369                 ImplItemKind::Macro(ref mac) => {
1370                     mac.to_tokens(tokens);
1371                     match mac.tts.last() {
1372                         Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1373                             // no semicolon
1374                         }
1375                         _ => tokens.append(";"),
1376                     }
1377                 }
1378             }
1379         }
1380     }
1381 
1382     impl ToTokens for ForeignItem {
to_tokens(&self, tokens: &mut Tokens)1383         fn to_tokens(&self, tokens: &mut Tokens) {
1384             tokens.append_all(self.attrs.outer());
1385             match self.node {
1386                 ForeignItemKind::Fn(ref decl, ref generics) => {
1387                     self.vis.to_tokens(tokens);
1388                     tokens.append("fn");
1389                     self.ident.to_tokens(tokens);
1390                     generics.to_tokens(tokens);
1391                     tokens.append("(");
1392                     tokens.append_separated(&decl.inputs, ",");
1393                     if decl.variadic {
1394                         if !decl.inputs.is_empty() {
1395                             tokens.append(",");
1396                         }
1397                         tokens.append("...");
1398                     }
1399                     tokens.append(")");
1400                     if let FunctionRetTy::Ty(ref ty) = decl.output {
1401                         tokens.append("->");
1402                         ty.to_tokens(tokens);
1403                     }
1404                     generics.where_clause.to_tokens(tokens);
1405                     tokens.append(";");
1406                 }
1407                 ForeignItemKind::Static(ref ty, mutability) => {
1408                     self.vis.to_tokens(tokens);
1409                     tokens.append("static");
1410                     mutability.to_tokens(tokens);
1411                     self.ident.to_tokens(tokens);
1412                     tokens.append(":");
1413                     ty.to_tokens(tokens);
1414                     tokens.append(";");
1415                 }
1416             }
1417         }
1418     }
1419 
1420     impl ToTokens for FnArg {
to_tokens(&self, tokens: &mut Tokens)1421         fn to_tokens(&self, tokens: &mut Tokens) {
1422             match *self {
1423                 FnArg::SelfRef(ref lifetime, mutability) => {
1424                     tokens.append("&");
1425                     lifetime.to_tokens(tokens);
1426                     mutability.to_tokens(tokens);
1427                     tokens.append("self");
1428                 }
1429                 FnArg::SelfValue(mutability) => {
1430                     mutability.to_tokens(tokens);
1431                     tokens.append("self");
1432                 }
1433                 FnArg::Captured(ref pat, ref ty) => {
1434                     pat.to_tokens(tokens);
1435                     tokens.append(":");
1436                     ty.to_tokens(tokens);
1437                 }
1438                 FnArg::Ignored(ref ty) => {
1439                     ty.to_tokens(tokens);
1440                 }
1441             }
1442         }
1443     }
1444 
1445     impl ToTokens for Constness {
to_tokens(&self, tokens: &mut Tokens)1446         fn to_tokens(&self, tokens: &mut Tokens) {
1447             match *self {
1448                 Constness::Const => tokens.append("const"),
1449                 Constness::NotConst => {
1450                     // nothing
1451                 }
1452             }
1453         }
1454     }
1455 
1456     impl ToTokens for Defaultness {
to_tokens(&self, tokens: &mut Tokens)1457         fn to_tokens(&self, tokens: &mut Tokens) {
1458             match *self {
1459                 Defaultness::Default => tokens.append("default"),
1460                 Defaultness::Final => {
1461                     // nothing
1462                 }
1463             }
1464         }
1465     }
1466 
1467     impl ToTokens for ImplPolarity {
to_tokens(&self, tokens: &mut Tokens)1468         fn to_tokens(&self, tokens: &mut Tokens) {
1469             match *self {
1470                 ImplPolarity::Negative => tokens.append("!"),
1471                 ImplPolarity::Positive => {
1472                     // nothing
1473                 }
1474             }
1475         }
1476     }
1477 }
1478