]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
auto merge of #8718 : bblum/rust/typeof, r=pcwalton
[rust.git] / src / libsyntax / ast.rs
1 // Copyright 2012 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};
14 use abi::AbiSet;
15 use opt_vec::OptVec;
16 use parse::token::{interner_get, str_to_ident};
17
18 use std::hashmap::HashMap;
19 use std::option::Option;
20 use std::to_str::ToStr;
21 use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
22
23 // an identifier contains a Name (index into the interner
24 // table) and a SyntaxContext to track renaming and
25 // macro expansion per Flatt et al., "Macros
26 // That Work Together"
27 #[deriving(Clone, Eq, IterBytes, ToStr)]
28 pub struct ident { name: Name, ctxt: SyntaxContext }
29
30 /// Construct an identifier with the given name and an empty context:
31 pub fn new_ident(name: Name) -> ident { ident {name: name, ctxt: empty_ctxt}}
32
33 /// A SyntaxContext represents a chain of macro-expandings
34 /// and renamings. Each macro expansion corresponds to
35 /// a fresh uint
36
37 // I'm representing this syntax context as an index into
38 // a table, in order to work around a compiler bug
39 // that's causing unreleased memory to cause core dumps
40 // and also perhaps to save some work in destructor checks.
41 // the special uint '0' will be used to indicate an empty
42 // syntax context.
43
44 // this uint is a reference to a table stored in thread-local
45 // storage.
46 pub type SyntaxContext = uint;
47
48 pub struct SCTable {
49     table : ~[SyntaxContext_],
50     mark_memo : HashMap<(SyntaxContext,Mrk),SyntaxContext>,
51     rename_memo : HashMap<(SyntaxContext,ident,Name),SyntaxContext>
52 }
53 // NB: these must be placed in any SCTable...
54 pub static empty_ctxt : uint = 0;
55 pub static illegal_ctxt : uint = 1;
56
57 #[deriving(Eq, Encodable, Decodable,IterBytes)]
58 pub enum SyntaxContext_ {
59     EmptyCtxt,
60     Mark (Mrk,SyntaxContext),
61     // flattening the name and syntaxcontext into the rename...
62     // HIDDEN INVARIANTS:
63     // 1) the first name in a Rename node
64     // can only be a programmer-supplied name.
65     // 2) Every Rename node with a given Name in the
66     // "to" slot must have the same name and context
67     // in the "from" slot. In essence, they're all
68     // pointers to a single "rename" event node.
69     Rename (ident,Name,SyntaxContext),
70     IllegalCtxt()
71 }
72
73 /// A name is a part of an identifier, representing a string or gensym. It's
74 /// the result of interning.
75 pub type Name = uint;
76 /// A mark represents a unique id associated with a macro expansion
77 pub type Mrk = uint;
78
79 impl<S:Encoder> Encodable<S> for ident {
80     fn encode(&self, s: &mut S) {
81         s.emit_str(interner_get(self.name));
82     }
83 }
84
85 #[deriving(IterBytes)]
86 impl<D:Decoder> Decodable<D> for ident {
87     fn decode(d: &mut D) -> ident {
88         str_to_ident(d.read_str())
89     }
90 }
91
92 /// Function name (not all functions have names)
93 pub type fn_ident = Option<ident>;
94
95 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
96 pub struct Lifetime {
97     id: NodeId,
98     span: span,
99     ident: ident
100 }
101
102 // a "Path" is essentially Rust's notion of a name;
103 // for instance: std::cmp::Eq  .  It's represented
104 // as a sequence of identifiers, along with a bunch
105 // of supporting information.
106 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
107 pub struct Path {
108     span: span,
109     /// A `::foo` path, is relative to the crate root rather than current
110     /// module (like paths in an import).
111     global: bool,
112     /// The segments in the path: the things separated by `::`.
113     segments: ~[PathSegment],
114 }
115
116 /// A segment of a path: an identifier, an optional lifetime, and a set of
117 /// types.
118 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
119 pub struct PathSegment {
120     /// The identifier portion of this path segment.
121     identifier: ident,
122     /// The lifetime parameter for this path segment. Currently only one
123     /// lifetime parameter is allowed.
124     lifetime: Option<Lifetime>,
125     /// The type parameters for this path segment, if present.
126     types: OptVec<Ty>,
127 }
128
129 pub type CrateNum = int;
130
131 pub type NodeId = int;
132
133 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes, ToStr)]
134 pub struct def_id {
135     crate: CrateNum,
136     node: NodeId,
137 }
138
139 pub static LOCAL_CRATE: CrateNum = 0;
140 pub static CRATE_NODE_ID: NodeId = 0;
141
142 // The AST represents all type param bounds as types.
143 // typeck::collect::compute_bounds matches these against
144 // the "special" built-in traits (see middle::lang_items) and
145 // detects Copy, Send, Send, and Freeze.
146 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
147 pub enum TyParamBound {
148     TraitTyParamBound(trait_ref),
149     RegionTyParamBound
150 }
151
152 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
153 pub struct TyParam {
154     ident: ident,
155     id: NodeId,
156     bounds: OptVec<TyParamBound>
157 }
158
159 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
160 pub struct Generics {
161     lifetimes: OptVec<Lifetime>,
162     ty_params: OptVec<TyParam>,
163 }
164
165 impl Generics {
166     pub fn is_parameterized(&self) -> bool {
167         self.lifetimes.len() + self.ty_params.len() > 0
168     }
169     pub fn is_lt_parameterized(&self) -> bool {
170         self.lifetimes.len() > 0
171     }
172     pub fn is_type_parameterized(&self) -> bool {
173         self.ty_params.len() > 0
174     }
175 }
176
177 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
178 pub enum MethodProvenance {
179     FromTrait(def_id),
180     FromImpl(def_id),
181 }
182
183 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
184 pub enum def {
185     def_fn(def_id, purity),
186     def_static_method(/* method */ def_id, MethodProvenance, purity),
187     def_self(NodeId),
188     def_self_ty(/* trait id */ NodeId),
189     def_mod(def_id),
190     def_foreign_mod(def_id),
191     def_static(def_id, bool /* is_mutbl */),
192     def_arg(NodeId, bool /* is_mutbl */),
193     def_local(NodeId, bool /* is_mutbl */),
194     def_variant(def_id /* enum */, def_id /* variant */),
195     def_ty(def_id),
196     def_trait(def_id),
197     def_prim_ty(prim_ty),
198     def_ty_param(def_id, uint),
199     def_binding(NodeId, binding_mode),
200     def_use(def_id),
201     def_upvar(NodeId,  // id of closed over var
202               @def,     // closed over def
203               NodeId,  // expr node that creates the closure
204               NodeId), // id for the block/body of the closure expr
205     def_struct(def_id),
206     def_typaram_binder(NodeId), /* struct, impl or trait with ty params */
207     def_region(NodeId),
208     def_label(NodeId),
209     def_method(def_id /* method */, Option<def_id> /* trait */),
210 }
211
212
213 // The set of MetaItems that define the compilation environment of the crate,
214 // used to drive conditional compilation
215 pub type CrateConfig = ~[@MetaItem];
216
217 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
218 pub struct Crate {
219     module: _mod,
220     attrs: ~[Attribute],
221     config: CrateConfig,
222     span: span,
223 }
224
225 pub type MetaItem = spanned<MetaItem_>;
226
227 #[deriving(Clone, Encodable, Decodable, IterBytes)]
228 pub enum MetaItem_ {
229     MetaWord(@str),
230     MetaList(@str, ~[@MetaItem]),
231     MetaNameValue(@str, lit),
232 }
233
234 // can't be derived because the MetaList requires an unordered comparison
235 impl Eq for MetaItem_ {
236     fn eq(&self, other: &MetaItem_) -> bool {
237         match *self {
238             MetaWord(ref ns) => match *other {
239                 MetaWord(ref no) => (*ns) == (*no),
240                 _ => false
241             },
242             MetaNameValue(ref ns, ref vs) => match *other {
243                 MetaNameValue(ref no, ref vo) => {
244                     (*ns) == (*no) && vs.node == vo.node
245                 }
246                 _ => false
247             },
248             MetaList(ref ns, ref miss) => match *other {
249                 MetaList(ref no, ref miso) => {
250                     ns == no &&
251                         miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
252                 }
253                 _ => false
254             }
255         }
256     }
257 }
258
259 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
260 pub struct Block {
261     view_items: ~[view_item],
262     stmts: ~[@stmt],
263     expr: Option<@expr>,
264     id: NodeId,
265     rules: BlockCheckMode,
266     span: span,
267 }
268
269 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
270 pub struct pat {
271     id: NodeId,
272     node: pat_,
273     span: span,
274 }
275
276 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
277 pub struct field_pat {
278     ident: ident,
279     pat: @pat,
280 }
281
282 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
283 pub enum binding_mode {
284     bind_by_ref(mutability),
285     bind_infer
286 }
287
288 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
289 pub enum pat_ {
290     pat_wild,
291     // A pat_ident may either be a new bound variable,
292     // or a nullary enum (in which case the second field
293     // is None).
294     // In the nullary enum case, the parser can't determine
295     // which it is. The resolver determines this, and
296     // records this pattern's NodeId in an auxiliary
297     // set (of "pat_idents that refer to nullary enums")
298     pat_ident(binding_mode, Path, Option<@pat>),
299     pat_enum(Path, Option<~[@pat]>), /* "none" means a * pattern where
300                                        * we don't bind the fields to names */
301     pat_struct(Path, ~[field_pat], bool),
302     pat_tup(~[@pat]),
303     pat_box(@pat),
304     pat_uniq(@pat),
305     pat_region(@pat), // borrowed pointer pattern
306     pat_lit(@expr),
307     pat_range(@expr, @expr),
308     // [a, b, ..i, y, z] is represented as
309     // pat_vec(~[a, b], Some(i), ~[y, z])
310     pat_vec(~[@pat], Option<@pat>, ~[@pat])
311 }
312
313 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
314 pub enum mutability {
315     m_mutbl,
316     m_imm,
317 }
318
319 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
320 pub enum Sigil {
321     BorrowedSigil,
322     OwnedSigil,
323     ManagedSigil
324 }
325
326 impl ToStr for Sigil {
327     fn to_str(&self) -> ~str {
328         match *self {
329             BorrowedSigil => ~"&",
330             OwnedSigil => ~"~",
331             ManagedSigil => ~"@"
332          }
333     }
334 }
335
336 #[deriving(Eq, Encodable, Decodable,IterBytes)]
337 pub enum vstore {
338     // FIXME (#3469): Change uint to @expr (actually only constant exprs)
339     vstore_fixed(Option<uint>),     // [1,2,3,4]
340     vstore_uniq,                    // ~[1,2,3,4]
341     vstore_box,                     // @[1,2,3,4]
342     vstore_slice(Option<Lifetime>) // &'foo? [1,2,3,4]
343 }
344
345 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
346 pub enum expr_vstore {
347     expr_vstore_uniq,                  // ~[1,2,3,4]
348     expr_vstore_box,                   // @[1,2,3,4]
349     expr_vstore_mut_box,               // @mut [1,2,3,4]
350     expr_vstore_slice,                 // &[1,2,3,4]
351     expr_vstore_mut_slice,             // &mut [1,2,3,4]
352 }
353
354 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
355 pub enum binop {
356     add,
357     subtract,
358     mul,
359     div,
360     rem,
361     and,
362     or,
363     bitxor,
364     bitand,
365     bitor,
366     shl,
367     shr,
368     eq,
369     lt,
370     le,
371     ne,
372     ge,
373     gt,
374 }
375
376 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
377 pub enum unop {
378     box(mutability),
379     uniq,
380     deref,
381     not,
382     neg
383 }
384
385 pub type stmt = spanned<stmt_>;
386
387 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
388 pub enum stmt_ {
389     // could be an item or a local (let) binding:
390     stmt_decl(@decl, NodeId),
391
392     // expr without trailing semi-colon (must have unit type):
393     stmt_expr(@expr, NodeId),
394
395     // expr with trailing semi-colon (may have any type):
396     stmt_semi(@expr, NodeId),
397
398     // bool: is there a trailing sem-colon?
399     stmt_mac(mac, bool),
400 }
401
402 // FIXME (pending discussion of #1697, #2178...): local should really be
403 // a refinement on pat.
404 #[deriving(Eq, Encodable, Decodable,IterBytes)]
405 pub struct Local {
406     is_mutbl: bool,
407     ty: Ty,
408     pat: @pat,
409     init: Option<@expr>,
410     id: NodeId,
411     span: span,
412 }
413
414 pub type decl = spanned<decl_>;
415
416 #[deriving(Eq, Encodable, Decodable,IterBytes)]
417 pub enum decl_ {
418     // a local (let) binding:
419     decl_local(@Local),
420     // an item binding:
421     decl_item(@item),
422 }
423
424 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
425 pub struct arm {
426     pats: ~[@pat],
427     guard: Option<@expr>,
428     body: Block,
429 }
430
431 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
432 pub struct Field {
433     ident: ident,
434     expr: @expr,
435     span: span,
436 }
437
438 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
439 pub enum BlockCheckMode {
440     DefaultBlock,
441     UnsafeBlock,
442 }
443
444 #[deriving(Eq, Encodable, Decodable,IterBytes)]
445 pub struct expr {
446     id: NodeId,
447     node: expr_,
448     span: span,
449 }
450
451 impl expr {
452     pub fn get_callee_id(&self) -> Option<NodeId> {
453         match self.node {
454             expr_method_call(callee_id, _, _, _, _, _) |
455             expr_index(callee_id, _, _) |
456             expr_binary(callee_id, _, _, _) |
457             expr_assign_op(callee_id, _, _, _) |
458             expr_unary(callee_id, _, _) => Some(callee_id),
459             _ => None,
460         }
461     }
462 }
463
464 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
465 pub enum CallSugar {
466     NoSugar,
467     DoSugar,
468     ForSugar
469 }
470
471 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
472 pub enum expr_ {
473     expr_vstore(@expr, expr_vstore),
474     expr_vec(~[@expr], mutability),
475     expr_call(@expr, ~[@expr], CallSugar),
476     expr_method_call(NodeId, @expr, ident, ~[Ty], ~[@expr], CallSugar),
477     expr_tup(~[@expr]),
478     expr_binary(NodeId, binop, @expr, @expr),
479     expr_unary(NodeId, unop, @expr),
480     expr_lit(@lit),
481     expr_cast(@expr, Ty),
482     expr_if(@expr, Block, Option<@expr>),
483     expr_while(@expr, Block),
484     expr_for_loop(@pat, @expr, Block),
485     /* Conditionless loop (can be exited with break, cont, or ret)
486        Same semantics as while(true) { body }, but typestate knows that the
487        (implicit) condition is always true. */
488     expr_loop(Block, Option<ident>),
489     expr_match(@expr, ~[arm]),
490     expr_fn_block(fn_decl, Block),
491     expr_do_body(@expr),
492     expr_block(Block),
493
494     expr_assign(@expr, @expr),
495     expr_assign_op(NodeId, binop, @expr, @expr),
496     expr_field(@expr, ident, ~[Ty]),
497     expr_index(NodeId, @expr, @expr),
498     expr_path(Path),
499
500     /// The special identifier `self`.
501     expr_self,
502     expr_addr_of(mutability, @expr),
503     expr_break(Option<ident>),
504     expr_again(Option<ident>),
505     expr_ret(Option<@expr>),
506     expr_log(@expr, @expr),
507
508     expr_inline_asm(inline_asm),
509
510     expr_mac(mac),
511
512     // A struct literal expression.
513     expr_struct(Path, ~[Field], Option<@expr> /* base */),
514
515     // A vector literal constructed from one repeated element.
516     expr_repeat(@expr /* element */, @expr /* count */, mutability),
517
518     // No-op: used solely so we can pretty-print faithfully
519     expr_paren(@expr)
520 }
521
522 // When the main rust parser encounters a syntax-extension invocation, it
523 // parses the arguments to the invocation as a token-tree. This is a very
524 // loose structure, such that all sorts of different AST-fragments can
525 // be passed to syntax extensions using a uniform type.
526 //
527 // If the syntax extension is an MBE macro, it will attempt to match its
528 // LHS "matchers" against the provided token tree, and if it finds a
529 // match, will transcribe the RHS token tree, splicing in any captured
530 // macro_parser::matched_nonterminals into the tt_nonterminals it finds.
531 //
532 // The RHS of an MBE macro is the only place a tt_nonterminal or tt_seq
533 // makes any real sense. You could write them elsewhere but nothing
534 // else knows what to do with them, so you'll probably get a syntax
535 // error.
536 //
537 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
538 #[doc="For macro invocations; parsing is delegated to the macro"]
539 pub enum token_tree {
540     // a single token
541     tt_tok(span, ::parse::token::Token),
542     // a delimited sequence (the delimiters appear as the first
543     // and last elements of the vector)
544     tt_delim(@mut ~[token_tree]),
545     // These only make sense for right-hand-sides of MBE macros:
546
547     // a kleene-style repetition sequence with a span, a tt_forest,
548     // an optional separator (?), and a boolean where true indicates
549     // zero or more (*), and false indicates one or more (+).
550     tt_seq(span, @mut ~[token_tree], Option<::parse::token::Token>, bool),
551
552     // a syntactic variable that will be filled in by macro expansion.
553     tt_nonterminal(span, ident)
554 }
555
556 //
557 // Matchers are nodes defined-by and recognized-by the main rust parser and
558 // language, but they're only ever found inside syntax-extension invocations;
559 // indeed, the only thing that ever _activates_ the rules in the rust parser
560 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
561 // itself. Matchers represent a small sub-language for pattern-matching
562 // token-trees, and are thus primarily used by the macro-defining extension
563 // itself.
564 //
565 // match_tok
566 // ---------
567 //
568 //     A matcher that matches a single token, denoted by the token itself. So
569 //     long as there's no $ involved.
570 //
571 //
572 // match_seq
573 // ---------
574 //
575 //     A matcher that matches a sequence of sub-matchers, denoted various
576 //     possible ways:
577 //
578 //             $(M)*       zero or more Ms
579 //             $(M)+       one or more Ms
580 //             $(M),+      one or more comma-separated Ms
581 //             $(A B C);*  zero or more semi-separated 'A B C' seqs
582 //
583 //
584 // match_nonterminal
585 // -----------------
586 //
587 //     A matcher that matches one of a few interesting named rust
588 //     nonterminals, such as types, expressions, items, or raw token-trees. A
589 //     black-box matcher on expr, for example, binds an expr to a given ident,
590 //     and that ident can re-occur as an interpolation in the RHS of a
591 //     macro-by-example rule. For example:
592 //
593 //        $foo:expr   =>     1 + $foo    // interpolate an expr
594 //        $foo:tt     =>     $foo        // interpolate a token-tree
595 //        $foo:tt     =>     bar! $foo   // only other valid interpolation
596 //                                       // is in arg position for another
597 //                                       // macro
598 //
599 // As a final, horrifying aside, note that macro-by-example's input is
600 // also matched by one of these matchers. Holy self-referential! It is matched
601 // by an match_seq, specifically this one:
602 //
603 //                   $( $lhs:matchers => $rhs:tt );+
604 //
605 // If you understand that, you have closed to loop and understand the whole
606 // macro system. Congratulations.
607 //
608 pub type matcher = spanned<matcher_>;
609
610 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
611 pub enum matcher_ {
612     // match one token
613     match_tok(::parse::token::Token),
614     // match repetitions of a sequence: body, separator, zero ok?,
615     // lo, hi position-in-match-array used:
616     match_seq(~[matcher], Option<::parse::token::Token>, bool, uint, uint),
617     // parse a Rust NT: name to bind, name of NT, position in match array:
618     match_nonterminal(ident, ident, uint)
619 }
620
621 pub type mac = spanned<mac_>;
622
623 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
624 pub enum mac_ {
625     mac_invoc_tt(Path,~[token_tree]),   // new macro-invocation
626 }
627
628 pub type lit = spanned<lit_>;
629
630 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
631 pub enum lit_ {
632     lit_str(@str),
633     lit_int(i64, int_ty),
634     lit_uint(u64, uint_ty),
635     lit_int_unsuffixed(i64),
636     lit_float(@str, float_ty),
637     lit_float_unsuffixed(@str),
638     lit_nil,
639     lit_bool(bool),
640 }
641
642 // NB: If you change this, you'll probably want to change the corresponding
643 // type structure in middle/ty.rs as well.
644 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
645 pub struct mt {
646     ty: ~Ty,
647     mutbl: mutability,
648 }
649
650 #[deriving(Eq, Encodable, Decodable,IterBytes)]
651 pub struct TypeField {
652     ident: ident,
653     mt: mt,
654     span: span,
655 }
656
657 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
658 pub struct TypeMethod {
659     ident: ident,
660     attrs: ~[Attribute],
661     purity: purity,
662     decl: fn_decl,
663     generics: Generics,
664     explicit_self: explicit_self,
665     id: NodeId,
666     span: span,
667 }
668
669 // A trait method is either required (meaning it doesn't have an
670 // implementation, just a signature) or provided (meaning it has a default
671 // implementation).
672 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
673 pub enum trait_method {
674     required(TypeMethod),
675     provided(@method),
676 }
677
678 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
679 pub enum int_ty {
680     ty_i,
681     ty_char,
682     ty_i8,
683     ty_i16,
684     ty_i32,
685     ty_i64,
686 }
687
688 impl ToStr for int_ty {
689     fn to_str(&self) -> ~str {
690         ::ast_util::int_ty_to_str(*self)
691     }
692 }
693
694 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
695 pub enum uint_ty {
696     ty_u,
697     ty_u8,
698     ty_u16,
699     ty_u32,
700     ty_u64,
701 }
702
703 impl ToStr for uint_ty {
704     fn to_str(&self) -> ~str {
705         ::ast_util::uint_ty_to_str(*self)
706     }
707 }
708
709 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
710 pub enum float_ty {
711     ty_f,
712     ty_f32,
713     ty_f64,
714 }
715
716 impl ToStr for float_ty {
717     fn to_str(&self) -> ~str {
718         ::ast_util::float_ty_to_str(*self)
719     }
720 }
721
722 // NB Eq method appears below.
723 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
724 pub struct Ty {
725     id: NodeId,
726     node: ty_,
727     span: span,
728 }
729
730 // Not represented directly in the AST, referred to by name through a ty_path.
731 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
732 pub enum prim_ty {
733     ty_int(int_ty),
734     ty_uint(uint_ty),
735     ty_float(float_ty),
736     ty_str,
737     ty_bool,
738 }
739
740 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
741 pub enum Onceness {
742     Once,
743     Many
744 }
745
746 #[deriving(IterBytes)]
747 impl ToStr for Onceness {
748     fn to_str(&self) -> ~str {
749         match *self {
750             Once => ~"once",
751             Many => ~"many"
752         }
753     }
754 }
755
756 #[deriving(Eq, Encodable, Decodable,IterBytes)]
757 pub struct TyClosure {
758     sigil: Sigil,
759     region: Option<Lifetime>,
760     lifetimes: OptVec<Lifetime>,
761     purity: purity,
762     onceness: Onceness,
763     decl: fn_decl,
764     // Optional optvec distinguishes between "fn()" and "fn:()" so we can
765     // implement issue #7264. None means "fn()", which means infer a default
766     // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
767     // which means use no bounds (e.g., not even Owned on a ~fn()).
768     bounds: Option<OptVec<TyParamBound>>,
769 }
770
771 #[deriving(Eq, Encodable, Decodable,IterBytes)]
772 pub struct TyBareFn {
773     purity: purity,
774     abis: AbiSet,
775     lifetimes: OptVec<Lifetime>,
776     decl: fn_decl
777 }
778
779 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
780 pub enum ty_ {
781     ty_nil,
782     ty_bot, /* bottom type */
783     ty_box(mt),
784     ty_uniq(mt),
785     ty_vec(mt),
786     ty_fixed_length_vec(mt, @expr),
787     ty_ptr(mt),
788     ty_rptr(Option<Lifetime>, mt),
789     ty_closure(@TyClosure),
790     ty_bare_fn(@TyBareFn),
791     ty_tup(~[Ty]),
792     ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
793     ty_mac(mac),
794     ty_typeof(@expr),
795     // ty_infer means the type should be inferred instead of it having been
796     // specified. This should only appear at the "top level" of a type and not
797     // nested in one.
798     ty_infer,
799 }
800
801 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
802 pub enum asm_dialect {
803     asm_att,
804     asm_intel
805 }
806
807 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
808 pub struct inline_asm {
809     asm: @str,
810     clobbers: @str,
811     inputs: ~[(@str, @expr)],
812     outputs: ~[(@str, @expr)],
813     volatile: bool,
814     alignstack: bool,
815     dialect: asm_dialect
816 }
817
818 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
819 pub struct arg {
820     is_mutbl: bool,
821     ty: Ty,
822     pat: @pat,
823     id: NodeId,
824 }
825
826 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
827 pub struct fn_decl {
828     inputs: ~[arg],
829     output: Ty,
830     cf: ret_style,
831 }
832
833 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
834 pub enum purity {
835     unsafe_fn, // declared with "unsafe fn"
836     impure_fn, // declared with "fn"
837     extern_fn, // declared with "extern fn"
838 }
839
840 #[deriving(IterBytes)]
841 impl ToStr for purity {
842     fn to_str(&self) -> ~str {
843         match *self {
844             impure_fn => ~"impure",
845             unsafe_fn => ~"unsafe",
846             extern_fn => ~"extern"
847         }
848     }
849 }
850
851 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
852 pub enum ret_style {
853     noreturn, // functions with return type _|_ that always
854               // raise an error or exit (i.e. never return to the caller)
855     return_val, // everything else
856 }
857
858 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
859 pub enum explicit_self_ {
860     sty_static,                                // no self
861     sty_value,                                 // `self`
862     sty_region(Option<Lifetime>, mutability), // `&'lt self`
863     sty_box(mutability),                       // `@self`
864     sty_uniq                                   // `~self`
865 }
866
867 pub type explicit_self = spanned<explicit_self_>;
868
869 #[deriving(Eq, Encodable, Decodable,IterBytes)]
870 pub struct method {
871     ident: ident,
872     attrs: ~[Attribute],
873     generics: Generics,
874     explicit_self: explicit_self,
875     purity: purity,
876     decl: fn_decl,
877     body: Block,
878     id: NodeId,
879     span: span,
880     self_id: NodeId,
881     vis: visibility,
882 }
883
884 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
885 pub struct _mod {
886     view_items: ~[view_item],
887     items: ~[@item],
888 }
889
890 // Foreign mods can be named or anonymous
891 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
892 pub enum foreign_mod_sort {
893     named,
894     anonymous,
895 }
896
897 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
898 pub struct foreign_mod {
899     sort: foreign_mod_sort,
900     abis: AbiSet,
901     view_items: ~[view_item],
902     items: ~[@foreign_item],
903 }
904
905 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
906 pub struct variant_arg {
907     ty: Ty,
908     id: NodeId,
909 }
910
911 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
912 pub enum variant_kind {
913     tuple_variant_kind(~[variant_arg]),
914     struct_variant_kind(@struct_def),
915 }
916
917 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
918 pub struct enum_def {
919     variants: ~[variant],
920 }
921
922 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
923 pub struct variant_ {
924     name: ident,
925     attrs: ~[Attribute],
926     kind: variant_kind,
927     id: NodeId,
928     disr_expr: Option<@expr>,
929     vis: visibility,
930 }
931
932 pub type variant = spanned<variant_>;
933
934 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
935 pub struct path_list_ident_ {
936     name: ident,
937     id: NodeId,
938 }
939
940 pub type path_list_ident = spanned<path_list_ident_>;
941
942 pub type view_path = spanned<view_path_>;
943
944 #[deriving(Eq, Encodable, Decodable, IterBytes)]
945 pub enum view_path_ {
946
947     // quux = foo::bar::baz
948     //
949     // or just
950     //
951     // foo::bar::baz  (with 'baz =' implicitly on the left)
952     view_path_simple(ident, Path, NodeId),
953
954     // foo::bar::*
955     view_path_glob(Path, NodeId),
956
957     // foo::bar::{a,b,c}
958     view_path_list(Path, ~[path_list_ident], NodeId)
959 }
960
961 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
962 pub struct view_item {
963     node: view_item_,
964     attrs: ~[Attribute],
965     vis: visibility,
966     span: span,
967 }
968
969 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
970 pub enum view_item_ {
971     // ident: name used to refer to this crate in the code
972     // optional @str: if present, this is a location (containing
973     // arbitrary characters) from which to fetch the crate sources
974     // For example, extern mod whatever = "github.com/mozilla/rust"
975     view_item_extern_mod(ident, Option<@str>, ~[@MetaItem], NodeId),
976     view_item_use(~[@view_path]),
977 }
978
979 // Meta-data associated with an item
980 pub type Attribute = spanned<Attribute_>;
981
982 // Distinguishes between Attributes that decorate items and Attributes that
983 // are contained as statements within items. These two cases need to be
984 // distinguished for pretty-printing.
985 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
986 pub enum AttrStyle {
987     AttrOuter,
988     AttrInner,
989 }
990
991 // doc-comments are promoted to attributes that have is_sugared_doc = true
992 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
993 pub struct Attribute_ {
994     style: AttrStyle,
995     value: @MetaItem,
996     is_sugared_doc: bool,
997 }
998
999 /*
1000   trait_refs appear in impls.
1001   resolve maps each trait_ref's ref_id to its defining trait; that's all
1002   that the ref_id is for. The impl_id maps to the "self type" of this impl.
1003   If this impl is an item_impl, the impl_id is redundant (it could be the
1004   same as the impl's node id).
1005  */
1006 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1007 pub struct trait_ref {
1008     path: Path,
1009     ref_id: NodeId,
1010 }
1011
1012 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1013 pub enum visibility {
1014     public,
1015     private,
1016     inherited,
1017 }
1018
1019 impl visibility {
1020     pub fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1021         match self {
1022             &inherited => parent_visibility,
1023             &public | &private => *self
1024         }
1025     }
1026 }
1027
1028 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1029 pub struct struct_field_ {
1030     kind: struct_field_kind,
1031     id: NodeId,
1032     ty: Ty,
1033     attrs: ~[Attribute],
1034 }
1035
1036 pub type struct_field = spanned<struct_field_>;
1037
1038 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1039 pub enum struct_field_kind {
1040     named_field(ident, visibility),
1041     unnamed_field   // element of a tuple-like struct
1042 }
1043
1044 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1045 pub struct struct_def {
1046     fields: ~[@struct_field], /* fields, not including ctor */
1047     /* ID of the constructor. This is only used for tuple- or enum-like
1048      * structs. */
1049     ctor_id: Option<NodeId>
1050 }
1051
1052 /*
1053   FIXME (#3300): Should allow items to be anonymous. Right now
1054   we just use dummy names for anon items.
1055  */
1056 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1057 pub struct item {
1058     ident: ident,
1059     attrs: ~[Attribute],
1060     id: NodeId,
1061     node: item_,
1062     vis: visibility,
1063     span: span,
1064 }
1065
1066 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1067 pub enum item_ {
1068     item_static(Ty, mutability, @expr),
1069     item_fn(fn_decl, purity, AbiSet, Generics, Block),
1070     item_mod(_mod),
1071     item_foreign_mod(foreign_mod),
1072     item_ty(Ty, Generics),
1073     item_enum(enum_def, Generics),
1074     item_struct(@struct_def, Generics),
1075     item_trait(Generics, ~[trait_ref], ~[trait_method]),
1076     item_impl(Generics,
1077               Option<trait_ref>, // (optional) trait this impl implements
1078               Ty, // self
1079               ~[@method]),
1080     // a macro invocation (which includes macro definition)
1081     item_mac(mac),
1082 }
1083
1084 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1085 pub struct foreign_item {
1086     ident: ident,
1087     attrs: ~[Attribute],
1088     node: foreign_item_,
1089     id: NodeId,
1090     span: span,
1091     vis: visibility,
1092 }
1093
1094 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1095 pub enum foreign_item_ {
1096     foreign_item_fn(fn_decl, Generics),
1097     foreign_item_static(Ty, /* is_mutbl */ bool),
1098 }
1099
1100 // The data we save and restore about an inlined item or method.  This is not
1101 // part of the AST that we parse from a file, but it becomes part of the tree
1102 // that we trans.
1103 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1104 pub enum inlined_item {
1105     ii_item(@item),
1106     ii_method(def_id /* impl id */, bool /* is provided */, @method),
1107     ii_foreign(@foreign_item),
1108 }
1109
1110 /* hold off on tests ... they appear in a later merge.
1111 #[cfg(test)]
1112 mod test {
1113     use std::option::{None, Option, Some};
1114     use std::uint;
1115     use extra;
1116     use codemap::*;
1117     use super::*;
1118
1119
1120     #[test] fn xorpush_test () {
1121         let mut s = ~[];
1122         xorPush(&mut s,14);
1123         assert_eq!(s,~[14]);
1124         xorPush(&mut s,14);
1125         assert_eq!(s,~[]);
1126         xorPush(&mut s,14);
1127         assert_eq!(s,~[14]);
1128         xorPush(&mut s,15);
1129         assert_eq!(s,~[14,15]);
1130         xorPush (&mut s,16);
1131         assert_eq! (s,~[14,15,16]);
1132         xorPush (&mut s,16);
1133         assert_eq! (s,~[14,15]);
1134         xorPush (&mut s,15);
1135         assert_eq! (s,~[14]);
1136     }
1137
1138     #[test] fn test_marksof () {
1139         let stopname = uints_to_name(&~[12,14,78]);
1140         assert_eq!(s,~[]);
1141         xorPush(&mut s,14);
1142         assert_eq!(s,~[14]);
1143         xorPush(&mut s,15);
1144         assert_eq!(s,~[14,15]);
1145         xorPush (&mut s,16);
1146         assert_eq! (s,~[14,15,16]);
1147         xorPush (&mut s,16);
1148         assert_eq! (s,~[14,15]);
1149         xorPush (&mut s,15);
1150         assert_eq! (s,~[14]);
1151     }
1152
1153     #[test] fn test_marksof () {
1154         let stopname = uints_to_name(&~[12,14,78]);
1155         let name1 = uints_to_name(&~[4,9,7]);
1156         assert_eq!(marksof (MT,stopname),~[]);
1157         assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1158         // does xoring work?
1159         assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1160                      ~[16]);
1161         // does nested xoring work?
1162         assert_eq! (marksof (Mark (5,
1163                                     @Mark (10,
1164                                            @Mark (10,
1165                                                   @Mark (5,
1166                                                          @Mark (16,@MT))))),
1167                               stopname),
1168                      ~[16]);
1169         // stop has no effect on marks
1170         assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1171                      ~[9,14,12]);
1172         // rename where stop doesn't match:
1173         assert_eq! (marksof (Mark (9, @Rename
1174                                     (name1,
1175                                      @Mark (4, @MT),
1176                                      uints_to_name(&~[100,101,102]),
1177                                      @Mark (14, @MT))),
1178                               stopname),
1179                      ~[9,14]);
1180         // rename where stop does match
1181         ;
1182         assert_eq! (marksof (Mark(9, @Rename (name1,
1183                                                @Mark (4, @MT),
1184                                                stopname,
1185                                                @Mark (14, @MT))),
1186                               stopname),
1187                      ~[9]);
1188     }
1189
1190     // are ASTs encodable?
1191     #[test] fn check_asts_encodable() {
1192         let bogus_span = span {lo:BytePos(10),
1193                                hi:BytePos(20),
1194                                expn_info:None};
1195         let e : crate =
1196             spanned{
1197             node: crate_{
1198                 module: _mod {view_items: ~[], items: ~[]},
1199                 attrs: ~[],
1200                 config: ~[]
1201             },
1202             span: bogus_span};
1203         // doesn't matter which encoder we use....
1204         let _f = (@e as @extra::serialize::Encodable<extra::json::Encoder>);
1205     }
1206
1207
1208 }
1209
1210 */
1211 //
1212 // Local Variables:
1213 // mode: rust
1214 // fill-column: 78;
1215 // indent-tabs-mode: nil
1216 // c-basic-offset: 4
1217 // buffer-file-coding-system: utf-8-unix
1218 // End:
1219 //