blob: d1c53e0d4bcaf326c9fe4ecc62fc69ad9a522740 [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 { .. }`
39 Mod(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>),
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
83#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -070084pub enum ViewPath {
85 /// `foo::bar::baz as quux`
86 ///
87 /// or just
88 ///
89 /// `foo::bar::baz` (with `as baz` implicitly on the right)
David Tolnayaed77b02016-09-23 20:50:31 -070090 Simple(Ident, Path),
David Tolnayf38cdf62016-09-23 19:07:09 -070091
92 /// `foo::bar::*`
David Tolnayaed77b02016-09-23 20:50:31 -070093 Glob(Path),
David Tolnayf38cdf62016-09-23 19:07:09 -070094
David Tolnayaed77b02016-09-23 20:50:31 -070095 /// `foo::bar::{a, b, c}`
David Tolnaydaaf7742016-10-03 11:11:43 -070096 List(Path, Vec<PathListItem>),
David Tolnayf38cdf62016-09-23 19:07:09 -070097}
98
99#[derive(Debug, Clone, Eq, PartialEq)]
100pub struct PathListItem {
101 pub name: Ident,
102 /// renamed in list, e.g. `use foo::{bar as baz};`
103 pub rename: Option<Ident>,
104}
105
106#[derive(Debug, Copy, Clone, Eq, PartialEq)]
107pub enum Unsafety {
108 Unsafe,
109 Normal,
110}
111
112#[derive(Debug, Copy, Clone, Eq, PartialEq)]
113pub enum Constness {
114 Const,
115 NotConst,
116}
117
118#[derive(Debug, Copy, Clone, Eq, PartialEq)]
119pub enum Defaultness {
120 Default,
121 Final,
122}
123
124#[derive(Debug, Clone, Eq, PartialEq)]
125pub struct Abi(pub String);
126
127/// Foreign module declaration.
128///
David Tolnay35902302016-10-06 01:11:08 -0700129/// E.g. `extern { .. }` or `extern "C" { .. }`
David Tolnayf38cdf62016-09-23 19:07:09 -0700130#[derive(Debug, Clone, Eq, PartialEq)]
131pub struct ForeignMod {
David Tolnay35902302016-10-06 01:11:08 -0700132 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700133 pub items: Vec<ForeignItem>,
134}
135
136#[derive(Debug, Clone, Eq, PartialEq)]
137pub struct ForeignItem {
David Tolnayb79ee962016-09-04 09:39:20 -0700138 pub ident: Ident,
139 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700140 pub node: ForeignItemKind,
David Tolnayb79ee962016-09-04 09:39:20 -0700141 pub vis: Visibility,
David Tolnayf38cdf62016-09-23 19:07:09 -0700142}
143
David Tolnay771ecf42016-09-23 19:26:37 -0700144/// An item within an `extern` block
David Tolnayf38cdf62016-09-23 19:07:09 -0700145#[derive(Debug, Clone, Eq, PartialEq)]
146pub enum ForeignItemKind {
147 /// A foreign function
148 Fn(Box<FnDecl>, Generics),
David Tolnay35902302016-10-06 01:11:08 -0700149 /// A foreign static item (`static ext: u8`)
150 Static(Box<Ty>, Mutability),
David Tolnayf38cdf62016-09-23 19:07:09 -0700151}
152
153/// Represents an item declaration within a trait declaration,
154/// possibly including a default implementation. A trait item is
155/// either required (meaning it doesn't have an implementation, just a
156/// signature) or provided (meaning it has a default implementation).
157#[derive(Debug, Clone, Eq, PartialEq)]
158pub struct TraitItem {
159 pub ident: Ident,
David Tolnayb79ee962016-09-04 09:39:20 -0700160 pub attrs: Vec<Attribute>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700161 pub node: TraitItemKind,
162}
163
164#[derive(Debug, Clone, Eq, PartialEq)]
165pub enum TraitItemKind {
166 Const(Ty, Option<Expr>),
167 Method(MethodSig, Option<Block>),
168 Type(Vec<TyParamBound>, Option<Ty>),
169 Macro(Mac),
David Tolnayb79ee962016-09-04 09:39:20 -0700170}
171
David Tolnay55337722016-09-11 12:58:56 -0700172#[derive(Debug, Copy, Clone, Eq, PartialEq)]
David Tolnayf38cdf62016-09-23 19:07:09 -0700173pub enum ImplPolarity {
174 /// `impl Trait for Type`
175 Positive,
176 /// `impl !Trait for Type`
177 Negative,
David Tolnay55337722016-09-11 12:58:56 -0700178}
179
David Tolnayf38cdf62016-09-23 19:07:09 -0700180#[derive(Debug, Clone, Eq, PartialEq)]
181pub struct ImplItem {
182 pub ident: Ident,
183 pub vis: Visibility,
184 pub defaultness: Defaultness,
185 pub attrs: Vec<Attribute>,
186 pub node: ImplItemKind,
David Tolnayf4bbbd92016-09-23 14:41:55 -0700187}
188
David Tolnayf38cdf62016-09-23 19:07:09 -0700189#[derive(Debug, Clone, Eq, PartialEq)]
190pub enum ImplItemKind {
191 Const(Ty, Expr),
192 Method(MethodSig, Block),
193 Type(Ty),
194 Macro(Mac),
David Tolnay9d8f1972016-09-04 11:58:48 -0700195}
David Tolnayd5025812016-09-04 14:21:46 -0700196
David Tolnayf38cdf62016-09-23 19:07:09 -0700197/// Represents a method's signature in a trait declaration,
198/// or in an implementation.
199#[derive(Debug, Clone, Eq, PartialEq)]
200pub struct MethodSig {
201 pub unsafety: Unsafety,
202 pub constness: Constness,
David Tolnay0aecb732016-10-03 23:03:50 -0700203 pub abi: Option<Abi>,
David Tolnayf38cdf62016-09-23 19:07:09 -0700204 pub decl: FnDecl,
205 pub generics: Generics,
David Tolnayd5025812016-09-04 14:21:46 -0700206}
David Tolnayedf2b992016-09-23 20:43:45 -0700207
David Tolnay62f374c2016-10-02 13:37:00 -0700208/// Header (not the body) of a function declaration.
209///
210/// E.g. `fn foo(bar: baz)`
211#[derive(Debug, Clone, Eq, PartialEq)]
212pub struct FnDecl {
213 pub inputs: Vec<FnArg>,
214 pub output: FunctionRetTy,
215}
216
217/// An argument in a function header.
218///
219/// E.g. `bar: usize` as in `fn foo(bar: usize)`
220#[derive(Debug, Clone, Eq, PartialEq)]
David Tolnayca085422016-10-04 00:12:38 -0700221pub enum FnArg {
222 SelfRef(Option<Lifetime>, Mutability),
223 SelfValue(Mutability),
224 Captured(Pat, Ty),
225 Ignored(Ty),
David Tolnay62f374c2016-10-02 13:37:00 -0700226}
227
David Tolnayedf2b992016-09-23 20:43:45 -0700228#[cfg(feature = "parsing")]
229pub mod parsing {
230 use super::*;
David Tolnaye3198932016-10-04 00:21:34 -0700231 use {DelimToken, FunctionRetTy, Generics, Ident, Mac, TokenTree, VariantData, Visibility};
David Tolnay4a51dc72016-10-01 00:40:31 -0700232 use attr::parsing::outer_attr;
David Tolnay2f9fa632016-10-03 22:08:48 -0700233 use data::parsing::{struct_like_body, visibility};
David Tolnay62f374c2016-10-02 13:37:00 -0700234 use expr::parsing::{block, expr, pat};
David Tolnayca085422016-10-04 00:12:38 -0700235 use generics::parsing::{generics, lifetime, ty_param_bound, where_clause};
David Tolnayedf2b992016-09-23 20:43:45 -0700236 use ident::parsing::ident;
David Tolnay42602292016-10-01 22:25:45 -0700237 use lit::parsing::quoted_string;
David Tolnay84aa0752016-10-02 23:01:13 -0700238 use mac::parsing::delimited;
David Tolnayedf2b992016-09-23 20:43:45 -0700239 use macro_input::{Body, MacroInput};
240 use macro_input::parsing::macro_input;
David Tolnayf94e2362016-10-04 00:29:51 -0700241 use ty::parsing::{mutability, path, ty};
David Tolnayedf2b992016-09-23 20:43:45 -0700242
243 named!(pub item -> Item, alt!(
David Tolnaya96a3fa2016-09-24 07:17:42 -0700244 item_extern_crate
David Tolnaydaaf7742016-10-03 11:11:43 -0700245 // TODO: Use
David Tolnay47a877c2016-10-01 16:50:55 -0700246 |
247 item_static
248 |
249 item_const
David Tolnay42602292016-10-01 22:25:45 -0700250 |
251 item_fn
David Tolnay35902302016-10-06 01:11:08 -0700252 |
253 item_mod
254 |
255 item_foreign_mod
David Tolnay3cf52982016-10-01 17:11:37 -0700256 |
257 item_ty
David Tolnayedf2b992016-09-23 20:43:45 -0700258 |
David Tolnaya96a3fa2016-09-24 07:17:42 -0700259 item_struct_or_enum
David Tolnay2f9fa632016-10-03 22:08:48 -0700260 |
261 item_union
David Tolnay0aecb732016-10-03 23:03:50 -0700262 |
263 item_trait
David Tolnayf94e2362016-10-04 00:29:51 -0700264 |
265 item_default_impl
David Tolnay4c9be372016-10-06 00:47:37 -0700266 |
267 item_impl
David Tolnay84aa0752016-10-02 23:01:13 -0700268 |
269 item_mac
270 ));
271
272 named!(item_mac -> Item, do_parse!(
273 attrs: many0!(outer_attr) >>
274 path: ident >>
275 punct!("!") >>
276 name: option!(ident) >>
277 body: delimited >>
278 (Item {
279 ident: name.unwrap_or_else(|| Ident::new("")),
280 vis: Visibility::Inherited,
281 attrs: attrs,
282 node: ItemKind::Mac(Mac {
283 path: path.into(),
284 tts: vec![TokenTree::Delimited(body)],
285 }),
286 })
David Tolnayedf2b992016-09-23 20:43:45 -0700287 ));
288
David Tolnaya96a3fa2016-09-24 07:17:42 -0700289 named!(item_extern_crate -> Item, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700290 attrs: many0!(outer_attr) >>
David Tolnayedf2b992016-09-23 20:43:45 -0700291 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -0700292 keyword!("extern") >>
293 keyword!("crate") >>
David Tolnayedf2b992016-09-23 20:43:45 -0700294 id: ident >>
295 rename: option!(preceded!(
David Tolnay10413f02016-09-30 09:12:02 -0700296 keyword!("as"),
David Tolnayedf2b992016-09-23 20:43:45 -0700297 ident
298 )) >>
299 punct!(";") >>
300 ({
301 let (name, original_name) = match rename {
302 Some(rename) => (rename, Some(id)),
303 None => (id, None),
304 };
305 Item {
306 ident: name,
307 vis: vis,
308 attrs: attrs,
309 node: ItemKind::ExternCrate(original_name),
310 }
311 })
312 ));
313
David Tolnay47a877c2016-10-01 16:50:55 -0700314 named!(item_static -> Item, do_parse!(
315 attrs: many0!(outer_attr) >>
316 vis: visibility >>
317 keyword!("static") >>
318 mutability: mutability >>
319 id: ident >>
320 punct!(":") >>
321 ty: ty >>
322 punct!("=") >>
323 value: expr >>
324 punct!(";") >>
325 (Item {
326 ident: id,
327 vis: vis,
328 attrs: attrs,
329 node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
330 })
331 ));
332
333 named!(item_const -> Item, do_parse!(
334 attrs: many0!(outer_attr) >>
335 vis: visibility >>
336 keyword!("const") >>
337 id: ident >>
338 punct!(":") >>
339 ty: ty >>
340 punct!("=") >>
341 value: expr >>
342 punct!(";") >>
343 (Item {
344 ident: id,
345 vis: vis,
346 attrs: attrs,
347 node: ItemKind::Const(Box::new(ty), Box::new(value)),
348 })
349 ));
350
David Tolnay42602292016-10-01 22:25:45 -0700351 named!(item_fn -> Item, do_parse!(
352 attrs: many0!(outer_attr) >>
353 vis: visibility >>
354 constness: constness >>
355 unsafety: unsafety >>
356 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
357 keyword!("fn") >>
358 name: ident >>
359 generics: generics >>
360 punct!("(") >>
361 inputs: separated_list!(punct!(","), fn_arg) >>
362 punct!(")") >>
363 ret: option!(preceded!(punct!("->"), ty)) >>
364 where_clause: where_clause >>
365 body: block >>
366 (Item {
367 ident: name,
368 vis: vis,
369 attrs: attrs,
370 node: ItemKind::Fn(
371 Box::new(FnDecl {
372 inputs: inputs,
373 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
374 }),
375 unsafety,
376 constness,
377 abi.map(Abi),
378 Generics {
379 where_clause: where_clause,
380 .. generics
381 },
382 Box::new(body),
383 ),
384 })
385 ));
386
David Tolnayca085422016-10-04 00:12:38 -0700387 named!(fn_arg -> FnArg, alt!(
388 do_parse!(
389 punct!("&") >>
390 lt: option!(lifetime) >>
391 mutability: mutability >>
392 keyword!("self") >>
393 (FnArg::SelfRef(lt, mutability))
394 )
395 |
396 do_parse!(
397 mutability: mutability >>
398 keyword!("self") >>
399 (FnArg::SelfValue(mutability))
400 )
401 |
402 do_parse!(
403 pat: pat >>
404 punct!(":") >>
405 ty: ty >>
406 (FnArg::Captured(pat, ty))
407 )
408 |
409 ty => { FnArg::Ignored }
David Tolnay62f374c2016-10-02 13:37:00 -0700410 ));
411
David Tolnay35902302016-10-06 01:11:08 -0700412 named!(item_mod -> Item, do_parse!(
413 attrs: many0!(outer_attr) >>
414 vis: visibility >>
415 keyword!("mod") >>
416 id: ident >>
417 punct!("{") >>
418 items: many0!(item) >>
419 punct!("}") >>
420 (Item {
421 ident: id,
422 vis: vis,
423 attrs: attrs,
424 node: ItemKind::Mod(items),
425 })
426 ));
427
428 named!(item_foreign_mod -> Item, do_parse!(
429 attrs: many0!(outer_attr) >>
430 keyword!("extern") >>
431 abi: option!(quoted_string) >>
432 punct!("{") >>
433 items: many0!(foreign_item) >>
434 punct!("}") >>
435 (Item {
436 ident: "".into(),
437 vis: Visibility::Inherited,
438 attrs: attrs,
439 node: ItemKind::ForeignMod(ForeignMod {
440 abi: abi.map(Abi),
441 items: items,
442 }),
443 })
444 ));
445
446 named!(foreign_item -> ForeignItem, alt!(
447 foreign_fn
448 |
449 foreign_static
450 ));
451
452 named!(foreign_fn -> ForeignItem, do_parse!(
453 attrs: many0!(outer_attr) >>
454 vis: visibility >>
455 keyword!("fn") >>
456 name: ident >>
457 generics: generics >>
458 punct!("(") >>
459 inputs: separated_list!(punct!(","), fn_arg) >>
460 punct!(")") >>
461 ret: option!(preceded!(punct!("->"), ty)) >>
462 where_clause: where_clause >>
463 punct!(";") >>
464 (ForeignItem {
465 ident: name,
466 attrs: attrs,
467 node: ForeignItemKind::Fn(
468 Box::new(FnDecl {
469 inputs: inputs,
470 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
471 }),
472 Generics {
473 where_clause: where_clause,
474 .. generics
475 },
476 ),
477 vis: vis,
478 })
479 ));
480
481 named!(foreign_static -> ForeignItem, do_parse!(
482 attrs: many0!(outer_attr) >>
483 vis: visibility >>
484 keyword!("static") >>
485 mutability: mutability >>
486 id: ident >>
487 punct!(":") >>
488 ty: ty >>
489 punct!(";") >>
490 (ForeignItem {
491 ident: id,
492 attrs: attrs,
493 node: ForeignItemKind::Static(Box::new(ty), mutability),
494 vis: vis,
495 })
496 ));
497
David Tolnay3cf52982016-10-01 17:11:37 -0700498 named!(item_ty -> Item, do_parse!(
499 attrs: many0!(outer_attr) >>
500 vis: visibility >>
501 keyword!("type") >>
502 id: ident >>
503 generics: generics >>
504 punct!("=") >>
505 ty: ty >>
506 punct!(";") >>
507 (Item {
508 ident: id,
509 vis: vis,
510 attrs: attrs,
511 node: ItemKind::Ty(Box::new(ty), generics),
512 })
513 ));
514
David Tolnaya96a3fa2016-09-24 07:17:42 -0700515 named!(item_struct_or_enum -> Item, map!(
David Tolnayedf2b992016-09-23 20:43:45 -0700516 macro_input,
517 |def: MacroInput| Item {
518 ident: def.ident,
519 vis: def.vis,
520 attrs: def.attrs,
521 node: match def.body {
522 Body::Enum(variants) => {
523 ItemKind::Enum(variants, def.generics)
524 }
525 Body::Struct(variant_data) => {
526 ItemKind::Struct(variant_data, def.generics)
527 }
528 }
529 }
530 ));
David Tolnay42602292016-10-01 22:25:45 -0700531
David Tolnay2f9fa632016-10-03 22:08:48 -0700532 named!(item_union -> Item, do_parse!(
533 attrs: many0!(outer_attr) >>
534 vis: visibility >>
535 keyword!("union") >>
536 id: ident >>
537 generics: generics >>
538 where_clause: where_clause >>
539 fields: struct_like_body >>
540 (Item {
541 ident: id,
542 vis: vis,
543 attrs: attrs,
544 node: ItemKind::Union(
545 VariantData::Struct(fields),
546 Generics {
547 where_clause: where_clause,
548 .. generics
549 },
550 ),
551 })
552 ));
553
David Tolnay0aecb732016-10-03 23:03:50 -0700554 named!(item_trait -> Item, do_parse!(
555 attrs: many0!(outer_attr) >>
556 vis: visibility >>
557 unsafety: unsafety >>
558 keyword!("trait") >>
559 id: ident >>
560 generics: generics >>
561 bounds: opt_vec!(preceded!(
562 punct!(":"),
563 separated_nonempty_list!(punct!("+"), ty_param_bound)
564 )) >>
565 where_clause: where_clause >>
566 punct!("{") >>
567 body: many0!(trait_item) >>
568 punct!("}") >>
569 (Item {
570 ident: id,
571 vis: vis,
572 attrs: attrs,
573 node: ItemKind::Trait(
574 unsafety,
575 Generics {
576 where_clause: where_clause,
577 .. generics
578 },
579 bounds,
580 body,
581 ),
582 })
583 ));
584
David Tolnayf94e2362016-10-04 00:29:51 -0700585 named!(item_default_impl -> Item, do_parse!(
586 attrs: many0!(outer_attr) >>
587 unsafety: unsafety >>
588 keyword!("impl") >>
589 path: path >>
590 keyword!("for") >>
591 punct!("..") >>
592 punct!("{") >>
593 punct!("}") >>
594 (Item {
595 ident: "".into(),
596 vis: Visibility::Inherited,
597 attrs: attrs,
598 node: ItemKind::DefaultImpl(unsafety, path),
599 })
600 ));
601
David Tolnay0aecb732016-10-03 23:03:50 -0700602 named!(trait_item -> TraitItem, alt!(
603 trait_item_const
604 |
605 trait_item_method
606 |
607 trait_item_type
608 |
609 trait_item_mac
610 ));
611
612 named!(trait_item_const -> TraitItem, do_parse!(
613 attrs: many0!(outer_attr) >>
614 keyword!("const") >>
615 id: ident >>
616 punct!(":") >>
617 ty: ty >>
618 value: option!(preceded!(punct!("="), expr)) >>
619 punct!(";") >>
620 (TraitItem {
621 ident: id,
622 attrs: attrs,
623 node: TraitItemKind::Const(ty, value),
624 })
625 ));
626
627 named!(trait_item_method -> TraitItem, do_parse!(
628 attrs: many0!(outer_attr) >>
629 constness: constness >>
630 unsafety: unsafety >>
631 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
632 keyword!("fn") >>
633 name: ident >>
634 generics: generics >>
635 punct!("(") >>
636 inputs: separated_list!(punct!(","), fn_arg) >>
637 punct!(")") >>
638 ret: option!(preceded!(punct!("->"), ty)) >>
639 where_clause: where_clause >>
640 body: option!(block) >>
641 cond!(body.is_none(), punct!(";")) >>
642 (TraitItem {
643 ident: name,
644 attrs: attrs,
645 node: TraitItemKind::Method(
646 MethodSig {
647 unsafety: unsafety,
648 constness: constness,
649 abi: abi.map(Abi),
650 decl: FnDecl {
651 inputs: inputs,
652 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
653 },
654 generics: Generics {
655 where_clause: where_clause,
656 .. generics
657 },
658 },
659 body,
660 ),
661 })
662 ));
663
664 named!(trait_item_type -> TraitItem, do_parse!(
665 attrs: many0!(outer_attr) >>
666 keyword!("type") >>
667 id: ident >>
668 bounds: opt_vec!(preceded!(
669 punct!(":"),
670 separated_nonempty_list!(punct!("+"), ty_param_bound)
671 )) >>
672 default: option!(preceded!(punct!("="), ty)) >>
David Tolnayca085422016-10-04 00:12:38 -0700673 punct!(";") >>
David Tolnay0aecb732016-10-03 23:03:50 -0700674 (TraitItem {
675 ident: id,
676 attrs: attrs,
677 node: TraitItemKind::Type(bounds, default),
678 })
679 ));
680
681 named!(trait_item_mac -> TraitItem, do_parse!(
682 attrs: many0!(outer_attr) >>
683 id: ident >>
684 punct!("!") >>
685 body: delimited >>
David Tolnaye3198932016-10-04 00:21:34 -0700686 cond!(match body.delim {
687 DelimToken::Paren | DelimToken::Bracket => true,
688 DelimToken::Brace => false,
689 }, punct!(";")) >>
David Tolnay0aecb732016-10-03 23:03:50 -0700690 (TraitItem {
691 ident: id.clone(),
692 attrs: attrs,
693 node: TraitItemKind::Macro(Mac {
694 path: id.into(),
695 tts: vec![TokenTree::Delimited(body)],
696 }),
697 })
698 ));
699
David Tolnay4c9be372016-10-06 00:47:37 -0700700 named!(item_impl -> Item, do_parse!(
701 attrs: many0!(outer_attr) >>
702 unsafety: unsafety >>
703 keyword!("impl") >>
704 generics: generics >>
705 polarity_path: alt!(
706 do_parse!(
707 polarity: impl_polarity >>
708 path: path >>
709 keyword!("for") >>
710 ((polarity, Some(path)))
711 )
712 |
713 epsilon!() => { |_| (ImplPolarity::Positive, None) }
714 ) >>
715 self_ty: ty >>
716 where_clause: where_clause >>
717 punct!("{") >>
718 body: many0!(impl_item) >>
719 punct!("}") >>
720 (Item {
721 ident: "".into(),
722 vis: Visibility::Inherited,
723 attrs: attrs,
724 node: ItemKind::Impl(
725 unsafety,
726 polarity_path.0,
727 Generics {
728 where_clause: where_clause,
729 .. generics
730 },
731 polarity_path.1,
732 Box::new(self_ty),
733 body,
734 ),
735 })
736 ));
737
738 named!(impl_item -> ImplItem, alt!(
739 impl_item_const
740 |
741 impl_item_method
742 |
743 impl_item_type
744 |
745 impl_item_macro
746 ));
747
748 named!(impl_item_const -> ImplItem, do_parse!(
749 attrs: many0!(outer_attr) >>
750 vis: visibility >>
751 defaultness: defaultness >>
752 keyword!("const") >>
753 id: ident >>
754 punct!(":") >>
755 ty: ty >>
756 punct!("=") >>
757 value: expr >>
758 punct!(";") >>
759 (ImplItem {
760 ident: id,
761 vis: vis,
762 defaultness: defaultness,
763 attrs: attrs,
764 node: ImplItemKind::Const(ty, value),
765 })
766 ));
767
768 named!(impl_item_method -> ImplItem, do_parse!(
769 attrs: many0!(outer_attr) >>
770 vis: visibility >>
771 defaultness: defaultness >>
772 constness: constness >>
773 unsafety: unsafety >>
774 abi: option!(preceded!(keyword!("extern"), quoted_string)) >>
775 keyword!("fn") >>
776 name: ident >>
777 generics: generics >>
778 punct!("(") >>
779 inputs: separated_list!(punct!(","), fn_arg) >>
780 punct!(")") >>
781 ret: option!(preceded!(punct!("->"), ty)) >>
782 where_clause: where_clause >>
783 body: block >>
784 (ImplItem {
785 ident: name,
786 vis: vis,
787 defaultness: defaultness,
788 attrs: attrs,
789 node: ImplItemKind::Method(
790 MethodSig {
791 unsafety: unsafety,
792 constness: constness,
793 abi: abi.map(Abi),
794 decl: FnDecl {
795 inputs: inputs,
796 output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
797 },
798 generics: Generics {
799 where_clause: where_clause,
800 .. generics
801 },
802 },
803 body,
804 ),
805 })
806 ));
807
808 named!(impl_item_type -> ImplItem, do_parse!(
809 attrs: many0!(outer_attr) >>
810 vis: visibility >>
811 defaultness: defaultness >>
812 keyword!("type") >>
813 id: ident >>
814 punct!("=") >>
815 ty: ty >>
816 punct!(";") >>
817 (ImplItem {
818 ident: id,
819 vis: vis,
820 defaultness: defaultness,
821 attrs: attrs,
822 node: ImplItemKind::Type(ty),
823 })
824 ));
825
826 named!(impl_item_macro -> ImplItem, do_parse!(
827 attrs: many0!(outer_attr) >>
828 id: ident >>
829 punct!("!") >>
830 body: delimited >>
831 cond!(match body.delim {
832 DelimToken::Paren | DelimToken::Bracket => true,
833 DelimToken::Brace => false,
834 }, punct!(";")) >>
835 (ImplItem {
836 ident: id.clone(),
837 vis: Visibility::Inherited,
838 defaultness: Defaultness::Final,
839 attrs: attrs,
840 node: ImplItemKind::Macro(Mac {
841 path: id.into(),
842 tts: vec![TokenTree::Delimited(body)],
843 }),
844 })
845 ));
846
847 named!(impl_polarity -> ImplPolarity, alt!(
848 punct!("!") => { |_| ImplPolarity::Negative }
849 |
850 epsilon!() => { |_| ImplPolarity::Positive }
851 ));
852
David Tolnay42602292016-10-01 22:25:45 -0700853 named!(constness -> Constness, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700854 keyword!("const") => { |_| Constness::Const }
David Tolnay42602292016-10-01 22:25:45 -0700855 |
856 epsilon!() => { |_| Constness::NotConst }
857 ));
858
859 named!(unsafety -> Unsafety, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700860 keyword!("unsafe") => { |_| Unsafety::Unsafe }
David Tolnay42602292016-10-01 22:25:45 -0700861 |
862 epsilon!() => { |_| Unsafety::Normal }
863 ));
David Tolnay4c9be372016-10-06 00:47:37 -0700864
865 named!(defaultness -> Defaultness, alt!(
866 keyword!("default") => { |_| Defaultness::Default }
867 |
868 epsilon!() => { |_| Defaultness::Final }
869 ));
David Tolnayedf2b992016-09-23 20:43:45 -0700870}
David Tolnay4a51dc72016-10-01 00:40:31 -0700871
872#[cfg(feature = "printing")]
873mod printing {
874 use super::*;
David Tolnaycc3d66e2016-10-02 23:36:05 -0700875 use {Delimited, DelimToken, FunctionRetTy, TokenTree};
David Tolnay4a51dc72016-10-01 00:40:31 -0700876 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -0700877 use data::VariantData;
David Tolnay4a51dc72016-10-01 00:40:31 -0700878 use quote::{Tokens, ToTokens};
879
880 impl ToTokens for Item {
881 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -0700882 tokens.append_all(self.attrs.outer());
David Tolnay4a51dc72016-10-01 00:40:31 -0700883 match self.node {
884 ItemKind::ExternCrate(ref original) => {
885 tokens.append("extern");
886 tokens.append("crate");
887 if let Some(ref original) = *original {
888 original.to_tokens(tokens);
889 tokens.append("as");
890 }
891 self.ident.to_tokens(tokens);
892 tokens.append(";");
893 }
894 ItemKind::Use(ref _view_path) => unimplemented!(),
David Tolnay47a877c2016-10-01 16:50:55 -0700895 ItemKind::Static(ref ty, ref mutability, ref expr) => {
896 self.vis.to_tokens(tokens);
897 tokens.append("static");
898 mutability.to_tokens(tokens);
899 self.ident.to_tokens(tokens);
900 tokens.append(":");
901 ty.to_tokens(tokens);
902 tokens.append("=");
903 expr.to_tokens(tokens);
904 tokens.append(";");
905 }
906 ItemKind::Const(ref ty, ref expr) => {
907 self.vis.to_tokens(tokens);
908 tokens.append("const");
909 self.ident.to_tokens(tokens);
910 tokens.append(":");
911 ty.to_tokens(tokens);
912 tokens.append("=");
913 expr.to_tokens(tokens);
914 tokens.append(";");
915 }
David Tolnay42602292016-10-01 22:25:45 -0700916 ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
917 self.vis.to_tokens(tokens);
918 constness.to_tokens(tokens);
919 unsafety.to_tokens(tokens);
920 abi.to_tokens(tokens);
921 tokens.append("fn");
922 self.ident.to_tokens(tokens);
923 generics.to_tokens(tokens);
David Tolnay62f374c2016-10-02 13:37:00 -0700924 tokens.append("(");
925 tokens.append_separated(&decl.inputs, ",");
926 tokens.append(")");
927 if let FunctionRetTy::Ty(ref ty) = decl.output {
928 tokens.append("->");
929 ty.to_tokens(tokens);
930 }
David Tolnay42602292016-10-01 22:25:45 -0700931 generics.where_clause.to_tokens(tokens);
932 block.to_tokens(tokens);
933 }
David Tolnay35902302016-10-06 01:11:08 -0700934 ItemKind::Mod(ref items) => {
935 self.vis.to_tokens(tokens);
936 tokens.append("mod");
937 self.ident.to_tokens(tokens);
938 tokens.append("{");
939 tokens.append_all(items);
940 tokens.append("}");
941 }
942 ItemKind::ForeignMod(ref foreign_mod) => {
943 self.vis.to_tokens(tokens);
944 match foreign_mod.abi {
945 Some(ref abi) => abi.to_tokens(tokens),
946 None => tokens.append("extern"),
947 }
948 tokens.append("{");
949 tokens.append_all(&foreign_mod.items);
950 tokens.append("}");
951 }
David Tolnay3cf52982016-10-01 17:11:37 -0700952 ItemKind::Ty(ref ty, ref generics) => {
953 self.vis.to_tokens(tokens);
954 tokens.append("type");
955 self.ident.to_tokens(tokens);
956 generics.to_tokens(tokens);
957 tokens.append("=");
958 ty.to_tokens(tokens);
959 tokens.append(";");
960 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700961 ItemKind::Enum(ref variants, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700962 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700963 tokens.append("enum");
964 self.ident.to_tokens(tokens);
965 generics.to_tokens(tokens);
966 generics.where_clause.to_tokens(tokens);
967 tokens.append("{");
968 for variant in variants {
969 variant.to_tokens(tokens);
970 tokens.append(",");
971 }
972 tokens.append("}");
973 }
974 ItemKind::Struct(ref variant_data, ref generics) => {
David Tolnay47a877c2016-10-01 16:50:55 -0700975 self.vis.to_tokens(tokens);
David Tolnay4a51dc72016-10-01 00:40:31 -0700976 tokens.append("struct");
977 self.ident.to_tokens(tokens);
978 generics.to_tokens(tokens);
979 generics.where_clause.to_tokens(tokens);
980 variant_data.to_tokens(tokens);
981 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -0700982 VariantData::Struct(_) => {
983 // no semicolon
984 }
David Tolnay4a51dc72016-10-01 00:40:31 -0700985 VariantData::Tuple(_) |
986 VariantData::Unit => tokens.append(";"),
987 }
988 }
David Tolnay2f9fa632016-10-03 22:08:48 -0700989 ItemKind::Union(ref variant_data, ref generics) => {
990 self.vis.to_tokens(tokens);
991 tokens.append("union");
992 self.ident.to_tokens(tokens);
993 generics.to_tokens(tokens);
994 generics.where_clause.to_tokens(tokens);
995 variant_data.to_tokens(tokens);
996 }
David Tolnayca085422016-10-04 00:12:38 -0700997 ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
998 self.vis.to_tokens(tokens);
999 unsafety.to_tokens(tokens);
1000 tokens.append("trait");
1001 self.ident.to_tokens(tokens);
1002 if !bound.is_empty() {
1003 tokens.append(":");
1004 tokens.append_separated(bound, "+");
1005 }
1006 generics.to_tokens(tokens);
1007 generics.where_clause.to_tokens(tokens);
1008 tokens.append("{");
1009 tokens.append_all(items);
1010 tokens.append("}");
1011 }
David Tolnayf94e2362016-10-04 00:29:51 -07001012 ItemKind::DefaultImpl(unsafety, ref path) => {
1013 unsafety.to_tokens(tokens);
1014 tokens.append("impl");
1015 path.to_tokens(tokens);
1016 tokens.append("for");
1017 tokens.append("..");
1018 tokens.append("{");
1019 tokens.append("}");
1020 }
David Tolnay4c9be372016-10-06 00:47:37 -07001021 ItemKind::Impl(unsafety,
1022 polarity,
1023 ref generics,
1024 ref path,
1025 ref ty,
1026 ref items) => {
1027 unsafety.to_tokens(tokens);
1028 tokens.append("impl");
1029 generics.to_tokens(tokens);
1030 if let Some(ref path) = *path {
1031 polarity.to_tokens(tokens);
1032 path.to_tokens(tokens);
1033 tokens.append("for");
1034 }
1035 ty.to_tokens(tokens);
1036 generics.where_clause.to_tokens(tokens);
1037 tokens.append("{");
1038 tokens.append_all(items);
1039 tokens.append("}");
1040 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001041 ItemKind::Mac(ref mac) => {
1042 mac.path.to_tokens(tokens);
1043 tokens.append("!");
1044 self.ident.to_tokens(tokens);
1045 for tt in &mac.tts {
1046 tt.to_tokens(tokens);
1047 }
1048 match mac.tts.last() {
David Tolnaydaaf7742016-10-03 11:11:43 -07001049 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1050 // no semicolon
1051 }
David Tolnaycc3d66e2016-10-02 23:36:05 -07001052 _ => tokens.append(";"),
1053 }
1054 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001055 }
1056 }
1057 }
David Tolnay42602292016-10-01 22:25:45 -07001058
David Tolnayca085422016-10-04 00:12:38 -07001059 impl ToTokens for TraitItem {
1060 fn to_tokens(&self, tokens: &mut Tokens) {
1061 tokens.append_all(self.attrs.outer());
1062 match self.node {
1063 TraitItemKind::Const(ref ty, ref expr) => {
1064 tokens.append("const");
1065 self.ident.to_tokens(tokens);
1066 tokens.append(":");
1067 ty.to_tokens(tokens);
1068 if let Some(ref expr) = *expr {
1069 tokens.append("=");
1070 expr.to_tokens(tokens);
1071 }
1072 tokens.append(";");
1073 }
1074 TraitItemKind::Method(ref sig, ref block) => {
1075 sig.unsafety.to_tokens(tokens);
1076 sig.abi.to_tokens(tokens);
1077 tokens.append("fn");
1078 self.ident.to_tokens(tokens);
1079 sig.generics.to_tokens(tokens);
1080 tokens.append("(");
1081 tokens.append_separated(&sig.decl.inputs, ",");
1082 tokens.append(")");
1083 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1084 tokens.append("->");
1085 ty.to_tokens(tokens);
1086 }
1087 sig.generics.where_clause.to_tokens(tokens);
1088 match *block {
1089 Some(ref block) => block.to_tokens(tokens),
1090 None => tokens.append(";"),
1091 }
1092 }
1093 TraitItemKind::Type(ref bound, ref default) => {
1094 tokens.append("type");
1095 self.ident.to_tokens(tokens);
1096 if !bound.is_empty() {
1097 tokens.append(":");
1098 tokens.append_separated(bound, "+");
1099 }
1100 if let Some(ref default) = *default {
1101 tokens.append("=");
1102 default.to_tokens(tokens);
1103 }
1104 tokens.append(";");
1105 }
1106 TraitItemKind::Macro(ref mac) => {
1107 mac.to_tokens(tokens);
David Tolnaye3198932016-10-04 00:21:34 -07001108 match mac.tts.last() {
1109 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1110 // no semicolon
1111 }
1112 _ => tokens.append(";"),
1113 }
David Tolnayca085422016-10-04 00:12:38 -07001114 }
1115 }
1116 }
1117 }
1118
David Tolnay4c9be372016-10-06 00:47:37 -07001119 impl ToTokens for ImplItem {
1120 fn to_tokens(&self, tokens: &mut Tokens) {
1121 tokens.append_all(self.attrs.outer());
1122 match self.node {
1123 ImplItemKind::Const(ref ty, ref expr) => {
1124 self.vis.to_tokens(tokens);
1125 self.defaultness.to_tokens(tokens);
1126 tokens.append("const");
1127 self.ident.to_tokens(tokens);
1128 tokens.append(":");
1129 ty.to_tokens(tokens);
1130 tokens.append("=");
1131 expr.to_tokens(tokens);
1132 tokens.append(";");
1133 }
1134 ImplItemKind::Method(ref sig, ref block) => {
1135 self.vis.to_tokens(tokens);
1136 self.defaultness.to_tokens(tokens);
1137 sig.unsafety.to_tokens(tokens);
1138 sig.abi.to_tokens(tokens);
1139 tokens.append("fn");
1140 self.ident.to_tokens(tokens);
1141 sig.generics.to_tokens(tokens);
1142 tokens.append("(");
1143 tokens.append_separated(&sig.decl.inputs, ",");
1144 tokens.append(")");
1145 if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
1146 tokens.append("->");
1147 ty.to_tokens(tokens);
1148 }
1149 sig.generics.where_clause.to_tokens(tokens);
1150 block.to_tokens(tokens);
1151 }
1152 ImplItemKind::Type(ref ty) => {
1153 self.vis.to_tokens(tokens);
1154 self.defaultness.to_tokens(tokens);
1155 tokens.append("type");
1156 self.ident.to_tokens(tokens);
1157 tokens.append("=");
1158 ty.to_tokens(tokens);
1159 tokens.append(";");
1160 }
1161 ImplItemKind::Macro(ref mac) => {
1162 mac.to_tokens(tokens);
1163 match mac.tts.last() {
1164 Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
1165 // no semicolon
1166 }
1167 _ => tokens.append(";"),
1168 }
1169 }
1170 }
1171 }
1172 }
1173
David Tolnay35902302016-10-06 01:11:08 -07001174 impl ToTokens for ForeignItem {
1175 fn to_tokens(&self, tokens: &mut Tokens) {
1176 tokens.append_all(self.attrs.outer());
1177 match self.node {
1178 ForeignItemKind::Fn(ref decl, ref generics) => {
1179 self.vis.to_tokens(tokens);
1180 tokens.append("fn");
1181 self.ident.to_tokens(tokens);
1182 generics.to_tokens(tokens);
1183 tokens.append("(");
1184 tokens.append_separated(&decl.inputs, ",");
1185 tokens.append(")");
1186 if let FunctionRetTy::Ty(ref ty) = decl.output {
1187 tokens.append("->");
1188 ty.to_tokens(tokens);
1189 }
1190 generics.where_clause.to_tokens(tokens);
1191 tokens.append(";");
1192 }
1193 ForeignItemKind::Static(ref ty, mutability) => {
1194 self.vis.to_tokens(tokens);
1195 tokens.append("static");
1196 mutability.to_tokens(tokens);
1197 self.ident.to_tokens(tokens);
1198 tokens.append(":");
1199 ty.to_tokens(tokens);
1200 tokens.append(";");
1201 }
1202 }
1203 }
1204 }
1205
David Tolnay62f374c2016-10-02 13:37:00 -07001206 impl ToTokens for FnArg {
1207 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayca085422016-10-04 00:12:38 -07001208 match *self {
1209 FnArg::SelfRef(ref lifetime, mutability) => {
1210 tokens.append("&");
1211 lifetime.to_tokens(tokens);
1212 mutability.to_tokens(tokens);
1213 tokens.append("self");
1214 }
1215 FnArg::SelfValue(mutability) => {
1216 mutability.to_tokens(tokens);
1217 tokens.append("self");
1218 }
1219 FnArg::Captured(ref pat, ref ty) => {
1220 pat.to_tokens(tokens);
1221 tokens.append(":");
1222 ty.to_tokens(tokens);
1223 }
1224 FnArg::Ignored(ref ty) => {
1225 ty.to_tokens(tokens);
1226 }
1227 }
David Tolnay62f374c2016-10-02 13:37:00 -07001228 }
1229 }
1230
David Tolnay42602292016-10-01 22:25:45 -07001231 impl ToTokens for Unsafety {
1232 fn to_tokens(&self, tokens: &mut Tokens) {
1233 match *self {
1234 Unsafety::Unsafe => tokens.append("unsafe"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001235 Unsafety::Normal => {
1236 // nothing
1237 }
David Tolnay42602292016-10-01 22:25:45 -07001238 }
1239 }
1240 }
1241
1242 impl ToTokens for Constness {
1243 fn to_tokens(&self, tokens: &mut Tokens) {
1244 match *self {
1245 Constness::Const => tokens.append("const"),
David Tolnaydaaf7742016-10-03 11:11:43 -07001246 Constness::NotConst => {
1247 // nothing
1248 }
David Tolnay42602292016-10-01 22:25:45 -07001249 }
1250 }
1251 }
1252
David Tolnay4c9be372016-10-06 00:47:37 -07001253 impl ToTokens for Defaultness {
1254 fn to_tokens(&self, tokens: &mut Tokens) {
1255 match *self {
1256 Defaultness::Default => tokens.append("default"),
1257 Defaultness::Final => {
1258 // nothing
1259 }
1260 }
1261 }
1262 }
1263
1264 impl ToTokens for ImplPolarity {
1265 fn to_tokens(&self, tokens: &mut Tokens) {
1266 match *self {
1267 ImplPolarity::Negative => tokens.append("!"),
1268 ImplPolarity::Positive => {
1269 // nothing
1270 }
1271 }
1272 }
1273 }
1274
David Tolnay42602292016-10-01 22:25:45 -07001275 impl ToTokens for Abi {
1276 fn to_tokens(&self, tokens: &mut Tokens) {
1277 tokens.append("extern");
1278 self.0.to_tokens(tokens);
1279 }
1280 }
David Tolnay4a51dc72016-10-01 00:40:31 -07001281}