]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
Add a few more derivings to AST types
[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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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<Gc<Item>>
260 }
261
262 pub type MetaItem = Spanned<MetaItem_>;
263
264 #[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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, Show)]
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, Show)]
314 pub struct FieldPat {
315     pub ident: Ident,
316     pub pat: Gc<Pat>,
317 }
318
319 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
320 pub enum BindingMode {
321     BindByRef(Mutability),
322     BindByValue(Mutability),
323 }
324
325 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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, Show)]
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, Show)]
465 pub enum BlockCheckMode {
466     DefaultBlock,
467     UnsafeBlock(UnsafeSource),
468 }
469
470 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
471 pub enum UnsafeSource {
472     CompilerGenerated,
473     UserProvided,
474 }
475
476 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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     ExprUnboxedFn(P<FnDecl>, P<Block>),
507     ExprBlock(P<Block>),
508
509     ExprAssign(Gc<Expr>, Gc<Expr>),
510     ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
511     ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
512     ExprIndex(Gc<Expr>, Gc<Expr>),
513
514     /// Variable reference, possibly containing `::` and/or
515     /// type parameters, e.g. foo::bar::<baz>
516     ExprPath(Path),
517
518     ExprAddrOf(Mutability, Gc<Expr>),
519     ExprBreak(Option<Ident>),
520     ExprAgain(Option<Ident>),
521     ExprRet(Option<Gc<Expr>>),
522
523     ExprInlineAsm(InlineAsm),
524
525     ExprMac(Mac),
526
527     /// A struct literal expression.
528     ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
529
530     /// A vector literal constructed from one repeated element.
531     ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
532
533     /// No-op: used solely so we can pretty-print faithfully
534     ExprParen(Gc<Expr>)
535 }
536
537 /// When the main rust parser encounters a syntax-extension invocation, it
538 /// parses the arguments to the invocation as a token-tree. This is a very
539 /// loose structure, such that all sorts of different AST-fragments can
540 /// be passed to syntax extensions using a uniform type.
541 ///
542 /// If the syntax extension is an MBE macro, it will attempt to match its
543 /// LHS "matchers" against the provided token tree, and if it finds a
544 /// match, will transcribe the RHS token tree, splicing in any captured
545 /// macro_parser::matched_nonterminals into the TTNonterminals it finds.
546 ///
547 /// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
548 /// makes any real sense. You could write them elsewhere but nothing
549 /// else knows what to do with them, so you'll probably get a syntax
550 /// error.
551 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
552 #[doc="For macro invocations; parsing is delegated to the macro"]
553 pub enum TokenTree {
554     /// A single token
555     TTTok(Span, ::parse::token::Token),
556     /// A delimited sequence (the delimiters appear as the first
557     /// and last elements of the vector)
558     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
559     TTDelim(Rc<Vec<TokenTree>>),
560
561     // These only make sense for right-hand-sides of MBE macros:
562
563     /// A kleene-style repetition sequence with a span, a TTForest,
564     /// an optional separator, and a boolean where true indicates
565     /// zero or more (..), and false indicates one or more (+).
566     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
567     TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
568
569     /// A syntactic variable that will be filled in by macro expansion.
570     TTNonterminal(Span, Ident)
571 }
572
573 // Matchers are nodes defined-by and recognized-by the main rust parser and
574 // language, but they're only ever found inside syntax-extension invocations;
575 // indeed, the only thing that ever _activates_ the rules in the rust parser
576 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
577 // itself. Matchers represent a small sub-language for pattern-matching
578 // token-trees, and are thus primarily used by the macro-defining extension
579 // itself.
580 //
581 // MatchTok
582 // --------
583 //
584 //     A matcher that matches a single token, denoted by the token itself. So
585 //     long as there's no $ involved.
586 //
587 //
588 // MatchSeq
589 // --------
590 //
591 //     A matcher that matches a sequence of sub-matchers, denoted various
592 //     possible ways:
593 //
594 //             $(M)*       zero or more Ms
595 //             $(M)+       one or more Ms
596 //             $(M),+      one or more comma-separated Ms
597 //             $(A B C);*  zero or more semi-separated 'A B C' seqs
598 //
599 //
600 // MatchNonterminal
601 // -----------------
602 //
603 //     A matcher that matches one of a few interesting named rust
604 //     nonterminals, such as types, expressions, items, or raw token-trees. A
605 //     black-box matcher on expr, for example, binds an expr to a given ident,
606 //     and that ident can re-occur as an interpolation in the RHS of a
607 //     macro-by-example rule. For example:
608 //
609 //        $foo:expr   =>     1 + $foo    // interpolate an expr
610 //        $foo:tt     =>     $foo        // interpolate a token-tree
611 //        $foo:tt     =>     bar! $foo   // only other valid interpolation
612 //                                       // is in arg position for another
613 //                                       // macro
614 //
615 // As a final, horrifying aside, note that macro-by-example's input is
616 // also matched by one of these matchers. Holy self-referential! It is matched
617 // by a MatchSeq, specifically this one:
618 //
619 //                   $( $lhs:matchers => $rhs:tt );+
620 //
621 // If you understand that, you have closed the loop and understand the whole
622 // macro system. Congratulations.
623 pub type Matcher = Spanned<Matcher_>;
624
625 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
626 pub enum Matcher_ {
627     /// Match one token
628     MatchTok(::parse::token::Token),
629     /// Match repetitions of a sequence: body, separator, zero ok?,
630     /// lo, hi position-in-match-array used:
631     MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
632     /// Parse a Rust NT: name to bind, name of NT, position in match array:
633     MatchNonterminal(Ident, Ident, uint)
634 }
635
636 pub type Mac = Spanned<Mac_>;
637
638 /// Represents a macro invocation. The Path indicates which macro
639 /// is being invoked, and the vector of token-trees contains the source
640 /// of the macro invocation.
641 /// There's only one flavor, now, so this could presumably be simplified.
642 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
643 pub enum Mac_ {
644     // NB: the additional ident for a macro_rules-style macro is actually
645     // stored in the enclosing item. Oog.
646     MacInvocTT(Path, Vec<TokenTree> , SyntaxContext),   // new macro-invocation
647 }
648
649 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
650 pub enum StrStyle {
651     CookedStr,
652     RawStr(uint)
653 }
654
655 pub type Lit = Spanned<Lit_>;
656
657 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
658 pub enum Lit_ {
659     LitStr(InternedString, StrStyle),
660     LitBinary(Rc<Vec<u8> >),
661     LitByte(u8),
662     LitChar(char),
663     LitInt(i64, IntTy),
664     LitUint(u64, UintTy),
665     LitIntUnsuffixed(i64),
666     LitFloat(InternedString, FloatTy),
667     LitFloatUnsuffixed(InternedString),
668     LitNil,
669     LitBool(bool),
670 }
671
672 // NB: If you change this, you'll probably want to change the corresponding
673 // type structure in middle/ty.rs as well.
674 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
675 pub struct MutTy {
676     pub ty: P<Ty>,
677     pub mutbl: Mutability,
678 }
679
680 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
681 pub struct TypeField {
682     pub ident: Ident,
683     pub mt: MutTy,
684     pub span: Span,
685 }
686
687 /// Represents a required method in a trait declaration,
688 /// one without a default implementation
689 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
690 pub struct TypeMethod {
691     pub ident: Ident,
692     pub attrs: Vec<Attribute>,
693     pub fn_style: FnStyle,
694     pub abi: Abi,
695     pub decl: P<FnDecl>,
696     pub generics: Generics,
697     pub explicit_self: ExplicitSelf,
698     pub id: NodeId,
699     pub span: Span,
700     pub vis: Visibility,
701 }
702
703 /// Represents a method declaration in a trait declaration, possibly including
704 /// a default implementation A trait method is either required (meaning it
705 /// doesn't have an implementation, just a signature) or provided (meaning it
706 /// has a default implementation).
707 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
708 pub enum TraitMethod {
709     Required(TypeMethod),
710     Provided(Gc<Method>),
711 }
712
713 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
714 pub enum IntTy {
715     TyI,
716     TyI8,
717     TyI16,
718     TyI32,
719     TyI64,
720 }
721
722 impl fmt::Show for IntTy {
723     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
724         write!(f, "{}", ast_util::int_ty_to_string(*self, None))
725     }
726 }
727
728 impl IntTy {
729     pub fn suffix_len(&self) -> uint {
730         match *self {
731             TyI => 1,
732             TyI8 => 2,
733             TyI16 | TyI32 | TyI64  => 3,
734         }
735     }
736 }
737
738 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
739 pub enum UintTy {
740     TyU,
741     TyU8,
742     TyU16,
743     TyU32,
744     TyU64,
745 }
746
747 impl UintTy {
748     pub fn suffix_len(&self) -> uint {
749         match *self {
750             TyU => 1,
751             TyU8 => 2,
752             TyU16 | TyU32 | TyU64  => 3,
753         }
754     }
755 }
756
757 impl fmt::Show for UintTy {
758     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
759         write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
760     }
761 }
762
763 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
764 pub enum FloatTy {
765     TyF32,
766     TyF64,
767 }
768
769 impl fmt::Show for FloatTy {
770     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
771         write!(f, "{}", ast_util::float_ty_to_string(*self))
772     }
773 }
774
775 impl FloatTy {
776     pub fn suffix_len(&self) -> uint {
777         match *self {
778             TyF32 | TyF64 => 3, // add F128 handling here
779         }
780     }
781 }
782
783 // NB PartialEq method appears below.
784 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
785 pub struct Ty {
786     pub id: NodeId,
787     pub node: Ty_,
788     pub span: Span,
789 }
790
791 /// Not represented directly in the AST, referred to by name through a ty_path.
792 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
793 pub enum PrimTy {
794     TyInt(IntTy),
795     TyUint(UintTy),
796     TyFloat(FloatTy),
797     TyStr,
798     TyBool,
799     TyChar
800 }
801
802 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
803 pub enum Onceness {
804     Once,
805     Many
806 }
807
808 impl fmt::Show for Onceness {
809     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
810         match *self {
811             Once => "once".fmt(f),
812             Many => "many".fmt(f),
813         }
814     }
815 }
816
817 /// Represents the type of a closure
818 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)]
819 pub struct ClosureTy {
820     pub lifetimes: Vec<Lifetime>,
821     pub fn_style: FnStyle,
822     pub onceness: Onceness,
823     pub decl: P<FnDecl>,
824     /// Optional optvec distinguishes between "fn()" and "fn:()" so we can
825     /// implement issue #7264. None means "fn()", which means infer a default
826     /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
827     /// which means use no bounds (e.g., not even Owned on a ~fn()).
828     pub bounds: Option<OwnedSlice<TyParamBound>>,
829 }
830
831 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)]
832 pub struct BareFnTy {
833     pub fn_style: FnStyle,
834     pub abi: Abi,
835     pub lifetimes: Vec<Lifetime>,
836     pub decl: P<FnDecl>
837 }
838
839 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
840 pub struct UnboxedFnTy {
841     pub decl: P<FnDecl>,
842 }
843
844 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
845 pub enum Ty_ {
846     TyNil,
847     TyBot, /* bottom type */
848     TyBox(P<Ty>),
849     TyUniq(P<Ty>),
850     TyVec(P<Ty>),
851     TyFixedLengthVec(P<Ty>, Gc<Expr>),
852     TyPtr(MutTy),
853     TyRptr(Option<Lifetime>, MutTy),
854     TyClosure(Gc<ClosureTy>, Option<Lifetime>),
855     TyProc(Gc<ClosureTy>),
856     TyBareFn(Gc<BareFnTy>),
857     TyUnboxedFn(Gc<UnboxedFnTy>),
858     TyTup(Vec<P<Ty>> ),
859     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
860     /// No-op; kept solely so that we can pretty-print faithfully
861     TyParen(P<Ty>),
862     TyTypeof(Gc<Expr>),
863     /// TyInfer means the type should be inferred instead of it having been
864     /// specified. This can appear anywhere in a type.
865     TyInfer,
866 }
867
868 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
869 pub enum AsmDialect {
870     AsmAtt,
871     AsmIntel
872 }
873
874 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
875 pub struct InlineAsm {
876     pub asm: InternedString,
877     pub asm_str_style: StrStyle,
878     pub clobbers: InternedString,
879     pub inputs: Vec<(InternedString, Gc<Expr>)>,
880     pub outputs: Vec<(InternedString, Gc<Expr>)>,
881     pub volatile: bool,
882     pub alignstack: bool,
883     pub dialect: AsmDialect
884 }
885
886 /// represents an argument in a function header
887 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
888 pub struct Arg {
889     pub ty: P<Ty>,
890     pub pat: Gc<Pat>,
891     pub id: NodeId,
892 }
893
894 impl Arg {
895     pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
896         let path = Spanned{span:span,node:self_ident};
897         Arg {
898             // HACK(eddyb) fake type for the self argument.
899             ty: P(Ty {
900                 id: DUMMY_NODE_ID,
901                 node: TyInfer,
902                 span: DUMMY_SP,
903             }),
904             pat: box(GC) Pat {
905                 id: DUMMY_NODE_ID,
906                 node: PatIdent(BindByValue(mutability), path, None),
907                 span: span
908             },
909             id: DUMMY_NODE_ID
910         }
911     }
912 }
913
914 /// represents the header (not the body) of a function declaration
915 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
916 pub struct FnDecl {
917     pub inputs: Vec<Arg>,
918     pub output: P<Ty>,
919     pub cf: RetStyle,
920     pub variadic: bool
921 }
922
923 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
924 pub enum FnStyle {
925     /// Declared with "unsafe fn"
926     UnsafeFn,
927     /// Declared with "fn"
928     NormalFn,
929 }
930
931 impl fmt::Show for FnStyle {
932     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
933         match *self {
934             NormalFn => "normal".fmt(f),
935             UnsafeFn => "unsafe".fmt(f),
936         }
937     }
938 }
939
940 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
941 pub enum RetStyle {
942     /// Functions with return type ! that always
943     /// raise an error or exit (i.e. never return to the caller)
944     NoReturn,
945     /// Everything else
946     Return,
947 }
948
949 /// Represents the kind of 'self' associated with a method
950 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
951 pub enum ExplicitSelf_ {
952     /// No self
953     SelfStatic,
954     /// `self`
955     SelfValue(Ident),
956     /// `&'lt self`, `&'lt mut self`
957     SelfRegion(Option<Lifetime>, Mutability, Ident),
958     /// `self: TYPE`
959     SelfExplicit(P<Ty>, Ident),
960 }
961
962 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
963
964 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
965 pub struct Method {
966     pub attrs: Vec<Attribute>,
967     pub id: NodeId,
968     pub span: Span,
969     pub node: Method_,
970 }
971
972 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
973 pub enum Method_ {
974     /// Represents a method declaration
975     MethDecl(Ident,
976              Generics,
977              Abi,
978              ExplicitSelf,
979              FnStyle,
980              P<FnDecl>,
981              P<Block>,
982              Visibility),
983     /// Represents a macro in method position
984     MethMac(Mac),
985 }
986
987 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
988 pub struct Mod {
989     /// A span from the first token past `{` to the last token until `}`.
990     /// For `mod foo;`, the inner span ranges from the first token
991     /// to the last token in the external file.
992     pub inner: Span,
993     pub view_items: Vec<ViewItem>,
994     pub items: Vec<Gc<Item>>,
995 }
996
997 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
998 pub struct ForeignMod {
999     pub abi: Abi,
1000     pub view_items: Vec<ViewItem>,
1001     pub items: Vec<Gc<ForeignItem>>,
1002 }
1003
1004 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1005 pub struct VariantArg {
1006     pub ty: P<Ty>,
1007     pub id: NodeId,
1008 }
1009
1010 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1011 pub enum VariantKind {
1012     TupleVariantKind(Vec<VariantArg>),
1013     StructVariantKind(Gc<StructDef>),
1014 }
1015
1016 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1017 pub struct EnumDef {
1018     pub variants: Vec<P<Variant>>,
1019 }
1020
1021 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1022 pub struct Variant_ {
1023     pub name: Ident,
1024     pub attrs: Vec<Attribute>,
1025     pub kind: VariantKind,
1026     pub id: NodeId,
1027     pub disr_expr: Option<Gc<Expr>>,
1028     pub vis: Visibility,
1029 }
1030
1031 pub type Variant = Spanned<Variant_>;
1032
1033 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1034 pub enum PathListItem_ {
1035     PathListIdent { pub name: Ident, pub id: NodeId },
1036     PathListMod { pub id: NodeId }
1037 }
1038
1039 impl PathListItem_ {
1040     pub fn id(&self) -> NodeId {
1041         match *self {
1042             PathListIdent { id, .. } | PathListMod { id } => id
1043         }
1044     }
1045 }
1046
1047 pub type PathListItem = Spanned<PathListItem_>;
1048
1049 pub type ViewPath = Spanned<ViewPath_>;
1050
1051 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1052 pub enum ViewPath_ {
1053
1054     /// `quux = foo::bar::baz`
1055     ///
1056     /// or just
1057     ///
1058     /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
1059     ViewPathSimple(Ident, Path, NodeId),
1060
1061     /// `foo::bar::*`
1062     ViewPathGlob(Path, NodeId),
1063
1064     /// `foo::bar::{a,b,c}`
1065     ViewPathList(Path, Vec<PathListItem> , NodeId)
1066 }
1067
1068 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1069 pub struct ViewItem {
1070     pub node: ViewItem_,
1071     pub attrs: Vec<Attribute>,
1072     pub vis: Visibility,
1073     pub span: Span,
1074 }
1075
1076 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1077 pub enum ViewItem_ {
1078     /// Ident: name used to refer to this crate in the code
1079     /// optional (InternedString,StrStyle): if present, this is a location
1080     /// (containing arbitrary characters) from which to fetch the crate sources
1081     /// For example, extern crate whatever = "github.com/rust-lang/rust"
1082     ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
1083     ViewItemUse(Gc<ViewPath>),
1084 }
1085
1086 /// Meta-data associated with an item
1087 pub type Attribute = Spanned<Attribute_>;
1088
1089 /// Distinguishes between Attributes that decorate items and Attributes that
1090 /// are contained as statements within items. These two cases need to be
1091 /// distinguished for pretty-printing.
1092 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1093 pub enum AttrStyle {
1094     AttrOuter,
1095     AttrInner,
1096 }
1097
1098 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1099 pub struct AttrId(pub uint);
1100
1101 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1102 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1103 pub struct Attribute_ {
1104     pub id: AttrId,
1105     pub style: AttrStyle,
1106     pub value: Gc<MetaItem>,
1107     pub is_sugared_doc: bool,
1108 }
1109
1110
1111 /// TraitRef's appear in impls.
1112 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1113 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1114 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1115 /// same as the impl's node id).
1116 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1117 pub struct TraitRef {
1118     pub path: Path,
1119     pub ref_id: NodeId,
1120 }
1121
1122 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1123 pub enum Visibility {
1124     Public,
1125     Inherited,
1126 }
1127
1128 impl Visibility {
1129     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1130         match self {
1131             &Inherited => parent_visibility,
1132             &Public => *self
1133         }
1134     }
1135 }
1136
1137 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1138 pub struct StructField_ {
1139     pub kind: StructFieldKind,
1140     pub id: NodeId,
1141     pub ty: P<Ty>,
1142     pub attrs: Vec<Attribute>,
1143 }
1144
1145 impl StructField_ {
1146     pub fn ident(&self) -> Option<Ident> {
1147         match self.kind {
1148             NamedField(ref ident, _) => Some(ident.clone()),
1149             UnnamedField(_) => None
1150         }
1151     }
1152 }
1153
1154 pub type StructField = Spanned<StructField_>;
1155
1156 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1157 pub enum StructFieldKind {
1158     NamedField(Ident, Visibility),
1159     /// Element of a tuple-like struct
1160     UnnamedField(Visibility),
1161 }
1162
1163 impl StructFieldKind {
1164     pub fn is_unnamed(&self) -> bool {
1165         match *self {
1166             UnnamedField(..) => true,
1167             NamedField(..) => false,
1168         }
1169     }
1170 }
1171
1172 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1173 pub struct StructDef {
1174     /// Fields, not including ctor
1175     pub fields: Vec<StructField>,
1176     /// ID of the constructor. This is only used for tuple- or enum-like
1177     /// structs.
1178     pub ctor_id: Option<NodeId>,
1179     /// Super struct, if specified.
1180     pub super_struct: Option<P<Ty>>,
1181     /// True iff the struct may be inherited from.
1182     pub is_virtual: bool,
1183 }
1184
1185 /*
1186   FIXME (#3300): Should allow items to be anonymous. Right now
1187   we just use dummy names for anon items.
1188  */
1189 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1190 pub struct Item {
1191     pub ident: Ident,
1192     pub attrs: Vec<Attribute>,
1193     pub id: NodeId,
1194     pub node: Item_,
1195     pub vis: Visibility,
1196     pub span: Span,
1197 }
1198
1199 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1200 pub enum Item_ {
1201     ItemStatic(P<Ty>, Mutability, Gc<Expr>),
1202     ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
1203     ItemMod(Mod),
1204     ItemForeignMod(ForeignMod),
1205     ItemTy(P<Ty>, Generics),
1206     ItemEnum(EnumDef, Generics),
1207     ItemStruct(Gc<StructDef>, Generics),
1208     /// Represents a Trait Declaration
1209     ItemTrait(Generics,
1210               Option<TyParamBound>, // (optional) default bound not required for Self.
1211                                     // Currently, only Sized makes sense here.
1212               Vec<TraitRef> ,
1213               Vec<TraitMethod>),
1214     ItemImpl(Generics,
1215              Option<TraitRef>, // (optional) trait this impl implements
1216              P<Ty>, // self
1217              Vec<Gc<Method>>),
1218     /// A macro invocation (which includes macro definition)
1219     ItemMac(Mac),
1220 }
1221
1222 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1223 pub struct ForeignItem {
1224     pub ident: Ident,
1225     pub attrs: Vec<Attribute>,
1226     pub node: ForeignItem_,
1227     pub id: NodeId,
1228     pub span: Span,
1229     pub vis: Visibility,
1230 }
1231
1232 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1233 pub enum ForeignItem_ {
1234     ForeignItemFn(P<FnDecl>, Generics),
1235     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1236 }
1237
1238 /// The data we save and restore about an inlined item or method.  This is not
1239 /// part of the AST that we parse from a file, but it becomes part of the tree
1240 /// that we trans.
1241 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1242 pub enum InlinedItem {
1243     IIItem(Gc<Item>),
1244     IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
1245     IIForeign(Gc<ForeignItem>),
1246 }
1247
1248 #[cfg(test)]
1249 mod test {
1250     use serialize::json;
1251     use serialize;
1252     use codemap::*;
1253     use super::*;
1254
1255     // are ASTs encodable?
1256     #[test]
1257     fn check_asts_encodable() {
1258         use std::io;
1259         let e = Crate {
1260             module: Mod {
1261                 inner: Span {
1262                     lo: BytePos(11),
1263                     hi: BytePos(19),
1264                     expn_info: None,
1265                 },
1266                 view_items: Vec::new(),
1267                 items: Vec::new(),
1268             },
1269             attrs: Vec::new(),
1270             config: Vec::new(),
1271             span: Span {
1272                 lo: BytePos(10),
1273                 hi: BytePos(20),
1274                 expn_info: None,
1275             },
1276             exported_macros: Vec::new(),
1277         };
1278         // doesn't matter which encoder we use....
1279         let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
1280     }
1281 }