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