blob: cc5b7c388f5d5347d8dd48b3724345a182402594 [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)]
121pub enum Unsafety {
122 Unsafe,
123 Normal,
124}
125
126#[derive(Debug, Copy, Clone, Eq, PartialEq)]
127pub enum Constness {
128 Const,
129 NotConst,
130}
131
132#[derive(Debug, Copy, Clone, Eq, PartialEq)]
133pub enum Defaultness {
134 Default,
135 Final,
136}
137
138#[derive(Debug, Clone, Eq, PartialEq)]
139pub struct Abi(pub String);
140
141/// Foreign module declaration.
142///
David Tolnay35902302016-10-06 01:11:08 -0700143/// E.g. `extern { .. }` or `extern "C" { .. }`
David Tolnayf38cdf62016-09-23 19:07:09 -0700144#[derive(Debug, Clone, Eq, PartialEq)]
145pub struct ForeignMod {
David Tolnay35902302016-10-06 01:11:08 -0700146 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700147 pub items: Vec<ForeignItem>,
148}
149
150#[derive(Debug, Clone, Eq, PartialEq)]
151pub struct ForeignItem {
David Tolnayb79ee962016-09-04 09:39:20 -0700152 pub ident: Ident,
153 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700154 pub node: ForeignItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -0700155 pub vis: Visibility,
David Tolnayf38cdf62016-09-23 19:07:09 -0700156}
157
David Tolnay771ecf42016-09-23 19:26:37 -0700158/// An item within an `extern` block
David Tolnayf38cdf62016-09-23 19:07:09 -0700159#[derive(Debug, Clone, Eq, PartialEq)]
160pub enum ForeignItemKind {
161 /// A foreign function
162 Fn(Box<FnDecl>, Generics),
David Tolnay35902302016-10-06 01:11:08 -0700163 /// A foreign static item (`static ext: u8`)
164 Static(Box<Ty>, Mutability),
David Tolnayf38cdf62016-09-23 19:07:09 -0700165}
166
167/// Represents an item declaration within a trait declaration,
168/// possibly including a default implementation. A trait item is
169/// either required (meaning it doesn't have an implementation, just a
170/// signature) or provided (meaning it has a default implementation).
171#[derive(Debug, Clone, Eq, PartialEq)]
172pub struct TraitItem {
173 pub ident: Ident,
David Tolnayb79ee962016-09-04 09:39:20 -0700174 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700175 pub node: TraitItemKind,
176}
177
178#[derive(Debug, Clone, Eq, PartialEq)]
179pub enum TraitItemKind {
180 Const(Ty, Option<Expr>),
181 Method(MethodSig, Option<Block>),
182 Type(Vec<TyParamBound>, Option<Ty>),
183 Macro(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -0700184}
185
David Tolnay55337722016-09-11 12:58:56 -0700186#[derive(Debug, Copy, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700187pub enum ImplPolarity {
188 /// `impl Trait for Type`
189 Positive,
190 /// `impl !Trait for Type`
191 Negative,
David Tolnay55337722016-09-11 12:58:56 -0700192}
193
David Tolnayf38cdf62016-09-23 19:07:09 -0700194#[derive(Debug, Clone, Eq, PartialEq)]
195pub struct ImplItem {
196 pub ident: Ident,
197 pub vis: Visibility,
198 pub defaultness: Defaultness,
199 pub attrs: Vec<Attribute>,
200 pub node: ImplItemKind,
David Tolnayf4bbbd92016-09-23 14:41:55 -0700201}
202
David Tolnayf38cdf62016-09-23 19:07:09 -0700203#[derive(Debug, Clone, Eq, PartialEq)]
204pub enum ImplItemKind {
205 Const(Ty, Expr),
206 Method(MethodSig, Block),
207 Type(Ty),
208 Macro(Mac),
David Tolnay9d8f1972016-09-04 11:58:48 -0700209}
David Tolnayd5025812016-09-04 14:21:46 -0700210
David Tolnayf38cdf62016-09-23 19:07:09 -0700211/// Represents a method's signature in a trait declaration,
212/// or in an implementation.
213#[derive(Debug, Clone, Eq, PartialEq)]
214pub struct MethodSig {
215 pub unsafety: Unsafety,
216 pub constness: Constness,
David Tolnay0aecb732016-10-03 23:03:50 -0700217 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700218 pub decl: FnDecl,
219 pub generics: Generics,
David Tolnayd5025812016-09-04 14:21:46 -0700220}
David Tolnayedf2b992016-09-23 20:43:45 -0700221
David Tolnay62f374c2016-10-02 13:37:00 -0700222/// Header (not the body) of a function declaration.
223///
224/// E.g. `fn foo(bar: baz)`
225#[derive(Debug, Clone, Eq, PartialEq)]
226pub struct FnDecl {
227 pub inputs: Vec<FnArg>,
228 pub output: FunctionRetTy,
229}
230
231/// An argument in a function header.
232///
233/// E.g. `bar: usize` as in `fn foo(bar: usize)`
234#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayca085422016-10-04 00:12:38 -0700235pub enum FnArg {
236 SelfRef(Option<Lifetime>, Mutability),
237 SelfValue(Mutability),
238 Captured(Pat, Ty),
239 Ignored(Ty),
David Tolnay62f374c2016-10-02 13:37:00 -0700240}
241
David Tolnayedf2b992016-09-23 20:43:45 -0700242#[cfg(feature = "parsing")]
243pub mod parsing {
244 use super::*;
David Tolnay4a057422016-10-08 00:02:31 -0700245 use {DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData, Visibility};
David Tolnay4a51dc72016-10-01 00:40:31 -0700246 use attr::parsing::outer_attr;
David Tolnay2f9fa632016-10-03 22:08:48 -0700247 use data::parsing::{struct_like_body, visibility};
David Tolnay62f374c2016-10-02 13:37:00 -0700248 use expr::parsing::{block, expr, pat};
David Tolnayca085422016-10-04 00:12:38 -0700249 use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
David Tolnayedf2b992016-09-23 20:43:45 -0700250 use ident::parsing::ident;
David Tolnay42602292016-10-01 22:25:45 -0700251 use lit::parsing::quoted_string;
David Tolnay84aa0752016-10-02 23:01:13 -0700252 use mac::parsing::delimited;
David Tolnayedf2b992016-09-23 20:43:45 -0700253 use macro_input::{Body, MacroInput};
254 use macro_input::parsing::macro_input;
David Tolnayf94e2362016-10-04 00:29:51 -0700255 use ty::parsing::{mutability, path, ty};
David Tolnayedf2b992016-09-23 20:43:45 -0700256
257 named!(pub item -> Item, alt!(
David Tolnaya96a3fa2016-09-24 07:17:42 -0700258 item_extern_crate
David Tolnay4a057422016-10-08 00:02:31 -0700259 |
260 item_use
David Tolnay47a877c2016-10-01 16:50:55 -0700261 |
262 item_static
263 |
264 item_const
David Tolnay42602292016-10-01 22:25:45 -0700265 |
266 item_fn
David Tolnay35902302016-10-06 01:11:08 -0700267 |
268 item_mod
269 |
270 item_foreign_mod
David Tolnay3cf52982016-10-01 17:11:37 -0700271 |
272 item_ty
David Tolnayedf2b992016-09-23 20:43:45 -0700273 |
David Tolnaya96a3fa2016-09-24 07:17:42 -0700274 item_struct_or_enum
David Tolnay2f9fa632016-10-03 22:08:48 -0700275 |
276 item_union
David Tolnay0aecb732016-10-03 23:03:50 -0700277 |
278 item_trait
David Tolnayf94e2362016-10-04 00:29:51 -0700279 |
280 item_default_impl
David Tolnay4c9be372016-10-06 00:47:37 -0700281 |
282 item_impl
David Tolnay84aa0752016-10-02 23:01:13 -0700283 |
284 item_mac
285 ));
286
David Tolnay453cfd12016-10-23 11:00:14 -0700287 named!(pub items -> Vec<Item>, many0!(item));
288
David Tolnay84aa0752016-10-02 23:01:13 -0700289 named!(item_mac -> Item, do_parse!(
290 attrs: many0!(outer_attr) >>
291 path: ident >>
292 punct!("!") >>
293 name: option!(ident) >>
294 body: delimited >>
David Tolnay1a8b3522016-10-08 22:27:00 -0700295 cond!(match body.delim {
296 DelimToken::Paren | DelimToken::Bracket => true,
297 DelimToken::Brace => false,
298 }, punct!(";")) >>
David Tolnay84aa0752016-10-02 23:01:13 -0700299 (Item {
300 ident: name.unwrap_or_else(|| Ident::new("")),
301 vis: Visibility::Inherited,
302 attrs: attrs,
303 node: ItemKind::Mac(Mac {
304 path: path.into(),
305 tts: vec![TokenTree::Delimited(body)],
306 }),
307 })
David Tolnayedf2b992016-09-23 20:43:45 -0700308 ));
309
David Tolnaya96a3fa2016-09-24 07:17:42 -0700310 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700311 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700312 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700313 keyword!("extern") >>
314 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700315 id: ident >>
316 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700317 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700318 ident
319 )) >>
320 punct!(";") >>
321 ({
322 let (name, original_name) = match rename {
323 Some(rename) => (rename, Some(id)),
324 None => (id, None),
325 };
326 Item {
327 ident: name,
328 vis: vis,
329 attrs: attrs,
330 node: ItemKind::ExternCrate(original_name),
331 }
332 })
333 ));
334
David Tolnay4a057422016-10-08 00:02:31 -0700335 named!(item_use -> Item, do_parse!(
336 attrs: many0!(outer_attr) >>
337 vis: visibility >>
338 keyword!("use") >>
339 what: view_path >>
340 punct!(";") >>
341 (Item {
342 ident: "".into(),
343 vis: vis,
344 attrs: attrs,
345 node: ItemKind::Use(Box::new(what)),
346 })
347 ));
348
349 named!(view_path -> ViewPath, alt!(
350 view_path_glob
351 |
352 view_path_list
353 |
354 view_path_list_root
355 |
356 view_path_simple // must be last
357 ));
358
359
360 named!(view_path_simple -> ViewPath, do_parse!(
361 path: path >>
362 rename: option!(preceded!(keyword!("as"), ident)) >>
363 (ViewPath::Simple(path, rename))
364 ));
365
366 named!(view_path_glob -> ViewPath, do_parse!(
367 path: path >>
368 punct!("::") >>
369 punct!("*") >>
370 (ViewPath::Glob(path))
371 ));
372
373 named!(view_path_list -> ViewPath, do_parse!(
374 path: path >>
375 punct!("::") >>
376 punct!("{") >>
377 items: separated_nonempty_list!(punct!(","), path_list_item) >>
378 punct!("}") >>
379 (ViewPath::List(path, items))
380 ));
381
382 named!(view_path_list_root -> ViewPath, do_parse!(
383 global: option!(punct!("::")) >>
384 punct!("{") >>
385 items: separated_nonempty_list!(punct!(","), path_list_item) >>
386 punct!("}") >>
387 (ViewPath::List(Path {
388 global: global.is_some(),
389 segments: Vec::new(),
390 }, items))
391 ));
392
393 named!(path_list_item -> PathListItem, do_parse!(
394 name: ident >>
395 rename: option!(preceded!(keyword!("as"), ident)) >>
396 (PathListItem {
397 name: name,
398 rename: rename,
399 })
400 ));
401
David Tolnay47a877c2016-10-01 16:50:55 -0700402 named!(item_static -> Item, do_parse!(
403 attrs: many0!(outer_attr) >>
404 vis: visibility >>
405 keyword!("static") >>
406 mutability: mutability >>
407 id: ident >>
408 punct!(":") >>
409 ty: ty >>
410 punct!("=") >>
411 value: expr >>
412 punct!(";") >>
413 (Item {
414 ident: id,
415 vis: vis,
416 attrs: attrs,
417 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
418 })
419 ));
420
421 named!(item_const -> Item, do_parse!(
422 attrs: many0!(outer_attr) >>
423 vis: visibility >>
424 keyword!("const") >>
425 id: ident >>
426 punct!(":") >>
427 ty: ty >>
428 punct!("=") >>
429 value: expr >>
430 punct!(";") >>
431 (Item {
432 ident: id,
433 vis: vis,
434 attrs: attrs,
435 node: ItemKind::Const(Box::new(ty), Box::new(value)),
436 })
437 ));
438
David Tolnay42602292016-10-01 22:25:45 -0700439 named!(item_fn -> Item, do_parse!(
440 attrs: many0!(outer_attr) >>
441 vis: visibility >>
442 constness: constness >>
443 unsafety: unsafety >>
444 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
445 keyword!("fn") >>
446 name: ident >>
447 generics: generics >>
448 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700449 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay42602292016-10-01 22:25:45 -0700450 punct!(")") >>
451 ret: option!(preceded!(punct!("->"), ty)) >>
452 where_clause: where_clause >>
453 body: block >>
454 (Item {
455 ident: name,
456 vis: vis,
457 attrs: attrs,
458 node: ItemKind::Fn(
459 Box::new(FnDecl {
460 inputs: inputs,
461 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
462 }),
463 unsafety,
464 constness,
465 abi.map(Abi),
466 Generics {
467 where_clause: where_clause,
468 .. generics
469 },
470 Box::new(body),
471 ),
472 })
473 ));
474
David Tolnayca085422016-10-04 00:12:38 -0700475 named!(fn_arg -> FnArg, alt!(
476 do_parse!(
477 punct!("&") >>
478 lt: option!(lifetime) >>
479 mutability: mutability >>
480 keyword!("self") >>
481 (FnArg::SelfRef(lt, mutability))
482 )
483 |
484 do_parse!(
485 mutability: mutability >>
486 keyword!("self") >>
487 (FnArg::SelfValue(mutability))
488 )
489 |
490 do_parse!(
491 pat: pat >>
492 punct!(":") >>
493 ty: ty >>
494 (FnArg::Captured(pat, ty))
495 )
496 |
497 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700498 ));
499
David Tolnay35902302016-10-06 01:11:08 -0700500 named!(item_mod -> Item, do_parse!(
501 attrs: many0!(outer_attr) >>
502 vis: visibility >>
503 keyword!("mod") >>
504 id: ident >>
David Tolnay37d10332016-10-13 20:51:04 -0700505 items: alt!(
506 punct!(";") => { |_| None }
507 |
David Tolnay453cfd12016-10-23 11:00:14 -0700508 delimited!(punct!("{"), items, punct!("}")) => { Some }
David Tolnay37d10332016-10-13 20:51:04 -0700509 ) >>
David Tolnay35902302016-10-06 01:11:08 -0700510 (Item {
511 ident: id,
512 vis: vis,
513 attrs: attrs,
514 node: ItemKind::Mod(items),
515 })
516 ));
517
518 named!(item_foreign_mod -> Item, do_parse!(
519 attrs: many0!(outer_attr) >>
520 keyword!("extern") >>
521 abi: option!(quoted_string) >>
522 punct!("{") >>
523 items: many0!(foreign_item) >>
524 punct!("}") >>
525 (Item {
526 ident: "".into(),
527 vis: Visibility::Inherited,
528 attrs: attrs,
529 node: ItemKind::ForeignMod(ForeignMod {
530 abi: abi.map(Abi),
531 items: items,
532 }),
533 })
534 ));
535
536 named!(foreign_item -> ForeignItem, alt!(
537 foreign_fn
538 |
539 foreign_static
540 ));
541
542 named!(foreign_fn -> ForeignItem, do_parse!(
543 attrs: many0!(outer_attr) >>
544 vis: visibility >>
545 keyword!("fn") >>
546 name: ident >>
547 generics: generics >>
548 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700549 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay35902302016-10-06 01:11:08 -0700550 punct!(")") >>
551 ret: option!(preceded!(punct!("->"), ty)) >>
552 where_clause: where_clause >>
553 punct!(";") >>
554 (ForeignItem {
555 ident: name,
556 attrs: attrs,
557 node: ForeignItemKind::Fn(
558 Box::new(FnDecl {
559 inputs: inputs,
560 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
561 }),
562 Generics {
563 where_clause: where_clause,
564 .. generics
565 },
566 ),
567 vis: vis,
568 })
569 ));
570
571 named!(foreign_static -> ForeignItem, do_parse!(
572 attrs: many0!(outer_attr) >>
573 vis: visibility >>
574 keyword!("static") >>
575 mutability: mutability >>
576 id: ident >>
577 punct!(":") >>
578 ty: ty >>
579 punct!(";") >>
580 (ForeignItem {
581 ident: id,
582 attrs: attrs,
583 node: ForeignItemKind::Static(Box::new(ty), mutability),
584 vis: vis,
585 })
586 ));
587
David Tolnay3cf52982016-10-01 17:11:37 -0700588 named!(item_ty -> Item, do_parse!(
589 attrs: many0!(outer_attr) >>
590 vis: visibility >>
591 keyword!("type") >>
592 id: ident >>
593 generics: generics >>
594 punct!("=") >>
595 ty: ty >>
596 punct!(";") >>
597 (Item {
598 ident: id,
599 vis: vis,
600 attrs: attrs,
601 node: ItemKind::Ty(Box::new(ty), generics),
602 })
603 ));
604
David Tolnaya96a3fa2016-09-24 07:17:42 -0700605 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700606 macro_input,
607 |def: MacroInput| Item {
608 ident: def.ident,
609 vis: def.vis,
610 attrs: def.attrs,
611 node: match def.body {
612 Body::Enum(variants) => {
613 ItemKind::Enum(variants, def.generics)
614 }
615 Body::Struct(variant_data) => {
616 ItemKind::Struct(variant_data, def.generics)
617 }
618 }
619 }
620 ));
David Tolnay42602292016-10-01 22:25:45 -0700621
David Tolnay2f9fa632016-10-03 22:08:48 -0700622 named!(item_union -> Item, do_parse!(
623 attrs: many0!(outer_attr) >>
624 vis: visibility >>
625 keyword!("union") >>
626 id: ident >>
627 generics: generics >>
628 where_clause: where_clause >>
629 fields: struct_like_body >>
630 (Item {
631 ident: id,
632 vis: vis,
633 attrs: attrs,
634 node: ItemKind::Union(
635 VariantData::Struct(fields),
636 Generics {
637 where_clause: where_clause,
638 .. generics
639 },
640 ),
641 })
642 ));
643
David Tolnay0aecb732016-10-03 23:03:50 -0700644 named!(item_trait -> Item, do_parse!(
645 attrs: many0!(outer_attr) >>
646 vis: visibility >>
647 unsafety: unsafety >>
648 keyword!("trait") >>
649 id: ident >>
650 generics: generics >>
651 bounds: opt_vec!(preceded!(
652 punct!(":"),
653 separated_nonempty_list!(punct!("+"), ty_param_bound)
654 )) >>
655 where_clause: where_clause >>
656 punct!("{") >>
657 body: many0!(trait_item) >>
658 punct!("}") >>
659 (Item {
660 ident: id,
661 vis: vis,
662 attrs: attrs,
663 node: ItemKind::Trait(
664 unsafety,
665 Generics {
666 where_clause: where_clause,
667 .. generics
668 },
669 bounds,
670 body,
671 ),
672 })
673 ));
674
David Tolnayf94e2362016-10-04 00:29:51 -0700675 named!(item_default_impl -> Item, do_parse!(
676 attrs: many0!(outer_attr) >>
677 unsafety: unsafety >>
678 keyword!("impl") >>
679 path: path >>
680 keyword!("for") >>
681 punct!("..") >>
682 punct!("{") >>
683 punct!("}") >>
684 (Item {
685 ident: "".into(),
686 vis: Visibility::Inherited,
687 attrs: attrs,
688 node: ItemKind::DefaultImpl(unsafety, path),
689 })
690 ));
691
David Tolnay0aecb732016-10-03 23:03:50 -0700692 named!(trait_item -> TraitItem, alt!(
693 trait_item_const
694 |
695 trait_item_method
696 |
697 trait_item_type
698 |
699 trait_item_mac
700 ));
701
702 named!(trait_item_const -> TraitItem, do_parse!(
703 attrs: many0!(outer_attr) >>
704 keyword!("const") >>
705 id: ident >>
706 punct!(":") >>
707 ty: ty >>
708 value: option!(preceded!(punct!("="), expr)) >>
709 punct!(";") >>
710 (TraitItem {
711 ident: id,
712 attrs: attrs,
713 node: TraitItemKind::Const(ty, value),
714 })
715 ));
716
717 named!(trait_item_method -> TraitItem, do_parse!(
718 attrs: many0!(outer_attr) >>
719 constness: constness >>
720 unsafety: unsafety >>
721 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
722 keyword!("fn") >>
723 name: ident >>
724 generics: generics >>
725 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700726 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700727 punct!(")") >>
728 ret: option!(preceded!(punct!("->"), ty)) >>
729 where_clause: where_clause >>
730 body: option!(block) >>
731 cond!(body.is_none(), punct!(";")) >>
732 (TraitItem {
733 ident: name,
734 attrs: attrs,
735 node: TraitItemKind::Method(
736 MethodSig {
737 unsafety: unsafety,
738 constness: constness,
739 abi: abi.map(Abi),
740 decl: FnDecl {
741 inputs: inputs,
742 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
743 },
744 generics: Generics {
745 where_clause: where_clause,
746 .. generics
747 },
748 },
749 body,
750 ),
751 })
752 ));
753
754 named!(trait_item_type -> TraitItem, do_parse!(
755 attrs: many0!(outer_attr) >>
756 keyword!("type") >>
757 id: ident >>
758 bounds: opt_vec!(preceded!(
759 punct!(":"),
760 separated_nonempty_list!(punct!("+"), ty_param_bound)
761 )) >>
762 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700763 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700764 (TraitItem {
765 ident: id,
766 attrs: attrs,
767 node: TraitItemKind::Type(bounds, default),
768 })
769 ));
770
771 named!(trait_item_mac -> TraitItem, do_parse!(
772 attrs: many0!(outer_attr) >>
773 id: ident >>
774 punct!("!") >>
775 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700776 cond!(match body.delim {
777 DelimToken::Paren | DelimToken::Bracket => true,
778 DelimToken::Brace => false,
779 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700780 (TraitItem {
781 ident: id.clone(),
782 attrs: attrs,
783 node: TraitItemKind::Macro(Mac {
784 path: id.into(),
785 tts: vec![TokenTree::Delimited(body)],
786 }),
787 })
788 ));
789
David Tolnay4c9be372016-10-06 00:47:37 -0700790 named!(item_impl -> Item, do_parse!(
791 attrs: many0!(outer_attr) >>
792 unsafety: unsafety >>
793 keyword!("impl") >>
794 generics: generics >>
795 polarity_path: alt!(
796 do_parse!(
797 polarity: impl_polarity >>
798 path: path >>
799 keyword!("for") >>
800 ((polarity, Some(path)))
801 )
802 |
803 epsilon!() => { |_| (ImplPolarity::Positive, None) }
804 ) >>
805 self_ty: ty >>
806 where_clause: where_clause >>
807 punct!("{") >>
808 body: many0!(impl_item) >>
809 punct!("}") >>
810 (Item {
811 ident: "".into(),
812 vis: Visibility::Inherited,
813 attrs: attrs,
814 node: ItemKind::Impl(
815 unsafety,
816 polarity_path.0,
817 Generics {
818 where_clause: where_clause,
819 .. generics
820 },
821 polarity_path.1,
822 Box::new(self_ty),
823 body,
824 ),
825 })
826 ));
827
828 named!(impl_item -> ImplItem, alt!(
829 impl_item_const
830 |
831 impl_item_method
832 |
833 impl_item_type
834 |
835 impl_item_macro
836 ));
837
838 named!(impl_item_const -> ImplItem, do_parse!(
839 attrs: many0!(outer_attr) >>
840 vis: visibility >>
841 defaultness: defaultness >>
842 keyword!("const") >>
843 id: ident >>
844 punct!(":") >>
845 ty: ty >>
846 punct!("=") >>
847 value: expr >>
848 punct!(";") >>
849 (ImplItem {
850 ident: id,
851 vis: vis,
852 defaultness: defaultness,
853 attrs: attrs,
854 node: ImplItemKind::Const(ty, value),
855 })
856 ));
857
858 named!(impl_item_method -> ImplItem, do_parse!(
859 attrs: many0!(outer_attr) >>
860 vis: visibility >>
861 defaultness: defaultness >>
862 constness: constness >>
863 unsafety: unsafety >>
864 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
865 keyword!("fn") >>
866 name: ident >>
867 generics: generics >>
868 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700869 inputs: terminated_list!(punct!(","), fn_arg) >>
David Tolnay4c9be372016-10-06 00:47:37 -0700870 punct!(")") >>
871 ret: option!(preceded!(punct!("->"), ty)) >>
872 where_clause: where_clause >>
873 body: block >>
874 (ImplItem {
875 ident: name,
876 vis: vis,
877 defaultness: defaultness,
878 attrs: attrs,
879 node: ImplItemKind::Method(
880 MethodSig {
881 unsafety: unsafety,
882 constness: constness,
883 abi: abi.map(Abi),
884 decl: FnDecl {
885 inputs: inputs,
886 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
887 },
888 generics: Generics {
889 where_clause: where_clause,
890 .. generics
891 },
892 },
893 body,
894 ),
895 })
896 ));
897
898 named!(impl_item_type -> ImplItem, do_parse!(
899 attrs: many0!(outer_attr) >>
900 vis: visibility >>
901 defaultness: defaultness >>
902 keyword!("type") >>
903 id: ident >>
904 punct!("=") >>
905 ty: ty >>
906 punct!(";") >>
907 (ImplItem {
908 ident: id,
909 vis: vis,
910 defaultness: defaultness,
911 attrs: attrs,
912 node: ImplItemKind::Type(ty),
913 })
914 ));
915
916 named!(impl_item_macro -> ImplItem, do_parse!(
917 attrs: many0!(outer_attr) >>
918 id: ident >>
919 punct!("!") >>
920 body: delimited >>
921 cond!(match body.delim {
922 DelimToken::Paren | DelimToken::Bracket => true,
923 DelimToken::Brace => false,
924 }, punct!(";")) >>
925 (ImplItem {
926 ident: id.clone(),
927 vis: Visibility::Inherited,
928 defaultness: Defaultness::Final,
929 attrs: attrs,
930 node: ImplItemKind::Macro(Mac {
931 path: id.into(),
932 tts: vec![TokenTree::Delimited(body)],
933 }),
934 })
935 ));
936
937 named!(impl_polarity -> ImplPolarity, alt!(
938 punct!("!") => { |_| ImplPolarity::Negative }
939 |
940 epsilon!() => { |_| ImplPolarity::Positive }
941 ));
942
David Tolnay42602292016-10-01 22:25:45 -0700943 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700944 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -0700945 |
946 epsilon!() => { |_| Constness::NotConst }
947 ));
948
949 named!(unsafety -> Unsafety, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700950 keyword!("unsafe") => { |_| Unsafety::Unsafe }
David Tolnay42602292016-10-01 22:25:45 -0700951 |
952 epsilon!() => { |_| Unsafety::Normal }
953 ));
David Tolnay4c9be372016-10-06 00:47:37 -0700954
955 named!(defaultness -> Defaultness, alt!(
956 keyword!("default") => { |_| Defaultness::Default }
957 |
958 epsilon!() => { |_| Defaultness::Final }
959 ));
David Tolnayedf2b992016-09-23 20:43:45 -0700960}
David Tolnay4a51dc72016-10-01 00:40:31 -0700961
962#[cfg(feature = "printing")]
963mod printing {
964 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -0700965 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -0700966 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -0700967 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -0700968 use quote::{Tokens, ToTokens};
969
970 impl ToTokens for Item {
971 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700972 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -0700973 match self.node {
974 ItemKind::ExternCrate(ref original) => {
975 tokens.append("extern");
976 tokens.append("crate");
977 if let Some(ref original) = *original {
978 original.to_tokens(tokens);
979 tokens.append("as");
980 }
981 self.ident.to_tokens(tokens);
982 tokens.append(";");
983 }
David Tolnay4a057422016-10-08 00:02:31 -0700984 ItemKind::Use(ref view_path) => {
985 self.vis.to_tokens(tokens);
986 tokens.append("use");
987 view_path.to_tokens(tokens);
988 tokens.append(";");
989 }
David Tolnay47a877c2016-10-01 16:50:55 -0700990 ItemKind::Static(ref ty, ref mutability, ref expr) => {
991 self.vis.to_tokens(tokens);
992 tokens.append("static");
993 mutability.to_tokens(tokens);
994 self.ident.to_tokens(tokens);
995 tokens.append(":");
996 ty.to_tokens(tokens);
997 tokens.append("=");
998 expr.to_tokens(tokens);
999 tokens.append(";");
1000 }
1001 ItemKind::Const(ref ty, ref expr) => {
1002 self.vis.to_tokens(tokens);
1003 tokens.append("const");
1004 self.ident.to_tokens(tokens);
1005 tokens.append(":");
1006 ty.to_tokens(tokens);
1007 tokens.append("=");
1008 expr.to_tokens(tokens);
1009 tokens.append(";");
1010 }
David Tolnay42602292016-10-01 22:25:45 -07001011 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
1012 self.vis.to_tokens(tokens);
1013 constness.to_tokens(tokens);
1014 unsafety.to_tokens(tokens);
1015 abi.to_tokens(tokens);
1016 tokens.append("fn");
1017 self.ident.to_tokens(tokens);
1018 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -07001019 tokens.append("(");
1020 tokens.append_separated(&decl.inputs, ",");
1021 tokens.append(")");
1022 if let FunctionRetTy::Ty(ref ty) = decl.output {
1023 tokens.append("->");
1024 ty.to_tokens(tokens);
1025 }
David Tolnay42602292016-10-01 22:25:45 -07001026 generics.where_clause.to_tokens(tokens);
1027 block.to_tokens(tokens);
1028 }
David Tolnay35902302016-10-06 01:11:08 -07001029 ItemKind::Mod(ref items) => {
1030 self.vis.to_tokens(tokens);
1031 tokens.append("mod");
1032 self.ident.to_tokens(tokens);
David Tolnay37d10332016-10-13 20:51:04 -07001033 match *items {
1034 Some(ref items) => {
1035 tokens.append("{");
1036 tokens.append_all(items);
1037 tokens.append("}");
1038 }
1039 None => tokens.append(";"),
1040 }
David Tolnay35902302016-10-06 01:11:08 -07001041 }
1042 ItemKind::ForeignMod(ref foreign_mod) => {
1043 self.vis.to_tokens(tokens);
1044 match foreign_mod.abi {
1045 Some(ref abi) => abi.to_tokens(tokens),
1046 None => tokens.append("extern"),
1047 }
1048 tokens.append("{");
1049 tokens.append_all(&foreign_mod.items);
1050 tokens.append("}");
1051 }
David Tolnay3cf52982016-10-01 17:11:37 -07001052 ItemKind::Ty(ref ty, ref generics) => {
1053 self.vis.to_tokens(tokens);
1054 tokens.append("type");
1055 self.ident.to_tokens(tokens);
1056 generics.to_tokens(tokens);
1057 tokens.append("=");
1058 ty.to_tokens(tokens);
1059 tokens.append(";");
1060 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001061 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001062 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001063 tokens.append("enum");
1064 self.ident.to_tokens(tokens);
1065 generics.to_tokens(tokens);
1066 generics.where_clause.to_tokens(tokens);
1067 tokens.append("{");
1068 for variant in variants {
1069 variant.to_tokens(tokens);
1070 tokens.append(",");
1071 }
1072 tokens.append("}");
1073 }
1074 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -07001075 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -07001076 tokens.append("struct");
1077 self.ident.to_tokens(tokens);
1078 generics.to_tokens(tokens);
1079 generics.where_clause.to_tokens(tokens);
1080 variant_data.to_tokens(tokens);
1081 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -07001082 VariantData::Struct(_) => {
1083 // no semicolon
1084 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001085 VariantData::Tuple(_) |
1086 VariantData::Unit => tokens.append(";"),
1087 }
1088 }
David Tolnay2f9fa632016-10-03 22:08:48 -07001089 ItemKind::Union(ref variant_data, ref generics) => {
1090 self.vis.to_tokens(tokens);
1091 tokens.append("union");
1092 self.ident.to_tokens(tokens);
1093 generics.to_tokens(tokens);
1094 generics.where_clause.to_tokens(tokens);
1095 variant_data.to_tokens(tokens);
1096 }
David Tolnayca085422016-10-04 00:12:38 -07001097 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
1098 self.vis.to_tokens(tokens);
1099 unsafety.to_tokens(tokens);
1100 tokens.append("trait");
1101 self.ident.to_tokens(tokens);
1102 if !bound.is_empty() {
1103 tokens.append(":");
1104 tokens.append_separated(bound, "+");
1105 }
1106 generics.to_tokens(tokens);
1107 generics.where_clause.to_tokens(tokens);
1108 tokens.append("{");
1109 tokens.append_all(items);
1110 tokens.append("}");
1111 }
David Tolnayf94e2362016-10-04 00:29:51 -07001112 ItemKind::DefaultImpl(unsafety, ref path) => {
1113 unsafety.to_tokens(tokens);
1114 tokens.append("impl");
1115 path.to_tokens(tokens);
1116 tokens.append("for");
1117 tokens.append("..");
1118 tokens.append("{");
1119 tokens.append("}");
1120 }
David Tolnay3bcfb722016-10-08 11:58:36 -07001121 ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => {
David Tolnay4c9be372016-10-06 00:47:37 -07001122 unsafety.to_tokens(tokens);
1123 tokens.append("impl");
1124 generics.to_tokens(tokens);
1125 if let Some(ref path) = *path {
1126 polarity.to_tokens(tokens);
1127 path.to_tokens(tokens);
1128 tokens.append("for");
1129 }
1130 ty.to_tokens(tokens);
1131 generics.where_clause.to_tokens(tokens);
1132 tokens.append("{");
1133 tokens.append_all(items);
1134 tokens.append("}");
1135 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001136 ItemKind::Mac(ref mac) => {
1137 mac.path.to_tokens(tokens);
1138 tokens.append("!");
1139 self.ident.to_tokens(tokens);
1140 for tt in &mac.tts {
1141 tt.to_tokens(tokens);
1142 }
1143 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -07001144 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1145 // no semicolon
1146 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001147 _ => tokens.append(";"),
1148 }
1149 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001150 }
1151 }
1152 }
David Tolnay42602292016-10-01 22:25:45 -07001153
David Tolnay4a057422016-10-08 00:02:31 -07001154 impl ToTokens for ViewPath {
1155 fn to_tokens(&self, tokens: &mut Tokens) {
1156 match *self {
1157 ViewPath::Simple(ref path, ref rename) => {
1158 path.to_tokens(tokens);
1159 if let Some(ref rename) = *rename {
1160 tokens.append("as");
1161 rename.to_tokens(tokens);
1162 }
1163 }
1164 ViewPath::Glob(ref path) => {
1165 path.to_tokens(tokens);
1166 tokens.append("::");
1167 tokens.append("*");
1168 }
1169 ViewPath::List(ref path, ref items) => {
1170 path.to_tokens(tokens);
David Tolnay12417832016-10-08 00:12:37 -07001171 if path.global || !path.segments.is_empty() {
1172 tokens.append("::");
1173 }
David Tolnay4a057422016-10-08 00:02:31 -07001174 tokens.append("{");
1175 tokens.append_separated(items, ",");
1176 tokens.append("}");
1177 }
1178 }
1179 }
1180 }
1181
1182 impl ToTokens for PathListItem {
1183 fn to_tokens(&self, tokens: &mut Tokens) {
1184 self.name.to_tokens(tokens);
1185 if let Some(ref rename) = self.rename {
1186 tokens.append("as");
1187 rename.to_tokens(tokens);
1188 }
1189 }
1190 }
1191
David Tolnayca085422016-10-04 00:12:38 -07001192 impl ToTokens for TraitItem {
1193 fn to_tokens(&self, tokens: &mut Tokens) {
1194 tokens.append_all(self.attrs.outer());
1195 match self.node {
1196 TraitItemKind::Const(ref ty, ref expr) => {
1197 tokens.append("const");
1198 self.ident.to_tokens(tokens);
1199 tokens.append(":");
1200 ty.to_tokens(tokens);
1201 if let Some(ref expr) = *expr {
1202 tokens.append("=");
1203 expr.to_tokens(tokens);
1204 }
1205 tokens.append(";");
1206 }
1207 TraitItemKind::Method(ref sig, ref block) => {
1208 sig.unsafety.to_tokens(tokens);
1209 sig.abi.to_tokens(tokens);
1210 tokens.append("fn");
1211 self.ident.to_tokens(tokens);
1212 sig.generics.to_tokens(tokens);
1213 tokens.append("(");
1214 tokens.append_separated(&sig.decl.inputs, ",");
1215 tokens.append(")");
1216 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1217 tokens.append("->");
1218 ty.to_tokens(tokens);
1219 }
1220 sig.generics.where_clause.to_tokens(tokens);
1221 match *block {
1222 Some(ref block) => block.to_tokens(tokens),
1223 None => tokens.append(";"),
1224 }
1225 }
1226 TraitItemKind::Type(ref bound, ref default) => {
1227 tokens.append("type");
1228 self.ident.to_tokens(tokens);
1229 if !bound.is_empty() {
1230 tokens.append(":");
1231 tokens.append_separated(bound, "+");
1232 }
1233 if let Some(ref default) = *default {
1234 tokens.append("=");
1235 default.to_tokens(tokens);
1236 }
1237 tokens.append(";");
1238 }
1239 TraitItemKind::Macro(ref mac) => {
1240 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -07001241 match mac.tts.last() {
1242 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1243 // no semicolon
1244 }
1245 _ => tokens.append(";"),
1246 }
David Tolnayca085422016-10-04 00:12:38 -07001247 }
1248 }
1249 }
1250 }
1251
David Tolnay4c9be372016-10-06 00:47:37 -07001252 impl ToTokens for ImplItem {
1253 fn to_tokens(&self, tokens: &mut Tokens) {
1254 tokens.append_all(self.attrs.outer());
1255 match self.node {
1256 ImplItemKind::Const(ref ty, ref expr) => {
1257 self.vis.to_tokens(tokens);
1258 self.defaultness.to_tokens(tokens);
1259 tokens.append("const");
1260 self.ident.to_tokens(tokens);
1261 tokens.append(":");
1262 ty.to_tokens(tokens);
1263 tokens.append("=");
1264 expr.to_tokens(tokens);
1265 tokens.append(";");
1266 }
1267 ImplItemKind::Method(ref sig, ref block) => {
1268 self.vis.to_tokens(tokens);
1269 self.defaultness.to_tokens(tokens);
1270 sig.unsafety.to_tokens(tokens);
1271 sig.abi.to_tokens(tokens);
1272 tokens.append("fn");
1273 self.ident.to_tokens(tokens);
1274 sig.generics.to_tokens(tokens);
1275 tokens.append("(");
1276 tokens.append_separated(&sig.decl.inputs, ",");
1277 tokens.append(")");
1278 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1279 tokens.append("->");
1280 ty.to_tokens(tokens);
1281 }
1282 sig.generics.where_clause.to_tokens(tokens);
1283 block.to_tokens(tokens);
1284 }
1285 ImplItemKind::Type(ref ty) => {
1286 self.vis.to_tokens(tokens);
1287 self.defaultness.to_tokens(tokens);
1288 tokens.append("type");
1289 self.ident.to_tokens(tokens);
1290 tokens.append("=");
1291 ty.to_tokens(tokens);
1292 tokens.append(";");
1293 }
1294 ImplItemKind::Macro(ref mac) => {
1295 mac.to_tokens(tokens);
1296 match mac.tts.last() {
1297 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1298 // no semicolon
1299 }
1300 _ => tokens.append(";"),
1301 }
1302 }
1303 }
1304 }
1305 }
1306
David Tolnay35902302016-10-06 01:11:08 -07001307 impl ToTokens for ForeignItem {
1308 fn to_tokens(&self, tokens: &mut Tokens) {
1309 tokens.append_all(self.attrs.outer());
1310 match self.node {
1311 ForeignItemKind::Fn(ref decl, ref generics) => {
1312 self.vis.to_tokens(tokens);
1313 tokens.append("fn");
1314 self.ident.to_tokens(tokens);
1315 generics.to_tokens(tokens);
1316 tokens.append("(");
1317 tokens.append_separated(&decl.inputs, ",");
1318 tokens.append(")");
1319 if let FunctionRetTy::Ty(ref ty) = decl.output {
1320 tokens.append("->");
1321 ty.to_tokens(tokens);
1322 }
1323 generics.where_clause.to_tokens(tokens);
1324 tokens.append(";");
1325 }
1326 ForeignItemKind::Static(ref ty, mutability) => {
1327 self.vis.to_tokens(tokens);
1328 tokens.append("static");
1329 mutability.to_tokens(tokens);
1330 self.ident.to_tokens(tokens);
1331 tokens.append(":");
1332 ty.to_tokens(tokens);
1333 tokens.append(";");
1334 }
1335 }
1336 }
1337 }
1338
David Tolnay62f374c2016-10-02 13:37:00 -07001339 impl ToTokens for FnArg {
1340 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001341 match *self {
1342 FnArg::SelfRef(ref lifetime, mutability) => {
1343 tokens.append("&");
1344 lifetime.to_tokens(tokens);
1345 mutability.to_tokens(tokens);
1346 tokens.append("self");
1347 }
1348 FnArg::SelfValue(mutability) => {
1349 mutability.to_tokens(tokens);
1350 tokens.append("self");
1351 }
1352 FnArg::Captured(ref pat, ref ty) => {
1353 pat.to_tokens(tokens);
1354 tokens.append(":");
1355 ty.to_tokens(tokens);
1356 }
1357 FnArg::Ignored(ref ty) => {
1358 ty.to_tokens(tokens);
1359 }
1360 }
David Tolnay62f374c2016-10-02 13:37:00 -07001361 }
1362 }
1363
David Tolnay42602292016-10-01 22:25:45 -07001364 impl ToTokens for Unsafety {
1365 fn to_tokens(&self, tokens: &mut Tokens) {
1366 match *self {
1367 Unsafety::Unsafe => tokens.append("unsafe"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001368 Unsafety::Normal => {
1369 // nothing
1370 }
David Tolnay42602292016-10-01 22:25:45 -07001371 }
1372 }
1373 }
1374
1375 impl ToTokens for Constness {
1376 fn to_tokens(&self, tokens: &mut Tokens) {
1377 match *self {
1378 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001379 Constness::NotConst => {
1380 // nothing
1381 }
David Tolnay42602292016-10-01 22:25:45 -07001382 }
1383 }
1384 }
1385
David Tolnay4c9be372016-10-06 00:47:37 -07001386 impl ToTokens for Defaultness {
1387 fn to_tokens(&self, tokens: &mut Tokens) {
1388 match *self {
1389 Defaultness::Default => tokens.append("default"),
1390 Defaultness::Final => {
1391 // nothing
1392 }
1393 }
1394 }
1395 }
1396
1397 impl ToTokens for ImplPolarity {
1398 fn to_tokens(&self, tokens: &mut Tokens) {
1399 match *self {
1400 ImplPolarity::Negative => tokens.append("!"),
1401 ImplPolarity::Positive => {
1402 // nothing
1403 }
1404 }
1405 }
1406 }
1407
David Tolnay42602292016-10-01 22:25:45 -07001408 impl ToTokens for Abi {
1409 fn to_tokens(&self, tokens: &mut Tokens) {
1410 tokens.append("extern");
1411 self.0.to_tokens(tokens);
1412 }
1413 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001414}