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