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