blob: 7ba0ac5981ced9ebd16e0160bb7a8f3b232601fd [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnay771ecf42016-09-23 19:26:37 -07003/// An item
4///
5/// The name might be a dummy name in case of anonymous items
David Tolnayb79ee962016-09-04 09:39:20 -07006#[derive(Debug, Clone, Eq, PartialEq)]
7pub struct Item {
8 pub ident: Ident,
9 pub vis: Visibility,
10 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -070011 pub node: ItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -070012}
13
14#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -070015pub 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 { .. }`
David Tolnay42602292016-10-01 22:25:45 -070035 Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
David Tolnayf38cdf62016-09-23 19:07:09 -070036 /// A module declaration (`mod` or `pub mod`).
37 ///
38 /// E.g. `mod foo;` or `mod foo { .. }`
David Tolnay37d10332016-10-13 20:51:04 -070039 Mod(Option<Vec<Item>>),
David Tolnayf38cdf62016-09-23 19:07:09 -070040 /// 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>),
David Tolnay0aecb732016-10-03 23:03:50 -070064 /// Default trait implementation.
David Tolnayf38cdf62016-09-23 19:07:09 -070065 ///
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,
David Tolnaydaaf7742016-10-03 11:11:43 -070072 ImplPolarity,
73 Generics,
74 Option<Path>, // (optional) trait this impl implements
75 Box<Ty>, // self
76 Vec<ImplItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -070077 /// A macro invocation (which includes macro definition).
78 ///
79 /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
80 Mac(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -070081}
82
David Tolnay453cfd12016-10-23 11:00:14 -070083impl From<MacroInput> for Item {
84 fn from(input: MacroInput) -> 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
David Tolnayb79ee962016-09-04 09:39:20 -070097#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -070098pub enum ViewPath {
99 /// `foo::bar::baz as quux`
100 ///
101 /// or just
102 ///
103 /// `foo::bar::baz` (with `as baz` implicitly on the right)
David Tolnay4a057422016-10-08 00:02:31 -0700104 Simple(Path, Option<Ident>),
David Tolnayf38cdf62016-09-23 19:07:09 -0700105
106 /// `foo::bar::*`
David Tolnayaed77b02016-09-23 20:50:31 -0700107 Glob(Path),
David Tolnayf38cdf62016-09-23 19:07:09 -0700108
David Tolnayaed77b02016-09-23 20:50:31 -0700109 /// `foo::bar::{a, b, c}`
David Tolnaydaaf7742016-10-03 11:11:43 -0700110 List(Path, Vec<PathListItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -0700111}
112
113#[derive(Debug, Clone, Eq, PartialEq)]
114pub 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)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700121pub enum Constness {
122 Const,
123 NotConst,
124}
125
126#[derive(Debug, Copy, Clone, Eq, PartialEq)]
127pub enum Defaultness {
128 Default,
129 Final,
130}
131
David Tolnayf38cdf62016-09-23 19:07:09 -0700132/// Foreign module declaration.
133///
David Tolnay35902302016-10-06 01:11:08 -0700134/// E.g. `extern { .. }` or `extern "C" { .. }`
David Tolnayf38cdf62016-09-23 19:07:09 -0700135#[derive(Debug, Clone, Eq, PartialEq)]
136pub struct ForeignMod {
David Tolnayb8d8ef52016-10-29 14:30:08 -0700137 pub abi: Abi,
David Tolnayf38cdf62016-09-23 19:07:09 -0700138 pub items: Vec<ForeignItem>,
139}
140
141#[derive(Debug, Clone, Eq, PartialEq)]
142pub struct ForeignItem {
David Tolnayb79ee962016-09-04 09:39:20 -0700143 pub ident: Ident,
144 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700145 pub node: ForeignItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -0700146 pub vis: Visibility,
David Tolnayf38cdf62016-09-23 19:07:09 -0700147}
148
David Tolnay771ecf42016-09-23 19:26:37 -0700149/// An item within an `extern` block
David Tolnayf38cdf62016-09-23 19:07:09 -0700150#[derive(Debug, Clone, Eq, PartialEq)]
151pub enum ForeignItemKind {
152 /// A foreign function
153 Fn(Box<FnDecl>, Generics),
David Tolnay35902302016-10-06 01:11:08 -0700154 /// A foreign static item (`static ext: u8`)
155 Static(Box<Ty>, Mutability),
David Tolnayf38cdf62016-09-23 19:07:09 -0700156}
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)]
163pub struct TraitItem {
164 pub ident: Ident,
David Tolnayb79ee962016-09-04 09:39:20 -0700165 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700166 pub node: TraitItemKind,
167}
168
169#[derive(Debug, Clone, Eq, PartialEq)]
170pub enum TraitItemKind {
171 Const(Ty, Option<Expr>),
172 Method(MethodSig, Option<Block>),
173 Type(Vec<TyParamBound>, Option<Ty>),
174 Macro(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -0700175}
176
David Tolnay55337722016-09-11 12:58:56 -0700177#[derive(Debug, Copy, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700178pub enum ImplPolarity {
179 /// `impl Trait for Type`
180 Positive,
181 /// `impl !Trait for Type`
182 Negative,
David Tolnay55337722016-09-11 12:58:56 -0700183}
184
David Tolnayf38cdf62016-09-23 19:07:09 -0700185#[derive(Debug, Clone, Eq, PartialEq)]
186pub struct ImplItem {
187 pub ident: Ident,
188 pub vis: Visibility,
189 pub defaultness: Defaultness,
190 pub attrs: Vec<Attribute>,
191 pub node: ImplItemKind,
David Tolnayf4bbbd92016-09-23 14:41:55 -0700192}
193
David Tolnayf38cdf62016-09-23 19:07:09 -0700194#[derive(Debug, Clone, Eq, PartialEq)]
195pub enum ImplItemKind {
196 Const(Ty, Expr),
197 Method(MethodSig, Block),
198 Type(Ty),
199 Macro(Mac),
David Tolnay9d8f1972016-09-04 11:58:48 -0700200}
David Tolnayd5025812016-09-04 14:21:46 -0700201
David Tolnayf38cdf62016-09-23 19:07:09 -0700202/// Represents a method's signature in a trait declaration,
203/// or in an implementation.
204#[derive(Debug, Clone, Eq, PartialEq)]
205pub struct MethodSig {
206 pub unsafety: Unsafety,
207 pub constness: Constness,
David Tolnay0aecb732016-10-03 23:03:50 -0700208 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700209 pub decl: FnDecl,
210 pub generics: Generics,
David Tolnayd5025812016-09-04 14:21:46 -0700211}
David Tolnayedf2b992016-09-23 20:43:45 -0700212
David Tolnay62f374c2016-10-02 13:37:00 -0700213/// Header (not the body) of a function declaration.
214///
215/// E.g. `fn foo(bar: baz)`
216#[derive(Debug, Clone, Eq, PartialEq)]
217pub struct FnDecl {
218 pub inputs: Vec<FnArg>,
219 pub output: FunctionRetTy,
David Tolnay292e6002016-10-29 22:03:51 -0700220 pub variadic: bool,
David Tolnay62f374c2016-10-02 13:37:00 -0700221}
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)]
David Tolnayca085422016-10-04 00:12:38 -0700227pub enum FnArg {
228 SelfRef(Option<Lifetime>, Mutability),
229 SelfValue(Mutability),
230 Captured(Pat, Ty),
231 Ignored(Ty),
David Tolnay62f374c2016-10-02 13:37:00 -0700232}
233
David Tolnayedf2b992016-09-23 20:43:45 -0700234#[cfg(feature = "parsing")]
235pub mod parsing {
236 use super::*;
David Tolnay3b9783a2016-10-29 22:37:09 -0700237 use {Block, DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData,
238 Visibility};
David Tolnay7b8009b2016-10-25 22:36:00 -0700239 use attr::parsing::{inner_attr, outer_attr};
David Tolnay2f9fa632016-10-03 22:08:48 -0700240 use data::parsing::{struct_like_body, visibility};
David Tolnay5859df12016-10-29 22:49:54 -0700241 use expr::parsing::{expr, pat, within_block};
David Tolnayca085422016-10-04 00:12:38 -0700242 use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
David Tolnayedf2b992016-09-23 20:43:45 -0700243 use ident::parsing::ident;
David Tolnay84aa0752016-10-02 23:01:13 -0700244 use mac::parsing::delimited;
David Tolnayedf2b992016-09-23 20:43:45 -0700245 use macro_input::{Body, MacroInput};
246 use macro_input::parsing::macro_input;
David Tolnayb8d8ef52016-10-29 14:30:08 -0700247 use ty::parsing::{abi, mutability, path, ty, unsafety};
David Tolnayedf2b992016-09-23 20:43:45 -0700248
249 named!(pub item -> Item, alt!(
David Tolnaya96a3fa2016-09-24 07:17:42 -0700250 item_extern_crate
David Tolnay4a057422016-10-08 00:02:31 -0700251 |
252 item_use
David Tolnay47a877c2016-10-01 16:50:55 -0700253 |
254 item_static
255 |
256 item_const
David Tolnay42602292016-10-01 22:25:45 -0700257 |
258 item_fn
David Tolnay35902302016-10-06 01:11:08 -0700259 |
260 item_mod
261 |
262 item_foreign_mod
David Tolnay3cf52982016-10-01 17:11:37 -0700263 |
264 item_ty
David Tolnayedf2b992016-09-23 20:43:45 -0700265 |
David Tolnaya96a3fa2016-09-24 07:17:42 -0700266 item_struct_or_enum
David Tolnay2f9fa632016-10-03 22:08:48 -0700267 |
268 item_union
David Tolnay0aecb732016-10-03 23:03:50 -0700269 |
270 item_trait
David Tolnayf94e2362016-10-04 00:29:51 -0700271 |
272 item_default_impl
David Tolnay4c9be372016-10-06 00:47:37 -0700273 |
274 item_impl
David Tolnay84aa0752016-10-02 23:01:13 -0700275 |
276 item_mac
277 ));
278
David Tolnay453cfd12016-10-23 11:00:14 -0700279 named!(pub items -> Vec<Item>, many0!(item));
280
David Tolnay84aa0752016-10-02 23:01:13 -0700281 named!(item_mac -> Item, do_parse!(
282 attrs: many0!(outer_attr) >>
283 path: ident >>
284 punct!("!") >>
285 name: option!(ident) >>
286 body: delimited >>
David Tolnay1a8b3522016-10-08 22:27:00 -0700287 cond!(match body.delim {
288 DelimToken::Paren | DelimToken::Bracket => true,
289 DelimToken::Brace => false,
290 }, punct!(";")) >>
David Tolnay84aa0752016-10-02 23:01:13 -0700291 (Item {
292 ident: name.unwrap_or_else(|| Ident::new("")),
293 vis: Visibility::Inherited,
294 attrs: attrs,
295 node: ItemKind::Mac(Mac {
296 path: path.into(),
297 tts: vec![TokenTree::Delimited(body)],
298 }),
299 })
David Tolnayedf2b992016-09-23 20:43:45 -0700300 ));
301
David Tolnaya96a3fa2016-09-24 07:17:42 -0700302 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700303 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700304 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700305 keyword!("extern") >>
306 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700307 id: ident >>
308 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700309 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700310 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
David Tolnay4a057422016-10-08 00:02:31 -0700327 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: separated_nonempty_list!(punct!(","), path_list_item) >>
David Tolnaybcd4e362016-10-29 22:58:48 -0700370 option!(punct!(",")) >>
David Tolnay4a057422016-10-08 00:02:31 -0700371 punct!("}") >>
372 (ViewPath::List(path, items))
373 ));
374
375 named!(view_path_list_root -> ViewPath, do_parse!(
376 global: option!(punct!("::")) >>
377 punct!("{") >>
378 items: separated_nonempty_list!(punct!(","), path_list_item) >>
David Tolnaybcd4e362016-10-29 22:58:48 -0700379 option!(punct!(",")) >>
David Tolnay4a057422016-10-08 00:02:31 -0700380 punct!("}") >>
381 (ViewPath::List(Path {
382 global: global.is_some(),
383 segments: Vec::new(),
384 }, items))
385 ));
386
387 named!(path_list_item -> PathListItem, do_parse!(
David Tolnaye6e42542016-10-24 22:37:11 -0700388 name: alt!(
389 ident
390 |
391 map!(keyword!("self"), Into::into)
392 ) >>
David Tolnay4a057422016-10-08 00:02:31 -0700393 rename: option!(preceded!(keyword!("as"), ident)) >>
394 (PathListItem {
395 name: name,
396 rename: rename,
397 })
398 ));
399
David Tolnay47a877c2016-10-01 16:50:55 -0700400 named!(item_static -> Item, do_parse!(
401 attrs: many0!(outer_attr) >>
402 vis: visibility >>
403 keyword!("static") >>
404 mutability: mutability >>
405 id: ident >>
406 punct!(":") >>
407 ty: ty >>
408 punct!("=") >>
409 value: expr >>
410 punct!(";") >>
411 (Item {
412 ident: id,
413 vis: vis,
414 attrs: attrs,
415 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
416 })
417 ));
418
419 named!(item_const -> Item, do_parse!(
420 attrs: many0!(outer_attr) >>
421 vis: visibility >>
422 keyword!("const") >>
423 id: ident >>
424 punct!(":") >>
425 ty: ty >>
426 punct!("=") >>
427 value: expr >>
428 punct!(";") >>
429 (Item {
430 ident: id,
431 vis: vis,
432 attrs: attrs,
433 node: ItemKind::Const(Box::new(ty), Box::new(value)),
434 })
435 ));
436
David Tolnay42602292016-10-01 22:25:45 -0700437 named!(item_fn -> Item, do_parse!(
David Tolnay3b9783a2016-10-29 22:37:09 -0700438 outer_attrs: many0!(outer_attr) >>
David Tolnay42602292016-10-01 22:25:45 -0700439 vis: visibility >>
440 constness: constness >>
441 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700442 abi: option!(abi) >>
David Tolnay42602292016-10-01 22:25:45 -0700443 keyword!("fn") >>
444 name: ident >>
445 generics: generics >>
446 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700447 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay42602292016-10-01 22:25:45 -0700448 punct!(")") >>
449 ret: option!(preceded!(punct!("->"), ty)) >>
450 where_clause: where_clause >>
David Tolnay3b9783a2016-10-29 22:37:09 -0700451 punct!("{") >>
452 inner_attrs: many0!(inner_attr) >>
453 stmts: within_block >>
454 punct!("}") >>
David Tolnay42602292016-10-01 22:25:45 -0700455 (Item {
456 ident: name,
457 vis: vis,
David Tolnay3b9783a2016-10-29 22:37:09 -0700458 attrs: {
459 let mut attrs = outer_attrs;
460 attrs.extend(inner_attrs);
461 attrs
462 },
David Tolnay42602292016-10-01 22:25:45 -0700463 node: ItemKind::Fn(
464 Box::new(FnDecl {
465 inputs: inputs,
466 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700467 variadic: false,
David Tolnay42602292016-10-01 22:25:45 -0700468 }),
469 unsafety,
470 constness,
David Tolnayb8d8ef52016-10-29 14:30:08 -0700471 abi,
David Tolnay42602292016-10-01 22:25:45 -0700472 Generics {
473 where_clause: where_clause,
474 .. generics
475 },
David Tolnay3b9783a2016-10-29 22:37:09 -0700476 Box::new(Block {
477 stmts: stmts,
478 }),
David Tolnay42602292016-10-01 22:25:45 -0700479 ),
480 })
481 ));
482
David Tolnayca085422016-10-04 00:12:38 -0700483 named!(fn_arg -> FnArg, alt!(
484 do_parse!(
485 punct!("&") >>
486 lt: option!(lifetime) >>
487 mutability: mutability >>
488 keyword!("self") >>
David Tolnay7a2b6ed2016-10-25 22:15:38 -0700489 not!(peek!(punct!(":"))) >>
David Tolnayca085422016-10-04 00:12:38 -0700490 (FnArg::SelfRef(lt, mutability))
491 )
492 |
493 do_parse!(
494 mutability: mutability >>
495 keyword!("self") >>
David Tolnay7a2b6ed2016-10-25 22:15:38 -0700496 not!(peek!(punct!(":"))) >>
David Tolnayca085422016-10-04 00:12:38 -0700497 (FnArg::SelfValue(mutability))
498 )
499 |
500 do_parse!(
501 pat: pat >>
502 punct!(":") >>
503 ty: ty >>
504 (FnArg::Captured(pat, ty))
505 )
506 |
507 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700508 ));
509
David Tolnay35902302016-10-06 01:11:08 -0700510 named!(item_mod -> Item, do_parse!(
David Tolnay7b8009b2016-10-25 22:36:00 -0700511 outer_attrs: many0!(outer_attr) >>
David Tolnay35902302016-10-06 01:11:08 -0700512 vis: visibility >>
513 keyword!("mod") >>
514 id: ident >>
David Tolnay7b8009b2016-10-25 22:36:00 -0700515 content: alt!(
David Tolnay37d10332016-10-13 20:51:04 -0700516 punct!(";") => { |_| None }
517 |
David Tolnay7b8009b2016-10-25 22:36:00 -0700518 delimited!(
519 punct!("{"),
520 tuple!(
521 many0!(inner_attr),
522 items
523 ),
524 punct!("}")
525 ) => { Some }
David Tolnay37d10332016-10-13 20:51:04 -0700526 ) >>
David Tolnay7b8009b2016-10-25 22:36:00 -0700527 (match content {
528 Some((inner_attrs, items)) => Item {
529 ident: id,
530 vis: vis,
531 attrs: {
532 let mut attrs = outer_attrs;
533 attrs.extend(inner_attrs);
534 attrs
535 },
536 node: ItemKind::Mod(Some(items)),
537 },
538 None => Item {
539 ident: id,
540 vis: vis,
541 attrs: outer_attrs,
542 node: ItemKind::Mod(None),
543 },
David Tolnay35902302016-10-06 01:11:08 -0700544 })
545 ));
546
547 named!(item_foreign_mod -> Item, do_parse!(
548 attrs: many0!(outer_attr) >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700549 abi: abi >>
David Tolnay35902302016-10-06 01:11:08 -0700550 punct!("{") >>
551 items: many0!(foreign_item) >>
552 punct!("}") >>
553 (Item {
554 ident: "".into(),
555 vis: Visibility::Inherited,
556 attrs: attrs,
557 node: ItemKind::ForeignMod(ForeignMod {
David Tolnayb8d8ef52016-10-29 14:30:08 -0700558 abi: abi,
David Tolnay35902302016-10-06 01:11:08 -0700559 items: items,
560 }),
561 })
562 ));
563
564 named!(foreign_item -> ForeignItem, alt!(
565 foreign_fn
566 |
567 foreign_static
568 ));
569
570 named!(foreign_fn -> ForeignItem, do_parse!(
571 attrs: many0!(outer_attr) >>
572 vis: visibility >>
573 keyword!("fn") >>
574 name: ident >>
575 generics: generics >>
576 punct!("(") >>
David Tolnay292e6002016-10-29 22:03:51 -0700577 inputs: separated_list!(punct!(","), fn_arg) >>
578 trailing_comma: option!(punct!(",")) >>
579 variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
David Tolnay35902302016-10-06 01:11:08 -0700580 punct!(")") >>
581 ret: option!(preceded!(punct!("->"), ty)) >>
582 where_clause: where_clause >>
583 punct!(";") >>
584 (ForeignItem {
585 ident: name,
586 attrs: attrs,
587 node: ForeignItemKind::Fn(
588 Box::new(FnDecl {
589 inputs: inputs,
590 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700591 variadic: variadic.is_some(),
David Tolnay35902302016-10-06 01:11:08 -0700592 }),
593 Generics {
594 where_clause: where_clause,
595 .. generics
596 },
597 ),
598 vis: vis,
599 })
600 ));
601
602 named!(foreign_static -> ForeignItem, do_parse!(
603 attrs: many0!(outer_attr) >>
604 vis: visibility >>
605 keyword!("static") >>
606 mutability: mutability >>
607 id: ident >>
608 punct!(":") >>
609 ty: ty >>
610 punct!(";") >>
611 (ForeignItem {
612 ident: id,
613 attrs: attrs,
614 node: ForeignItemKind::Static(Box::new(ty), mutability),
615 vis: vis,
616 })
617 ));
618
David Tolnay3cf52982016-10-01 17:11:37 -0700619 named!(item_ty -> Item, do_parse!(
620 attrs: many0!(outer_attr) >>
621 vis: visibility >>
622 keyword!("type") >>
623 id: ident >>
624 generics: generics >>
David Tolnay04bb3ad2016-10-30 10:59:01 -0700625 where_clause: where_clause >>
David Tolnay3cf52982016-10-01 17:11:37 -0700626 punct!("=") >>
627 ty: ty >>
628 punct!(";") >>
629 (Item {
630 ident: id,
631 vis: vis,
632 attrs: attrs,
David Tolnay04bb3ad2016-10-30 10:59:01 -0700633 node: ItemKind::Ty(
634 Box::new(ty),
635 Generics {
636 where_clause: where_clause,
637 ..generics
638 },
639 ),
David Tolnay3cf52982016-10-01 17:11:37 -0700640 })
641 ));
642
David Tolnaya96a3fa2016-09-24 07:17:42 -0700643 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700644 macro_input,
645 |def: MacroInput| Item {
646 ident: def.ident,
647 vis: def.vis,
648 attrs: def.attrs,
649 node: match def.body {
650 Body::Enum(variants) => {
651 ItemKind::Enum(variants, def.generics)
652 }
653 Body::Struct(variant_data) => {
654 ItemKind::Struct(variant_data, def.generics)
655 }
656 }
657 }
658 ));
David Tolnay42602292016-10-01 22:25:45 -0700659
David Tolnay2f9fa632016-10-03 22:08:48 -0700660 named!(item_union -> Item, do_parse!(
661 attrs: many0!(outer_attr) >>
662 vis: visibility >>
663 keyword!("union") >>
664 id: ident >>
665 generics: generics >>
666 where_clause: where_clause >>
667 fields: struct_like_body >>
668 (Item {
669 ident: id,
670 vis: vis,
671 attrs: attrs,
672 node: ItemKind::Union(
673 VariantData::Struct(fields),
674 Generics {
675 where_clause: where_clause,
676 .. generics
677 },
678 ),
679 })
680 ));
681
David Tolnay0aecb732016-10-03 23:03:50 -0700682 named!(item_trait -> Item, do_parse!(
683 attrs: many0!(outer_attr) >>
684 vis: visibility >>
685 unsafety: unsafety >>
686 keyword!("trait") >>
687 id: ident >>
688 generics: generics >>
689 bounds: opt_vec!(preceded!(
690 punct!(":"),
691 separated_nonempty_list!(punct!("+"), ty_param_bound)
692 )) >>
693 where_clause: where_clause >>
694 punct!("{") >>
695 body: many0!(trait_item) >>
696 punct!("}") >>
697 (Item {
698 ident: id,
699 vis: vis,
700 attrs: attrs,
701 node: ItemKind::Trait(
702 unsafety,
703 Generics {
704 where_clause: where_clause,
705 .. generics
706 },
707 bounds,
708 body,
709 ),
710 })
711 ));
712
David Tolnayf94e2362016-10-04 00:29:51 -0700713 named!(item_default_impl -> Item, do_parse!(
714 attrs: many0!(outer_attr) >>
715 unsafety: unsafety >>
716 keyword!("impl") >>
717 path: path >>
718 keyword!("for") >>
719 punct!("..") >>
720 punct!("{") >>
721 punct!("}") >>
722 (Item {
723 ident: "".into(),
724 vis: Visibility::Inherited,
725 attrs: attrs,
726 node: ItemKind::DefaultImpl(unsafety, path),
727 })
728 ));
729
David Tolnay0aecb732016-10-03 23:03:50 -0700730 named!(trait_item -> TraitItem, alt!(
731 trait_item_const
732 |
733 trait_item_method
734 |
735 trait_item_type
736 |
737 trait_item_mac
738 ));
739
740 named!(trait_item_const -> TraitItem, do_parse!(
741 attrs: many0!(outer_attr) >>
742 keyword!("const") >>
743 id: ident >>
744 punct!(":") >>
745 ty: ty >>
746 value: option!(preceded!(punct!("="), expr)) >>
747 punct!(";") >>
748 (TraitItem {
749 ident: id,
750 attrs: attrs,
751 node: TraitItemKind::Const(ty, value),
752 })
753 ));
754
755 named!(trait_item_method -> TraitItem, do_parse!(
David Tolnay5859df12016-10-29 22:49:54 -0700756 outer_attrs: many0!(outer_attr) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700757 constness: constness >>
758 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700759 abi: option!(abi) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700760 keyword!("fn") >>
761 name: ident >>
762 generics: generics >>
763 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700764 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700765 punct!(")") >>
766 ret: option!(preceded!(punct!("->"), ty)) >>
767 where_clause: where_clause >>
David Tolnay5859df12016-10-29 22:49:54 -0700768 body: option!(delimited!(
769 punct!("{"),
770 tuple!(many0!(inner_attr), within_block),
771 punct!("}")
772 )) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700773 cond!(body.is_none(), punct!(";")) >>
David Tolnay5859df12016-10-29 22:49:54 -0700774 ({
775 let (inner_attrs, stmts) = match body {
776 Some((inner_attrs, stmts)) => (inner_attrs, Some(stmts)),
777 None => (Vec::new(), None),
778 };
779 TraitItem {
780 ident: name,
781 attrs: {
782 let mut attrs = outer_attrs;
783 attrs.extend(inner_attrs);
784 attrs
David Tolnay0aecb732016-10-03 23:03:50 -0700785 },
David Tolnay5859df12016-10-29 22:49:54 -0700786 node: TraitItemKind::Method(
787 MethodSig {
788 unsafety: unsafety,
789 constness: constness,
790 abi: abi,
791 decl: FnDecl {
792 inputs: inputs,
793 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
794 variadic: false,
795 },
796 generics: Generics {
797 where_clause: where_clause,
798 .. generics
799 },
800 },
801 stmts.map(|stmts| Block { stmts: stmts }),
802 ),
803 }
David Tolnay0aecb732016-10-03 23:03:50 -0700804 })
805 ));
806
807 named!(trait_item_type -> TraitItem, do_parse!(
808 attrs: many0!(outer_attr) >>
809 keyword!("type") >>
810 id: ident >>
811 bounds: opt_vec!(preceded!(
812 punct!(":"),
813 separated_nonempty_list!(punct!("+"), ty_param_bound)
814 )) >>
815 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700816 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700817 (TraitItem {
818 ident: id,
819 attrs: attrs,
820 node: TraitItemKind::Type(bounds, default),
821 })
822 ));
823
824 named!(trait_item_mac -> TraitItem, do_parse!(
825 attrs: many0!(outer_attr) >>
826 id: ident >>
827 punct!("!") >>
828 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700829 cond!(match body.delim {
830 DelimToken::Paren | DelimToken::Bracket => true,
831 DelimToken::Brace => false,
832 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700833 (TraitItem {
834 ident: id.clone(),
835 attrs: attrs,
836 node: TraitItemKind::Macro(Mac {
837 path: id.into(),
838 tts: vec![TokenTree::Delimited(body)],
839 }),
840 })
841 ));
842
David Tolnay4c9be372016-10-06 00:47:37 -0700843 named!(item_impl -> Item, do_parse!(
844 attrs: many0!(outer_attr) >>
845 unsafety: unsafety >>
846 keyword!("impl") >>
847 generics: generics >>
848 polarity_path: alt!(
849 do_parse!(
850 polarity: impl_polarity >>
851 path: path >>
852 keyword!("for") >>
853 ((polarity, Some(path)))
854 )
855 |
856 epsilon!() => { |_| (ImplPolarity::Positive, None) }
857 ) >>
858 self_ty: ty >>
859 where_clause: where_clause >>
860 punct!("{") >>
861 body: many0!(impl_item) >>
862 punct!("}") >>
863 (Item {
864 ident: "".into(),
865 vis: Visibility::Inherited,
866 attrs: attrs,
867 node: ItemKind::Impl(
868 unsafety,
869 polarity_path.0,
870 Generics {
871 where_clause: where_clause,
872 .. generics
873 },
874 polarity_path.1,
875 Box::new(self_ty),
876 body,
877 ),
878 })
879 ));
880
881 named!(impl_item -> ImplItem, alt!(
882 impl_item_const
883 |
884 impl_item_method
885 |
886 impl_item_type
887 |
888 impl_item_macro
889 ));
890
891 named!(impl_item_const -> ImplItem, do_parse!(
892 attrs: many0!(outer_attr) >>
893 vis: visibility >>
894 defaultness: defaultness >>
895 keyword!("const") >>
896 id: ident >>
897 punct!(":") >>
898 ty: ty >>
899 punct!("=") >>
900 value: expr >>
901 punct!(";") >>
902 (ImplItem {
903 ident: id,
904 vis: vis,
905 defaultness: defaultness,
906 attrs: attrs,
907 node: ImplItemKind::Const(ty, value),
908 })
909 ));
910
911 named!(impl_item_method -> ImplItem, do_parse!(
David Tolnay3b9783a2016-10-29 22:37:09 -0700912 outer_attrs: many0!(outer_attr) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700913 vis: visibility >>
914 defaultness: defaultness >>
915 constness: constness >>
916 unsafety: unsafety >>
David Tolnayb8d8ef52016-10-29 14:30:08 -0700917 abi: option!(abi) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700918 keyword!("fn") >>
919 name: ident >>
920 generics: generics >>
921 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700922 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700923 punct!(")") >>
924 ret: option!(preceded!(punct!("->"), ty)) >>
925 where_clause: where_clause >>
David Tolnay3b9783a2016-10-29 22:37:09 -0700926 punct!("{") >>
927 inner_attrs: many0!(inner_attr) >>
928 stmts: within_block >>
929 punct!("}") >>
David Tolnay4c9be372016-10-06 00:47:37 -0700930 (ImplItem {
931 ident: name,
932 vis: vis,
933 defaultness: defaultness,
David Tolnay3b9783a2016-10-29 22:37:09 -0700934 attrs: {
935 let mut attrs = outer_attrs;
936 attrs.extend(inner_attrs);
937 attrs
938 },
David Tolnay4c9be372016-10-06 00:47:37 -0700939 node: ImplItemKind::Method(
940 MethodSig {
941 unsafety: unsafety,
942 constness: constness,
David Tolnayb8d8ef52016-10-29 14:30:08 -0700943 abi: abi,
David Tolnay4c9be372016-10-06 00:47:37 -0700944 decl: FnDecl {
945 inputs: inputs,
946 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
David Tolnay292e6002016-10-29 22:03:51 -0700947 variadic: false,
David Tolnay4c9be372016-10-06 00:47:37 -0700948 },
949 generics: Generics {
950 where_clause: where_clause,
951 .. generics
952 },
953 },
David Tolnay3b9783a2016-10-29 22:37:09 -0700954 Block {
955 stmts: stmts,
956 },
David Tolnay4c9be372016-10-06 00:47:37 -0700957 ),
958 })
959 ));
960
961 named!(impl_item_type -> ImplItem, do_parse!(
962 attrs: many0!(outer_attr) >>
963 vis: visibility >>
964 defaultness: defaultness >>
965 keyword!("type") >>
966 id: ident >>
967 punct!("=") >>
968 ty: ty >>
969 punct!(";") >>
970 (ImplItem {
971 ident: id,
972 vis: vis,
973 defaultness: defaultness,
974 attrs: attrs,
975 node: ImplItemKind::Type(ty),
976 })
977 ));
978
979 named!(impl_item_macro -> ImplItem, do_parse!(
980 attrs: many0!(outer_attr) >>
981 id: ident >>
982 punct!("!") >>
983 body: delimited >>
984 cond!(match body.delim {
985 DelimToken::Paren | DelimToken::Bracket => true,
986 DelimToken::Brace => false,
987 }, punct!(";")) >>
988 (ImplItem {
989 ident: id.clone(),
990 vis: Visibility::Inherited,
991 defaultness: Defaultness::Final,
992 attrs: attrs,
993 node: ImplItemKind::Macro(Mac {
994 path: id.into(),
995 tts: vec![TokenTree::Delimited(body)],
996 }),
997 })
998 ));
999
1000 named!(impl_polarity -> ImplPolarity, alt!(
1001 punct!("!") => { |_| ImplPolarity::Negative }
1002 |
1003 epsilon!() => { |_| ImplPolarity::Positive }
1004 ));
1005
David Tolnay42602292016-10-01 22:25:45 -07001006 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -07001007 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -07001008 |
1009 epsilon!() => { |_| Constness::NotConst }
1010 ));
1011
David Tolnay4c9be372016-10-06 00:47:37 -07001012 named!(defaultness -> Defaultness, alt!(
1013 keyword!("default") => { |_| Defaultness::Default }
1014 |
1015 epsilon!() => { |_| Defaultness::Final }
1016 ));
David Tolnayedf2b992016-09-23 20:43:45 -07001017}
David Tolnay4a51dc72016-10-01 00:40:31 -07001018
1019#[cfg(feature = "printing")]
1020mod printing {
1021 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -07001022 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -07001023 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -07001024 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -07001025 use quote::{Tokens, ToTokens};
1026
1027 impl ToTokens for Item {
1028 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001029 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -07001030 match self.node {
1031 ItemKind::ExternCrate(ref original) => {
David Tolnaycbd9f7d2016-10-30 00:26:29 -07001032 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001033 tokens.append("extern");
1034 tokens.append("crate");
1035 if let Some(ref original) = *original {
1036 original.to_tokens(tokens);
1037 tokens.append("as");
1038 }
1039 self.ident.to_tokens(tokens);
1040 tokens.append(";");
1041 }
David Tolnay4a057422016-10-08 00:02:31 -07001042 ItemKind::Use(ref view_path) => {
1043 self.vis.to_tokens(tokens);
1044 tokens.append("use");
1045 view_path.to_tokens(tokens);
1046 tokens.append(";");
1047 }
David Tolnay47a877c2016-10-01 16:50:55 -07001048 ItemKind::Static(ref ty, ref mutability, ref expr) => {
1049 self.vis.to_tokens(tokens);
1050 tokens.append("static");
1051 mutability.to_tokens(tokens);
1052 self.ident.to_tokens(tokens);
1053 tokens.append(":");
1054 ty.to_tokens(tokens);
1055 tokens.append("=");
1056 expr.to_tokens(tokens);
1057 tokens.append(";");
1058 }
1059 ItemKind::Const(ref ty, ref expr) => {
1060 self.vis.to_tokens(tokens);
1061 tokens.append("const");
1062 self.ident.to_tokens(tokens);
1063 tokens.append(":");
1064 ty.to_tokens(tokens);
1065 tokens.append("=");
1066 expr.to_tokens(tokens);
1067 tokens.append(";");
1068 }
David Tolnay42602292016-10-01 22:25:45 -07001069 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
1070 self.vis.to_tokens(tokens);
1071 constness.to_tokens(tokens);
1072 unsafety.to_tokens(tokens);
1073 abi.to_tokens(tokens);
1074 tokens.append("fn");
1075 self.ident.to_tokens(tokens);
1076 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -07001077 tokens.append("(");
1078 tokens.append_separated(&decl.inputs, ",");
1079 tokens.append(")");
1080 if let FunctionRetTy::Ty(ref ty) = decl.output {
1081 tokens.append("->");
1082 ty.to_tokens(tokens);
1083 }
David Tolnay42602292016-10-01 22:25:45 -07001084 generics.where_clause.to_tokens(tokens);
David Tolnay3b9783a2016-10-29 22:37:09 -07001085 tokens.append("{");
1086 tokens.append_all(self.attrs.inner());
1087 tokens.append_all(&block.stmts);
1088 tokens.append("}");
David Tolnay42602292016-10-01 22:25:45 -07001089 }
David Tolnay35902302016-10-06 01:11:08 -07001090 ItemKind::Mod(ref items) => {
1091 self.vis.to_tokens(tokens);
1092 tokens.append("mod");
1093 self.ident.to_tokens(tokens);
David Tolnay37d10332016-10-13 20:51:04 -07001094 match *items {
1095 Some(ref items) => {
1096 tokens.append("{");
David Tolnay7b8009b2016-10-25 22:36:00 -07001097 tokens.append_all(self.attrs.inner());
David Tolnay37d10332016-10-13 20:51:04 -07001098 tokens.append_all(items);
1099 tokens.append("}");
1100 }
1101 None => tokens.append(";"),
1102 }
David Tolnay35902302016-10-06 01:11:08 -07001103 }
1104 ItemKind::ForeignMod(ref foreign_mod) => {
1105 self.vis.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001106 foreign_mod.abi.to_tokens(tokens);
David Tolnay35902302016-10-06 01:11:08 -07001107 tokens.append("{");
1108 tokens.append_all(&foreign_mod.items);
1109 tokens.append("}");
1110 }
David Tolnay3cf52982016-10-01 17:11:37 -07001111 ItemKind::Ty(ref ty, ref generics) => {
1112 self.vis.to_tokens(tokens);
1113 tokens.append("type");
1114 self.ident.to_tokens(tokens);
1115 generics.to_tokens(tokens);
David Tolnay04bb3ad2016-10-30 10:59:01 -07001116 generics.where_clause.to_tokens(tokens);
David Tolnay3cf52982016-10-01 17:11:37 -07001117 tokens.append("=");
1118 ty.to_tokens(tokens);
1119 tokens.append(";");
1120 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001121 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001122 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001123 tokens.append("enum");
1124 self.ident.to_tokens(tokens);
1125 generics.to_tokens(tokens);
1126 generics.where_clause.to_tokens(tokens);
1127 tokens.append("{");
1128 for variant in variants {
1129 variant.to_tokens(tokens);
1130 tokens.append(",");
1131 }
1132 tokens.append("}");
1133 }
1134 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001135 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001136 tokens.append("struct");
1137 self.ident.to_tokens(tokens);
1138 generics.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001139 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -07001140 VariantData::Struct(_) => {
David Tolnay28c1db62016-10-27 22:48:18 -07001141 generics.where_clause.to_tokens(tokens);
1142 variant_data.to_tokens(tokens);
David Tolnaydaaf7742016-10-03 11:11:43 -07001143 // no semicolon
1144 }
David Tolnay28c1db62016-10-27 22:48:18 -07001145 VariantData::Tuple(_) => {
1146 variant_data.to_tokens(tokens);
1147 generics.where_clause.to_tokens(tokens);
1148 tokens.append(";");
1149 }
1150 VariantData::Unit => {
1151 generics.where_clause.to_tokens(tokens);
1152 tokens.append(";");
1153 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001154 }
1155 }
David Tolnay2f9fa632016-10-03 22:08:48 -07001156 ItemKind::Union(ref variant_data, ref generics) => {
1157 self.vis.to_tokens(tokens);
1158 tokens.append("union");
1159 self.ident.to_tokens(tokens);
1160 generics.to_tokens(tokens);
1161 generics.where_clause.to_tokens(tokens);
1162 variant_data.to_tokens(tokens);
1163 }
David Tolnayca085422016-10-04 00:12:38 -07001164 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
1165 self.vis.to_tokens(tokens);
1166 unsafety.to_tokens(tokens);
1167 tokens.append("trait");
1168 self.ident.to_tokens(tokens);
David Tolnaye4606332016-10-25 21:57:41 -07001169 generics.to_tokens(tokens);
David Tolnayca085422016-10-04 00:12:38 -07001170 if !bound.is_empty() {
1171 tokens.append(":");
1172 tokens.append_separated(bound, "+");
1173 }
David Tolnayca085422016-10-04 00:12:38 -07001174 generics.where_clause.to_tokens(tokens);
1175 tokens.append("{");
1176 tokens.append_all(items);
1177 tokens.append("}");
1178 }
David Tolnayf94e2362016-10-04 00:29:51 -07001179 ItemKind::DefaultImpl(unsafety, ref path) => {
1180 unsafety.to_tokens(tokens);
1181 tokens.append("impl");
1182 path.to_tokens(tokens);
1183 tokens.append("for");
1184 tokens.append("..");
1185 tokens.append("{");
1186 tokens.append("}");
1187 }
David Tolnay3bcfb722016-10-08 11:58:36 -07001188 ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => {
David Tolnay4c9be372016-10-06 00:47:37 -07001189 unsafety.to_tokens(tokens);
1190 tokens.append("impl");
1191 generics.to_tokens(tokens);
1192 if let Some(ref path) = *path {
1193 polarity.to_tokens(tokens);
1194 path.to_tokens(tokens);
1195 tokens.append("for");
1196 }
1197 ty.to_tokens(tokens);
1198 generics.where_clause.to_tokens(tokens);
1199 tokens.append("{");
1200 tokens.append_all(items);
1201 tokens.append("}");
1202 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001203 ItemKind::Mac(ref mac) => {
1204 mac.path.to_tokens(tokens);
1205 tokens.append("!");
1206 self.ident.to_tokens(tokens);
1207 for tt in &mac.tts {
1208 tt.to_tokens(tokens);
1209 }
1210 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -07001211 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1212 // no semicolon
1213 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001214 _ => tokens.append(";"),
1215 }
1216 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001217 }
1218 }
1219 }
David Tolnay42602292016-10-01 22:25:45 -07001220
David Tolnay4a057422016-10-08 00:02:31 -07001221 impl ToTokens for ViewPath {
1222 fn to_tokens(&self, tokens: &mut Tokens) {
1223 match *self {
1224 ViewPath::Simple(ref path, ref rename) => {
1225 path.to_tokens(tokens);
1226 if let Some(ref rename) = *rename {
1227 tokens.append("as");
1228 rename.to_tokens(tokens);
1229 }
1230 }
1231 ViewPath::Glob(ref path) => {
1232 path.to_tokens(tokens);
1233 tokens.append("::");
1234 tokens.append("*");
1235 }
1236 ViewPath::List(ref path, ref items) => {
1237 path.to_tokens(tokens);
David Tolnay12417832016-10-08 00:12:37 -07001238 if path.global || !path.segments.is_empty() {
1239 tokens.append("::");
1240 }
David Tolnay4a057422016-10-08 00:02:31 -07001241 tokens.append("{");
1242 tokens.append_separated(items, ",");
1243 tokens.append("}");
1244 }
1245 }
1246 }
1247 }
1248
1249 impl ToTokens for PathListItem {
1250 fn to_tokens(&self, tokens: &mut Tokens) {
1251 self.name.to_tokens(tokens);
1252 if let Some(ref rename) = self.rename {
1253 tokens.append("as");
1254 rename.to_tokens(tokens);
1255 }
1256 }
1257 }
1258
David Tolnayca085422016-10-04 00:12:38 -07001259 impl ToTokens for TraitItem {
1260 fn to_tokens(&self, tokens: &mut Tokens) {
1261 tokens.append_all(self.attrs.outer());
1262 match self.node {
1263 TraitItemKind::Const(ref ty, ref expr) => {
1264 tokens.append("const");
1265 self.ident.to_tokens(tokens);
1266 tokens.append(":");
1267 ty.to_tokens(tokens);
1268 if let Some(ref expr) = *expr {
1269 tokens.append("=");
1270 expr.to_tokens(tokens);
1271 }
1272 tokens.append(";");
1273 }
1274 TraitItemKind::Method(ref sig, ref block) => {
David Tolnayb31d3f02016-10-25 21:15:13 -07001275 sig.constness.to_tokens(tokens);
David Tolnayca085422016-10-04 00:12:38 -07001276 sig.unsafety.to_tokens(tokens);
1277 sig.abi.to_tokens(tokens);
1278 tokens.append("fn");
1279 self.ident.to_tokens(tokens);
1280 sig.generics.to_tokens(tokens);
1281 tokens.append("(");
1282 tokens.append_separated(&sig.decl.inputs, ",");
1283 tokens.append(")");
1284 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1285 tokens.append("->");
1286 ty.to_tokens(tokens);
1287 }
1288 sig.generics.where_clause.to_tokens(tokens);
1289 match *block {
David Tolnay3b9783a2016-10-29 22:37:09 -07001290 Some(ref block) => {
1291 tokens.append("{");
1292 tokens.append_all(self.attrs.inner());
1293 tokens.append_all(&block.stmts);
1294 tokens.append("}");
1295 }
David Tolnayca085422016-10-04 00:12:38 -07001296 None => tokens.append(";"),
1297 }
1298 }
1299 TraitItemKind::Type(ref bound, ref default) => {
1300 tokens.append("type");
1301 self.ident.to_tokens(tokens);
1302 if !bound.is_empty() {
1303 tokens.append(":");
1304 tokens.append_separated(bound, "+");
1305 }
1306 if let Some(ref default) = *default {
1307 tokens.append("=");
1308 default.to_tokens(tokens);
1309 }
1310 tokens.append(";");
1311 }
1312 TraitItemKind::Macro(ref mac) => {
1313 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -07001314 match mac.tts.last() {
1315 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1316 // no semicolon
1317 }
1318 _ => tokens.append(";"),
1319 }
David Tolnayca085422016-10-04 00:12:38 -07001320 }
1321 }
1322 }
1323 }
1324
David Tolnay4c9be372016-10-06 00:47:37 -07001325 impl ToTokens for ImplItem {
1326 fn to_tokens(&self, tokens: &mut Tokens) {
1327 tokens.append_all(self.attrs.outer());
1328 match self.node {
1329 ImplItemKind::Const(ref ty, ref expr) => {
1330 self.vis.to_tokens(tokens);
1331 self.defaultness.to_tokens(tokens);
1332 tokens.append("const");
1333 self.ident.to_tokens(tokens);
1334 tokens.append(":");
1335 ty.to_tokens(tokens);
1336 tokens.append("=");
1337 expr.to_tokens(tokens);
1338 tokens.append(";");
1339 }
1340 ImplItemKind::Method(ref sig, ref block) => {
1341 self.vis.to_tokens(tokens);
1342 self.defaultness.to_tokens(tokens);
David Tolnayb31d3f02016-10-25 21:15:13 -07001343 sig.constness.to_tokens(tokens);
David Tolnay4c9be372016-10-06 00:47:37 -07001344 sig.unsafety.to_tokens(tokens);
1345 sig.abi.to_tokens(tokens);
1346 tokens.append("fn");
1347 self.ident.to_tokens(tokens);
1348 sig.generics.to_tokens(tokens);
1349 tokens.append("(");
1350 tokens.append_separated(&sig.decl.inputs, ",");
1351 tokens.append(")");
1352 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1353 tokens.append("->");
1354 ty.to_tokens(tokens);
1355 }
1356 sig.generics.where_clause.to_tokens(tokens);
David Tolnay5859df12016-10-29 22:49:54 -07001357 tokens.append("{");
1358 tokens.append_all(self.attrs.inner());
1359 tokens.append_all(&block.stmts);
1360 tokens.append("}");
David Tolnay4c9be372016-10-06 00:47:37 -07001361 }
1362 ImplItemKind::Type(ref ty) => {
1363 self.vis.to_tokens(tokens);
1364 self.defaultness.to_tokens(tokens);
1365 tokens.append("type");
1366 self.ident.to_tokens(tokens);
1367 tokens.append("=");
1368 ty.to_tokens(tokens);
1369 tokens.append(";");
1370 }
1371 ImplItemKind::Macro(ref mac) => {
1372 mac.to_tokens(tokens);
1373 match mac.tts.last() {
1374 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1375 // no semicolon
1376 }
1377 _ => tokens.append(";"),
1378 }
1379 }
1380 }
1381 }
1382 }
1383
David Tolnay35902302016-10-06 01:11:08 -07001384 impl ToTokens for ForeignItem {
1385 fn to_tokens(&self, tokens: &mut Tokens) {
1386 tokens.append_all(self.attrs.outer());
1387 match self.node {
1388 ForeignItemKind::Fn(ref decl, ref generics) => {
1389 self.vis.to_tokens(tokens);
1390 tokens.append("fn");
1391 self.ident.to_tokens(tokens);
1392 generics.to_tokens(tokens);
1393 tokens.append("(");
1394 tokens.append_separated(&decl.inputs, ",");
David Tolnay292e6002016-10-29 22:03:51 -07001395 if decl.variadic {
1396 if !decl.inputs.is_empty() {
1397 tokens.append(",");
1398 }
1399 tokens.append("...");
1400 }
David Tolnay35902302016-10-06 01:11:08 -07001401 tokens.append(")");
1402 if let FunctionRetTy::Ty(ref ty) = decl.output {
1403 tokens.append("->");
1404 ty.to_tokens(tokens);
1405 }
1406 generics.where_clause.to_tokens(tokens);
1407 tokens.append(";");
1408 }
1409 ForeignItemKind::Static(ref ty, mutability) => {
1410 self.vis.to_tokens(tokens);
1411 tokens.append("static");
1412 mutability.to_tokens(tokens);
1413 self.ident.to_tokens(tokens);
1414 tokens.append(":");
1415 ty.to_tokens(tokens);
1416 tokens.append(";");
1417 }
1418 }
1419 }
1420 }
1421
David Tolnay62f374c2016-10-02 13:37:00 -07001422 impl ToTokens for FnArg {
1423 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001424 match *self {
1425 FnArg::SelfRef(ref lifetime, mutability) => {
1426 tokens.append("&");
1427 lifetime.to_tokens(tokens);
1428 mutability.to_tokens(tokens);
1429 tokens.append("self");
1430 }
1431 FnArg::SelfValue(mutability) => {
1432 mutability.to_tokens(tokens);
1433 tokens.append("self");
1434 }
1435 FnArg::Captured(ref pat, ref ty) => {
1436 pat.to_tokens(tokens);
1437 tokens.append(":");
1438 ty.to_tokens(tokens);
1439 }
1440 FnArg::Ignored(ref ty) => {
1441 ty.to_tokens(tokens);
1442 }
1443 }
David Tolnay62f374c2016-10-02 13:37:00 -07001444 }
1445 }
1446
David Tolnay42602292016-10-01 22:25:45 -07001447 impl ToTokens for Constness {
1448 fn to_tokens(&self, tokens: &mut Tokens) {
1449 match *self {
1450 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001451 Constness::NotConst => {
1452 // nothing
1453 }
David Tolnay42602292016-10-01 22:25:45 -07001454 }
1455 }
1456 }
1457
David Tolnay4c9be372016-10-06 00:47:37 -07001458 impl ToTokens for Defaultness {
1459 fn to_tokens(&self, tokens: &mut Tokens) {
1460 match *self {
1461 Defaultness::Default => tokens.append("default"),
1462 Defaultness::Final => {
1463 // nothing
1464 }
1465 }
1466 }
1467 }
1468
1469 impl ToTokens for ImplPolarity {
1470 fn to_tokens(&self, tokens: &mut Tokens) {
1471 match *self {
1472 ImplPolarity::Negative => tokens.append("!"),
1473 ImplPolarity::Positive => {
1474 // nothing
1475 }
1476 }
1477 }
1478 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001479}