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.
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.
11 // The Rust abstract syntax tree.
13 use codemap::{span, spanned};
16 use parse::token::{interner_get, str_to_ident};
18 use std::hashmap::HashMap;
19 use std::option::Option;
20 use std::to_str::ToStr;
21 use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
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 }
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}}
33 /// A SyntaxContext represents a chain of macro-expandings
34 /// and renamings. Each macro expansion corresponds to
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
44 // this uint is a reference to a table stored in thread-local
46 pub type SyntaxContext = uint;
49 table : ~[SyntaxContext_],
50 mark_memo : HashMap<(SyntaxContext,Mrk),SyntaxContext>,
51 rename_memo : HashMap<(SyntaxContext,ident,Name),SyntaxContext>
53 // NB: these must be placed in any SCTable...
54 pub static empty_ctxt : uint = 0;
55 pub static illegal_ctxt : uint = 1;
57 #[deriving(Eq, Encodable, Decodable,IterBytes)]
58 pub enum SyntaxContext_ {
60 Mark (Mrk,SyntaxContext),
61 // flattening the name and syntaxcontext into the rename...
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),
73 /// A name is a part of an identifier, representing a string or gensym. It's
74 /// the result of interning.
76 /// A mark represents a unique id associated with a macro expansion
79 impl<S:Encoder> Encodable<S> for ident {
80 fn encode(&self, s: &mut S) {
81 s.emit_str(interner_get(self.name));
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())
92 /// Function name (not all functions have names)
93 pub type fn_ident = Option<ident>;
95 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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)]
109 /// A `::foo` path, is relative to the crate root rather than current
110 /// module (like paths in an import).
112 /// The segments in the path (the things separated by ::)
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>`
120 pub type CrateNum = int;
122 pub type node_id = int;
124 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
130 pub static local_crate: CrateNum = 0;
131 pub static crate_node_id: node_id = 0;
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),
143 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
147 bounds: OptVec<TyParamBound>
150 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
151 pub struct Generics {
152 lifetimes: OptVec<Lifetime>,
153 ty_params: OptVec<TyParam>,
157 pub fn is_parameterized(&self) -> bool {
158 self.lifetimes.len() + self.ty_params.len() > 0
160 pub fn is_lt_parameterized(&self) -> bool {
161 self.lifetimes.len() > 0
163 pub fn is_type_parameterized(&self) -> bool {
164 self.ty_params.len() > 0
168 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
170 def_fn(def_id, purity),
171 def_static_method(/* method */ def_id,
172 /* trait */ Option<def_id>,
174 def_self(node_id, bool /* is_implicit */),
175 def_self_ty(/* trait id */ node_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 */),
184 def_prim_ty(prim_ty),
185 def_ty_param(def_id, uint),
186 def_binding(node_id, binding_mode),
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
193 def_typaram_binder(node_id), /* struct, impl or trait with ty params */
196 def_method(def_id /* method */, Option<def_id> /* trait */),
200 // The set of MetaItems that define the compilation environment of the crate,
201 // used to drive conditional compilation
202 pub type CrateConfig = ~[@MetaItem];
204 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
212 pub type MetaItem = spanned<MetaItem_>;
214 #[deriving(Clone, Encodable, Decodable, IterBytes)]
217 MetaList(@str, ~[@MetaItem]),
218 MetaNameValue(@str, lit),
221 // can't be derived because the MetaList requires an unordered comparison
222 impl Eq for MetaItem_ {
223 fn eq(&self, other: &MetaItem_) -> bool {
225 MetaWord(ref ns) => match *other {
226 MetaWord(ref no) => (*ns) == (*no),
229 MetaNameValue(ref ns, ref vs) => match *other {
230 MetaNameValue(ref no, ref vo) => {
231 (*ns) == (*no) && vs.node == vo.node
235 MetaList(ref ns, ref miss) => match *other {
236 MetaList(ref no, ref miso) => {
238 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
246 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
248 view_items: ~[view_item],
252 rules: blk_check_mode,
256 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
263 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
264 pub struct field_pat {
269 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
270 pub enum binding_mode {
271 bind_by_ref(mutability),
275 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
278 // A pat_ident may either be a new bound variable,
279 // or a nullary enum (in which case the second field
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),
292 pat_region(@pat), // borrowed pointer pattern
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])
300 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
301 pub enum mutability { m_mutbl, m_imm, m_const, }
303 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
310 impl ToStr for Sigil {
311 fn to_str(&self) -> ~str {
313 BorrowedSigil => ~"&",
320 #[deriving(Eq, Encodable, Decodable,IterBytes)]
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]
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]
338 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
360 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
369 pub type stmt = spanned<stmt_>;
371 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
373 // could be an item or a local (let) binding:
374 stmt_decl(@decl, node_id),
376 // expr without trailing semi-colon (must have unit type):
377 stmt_expr(@expr, node_id),
379 // expr with trailing semi-colon (may have any type):
380 stmt_semi(@expr, node_id),
382 // bool: is there a trailing sem-colon?
386 // FIXME (pending discussion of #1697, #2178...): local should really be
387 // a refinement on pat.
388 #[deriving(Eq, Encodable, Decodable,IterBytes)]
398 pub type decl = spanned<decl_>;
400 #[deriving(Eq, Encodable, Decodable,IterBytes)]
402 // a local (let) binding:
408 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
411 guard: Option<@expr>,
415 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
422 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
423 pub enum blk_check_mode {
428 #[deriving(Eq, Encodable, Decodable,IterBytes)]
436 pub fn get_callee_id(&self) -> Option<node_id> {
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),
448 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
455 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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),
462 expr_binary(node_id, binop, @expr, @expr),
463 expr_unary(node_id, unop, @expr),
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
477 expr_loop_body(@expr),
478 // Like expr_loop_body but for 'do' blocks
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),
488 /// The special identifier `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),
496 expr_inline_asm(inline_asm),
500 // A struct literal expression.
501 expr_struct(Path, ~[Field], Option<@expr>),
503 // A vector literal constructed from one repeated element.
504 expr_repeat(@expr /* element */, @expr /* count */, mutability),
506 // No-op: used solely so we can pretty-print faithfully
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.
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.
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
525 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
526 #[doc="For macro invocations; parsing is delegated to the macro"]
527 pub enum token_tree {
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:
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),
540 // a syntactic variable that will be filled in by macro expansion.
541 tt_nonterminal(span, ident)
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
556 // A matcher that matches a single token, denoted by the token itself. So
557 // long as there's no $ involved.
563 // A matcher that matches a sequence of sub-matchers, denoted various
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
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:
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
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:
591 // $( $lhs:matchers => $rhs:tt );+
593 // If you understand that, you have closed to loop and understand the whole
594 // macro system. Congratulations.
596 pub type matcher = spanned<matcher_>;
598 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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)
609 pub type mac = spanned<mac_>;
611 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
613 mac_invoc_tt(Path,~[token_tree]), // new macro-invocation
616 pub type lit = spanned<lit_>;
618 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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),
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)]
638 #[deriving(Eq, Encodable, Decodable,IterBytes)]
639 pub struct ty_field_ {
644 pub type ty_field = spanned<ty_field_>;
646 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
647 pub struct ty_method {
653 explicit_self: explicit_self,
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
661 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
662 pub enum trait_method {
667 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
677 impl ToStr for int_ty {
678 fn to_str(&self) -> ~str {
679 ::ast_util::int_ty_to_str(*self)
683 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
692 impl ToStr for uint_ty {
693 fn to_str(&self) -> ~str {
694 ::ast_util::uint_ty_to_str(*self)
698 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
705 impl ToStr for float_ty {
706 fn to_str(&self) -> ~str {
707 ::ast_util::float_ty_to_str(*self)
711 // NB Eq method appears below.
712 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
719 // Not represented directly in the AST, referred to by name through a ty_path.
720 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
729 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
735 #[deriving(IterBytes)]
736 impl ToStr for Onceness {
737 fn to_str(&self) -> ~str {
745 #[deriving(Eq, Encodable, Decodable,IterBytes)]
746 pub struct TyClosure {
748 region: Option<Lifetime>,
749 lifetimes: OptVec<Lifetime>,
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>>,
760 #[deriving(Eq, Encodable, Decodable,IterBytes)]
761 pub struct TyBareFn {
764 lifetimes: OptVec<Lifetime>,
768 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
771 ty_bot, /* bottom type */
775 ty_fixed_length_vec(mt, @expr),
777 ty_rptr(Option<Lifetime>, mt),
778 ty_closure(@TyClosure),
779 ty_bare_fn(@TyBareFn),
781 ty_path(Path, Option<OptVec<TyParamBound>>, node_id), // for #7264; see above
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
789 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
790 pub enum asm_dialect {
795 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
796 pub struct inline_asm {
799 inputs: ~[(@str, @expr)],
800 outputs: ~[(@str, @expr)],
806 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
814 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
821 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
823 unsafe_fn, // declared with "unsafe fn"
824 impure_fn, // declared with "fn"
825 extern_fn, // declared with "extern fn"
828 #[deriving(IterBytes)]
829 impl ToStr for purity {
830 fn to_str(&self) -> ~str {
832 impure_fn => ~"impure",
833 unsafe_fn => ~"unsafe",
834 extern_fn => ~"extern"
839 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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
846 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
847 pub enum explicit_self_ {
848 sty_static, // no self
850 sty_region(Option<Lifetime>, mutability), // `&'lt self`
851 sty_box(mutability), // `@self`
855 pub type explicit_self = spanned<explicit_self_>;
857 #[deriving(Eq, Encodable, Decodable,IterBytes)]
862 explicit_self: explicit_self,
872 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
874 view_items: ~[view_item],
878 // Foreign mods can be named or anonymous
879 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
880 pub enum foreign_mod_sort {
885 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
886 pub struct foreign_mod {
887 sort: foreign_mod_sort,
889 view_items: ~[view_item],
890 items: ~[@foreign_item],
893 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
894 pub struct variant_arg {
899 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
900 pub enum variant_kind {
901 tuple_variant_kind(~[variant_arg]),
902 struct_variant_kind(@struct_def),
905 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
906 pub struct enum_def {
907 variants: ~[variant],
910 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
911 pub struct variant_ {
916 disr_expr: Option<@expr>,
920 pub type variant = spanned<variant_>;
922 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
923 pub struct path_list_ident_ {
928 pub type path_list_ident = spanned<path_list_ident_>;
930 pub type view_path = spanned<view_path_>;
932 #[deriving(Eq, Encodable, Decodable, IterBytes)]
933 pub enum view_path_ {
935 // quux = foo::bar::baz
939 // foo::bar::baz (with 'baz =' implicitly on the left)
940 view_path_simple(ident, Path, node_id),
943 view_path_glob(Path, node_id),
946 view_path_list(Path, ~[path_list_ident], node_id)
949 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
950 pub struct view_item {
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]),
963 // Meta-data associated with an item
964 pub type Attribute = spanned<Attribute_>;
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)]
975 // doc-comments are promoted to attributes that have is_sugared_doc = true
976 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
977 pub struct Attribute_ {
980 is_sugared_doc: bool,
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).
990 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
991 pub struct trait_ref {
996 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
997 pub enum visibility {
1004 pub fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1006 &inherited => parent_visibility,
1007 &public | &private => *self
1012 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1013 pub struct struct_field_ {
1014 kind: struct_field_kind,
1017 attrs: ~[Attribute],
1020 pub type struct_field = spanned<struct_field_>;
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
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
1033 ctor_id: Option<node_id>
1037 FIXME (#3300): Should allow items to be anonymous. Right now
1038 we just use dummy names for anon items.
1040 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1043 attrs: ~[Attribute],
1050 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1052 item_static(Ty, mutability, @expr),
1053 item_fn(fn_decl, purity, AbiSet, Generics, Block),
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]),
1061 Option<trait_ref>, // (optional) trait this impl implements
1064 // a macro invocation (which includes macro definition)
1068 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1069 pub struct foreign_item {
1071 attrs: ~[Attribute],
1072 node: foreign_item_,
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),
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
1087 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1088 pub enum inlined_item {
1090 ii_method(def_id /* impl id */, bool /* is provided */, @method),
1091 ii_foreign(@foreign_item),
1094 /* hold off on tests ... they appear in a later merge.
1097 use core::option::{None, Option, Some};
1104 #[test] fn xorpush_test () {
1107 assert_eq!(s,~[14]);
1111 assert_eq!(s,~[14]);
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]);
1122 #[test] fn test_marksof () {
1123 let stopname = uints_to_name(&~[12,14,78]);
1126 assert_eq!(s,~[14]);
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]);
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),
1145 // does nested xoring work?
1146 assert_eq! (marksof (Mark (5,
1153 // stop has no effect on marks
1154 assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1156 // rename where stop doesn't match:
1157 assert_eq! (marksof (Mark (9, @Rename
1160 uints_to_name(&~[100,101,102]),
1164 // rename where stop does match
1166 assert_eq! (marksof (Mark(9, @Rename (name1,
1174 // are ASTs encodable?
1175 #[test] fn check_asts_encodable() {
1176 let bogus_span = span {lo:BytePos(10),
1182 module: _mod {view_items: ~[], items: ~[]},
1187 // doesn't matter which encoder we use....
1188 let _f = (@e as @extra::serialize::Encodable<extra::json::Encoder>);
1199 // indent-tabs-mode: nil
1200 // c-basic-offset: 4
1201 // buffer-file-coding-system: utf-8-unix