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