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