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