]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
Removed some unnecessary RefCells from resolve
[rust.git] / src / libsyntax / ast.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // The Rust abstract syntax tree.
12
13 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
14 use abi::Abi;
15 use ast_util;
16 use owned_slice::OwnedSlice;
17 use parse::token::{InternedString, str_to_ident};
18 use parse::token;
19 use ptr::P;
20
21 use std::fmt;
22 use std::num::Zero;
23 use std::fmt::Show;
24 use std::rc::Rc;
25 use serialize::{Encodable, Decodable, Encoder, Decoder};
26
27 // FIXME #6993: in librustc, uses of "ident" should be replaced
28 // by just "Name".
29
30 /// An identifier contains a Name (index into the interner
31 /// table) and a SyntaxContext to track renaming and
32 /// macro expansion per Flatt et al., "Macros
33 /// That Work Together"
34 #[deriving(Clone, Hash, PartialOrd, Eq, Ord)]
35 pub struct Ident {
36     pub name: Name,
37     pub ctxt: SyntaxContext
38 }
39
40 impl Ident {
41     /// Construct an identifier with the given name and an empty context:
42     pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
43
44     pub fn as_str<'a>(&'a self) -> &'a str {
45         self.name.as_str()
46     }
47
48     pub fn encode_with_hygiene(&self) -> String {
49         format!("\x00name_{:u},ctxt_{:u}\x00",
50                 self.name.uint(),
51                 self.ctxt)
52     }
53 }
54
55 impl Show for Ident {
56     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57         write!(f, "{}#{}", self.name, self.ctxt)
58     }
59 }
60
61 impl Show for Name {
62     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63         let Name(nm) = *self;
64         write!(f, "\"{}\"({})", token::get_name(*self).get(), nm)
65     }
66 }
67
68 impl PartialEq for Ident {
69     fn eq(&self, other: &Ident) -> bool {
70         if self.ctxt == other.ctxt {
71             self.name == other.name
72         } else {
73             // IF YOU SEE ONE OF THESE FAILS: it means that you're comparing
74             // idents that have different contexts. You can't fix this without
75             // knowing whether the comparison should be hygienic or non-hygienic.
76             // if it should be non-hygienic (most things are), just compare the
77             // 'name' fields of the idents. Or, even better, replace the idents
78             // with Name's.
79             //
80             // On the other hand, if the comparison does need to be hygienic,
81             // one example and its non-hygienic counterpart would be:
82             //      syntax::parse::token::mtwt_token_eq
83             //      syntax::ext::tt::macro_parser::token_name_eq
84             fail!("not allowed to compare these idents: {:?}, {:?}. \
85                    Probably related to issue \\#6993", self, other);
86         }
87     }
88     fn ne(&self, other: &Ident) -> bool {
89         ! self.eq(other)
90     }
91 }
92
93 /// A SyntaxContext represents a chain of macro-expandings
94 /// and renamings. Each macro expansion corresponds to
95 /// a fresh uint
96
97 // I'm representing this syntax context as an index into
98 // a table, in order to work around a compiler bug
99 // that's causing unreleased memory to cause core dumps
100 // and also perhaps to save some work in destructor checks.
101 // the special uint '0' will be used to indicate an empty
102 // syntax context.
103
104 // this uint is a reference to a table stored in thread-local
105 // storage.
106 pub type SyntaxContext = u32;
107 pub static EMPTY_CTXT : SyntaxContext = 0;
108 pub static ILLEGAL_CTXT : SyntaxContext = 1;
109
110 /// A name is a part of an identifier, representing a string or gensym. It's
111 /// the result of interning.
112 #[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
113 pub struct Name(pub u32);
114
115 impl Name {
116     pub fn as_str<'a>(&'a self) -> &'a str {
117         unsafe {
118             // FIXME #12938: can't use copy_lifetime since &str isn't a &T
119             ::std::mem::transmute(token::get_name(*self).get())
120         }
121     }
122
123     pub fn uint(&self) -> uint {
124         let Name(nm) = *self;
125         nm as uint
126     }
127
128     pub fn ident(&self) -> Ident {
129         Ident { name: *self, ctxt: 0 }
130     }
131 }
132
133 /// A mark represents a unique id associated with a macro expansion
134 pub type Mrk = u32;
135
136 impl<S: Encoder<E>, E> Encodable<S, E> for Ident {
137     fn encode(&self, s: &mut S) -> Result<(), E> {
138         s.emit_str(token::get_ident(*self).get())
139     }
140 }
141
142 impl<D:Decoder<E>, E> Decodable<D, E> for Ident {
143     fn decode(d: &mut D) -> Result<Ident, E> {
144         Ok(str_to_ident(try!(d.read_str()).as_slice()))
145     }
146 }
147
148 /// Function name (not all functions have names)
149 pub type FnIdent = Option<Ident>;
150
151 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
152 pub struct Lifetime {
153     pub id: NodeId,
154     pub span: Span,
155     pub name: Name
156 }
157
158 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
159 pub struct LifetimeDef {
160     pub lifetime: Lifetime,
161     pub bounds: Vec<Lifetime>
162 }
163
164 /// A "Path" is essentially Rust's notion of a name; for instance:
165 /// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
166 /// along with a bunch of supporting information.
167 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
168 pub struct Path {
169     pub span: Span,
170     /// A `::foo` path, is relative to the crate root rather than current
171     /// module (like paths in an import).
172     pub global: bool,
173     /// The segments in the path: the things separated by `::`.
174     pub segments: Vec<PathSegment> ,
175 }
176
177 /// A segment of a path: an identifier, an optional lifetime, and a set of
178 /// types.
179 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
180 pub struct PathSegment {
181     /// The identifier portion of this path segment.
182     pub identifier: Ident,
183     /// The lifetime parameters for this path segment.
184     pub lifetimes: Vec<Lifetime>,
185     /// The type parameters for this path segment, if present.
186     pub types: OwnedSlice<P<Ty>>,
187 }
188
189 pub type CrateNum = u32;
190
191 pub type NodeId = u32;
192
193 #[deriving(Clone, Eq, Ord, PartialOrd, PartialEq, Encodable, Decodable, Hash, Show)]
194 pub struct DefId {
195     pub krate: CrateNum,
196     pub node: NodeId,
197 }
198
199 /// Item definitions in the currently-compiled crate would have the CrateNum
200 /// LOCAL_CRATE in their DefId.
201 pub static LOCAL_CRATE: CrateNum = 0;
202 pub static CRATE_NODE_ID: NodeId = 0;
203
204 /// When parsing and doing expansions, we initially give all AST nodes this AST
205 /// node value. Then later, in the renumber pass, we renumber them to have
206 /// small, positive ids.
207 pub static DUMMY_NODE_ID: NodeId = -1;
208
209 /// The AST represents all type param bounds as types.
210 /// typeck::collect::compute_bounds matches these against
211 /// the "special" built-in traits (see middle::lang_items) and
212 /// detects Copy, Send and Sync.
213 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
214 pub enum TyParamBound {
215     TraitTyParamBound(TraitRef),
216     UnboxedFnTyParamBound(P<UnboxedFnBound>),
217     RegionTyParamBound(Lifetime)
218 }
219
220 pub type TyParamBounds = OwnedSlice<TyParamBound>;
221
222 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
223 pub struct UnboxedFnBound {
224     pub path: Path,
225     pub decl: P<FnDecl>,
226     pub lifetimes: Vec<LifetimeDef>,
227     pub ref_id: NodeId,
228 }
229
230 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
231 pub struct TyParam {
232     pub ident: Ident,
233     pub id: NodeId,
234     pub bounds: TyParamBounds,
235     pub unbound: Option<TyParamBound>,
236     pub default: Option<P<Ty>>,
237     pub span: Span
238 }
239
240 /// Represents lifetimes and type parameters attached to a declaration
241 /// of a function, enum, trait, etc.
242 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
243 pub struct Generics {
244     pub lifetimes: Vec<LifetimeDef>,
245     pub ty_params: OwnedSlice<TyParam>,
246     pub where_clause: WhereClause,
247 }
248
249 impl Generics {
250     pub fn is_parameterized(&self) -> bool {
251         self.lifetimes.len() + self.ty_params.len() > 0
252     }
253     pub fn is_lt_parameterized(&self) -> bool {
254         self.lifetimes.len() > 0
255     }
256     pub fn is_type_parameterized(&self) -> bool {
257         self.ty_params.len() > 0
258     }
259 }
260
261 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
262 pub struct WhereClause {
263     pub id: NodeId,
264     pub predicates: Vec<WherePredicate>,
265 }
266
267 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
268 pub struct WherePredicate {
269     pub id: NodeId,
270     pub span: Span,
271     pub ident: Ident,
272     pub bounds: OwnedSlice<TyParamBound>,
273 }
274
275 /// The set of MetaItems that define the compilation environment of the crate,
276 /// used to drive conditional compilation
277 pub type CrateConfig = Vec<P<MetaItem>> ;
278
279 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
280 pub struct Crate {
281     pub module: Mod,
282     pub attrs: Vec<Attribute>,
283     pub config: CrateConfig,
284     pub span: Span,
285     pub exported_macros: Vec<P<Item>>
286 }
287
288 pub type MetaItem = Spanned<MetaItem_>;
289
290 #[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)]
291 pub enum MetaItem_ {
292     MetaWord(InternedString),
293     MetaList(InternedString, Vec<P<MetaItem>>),
294     MetaNameValue(InternedString, Lit),
295 }
296
297 // can't be derived because the MetaList requires an unordered comparison
298 impl PartialEq for MetaItem_ {
299     fn eq(&self, other: &MetaItem_) -> bool {
300         match *self {
301             MetaWord(ref ns) => match *other {
302                 MetaWord(ref no) => (*ns) == (*no),
303                 _ => false
304             },
305             MetaNameValue(ref ns, ref vs) => match *other {
306                 MetaNameValue(ref no, ref vo) => {
307                     (*ns) == (*no) && vs.node == vo.node
308                 }
309                 _ => false
310             },
311             MetaList(ref ns, ref miss) => match *other {
312                 MetaList(ref no, ref miso) => {
313                     ns == no &&
314                         miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
315                 }
316                 _ => false
317             }
318         }
319     }
320 }
321
322 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
323 pub struct Block {
324     pub view_items: Vec<ViewItem>,
325     pub stmts: Vec<P<Stmt>>,
326     pub expr: Option<P<Expr>>,
327     pub id: NodeId,
328     pub rules: BlockCheckMode,
329     pub span: Span,
330 }
331
332 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
333 pub struct Pat {
334     pub id: NodeId,
335     pub node: Pat_,
336     pub span: Span,
337 }
338
339 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
340 pub struct FieldPat {
341     pub ident: Ident,
342     pub pat: P<Pat>,
343 }
344
345 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
346 pub enum BindingMode {
347     BindByRef(Mutability),
348     BindByValue(Mutability),
349 }
350
351 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
352 pub enum PatWildKind {
353     /// Represents the wildcard pattern `_`
354     PatWildSingle,
355
356     /// Represents the wildcard pattern `..`
357     PatWildMulti,
358 }
359
360 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
361 pub enum Pat_ {
362     /// Represents a wildcard pattern (either `_` or `..`)
363     PatWild(PatWildKind),
364
365     /// A PatIdent may either be a new bound variable,
366     /// or a nullary enum (in which case the third field
367     /// is None).
368     /// In the nullary enum case, the parser can't determine
369     /// which it is. The resolver determines this, and
370     /// records this pattern's NodeId in an auxiliary
371     /// set (of "PatIdents that refer to nullary enums")
372     PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>),
373
374     /// "None" means a * pattern where we don't bind the fields to names.
375     PatEnum(Path, Option<Vec<P<Pat>>>),
376
377     PatStruct(Path, Vec<FieldPat>, bool),
378     PatTup(Vec<P<Pat>>),
379     PatBox(P<Pat>),
380     PatRegion(P<Pat>), // reference pattern
381     PatLit(P<Expr>),
382     PatRange(P<Expr>, P<Expr>),
383     /// [a, b, ..i, y, z] is represented as:
384     ///     PatVec(~[a, b], Some(i), ~[y, z])
385     PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
386     PatMac(Mac),
387 }
388
389 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
390 pub enum Mutability {
391     MutMutable,
392     MutImmutable,
393 }
394
395 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
396 pub enum BinOp {
397     BiAdd,
398     BiSub,
399     BiMul,
400     BiDiv,
401     BiRem,
402     BiAnd,
403     BiOr,
404     BiBitXor,
405     BiBitAnd,
406     BiBitOr,
407     BiShl,
408     BiShr,
409     BiEq,
410     BiLt,
411     BiLe,
412     BiNe,
413     BiGe,
414     BiGt,
415 }
416
417 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
418 pub enum UnOp {
419     UnBox,
420     UnUniq,
421     UnDeref,
422     UnNot,
423     UnNeg
424 }
425
426 pub type Stmt = Spanned<Stmt_>;
427
428 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
429 pub enum Stmt_ {
430     /// Could be an item or a local (let) binding:
431     StmtDecl(P<Decl>, NodeId),
432
433     /// Expr without trailing semi-colon (must have unit type):
434     StmtExpr(P<Expr>, NodeId),
435
436     /// Expr with trailing semi-colon (may have any type):
437     StmtSemi(P<Expr>, NodeId),
438
439     /// bool: is there a trailing sem-colon?
440     StmtMac(Mac, bool),
441 }
442
443 /// Where a local declaration came from: either a true `let ... =
444 /// ...;`, or one desugared from the pattern of a for loop.
445 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
446 pub enum LocalSource {
447     LocalLet,
448     LocalFor,
449 }
450
451 // FIXME (pending discussion of #1697, #2178...): local should really be
452 // a refinement on pat.
453 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
454 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
455 pub struct Local {
456     pub ty: P<Ty>,
457     pub pat: P<Pat>,
458     pub init: Option<P<Expr>>,
459     pub id: NodeId,
460     pub span: Span,
461     pub source: LocalSource,
462 }
463
464 pub type Decl = Spanned<Decl_>;
465
466 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
467 pub enum Decl_ {
468     /// A local (let) binding:
469     DeclLocal(P<Local>),
470     /// An item binding:
471     DeclItem(P<Item>),
472 }
473
474 /// represents one arm of a 'match'
475 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
476 pub struct Arm {
477     pub attrs: Vec<Attribute>,
478     pub pats: Vec<P<Pat>>,
479     pub guard: Option<P<Expr>>,
480     pub body: P<Expr>,
481 }
482
483 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
484 pub struct Field {
485     pub ident: SpannedIdent,
486     pub expr: P<Expr>,
487     pub span: Span,
488 }
489
490 pub type SpannedIdent = Spanned<Ident>;
491
492 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
493 pub enum BlockCheckMode {
494     DefaultBlock,
495     UnsafeBlock(UnsafeSource),
496 }
497
498 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
499 pub enum UnsafeSource {
500     CompilerGenerated,
501     UserProvided,
502 }
503
504 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
505 pub struct Expr {
506     pub id: NodeId,
507     pub node: Expr_,
508     pub span: Span,
509 }
510
511 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
512 pub enum Expr_ {
513     /// First expr is the place; second expr is the value.
514     ExprBox(P<Expr>, P<Expr>),
515     ExprVec(Vec<P<Expr>>),
516     ExprCall(P<Expr>, Vec<P<Expr>>),
517     ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
518     ExprTup(Vec<P<Expr>>),
519     ExprBinary(BinOp, P<Expr>, P<Expr>),
520     ExprUnary(UnOp, P<Expr>),
521     ExprLit(P<Lit>),
522     ExprCast(P<Expr>, P<Ty>),
523     ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
524     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
525     ExprWhile(P<Expr>, P<Block>, Option<Ident>),
526     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
527     ExprForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
528     // Conditionless loop (can be exited with break, cont, or ret)
529     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
530     ExprLoop(P<Block>, Option<Ident>),
531     ExprMatch(P<Expr>, Vec<Arm>),
532     ExprFnBlock(CaptureClause, P<FnDecl>, P<Block>),
533     ExprProc(P<FnDecl>, P<Block>),
534     ExprUnboxedFn(CaptureClause, UnboxedClosureKind, P<FnDecl>, P<Block>),
535     ExprBlock(P<Block>),
536
537     ExprAssign(P<Expr>, P<Expr>),
538     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
539     ExprField(P<Expr>, SpannedIdent, Vec<P<Ty>>),
540     ExprTupField(P<Expr>, Spanned<uint>, Vec<P<Ty>>),
541     ExprIndex(P<Expr>, P<Expr>),
542     ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability),
543
544     /// Variable reference, possibly containing `::` and/or
545     /// type parameters, e.g. foo::bar::<baz>
546     ExprPath(Path),
547
548     ExprAddrOf(Mutability, P<Expr>),
549     ExprBreak(Option<Ident>),
550     ExprAgain(Option<Ident>),
551     ExprRet(Option<P<Expr>>),
552
553     ExprInlineAsm(InlineAsm),
554
555     ExprMac(Mac),
556
557     /// A struct literal expression.
558     ExprStruct(Path, Vec<Field>, Option<P<Expr>> /* base */),
559
560     /// A vector literal constructed from one repeated element.
561     ExprRepeat(P<Expr> /* element */, P<Expr> /* count */),
562
563     /// No-op: used solely so we can pretty-print faithfully
564     ExprParen(P<Expr>)
565 }
566
567 /// A "qualified path":
568 ///
569 ///     <Vec<T> as SomeTrait>::SomeAssociatedItem
570 ///      ^~~~~     ^~~~~~~~~   ^~~~~~~~~~~~~~~~~~
571 ///      for_type  trait_name  item_name
572 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
573 pub struct QPath {
574     pub for_type: P<Ty>,
575     pub trait_name: Path,
576     pub item_name: Ident,
577 }
578
579 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
580 pub enum CaptureClause {
581     CaptureByValue,
582     CaptureByRef,
583 }
584
585 /// When the main rust parser encounters a syntax-extension invocation, it
586 /// parses the arguments to the invocation as a token-tree. This is a very
587 /// loose structure, such that all sorts of different AST-fragments can
588 /// be passed to syntax extensions using a uniform type.
589 ///
590 /// If the syntax extension is an MBE macro, it will attempt to match its
591 /// LHS "matchers" against the provided token tree, and if it finds a
592 /// match, will transcribe the RHS token tree, splicing in any captured
593 /// macro_parser::matched_nonterminals into the TTNonterminals it finds.
594 ///
595 /// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
596 /// makes any real sense. You could write them elsewhere but nothing
597 /// else knows what to do with them, so you'll probably get a syntax
598 /// error.
599 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
600 #[doc="For macro invocations; parsing is delegated to the macro"]
601 pub enum TokenTree {
602     /// A single token
603     TTTok(Span, ::parse::token::Token),
604     /// A delimited sequence (the delimiters appear as the first
605     /// and last elements of the vector)
606     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
607     TTDelim(Rc<Vec<TokenTree>>),
608
609     // These only make sense for right-hand-sides of MBE macros:
610
611     /// A kleene-style repetition sequence with a span, a TTForest,
612     /// an optional separator, and a boolean where true indicates
613     /// zero or more (..), and false indicates one or more (+).
614     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
615     TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
616
617     /// A syntactic variable that will be filled in by macro expansion.
618     TTNonterminal(Span, Ident)
619 }
620
621 // Matchers are nodes defined-by and recognized-by the main rust parser and
622 // language, but they're only ever found inside syntax-extension invocations;
623 // indeed, the only thing that ever _activates_ the rules in the rust parser
624 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
625 // itself. Matchers represent a small sub-language for pattern-matching
626 // token-trees, and are thus primarily used by the macro-defining extension
627 // itself.
628 //
629 // MatchTok
630 // --------
631 //
632 //     A matcher that matches a single token, denoted by the token itself. So
633 //     long as there's no $ involved.
634 //
635 //
636 // MatchSeq
637 // --------
638 //
639 //     A matcher that matches a sequence of sub-matchers, denoted various
640 //     possible ways:
641 //
642 //             $(M)*       zero or more Ms
643 //             $(M)+       one or more Ms
644 //             $(M),+      one or more comma-separated Ms
645 //             $(A B C);*  zero or more semi-separated 'A B C' seqs
646 //
647 //
648 // MatchNonterminal
649 // -----------------
650 //
651 //     A matcher that matches one of a few interesting named rust
652 //     nonterminals, such as types, expressions, items, or raw token-trees. A
653 //     black-box matcher on expr, for example, binds an expr to a given ident,
654 //     and that ident can re-occur as an interpolation in the RHS of a
655 //     macro-by-example rule. For example:
656 //
657 //        $foo:expr   =>     1 + $foo    // interpolate an expr
658 //        $foo:tt     =>     $foo        // interpolate a token-tree
659 //        $foo:tt     =>     bar! $foo   // only other valid interpolation
660 //                                       // is in arg position for another
661 //                                       // macro
662 //
663 // As a final, horrifying aside, note that macro-by-example's input is
664 // also matched by one of these matchers. Holy self-referential! It is matched
665 // by a MatchSeq, specifically this one:
666 //
667 //                   $( $lhs:matchers => $rhs:tt );+
668 //
669 // If you understand that, you have closed the loop and understand the whole
670 // macro system. Congratulations.
671 pub type Matcher = Spanned<Matcher_>;
672
673 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
674 pub enum Matcher_ {
675     /// Match one token
676     MatchTok(::parse::token::Token),
677     /// Match repetitions of a sequence: body, separator, zero ok?,
678     /// lo, hi position-in-match-array used:
679     MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
680     /// Parse a Rust NT: name to bind, name of NT, position in match array:
681     MatchNonterminal(Ident, Ident, uint)
682 }
683
684 pub type Mac = Spanned<Mac_>;
685
686 /// Represents a macro invocation. The Path indicates which macro
687 /// is being invoked, and the vector of token-trees contains the source
688 /// of the macro invocation.
689 /// There's only one flavor, now, so this could presumably be simplified.
690 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
691 pub enum Mac_ {
692     // NB: the additional ident for a macro_rules-style macro is actually
693     // stored in the enclosing item. Oog.
694     MacInvocTT(Path, Vec<TokenTree> , SyntaxContext),   // new macro-invocation
695 }
696
697 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
698 pub enum StrStyle {
699     CookedStr,
700     RawStr(uint)
701 }
702
703 pub type Lit = Spanned<Lit_>;
704
705 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
706 pub enum Sign {
707     Minus,
708     Plus
709 }
710
711 impl<T: PartialOrd+Zero> Sign {
712     pub fn new(n: T) -> Sign {
713         if n < Zero::zero() {
714             Minus
715         } else {
716             Plus
717         }
718     }
719 }
720
721 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
722 pub enum LitIntType {
723     SignedIntLit(IntTy, Sign),
724     UnsignedIntLit(UintTy),
725     UnsuffixedIntLit(Sign)
726 }
727
728 impl LitIntType {
729     pub fn suffix_len(&self) -> uint {
730         match *self {
731             UnsuffixedIntLit(_) => 0,
732             SignedIntLit(s, _) => s.suffix_len(),
733             UnsignedIntLit(u) => u.suffix_len()
734         }
735     }
736 }
737
738 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
739 pub enum Lit_ {
740     LitStr(InternedString, StrStyle),
741     LitBinary(Rc<Vec<u8> >),
742     LitByte(u8),
743     LitChar(char),
744     LitInt(u64, LitIntType),
745     LitFloat(InternedString, FloatTy),
746     LitFloatUnsuffixed(InternedString),
747     LitNil,
748     LitBool(bool),
749 }
750
751 // NB: If you change this, you'll probably want to change the corresponding
752 // type structure in middle/ty.rs as well.
753 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
754 pub struct MutTy {
755     pub ty: P<Ty>,
756     pub mutbl: Mutability,
757 }
758
759 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
760 pub struct TypeField {
761     pub ident: Ident,
762     pub mt: MutTy,
763     pub span: Span,
764 }
765
766 /// Represents a required method in a trait declaration,
767 /// one without a default implementation
768 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
769 pub struct TypeMethod {
770     pub ident: Ident,
771     pub attrs: Vec<Attribute>,
772     pub fn_style: FnStyle,
773     pub abi: Abi,
774     pub decl: P<FnDecl>,
775     pub generics: Generics,
776     pub explicit_self: ExplicitSelf,
777     pub id: NodeId,
778     pub span: Span,
779     pub vis: Visibility,
780 }
781
782 /// Represents a method declaration in a trait declaration, possibly including
783 /// a default implementation A trait method is either required (meaning it
784 /// doesn't have an implementation, just a signature) or provided (meaning it
785 /// has a default implementation).
786 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
787 pub enum TraitItem {
788     RequiredMethod(TypeMethod),
789     ProvidedMethod(P<Method>),
790     TypeTraitItem(P<AssociatedType>),
791 }
792
793 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
794 pub enum ImplItem {
795     MethodImplItem(P<Method>),
796     TypeImplItem(P<Typedef>),
797 }
798
799 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
800 pub struct AssociatedType {
801     pub id: NodeId,
802     pub span: Span,
803     pub ident: Ident,
804     pub attrs: Vec<Attribute>,
805 }
806
807 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
808 pub struct Typedef {
809     pub id: NodeId,
810     pub span: Span,
811     pub ident: Ident,
812     pub vis: Visibility,
813     pub attrs: Vec<Attribute>,
814     pub typ: P<Ty>,
815 }
816
817 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
818 pub enum IntTy {
819     TyI,
820     TyI8,
821     TyI16,
822     TyI32,
823     TyI64,
824 }
825
826 impl fmt::Show for IntTy {
827     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
828         write!(f, "{}", ast_util::int_ty_to_string(*self, None))
829     }
830 }
831
832 impl IntTy {
833     pub fn suffix_len(&self) -> uint {
834         match *self {
835             TyI => 1,
836             TyI8 => 2,
837             TyI16 | TyI32 | TyI64  => 3,
838         }
839     }
840 }
841
842 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
843 pub enum UintTy {
844     TyU,
845     TyU8,
846     TyU16,
847     TyU32,
848     TyU64,
849 }
850
851 impl UintTy {
852     pub fn suffix_len(&self) -> uint {
853         match *self {
854             TyU => 1,
855             TyU8 => 2,
856             TyU16 | TyU32 | TyU64  => 3,
857         }
858     }
859 }
860
861 impl fmt::Show for UintTy {
862     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
863         write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
864     }
865 }
866
867 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
868 pub enum FloatTy {
869     TyF32,
870     TyF64,
871 }
872
873 impl fmt::Show for FloatTy {
874     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
875         write!(f, "{}", ast_util::float_ty_to_string(*self))
876     }
877 }
878
879 impl FloatTy {
880     pub fn suffix_len(&self) -> uint {
881         match *self {
882             TyF32 | TyF64 => 3, // add F128 handling here
883         }
884     }
885 }
886
887 // NB PartialEq method appears below.
888 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
889 pub struct Ty {
890     pub id: NodeId,
891     pub node: Ty_,
892     pub span: Span,
893 }
894
895 /// Not represented directly in the AST, referred to by name through a ty_path.
896 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
897 pub enum PrimTy {
898     TyInt(IntTy),
899     TyUint(UintTy),
900     TyFloat(FloatTy),
901     TyStr,
902     TyBool,
903     TyChar
904 }
905
906 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
907 pub enum Onceness {
908     Once,
909     Many
910 }
911
912 impl fmt::Show for Onceness {
913     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
914         match *self {
915             Once => "once".fmt(f),
916             Many => "many".fmt(f),
917         }
918     }
919 }
920
921 /// Represents the type of a closure
922 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
923 pub struct ClosureTy {
924     pub lifetimes: Vec<LifetimeDef>,
925     pub fn_style: FnStyle,
926     pub onceness: Onceness,
927     pub decl: P<FnDecl>,
928     pub bounds: TyParamBounds,
929 }
930
931 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
932 pub struct BareFnTy {
933     pub fn_style: FnStyle,
934     pub abi: Abi,
935     pub lifetimes: Vec<LifetimeDef>,
936     pub decl: P<FnDecl>
937 }
938
939 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
940 pub struct UnboxedFnTy {
941     pub kind: UnboxedClosureKind,
942     pub decl: P<FnDecl>,
943 }
944
945 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
946 pub enum Ty_ {
947     TyNil,
948     TyBot, /* bottom type */
949     TyBox(P<Ty>),
950     TyUniq(P<Ty>),
951     TyVec(P<Ty>),
952     TyFixedLengthVec(P<Ty>, P<Expr>),
953     TyPtr(MutTy),
954     TyRptr(Option<Lifetime>, MutTy),
955     TyClosure(P<ClosureTy>),
956     TyProc(P<ClosureTy>),
957     TyBareFn(P<BareFnTy>),
958     TyUnboxedFn(P<UnboxedFnTy>),
959     TyTup(Vec<P<Ty>> ),
960     TyPath(Path, Option<TyParamBounds>, NodeId), // for #7264; see above
961     /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
962     TyQPath(P<QPath>),
963     /// No-op; kept solely so that we can pretty-print faithfully
964     TyParen(P<Ty>),
965     TyTypeof(P<Expr>),
966     /// TyInfer means the type should be inferred instead of it having been
967     /// specified. This can appear anywhere in a type.
968     TyInfer,
969 }
970
971 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
972 pub enum AsmDialect {
973     AsmAtt,
974     AsmIntel
975 }
976
977 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
978 pub struct InlineAsm {
979     pub asm: InternedString,
980     pub asm_str_style: StrStyle,
981     pub outputs: Vec<(InternedString, P<Expr>, bool)>,
982     pub inputs: Vec<(InternedString, P<Expr>)>,
983     pub clobbers: InternedString,
984     pub volatile: bool,
985     pub alignstack: bool,
986     pub dialect: AsmDialect,
987     pub expn_id: ExpnId,
988 }
989
990 /// represents an argument in a function header
991 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
992 pub struct Arg {
993     pub ty: P<Ty>,
994     pub pat: P<Pat>,
995     pub id: NodeId,
996 }
997
998 impl Arg {
999     pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1000         let path = Spanned{span:span,node:self_ident};
1001         Arg {
1002             // HACK(eddyb) fake type for the self argument.
1003             ty: P(Ty {
1004                 id: DUMMY_NODE_ID,
1005                 node: TyInfer,
1006                 span: DUMMY_SP,
1007             }),
1008             pat: P(Pat {
1009                 id: DUMMY_NODE_ID,
1010                 node: PatIdent(BindByValue(mutability), path, None),
1011                 span: span
1012             }),
1013             id: DUMMY_NODE_ID
1014         }
1015     }
1016 }
1017
1018 /// represents the header (not the body) of a function declaration
1019 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1020 pub struct FnDecl {
1021     pub inputs: Vec<Arg>,
1022     pub output: P<Ty>,
1023     pub cf: RetStyle,
1024     pub variadic: bool
1025 }
1026
1027 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1028 pub enum FnStyle {
1029     /// Declared with "unsafe fn"
1030     UnsafeFn,
1031     /// Declared with "fn"
1032     NormalFn,
1033 }
1034
1035 impl fmt::Show for FnStyle {
1036     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1037         match *self {
1038             NormalFn => "normal".fmt(f),
1039             UnsafeFn => "unsafe".fmt(f),
1040         }
1041     }
1042 }
1043
1044 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1045 pub enum RetStyle {
1046     /// Functions with return type ! that always
1047     /// raise an error or exit (i.e. never return to the caller)
1048     NoReturn,
1049     /// Everything else
1050     Return,
1051 }
1052
1053 /// Represents the kind of 'self' associated with a method
1054 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1055 pub enum ExplicitSelf_ {
1056     /// No self
1057     SelfStatic,
1058     /// `self`
1059     SelfValue(Ident),
1060     /// `&'lt self`, `&'lt mut self`
1061     SelfRegion(Option<Lifetime>, Mutability, Ident),
1062     /// `self: TYPE`
1063     SelfExplicit(P<Ty>, Ident),
1064 }
1065
1066 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
1067
1068 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1069 pub struct Method {
1070     pub attrs: Vec<Attribute>,
1071     pub id: NodeId,
1072     pub span: Span,
1073     pub node: Method_,
1074 }
1075
1076 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1077 pub enum Method_ {
1078     /// Represents a method declaration
1079     MethDecl(Ident,
1080              Generics,
1081              Abi,
1082              ExplicitSelf,
1083              FnStyle,
1084              P<FnDecl>,
1085              P<Block>,
1086              Visibility),
1087     /// Represents a macro in method position
1088     MethMac(Mac),
1089 }
1090
1091 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1092 pub struct Mod {
1093     /// A span from the first token past `{` to the last token until `}`.
1094     /// For `mod foo;`, the inner span ranges from the first token
1095     /// to the last token in the external file.
1096     pub inner: Span,
1097     pub view_items: Vec<ViewItem>,
1098     pub items: Vec<P<Item>>,
1099 }
1100
1101 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1102 pub struct ForeignMod {
1103     pub abi: Abi,
1104     pub view_items: Vec<ViewItem>,
1105     pub items: Vec<P<ForeignItem>>,
1106 }
1107
1108 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1109 pub struct VariantArg {
1110     pub ty: P<Ty>,
1111     pub id: NodeId,
1112 }
1113
1114 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1115 pub enum VariantKind {
1116     TupleVariantKind(Vec<VariantArg>),
1117     StructVariantKind(P<StructDef>),
1118 }
1119
1120 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1121 pub struct EnumDef {
1122     pub variants: Vec<P<Variant>>,
1123 }
1124
1125 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1126 pub struct Variant_ {
1127     pub name: Ident,
1128     pub attrs: Vec<Attribute>,
1129     pub kind: VariantKind,
1130     pub id: NodeId,
1131     pub disr_expr: Option<P<Expr>>,
1132     pub vis: Visibility,
1133 }
1134
1135 pub type Variant = Spanned<Variant_>;
1136
1137 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1138 pub enum PathListItem_ {
1139     PathListIdent { pub name: Ident, pub id: NodeId },
1140     PathListMod { pub id: NodeId }
1141 }
1142
1143 impl PathListItem_ {
1144     pub fn id(&self) -> NodeId {
1145         match *self {
1146             PathListIdent { id, .. } | PathListMod { id } => id
1147         }
1148     }
1149 }
1150
1151 pub type PathListItem = Spanned<PathListItem_>;
1152
1153 pub type ViewPath = Spanned<ViewPath_>;
1154
1155 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1156 pub enum ViewPath_ {
1157
1158     /// `foo::bar::baz as quux`
1159     ///
1160     /// or just
1161     ///
1162     /// `foo::bar::baz` (with `as baz` implicitly on the right)
1163     ViewPathSimple(Ident, Path, NodeId),
1164
1165     /// `foo::bar::*`
1166     ViewPathGlob(Path, NodeId),
1167
1168     /// `foo::bar::{a,b,c}`
1169     ViewPathList(Path, Vec<PathListItem> , NodeId)
1170 }
1171
1172 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1173 pub struct ViewItem {
1174     pub node: ViewItem_,
1175     pub attrs: Vec<Attribute>,
1176     pub vis: Visibility,
1177     pub span: Span,
1178 }
1179
1180 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1181 pub enum ViewItem_ {
1182     /// Ident: name used to refer to this crate in the code
1183     /// optional (InternedString,StrStyle): if present, this is a location
1184     /// (containing arbitrary characters) from which to fetch the crate sources
1185     /// For example, extern crate whatever = "github.com/rust-lang/rust"
1186     ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
1187     ViewItemUse(P<ViewPath>),
1188 }
1189
1190 /// Meta-data associated with an item
1191 pub type Attribute = Spanned<Attribute_>;
1192
1193 /// Distinguishes between Attributes that decorate items and Attributes that
1194 /// are contained as statements within items. These two cases need to be
1195 /// distinguished for pretty-printing.
1196 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1197 pub enum AttrStyle {
1198     AttrOuter,
1199     AttrInner,
1200 }
1201
1202 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1203 pub struct AttrId(pub uint);
1204
1205 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1206 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1207 pub struct Attribute_ {
1208     pub id: AttrId,
1209     pub style: AttrStyle,
1210     pub value: P<MetaItem>,
1211     pub is_sugared_doc: bool,
1212 }
1213
1214
1215 /// TraitRef's appear in impls.
1216 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1217 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1218 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1219 /// same as the impl's node id).
1220 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1221 pub struct TraitRef {
1222     pub path: Path,
1223     pub ref_id: NodeId,
1224     pub lifetimes: Vec<LifetimeDef>,
1225 }
1226
1227 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1228 pub enum Visibility {
1229     Public,
1230     Inherited,
1231 }
1232
1233 impl Visibility {
1234     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1235         match self {
1236             &Inherited => parent_visibility,
1237             &Public => *self
1238         }
1239     }
1240 }
1241
1242 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1243 pub struct StructField_ {
1244     pub kind: StructFieldKind,
1245     pub id: NodeId,
1246     pub ty: P<Ty>,
1247     pub attrs: Vec<Attribute>,
1248 }
1249
1250 impl StructField_ {
1251     pub fn ident(&self) -> Option<Ident> {
1252         match self.kind {
1253             NamedField(ref ident, _) => Some(ident.clone()),
1254             UnnamedField(_) => None
1255         }
1256     }
1257 }
1258
1259 pub type StructField = Spanned<StructField_>;
1260
1261 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1262 pub enum StructFieldKind {
1263     NamedField(Ident, Visibility),
1264     /// Element of a tuple-like struct
1265     UnnamedField(Visibility),
1266 }
1267
1268 impl StructFieldKind {
1269     pub fn is_unnamed(&self) -> bool {
1270         match *self {
1271             UnnamedField(..) => true,
1272             NamedField(..) => false,
1273         }
1274     }
1275 }
1276
1277 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1278 pub struct StructDef {
1279     /// Fields, not including ctor
1280     pub fields: Vec<StructField>,
1281     /// ID of the constructor. This is only used for tuple- or enum-like
1282     /// structs.
1283     pub ctor_id: Option<NodeId>,
1284     /// Super struct, if specified.
1285     pub super_struct: Option<P<Ty>>,
1286     /// True iff the struct may be inherited from.
1287     pub is_virtual: bool,
1288 }
1289
1290 /*
1291   FIXME (#3300): Should allow items to be anonymous. Right now
1292   we just use dummy names for anon items.
1293  */
1294 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1295 pub struct Item {
1296     pub ident: Ident,
1297     pub attrs: Vec<Attribute>,
1298     pub id: NodeId,
1299     pub node: Item_,
1300     pub vis: Visibility,
1301     pub span: Span,
1302 }
1303
1304 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1305 pub enum Item_ {
1306     ItemStatic(P<Ty>, Mutability, P<Expr>),
1307     ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
1308     ItemMod(Mod),
1309     ItemForeignMod(ForeignMod),
1310     ItemTy(P<Ty>, Generics),
1311     ItemEnum(EnumDef, Generics),
1312     ItemStruct(P<StructDef>, Generics),
1313     /// Represents a Trait Declaration
1314     ItemTrait(Generics,
1315               Option<TyParamBound>, // (optional) default bound not required for Self.
1316                                     // Currently, only Sized makes sense here.
1317               TyParamBounds,
1318               Vec<TraitItem>),
1319     ItemImpl(Generics,
1320              Option<TraitRef>, // (optional) trait this impl implements
1321              P<Ty>, // self
1322              Vec<ImplItem>),
1323     /// A macro invocation (which includes macro definition)
1324     ItemMac(Mac),
1325 }
1326
1327 impl Item_ {
1328     pub fn descriptive_variant(&self) -> &str {
1329         match *self {
1330             ItemStatic(..) => "static item",
1331             ItemFn(..) => "function",
1332             ItemMod(..) => "module",
1333             ItemForeignMod(..) => "foreign module",
1334             ItemTy(..) => "type alias",
1335             ItemEnum(..) => "enum",
1336             ItemStruct(..) => "struct",
1337             ItemTrait(..) => "trait",
1338             _ => "item"
1339         }
1340     }
1341 }
1342
1343 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1344 pub struct ForeignItem {
1345     pub ident: Ident,
1346     pub attrs: Vec<Attribute>,
1347     pub node: ForeignItem_,
1348     pub id: NodeId,
1349     pub span: Span,
1350     pub vis: Visibility,
1351 }
1352
1353 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1354 pub enum ForeignItem_ {
1355     ForeignItemFn(P<FnDecl>, Generics),
1356     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1357 }
1358
1359 impl ForeignItem_ {
1360     pub fn descriptive_variant(&self) -> &str {
1361         match *self {
1362             ForeignItemFn(..) => "foreign function",
1363             ForeignItemStatic(..) => "foreign static item"
1364         }
1365     }
1366 }
1367
1368 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1369 pub enum UnboxedClosureKind {
1370     FnUnboxedClosureKind,
1371     FnMutUnboxedClosureKind,
1372     FnOnceUnboxedClosureKind,
1373 }
1374
1375 /// The data we save and restore about an inlined item or method.  This is not
1376 /// part of the AST that we parse from a file, but it becomes part of the tree
1377 /// that we trans.
1378 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1379 pub enum InlinedItem {
1380     IIItem(P<Item>),
1381     IITraitItem(DefId /* impl id */, TraitItem),
1382     IIImplItem(DefId /* impl id */, ImplItem),
1383     IIForeign(P<ForeignItem>),
1384 }
1385
1386 #[cfg(test)]
1387 mod test {
1388     use serialize::json;
1389     use serialize;
1390     use codemap::*;
1391     use super::*;
1392
1393     // are ASTs encodable?
1394     #[test]
1395     fn check_asts_encodable() {
1396         use std::io;
1397         let e = Crate {
1398             module: Mod {
1399                 inner: Span {
1400                     lo: BytePos(11),
1401                     hi: BytePos(19),
1402                     expn_id: NO_EXPANSION,
1403                 },
1404                 view_items: Vec::new(),
1405                 items: Vec::new(),
1406             },
1407             attrs: Vec::new(),
1408             config: Vec::new(),
1409             span: Span {
1410                 lo: BytePos(10),
1411                 hi: BytePos(20),
1412                 expn_id: NO_EXPANSION,
1413             },
1414             exported_macros: Vec::new(),
1415         };
1416         // doesn't matter which encoder we use....
1417         let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
1418     }
1419 }