]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
auto merge of #15160 : alexcrichton/rust/remove-f128, r=brson
[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, "{}", ast_util::int_ty_to_str(*self, None))
679     }
680 }
681
682 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
683 pub enum UintTy {
684     TyU,
685     TyU8,
686     TyU16,
687     TyU32,
688     TyU64,
689 }
690
691 impl fmt::Show for UintTy {
692     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
693         write!(f, "{}", ast_util::uint_ty_to_str(*self, None))
694     }
695 }
696
697 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
698 pub enum FloatTy {
699     TyF32,
700     TyF64,
701 }
702
703 impl fmt::Show for FloatTy {
704     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
705         write!(f, "{}", ast_util::float_ty_to_str(*self))
706     }
707 }
708
709 // NB PartialEq method appears below.
710 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
711 pub struct Ty {
712     pub id: NodeId,
713     pub node: Ty_,
714     pub span: Span,
715 }
716
717 // Not represented directly in the AST, referred to by name through a ty_path.
718 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
719 pub enum PrimTy {
720     TyInt(IntTy),
721     TyUint(UintTy),
722     TyFloat(FloatTy),
723     TyStr,
724     TyBool,
725     TyChar
726 }
727
728 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
729 pub enum Onceness {
730     Once,
731     Many
732 }
733
734 impl fmt::Show for Onceness {
735     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
736         match *self {
737             Once => "once".fmt(f),
738             Many => "many".fmt(f),
739         }
740     }
741 }
742
743 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
744 pub struct ClosureTy {
745     pub lifetimes: Vec<Lifetime>,
746     pub fn_style: FnStyle,
747     pub onceness: Onceness,
748     pub decl: P<FnDecl>,
749     // Optional optvec distinguishes between "fn()" and "fn:()" so we can
750     // implement issue #7264. None means "fn()", which means infer a default
751     // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
752     // which means use no bounds (e.g., not even Owned on a ~fn()).
753     pub bounds: Option<OwnedSlice<TyParamBound>>,
754 }
755
756 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
757 pub struct BareFnTy {
758     pub fn_style: FnStyle,
759     pub abi: Abi,
760     pub lifetimes: Vec<Lifetime>,
761     pub decl: P<FnDecl>
762 }
763
764 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
765 pub struct UnboxedFnTy {
766     pub decl: P<FnDecl>,
767 }
768
769 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
770 pub enum Ty_ {
771     TyNil,
772     TyBot, /* bottom type */
773     TyBox(P<Ty>),
774     TyUniq(P<Ty>),
775     TyVec(P<Ty>),
776     TyFixedLengthVec(P<Ty>, Gc<Expr>),
777     TyPtr(MutTy),
778     TyRptr(Option<Lifetime>, MutTy),
779     TyClosure(Gc<ClosureTy>, Option<Lifetime>),
780     TyProc(Gc<ClosureTy>),
781     TyBareFn(Gc<BareFnTy>),
782     TyUnboxedFn(Gc<UnboxedFnTy>),
783     TyTup(Vec<P<Ty>> ),
784     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
785     // No-op; kept solely so that we can pretty-print faithfully
786     TyParen(P<Ty>),
787     TyTypeof(Gc<Expr>),
788     // TyInfer means the type should be inferred instead of it having been
789     // specified. This can appear anywhere in a type.
790     TyInfer,
791 }
792
793 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
794 pub enum AsmDialect {
795     AsmAtt,
796     AsmIntel
797 }
798
799 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
800 pub struct InlineAsm {
801     pub asm: InternedString,
802     pub asm_str_style: StrStyle,
803     pub clobbers: InternedString,
804     pub inputs: Vec<(InternedString, Gc<Expr>)>,
805     pub outputs: Vec<(InternedString, Gc<Expr>)>,
806     pub volatile: bool,
807     pub alignstack: bool,
808     pub dialect: AsmDialect
809 }
810
811 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
812 pub struct Arg {
813     pub ty: P<Ty>,
814     pub pat: Gc<Pat>,
815     pub id: NodeId,
816 }
817
818 impl Arg {
819     pub fn new_self(span: Span, mutability: Mutability) -> Arg {
820         let path = ast_util::ident_to_path(span, special_idents::self_);
821         Arg {
822             // HACK(eddyb) fake type for the self argument.
823             ty: P(Ty {
824                 id: DUMMY_NODE_ID,
825                 node: TyInfer,
826                 span: DUMMY_SP,
827             }),
828             pat: box(GC) Pat {
829                 id: DUMMY_NODE_ID,
830                 node: PatIdent(BindByValue(mutability), path, None),
831                 span: span
832             },
833             id: DUMMY_NODE_ID
834         }
835     }
836 }
837
838 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
839 pub struct FnDecl {
840     pub inputs: Vec<Arg>,
841     pub output: P<Ty>,
842     pub cf: RetStyle,
843     pub variadic: bool
844 }
845
846 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
847 pub enum FnStyle {
848     UnsafeFn, // declared with "unsafe fn"
849     NormalFn, // declared with "fn"
850 }
851
852 impl fmt::Show for FnStyle {
853     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
854         match *self {
855             NormalFn => "normal".fmt(f),
856             UnsafeFn => "unsafe".fmt(f),
857         }
858     }
859 }
860
861 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
862 pub enum RetStyle {
863     NoReturn, // functions with return type _|_ that always
864               // raise an error or exit (i.e. never return to the caller)
865     Return, // everything else
866 }
867
868 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
869 pub enum ExplicitSelf_ {
870     SelfStatic,                                // no self
871     SelfValue,                                 // `self`
872     SelfRegion(Option<Lifetime>, Mutability),  // `&'lt self`, `&'lt mut self`
873     SelfUniq                                   // `~self`
874 }
875
876 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
877
878 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
879 pub struct Method {
880     pub ident: Ident,
881     pub attrs: Vec<Attribute>,
882     pub generics: Generics,
883     pub explicit_self: ExplicitSelf,
884     pub fn_style: FnStyle,
885     pub decl: P<FnDecl>,
886     pub body: P<Block>,
887     pub id: NodeId,
888     pub span: Span,
889     pub vis: Visibility,
890 }
891
892 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
893 pub struct Mod {
894     /// A span from the first token past `{` to the last token until `}`.
895     /// For `mod foo;`, the inner span ranges from the first token
896     /// to the last token in the external file.
897     pub inner: Span,
898     pub view_items: Vec<ViewItem>,
899     pub items: Vec<Gc<Item>>,
900 }
901
902 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
903 pub struct ForeignMod {
904     pub abi: Abi,
905     pub view_items: Vec<ViewItem>,
906     pub items: Vec<Gc<ForeignItem>>,
907 }
908
909 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
910 pub struct VariantArg {
911     pub ty: P<Ty>,
912     pub id: NodeId,
913 }
914
915 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
916 pub enum VariantKind {
917     TupleVariantKind(Vec<VariantArg>),
918     StructVariantKind(Gc<StructDef>),
919 }
920
921 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
922 pub struct EnumDef {
923     pub variants: Vec<P<Variant>>,
924 }
925
926 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
927 pub struct Variant_ {
928     pub name: Ident,
929     pub attrs: Vec<Attribute>,
930     pub kind: VariantKind,
931     pub id: NodeId,
932     pub disr_expr: Option<Gc<Expr>>,
933     pub vis: Visibility,
934 }
935
936 pub type Variant = Spanned<Variant_>;
937
938 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
939 pub struct PathListIdent_ {
940     pub name: Ident,
941     pub id: NodeId,
942 }
943
944 pub type PathListIdent = Spanned<PathListIdent_>;
945
946 pub type ViewPath = Spanned<ViewPath_>;
947
948 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
949 pub enum ViewPath_ {
950
951     // quux = foo::bar::baz
952     //
953     // or just
954     //
955     // foo::bar::baz  (with 'baz =' implicitly on the left)
956     ViewPathSimple(Ident, Path, NodeId),
957
958     // foo::bar::*
959     ViewPathGlob(Path, NodeId),
960
961     // foo::bar::{a,b,c}
962     ViewPathList(Path, Vec<PathListIdent> , NodeId)
963 }
964
965 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
966 pub struct ViewItem {
967     pub node: ViewItem_,
968     pub attrs: Vec<Attribute>,
969     pub vis: Visibility,
970     pub span: Span,
971 }
972
973 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
974 pub enum ViewItem_ {
975     // ident: name used to refer to this crate in the code
976     // optional (InternedString,StrStyle): if present, this is a location
977     // (containing arbitrary characters) from which to fetch the crate sources
978     // For example, extern crate whatever = "github.com/rust-lang/rust"
979     ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
980     ViewItemUse(Gc<ViewPath>),
981 }
982
983 // Meta-data associated with an item
984 pub type Attribute = Spanned<Attribute_>;
985
986 // Distinguishes between Attributes that decorate items and Attributes that
987 // are contained as statements within items. These two cases need to be
988 // distinguished for pretty-printing.
989 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
990 pub enum AttrStyle {
991     AttrOuter,
992     AttrInner,
993 }
994
995 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
996 pub struct AttrId(pub uint);
997
998 // doc-comments are promoted to attributes that have is_sugared_doc = true
999 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1000 pub struct Attribute_ {
1001     pub id: AttrId,
1002     pub style: AttrStyle,
1003     pub value: Gc<MetaItem>,
1004     pub is_sugared_doc: bool,
1005 }
1006
1007 /*
1008   TraitRef's appear in impls.
1009   resolve maps each TraitRef's ref_id to its defining trait; that's all
1010   that the ref_id is for. The impl_id maps to the "self type" of this impl.
1011   If this impl is an ItemImpl, the impl_id is redundant (it could be the
1012   same as the impl's node id).
1013  */
1014 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1015 pub struct TraitRef {
1016     pub path: Path,
1017     pub ref_id: NodeId,
1018 }
1019
1020 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1021 pub enum Visibility {
1022     Public,
1023     Inherited,
1024 }
1025
1026 impl Visibility {
1027     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1028         match self {
1029             &Inherited => parent_visibility,
1030             &Public => *self
1031         }
1032     }
1033 }
1034
1035 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1036 pub enum Sized {
1037     DynSize,
1038     StaticSize,
1039 }
1040
1041 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1042 pub struct StructField_ {
1043     pub kind: StructFieldKind,
1044     pub id: NodeId,
1045     pub ty: P<Ty>,
1046     pub attrs: Vec<Attribute>,
1047 }
1048
1049 impl StructField_ {
1050     pub fn ident(&self) -> Option<Ident> {
1051         match self.kind {
1052             NamedField(ref ident, _) => Some(ident.clone()),
1053             UnnamedField(_) => None
1054         }
1055     }
1056 }
1057
1058 pub type StructField = Spanned<StructField_>;
1059
1060 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1061 pub enum StructFieldKind {
1062     NamedField(Ident, Visibility),
1063     UnnamedField(Visibility), // element of a tuple-like struct
1064 }
1065
1066 impl StructFieldKind {
1067     pub fn is_unnamed(&self) -> bool {
1068         match *self {
1069             UnnamedField(..) => true,
1070             NamedField(..) => false,
1071         }
1072     }
1073 }
1074
1075 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1076 pub struct StructDef {
1077     pub fields: Vec<StructField>, /* fields, not including ctor */
1078     /* ID of the constructor. This is only used for tuple- or enum-like
1079      * structs. */
1080     pub ctor_id: Option<NodeId>,
1081     pub super_struct: Option<P<Ty>>, // Super struct, if specified.
1082     pub is_virtual: bool,            // True iff the struct may be inherited from.
1083 }
1084
1085 /*
1086   FIXME (#3300): Should allow items to be anonymous. Right now
1087   we just use dummy names for anon items.
1088  */
1089 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1090 pub struct Item {
1091     pub ident: Ident,
1092     pub attrs: Vec<Attribute>,
1093     pub id: NodeId,
1094     pub node: Item_,
1095     pub vis: Visibility,
1096     pub span: Span,
1097 }
1098
1099 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1100 pub enum Item_ {
1101     ItemStatic(P<Ty>, Mutability, Gc<Expr>),
1102     ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
1103     ItemMod(Mod),
1104     ItemForeignMod(ForeignMod),
1105     ItemTy(P<Ty>, Generics),
1106     ItemEnum(EnumDef, Generics),
1107     ItemStruct(Gc<StructDef>, Generics),
1108     ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
1109     ItemImpl(Generics,
1110              Option<TraitRef>, // (optional) trait this impl implements
1111              P<Ty>, // self
1112              Vec<Gc<Method>>),
1113     // a macro invocation (which includes macro definition)
1114     ItemMac(Mac),
1115 }
1116
1117 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1118 pub struct ForeignItem {
1119     pub ident: Ident,
1120     pub attrs: Vec<Attribute>,
1121     pub node: ForeignItem_,
1122     pub id: NodeId,
1123     pub span: Span,
1124     pub vis: Visibility,
1125 }
1126
1127 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1128 pub enum ForeignItem_ {
1129     ForeignItemFn(P<FnDecl>, Generics),
1130     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1131 }
1132
1133 // The data we save and restore about an inlined item or method.  This is not
1134 // part of the AST that we parse from a file, but it becomes part of the tree
1135 // that we trans.
1136 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1137 pub enum InlinedItem {
1138     IIItem(Gc<Item>),
1139     IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
1140     IIForeign(Gc<ForeignItem>),
1141 }
1142
1143 #[cfg(test)]
1144 mod test {
1145     use serialize::json;
1146     use serialize;
1147     use codemap::*;
1148     use super::*;
1149
1150     // are ASTs encodable?
1151     #[test]
1152     fn check_asts_encodable() {
1153         use std::io;
1154         let e = Crate {
1155             module: Mod {
1156                 inner: Span {
1157                     lo: BytePos(11),
1158                     hi: BytePos(19),
1159                     expn_info: None,
1160                 },
1161                 view_items: Vec::new(),
1162                 items: Vec::new(),
1163             },
1164             attrs: Vec::new(),
1165             config: Vec::new(),
1166             span: Span {
1167                 lo: BytePos(10),
1168                 hi: BytePos(20),
1169                 expn_info: None,
1170             },
1171         };
1172         // doesn't matter which encoder we use....
1173         let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
1174     }
1175 }