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, ToStr)]
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: std::cmp::Eq . It's represented
104 // as a sequence of identifiers, along with a bunch
105 // of supporting information.
106 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
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 `::`.
113 segments: ~[PathSegment],
116 /// A segment of a path: an identifier, an optional lifetime, and a set of
118 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
119 pub struct PathSegment {
120 /// The identifier portion of this path segment.
122 /// The lifetime parameter for this path segment. Currently only one
123 /// lifetime parameter is allowed.
124 lifetime: Option<Lifetime>,
125 /// The type parameters for this path segment, if present.
129 pub type CrateNum = int;
131 pub type NodeId = int;
133 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes, ToStr)]
139 pub static LOCAL_CRATE: CrateNum = 0;
140 pub static CRATE_NODE_ID: NodeId = 0;
142 // The AST represents all type param bounds as types.
143 // typeck::collect::compute_bounds matches these against
144 // the "special" built-in traits (see middle::lang_items) and
145 // detects Copy, Send, Send, and Freeze.
146 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
147 pub enum TyParamBound {
148 TraitTyParamBound(trait_ref),
152 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
156 bounds: OptVec<TyParamBound>
159 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
160 pub struct Generics {
161 lifetimes: OptVec<Lifetime>,
162 ty_params: OptVec<TyParam>,
166 pub fn is_parameterized(&self) -> bool {
167 self.lifetimes.len() + self.ty_params.len() > 0
169 pub fn is_lt_parameterized(&self) -> bool {
170 self.lifetimes.len() > 0
172 pub fn is_type_parameterized(&self) -> bool {
173 self.ty_params.len() > 0
177 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
178 pub enum MethodProvenance {
183 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
185 def_fn(def_id, purity),
186 def_static_method(/* method */ def_id, MethodProvenance, purity),
188 def_self_ty(/* trait id */ NodeId),
190 def_foreign_mod(def_id),
191 def_static(def_id, bool /* is_mutbl */),
192 def_arg(NodeId, bool /* is_mutbl */),
193 def_local(NodeId, bool /* is_mutbl */),
194 def_variant(def_id /* enum */, def_id /* variant */),
197 def_prim_ty(prim_ty),
198 def_ty_param(def_id, uint),
199 def_binding(NodeId, binding_mode),
201 def_upvar(NodeId, // id of closed over var
202 @def, // closed over def
203 NodeId, // expr node that creates the closure
204 NodeId), // id for the block/body of the closure expr
206 def_typaram_binder(NodeId), /* struct, impl or trait with ty params */
209 def_method(def_id /* method */, Option<def_id> /* trait */),
213 // The set of MetaItems that define the compilation environment of the crate,
214 // used to drive conditional compilation
215 pub type CrateConfig = ~[@MetaItem];
217 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
225 pub type MetaItem = spanned<MetaItem_>;
227 #[deriving(Clone, Encodable, Decodable, IterBytes)]
230 MetaList(@str, ~[@MetaItem]),
231 MetaNameValue(@str, lit),
234 // can't be derived because the MetaList requires an unordered comparison
235 impl Eq for MetaItem_ {
236 fn eq(&self, other: &MetaItem_) -> bool {
238 MetaWord(ref ns) => match *other {
239 MetaWord(ref no) => (*ns) == (*no),
242 MetaNameValue(ref ns, ref vs) => match *other {
243 MetaNameValue(ref no, ref vo) => {
244 (*ns) == (*no) && vs.node == vo.node
248 MetaList(ref ns, ref miss) => match *other {
249 MetaList(ref no, ref miso) => {
251 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
259 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
261 view_items: ~[view_item],
265 rules: BlockCheckMode,
269 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
276 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
277 pub struct field_pat {
282 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
283 pub enum binding_mode {
284 bind_by_ref(mutability),
288 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
291 // A pat_ident may either be a new bound variable,
292 // or a nullary enum (in which case the second field
294 // In the nullary enum case, the parser can't determine
295 // which it is. The resolver determines this, and
296 // records this pattern's NodeId in an auxiliary
297 // set (of "pat_idents that refer to nullary enums")
298 pat_ident(binding_mode, Path, Option<@pat>),
299 pat_enum(Path, Option<~[@pat]>), /* "none" means a * pattern where
300 * we don't bind the fields to names */
301 pat_struct(Path, ~[field_pat], bool),
305 pat_region(@pat), // borrowed pointer pattern
307 pat_range(@expr, @expr),
308 // [a, b, ..i, y, z] is represented as
309 // pat_vec(~[a, b], Some(i), ~[y, z])
310 pat_vec(~[@pat], Option<@pat>, ~[@pat])
313 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
314 pub enum mutability {
319 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
326 impl ToStr for Sigil {
327 fn to_str(&self) -> ~str {
329 BorrowedSigil => ~"&",
336 #[deriving(Eq, Encodable, Decodable,IterBytes)]
338 // FIXME (#3469): Change uint to @expr (actually only constant exprs)
339 vstore_fixed(Option<uint>), // [1,2,3,4]
340 vstore_uniq, // ~[1,2,3,4]
341 vstore_box, // @[1,2,3,4]
342 vstore_slice(Option<Lifetime>) // &'foo? [1,2,3,4]
345 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
346 pub enum expr_vstore {
347 expr_vstore_uniq, // ~[1,2,3,4]
348 expr_vstore_box, // @[1,2,3,4]
349 expr_vstore_mut_box, // @mut [1,2,3,4]
350 expr_vstore_slice, // &[1,2,3,4]
351 expr_vstore_mut_slice, // &mut [1,2,3,4]
354 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
376 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
385 pub type stmt = spanned<stmt_>;
387 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
389 // could be an item or a local (let) binding:
390 stmt_decl(@decl, NodeId),
392 // expr without trailing semi-colon (must have unit type):
393 stmt_expr(@expr, NodeId),
395 // expr with trailing semi-colon (may have any type):
396 stmt_semi(@expr, NodeId),
398 // bool: is there a trailing sem-colon?
402 // FIXME (pending discussion of #1697, #2178...): local should really be
403 // a refinement on pat.
404 #[deriving(Eq, Encodable, Decodable,IterBytes)]
414 pub type decl = spanned<decl_>;
416 #[deriving(Eq, Encodable, Decodable,IterBytes)]
418 // a local (let) binding:
424 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
427 guard: Option<@expr>,
431 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
438 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
439 pub enum BlockCheckMode {
444 #[deriving(Eq, Encodable, Decodable,IterBytes)]
452 pub fn get_callee_id(&self) -> Option<NodeId> {
454 expr_method_call(callee_id, _, _, _, _, _) |
455 expr_index(callee_id, _, _) |
456 expr_binary(callee_id, _, _, _) |
457 expr_assign_op(callee_id, _, _, _) |
458 expr_unary(callee_id, _, _) => Some(callee_id),
464 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
471 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
473 expr_vstore(@expr, expr_vstore),
474 expr_vec(~[@expr], mutability),
475 expr_call(@expr, ~[@expr], CallSugar),
476 expr_method_call(NodeId, @expr, ident, ~[Ty], ~[@expr], CallSugar),
478 expr_binary(NodeId, binop, @expr, @expr),
479 expr_unary(NodeId, unop, @expr),
481 expr_cast(@expr, Ty),
482 expr_if(@expr, Block, Option<@expr>),
483 expr_while(@expr, Block),
484 expr_for_loop(@pat, @expr, Block),
485 /* Conditionless loop (can be exited with break, cont, or ret)
486 Same semantics as while(true) { body }, but typestate knows that the
487 (implicit) condition is always true. */
488 expr_loop(Block, Option<ident>),
489 expr_match(@expr, ~[arm]),
490 expr_fn_block(fn_decl, Block),
494 expr_assign(@expr, @expr),
495 expr_assign_op(NodeId, binop, @expr, @expr),
496 expr_field(@expr, ident, ~[Ty]),
497 expr_index(NodeId, @expr, @expr),
500 /// The special identifier `self`.
502 expr_addr_of(mutability, @expr),
503 expr_break(Option<ident>),
504 expr_again(Option<ident>),
505 expr_ret(Option<@expr>),
506 expr_log(@expr, @expr),
508 expr_inline_asm(inline_asm),
512 // A struct literal expression.
513 expr_struct(Path, ~[Field], Option<@expr> /* base */),
515 // A vector literal constructed from one repeated element.
516 expr_repeat(@expr /* element */, @expr /* count */, mutability),
518 // No-op: used solely so we can pretty-print faithfully
522 // When the main rust parser encounters a syntax-extension invocation, it
523 // parses the arguments to the invocation as a token-tree. This is a very
524 // loose structure, such that all sorts of different AST-fragments can
525 // be passed to syntax extensions using a uniform type.
527 // If the syntax extension is an MBE macro, it will attempt to match its
528 // LHS "matchers" against the provided token tree, and if it finds a
529 // match, will transcribe the RHS token tree, splicing in any captured
530 // macro_parser::matched_nonterminals into the tt_nonterminals it finds.
532 // The RHS of an MBE macro is the only place a tt_nonterminal or tt_seq
533 // makes any real sense. You could write them elsewhere but nothing
534 // else knows what to do with them, so you'll probably get a syntax
537 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
538 #[doc="For macro invocations; parsing is delegated to the macro"]
539 pub enum token_tree {
541 tt_tok(span, ::parse::token::Token),
542 // a delimited sequence (the delimiters appear as the first
543 // and last elements of the vector)
544 tt_delim(@mut ~[token_tree]),
545 // These only make sense for right-hand-sides of MBE macros:
547 // a kleene-style repetition sequence with a span, a tt_forest,
548 // an optional separator (?), and a boolean where true indicates
549 // zero or more (*), and false indicates one or more (+).
550 tt_seq(span, @mut ~[token_tree], Option<::parse::token::Token>, bool),
552 // a syntactic variable that will be filled in by macro expansion.
553 tt_nonterminal(span, ident)
557 // Matchers are nodes defined-by and recognized-by the main rust parser and
558 // language, but they're only ever found inside syntax-extension invocations;
559 // indeed, the only thing that ever _activates_ the rules in the rust parser
560 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
561 // itself. Matchers represent a small sub-language for pattern-matching
562 // token-trees, and are thus primarily used by the macro-defining extension
568 // A matcher that matches a single token, denoted by the token itself. So
569 // long as there's no $ involved.
575 // A matcher that matches a sequence of sub-matchers, denoted various
578 // $(M)* zero or more Ms
579 // $(M)+ one or more Ms
580 // $(M),+ one or more comma-separated Ms
581 // $(A B C);* zero or more semi-separated 'A B C' seqs
587 // A matcher that matches one of a few interesting named rust
588 // nonterminals, such as types, expressions, items, or raw token-trees. A
589 // black-box matcher on expr, for example, binds an expr to a given ident,
590 // and that ident can re-occur as an interpolation in the RHS of a
591 // macro-by-example rule. For example:
593 // $foo:expr => 1 + $foo // interpolate an expr
594 // $foo:tt => $foo // interpolate a token-tree
595 // $foo:tt => bar! $foo // only other valid interpolation
596 // // is in arg position for another
599 // As a final, horrifying aside, note that macro-by-example's input is
600 // also matched by one of these matchers. Holy self-referential! It is matched
601 // by an match_seq, specifically this one:
603 // $( $lhs:matchers => $rhs:tt );+
605 // If you understand that, you have closed to loop and understand the whole
606 // macro system. Congratulations.
608 pub type matcher = spanned<matcher_>;
610 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
613 match_tok(::parse::token::Token),
614 // match repetitions of a sequence: body, separator, zero ok?,
615 // lo, hi position-in-match-array used:
616 match_seq(~[matcher], Option<::parse::token::Token>, bool, uint, uint),
617 // parse a Rust NT: name to bind, name of NT, position in match array:
618 match_nonterminal(ident, ident, uint)
621 pub type mac = spanned<mac_>;
623 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
625 mac_invoc_tt(Path,~[token_tree]), // new macro-invocation
628 pub type lit = spanned<lit_>;
630 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
633 lit_int(i64, int_ty),
634 lit_uint(u64, uint_ty),
635 lit_int_unsuffixed(i64),
636 lit_float(@str, float_ty),
637 lit_float_unsuffixed(@str),
642 // NB: If you change this, you'll probably want to change the corresponding
643 // type structure in middle/ty.rs as well.
644 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
650 #[deriving(Eq, Encodable, Decodable,IterBytes)]
651 pub struct TypeField {
657 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
658 pub struct TypeMethod {
664 explicit_self: explicit_self,
669 // A trait method is either required (meaning it doesn't have an
670 // implementation, just a signature) or provided (meaning it has a default
672 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
673 pub enum trait_method {
674 required(TypeMethod),
678 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
688 impl ToStr for int_ty {
689 fn to_str(&self) -> ~str {
690 ::ast_util::int_ty_to_str(*self)
694 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
703 impl ToStr for uint_ty {
704 fn to_str(&self) -> ~str {
705 ::ast_util::uint_ty_to_str(*self)
709 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
716 impl ToStr for float_ty {
717 fn to_str(&self) -> ~str {
718 ::ast_util::float_ty_to_str(*self)
722 // NB Eq method appears below.
723 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
730 // Not represented directly in the AST, referred to by name through a ty_path.
731 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
740 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
746 #[deriving(IterBytes)]
747 impl ToStr for Onceness {
748 fn to_str(&self) -> ~str {
756 #[deriving(Eq, Encodable, Decodable,IterBytes)]
757 pub struct TyClosure {
759 region: Option<Lifetime>,
760 lifetimes: OptVec<Lifetime>,
764 // Optional optvec distinguishes between "fn()" and "fn:()" so we can
765 // implement issue #7264. None means "fn()", which means infer a default
766 // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
767 // which means use no bounds (e.g., not even Owned on a ~fn()).
768 bounds: Option<OptVec<TyParamBound>>,
771 #[deriving(Eq, Encodable, Decodable,IterBytes)]
772 pub struct TyBareFn {
775 lifetimes: OptVec<Lifetime>,
779 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
782 ty_bot, /* bottom type */
786 ty_fixed_length_vec(mt, @expr),
788 ty_rptr(Option<Lifetime>, mt),
789 ty_closure(@TyClosure),
790 ty_bare_fn(@TyBareFn),
792 ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
795 // ty_infer means the type should be inferred instead of it having been
796 // specified. This should only appear at the "top level" of a type and not
801 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
802 pub enum asm_dialect {
807 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
808 pub struct inline_asm {
811 inputs: ~[(@str, @expr)],
812 outputs: ~[(@str, @expr)],
818 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
826 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
833 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
835 unsafe_fn, // declared with "unsafe fn"
836 impure_fn, // declared with "fn"
837 extern_fn, // declared with "extern fn"
840 #[deriving(IterBytes)]
841 impl ToStr for purity {
842 fn to_str(&self) -> ~str {
844 impure_fn => ~"impure",
845 unsafe_fn => ~"unsafe",
846 extern_fn => ~"extern"
851 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
853 noreturn, // functions with return type _|_ that always
854 // raise an error or exit (i.e. never return to the caller)
855 return_val, // everything else
858 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
859 pub enum explicit_self_ {
860 sty_static, // no self
862 sty_region(Option<Lifetime>, mutability), // `&'lt self`
863 sty_box(mutability), // `@self`
867 pub type explicit_self = spanned<explicit_self_>;
869 #[deriving(Eq, Encodable, Decodable,IterBytes)]
874 explicit_self: explicit_self,
884 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
886 view_items: ~[view_item],
890 // Foreign mods can be named or anonymous
891 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
892 pub enum foreign_mod_sort {
897 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
898 pub struct foreign_mod {
899 sort: foreign_mod_sort,
901 view_items: ~[view_item],
902 items: ~[@foreign_item],
905 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
906 pub struct variant_arg {
911 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
912 pub enum variant_kind {
913 tuple_variant_kind(~[variant_arg]),
914 struct_variant_kind(@struct_def),
917 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
918 pub struct enum_def {
919 variants: ~[variant],
922 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
923 pub struct variant_ {
928 disr_expr: Option<@expr>,
932 pub type variant = spanned<variant_>;
934 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
935 pub struct path_list_ident_ {
940 pub type path_list_ident = spanned<path_list_ident_>;
942 pub type view_path = spanned<view_path_>;
944 #[deriving(Eq, Encodable, Decodable, IterBytes)]
945 pub enum view_path_ {
947 // quux = foo::bar::baz
951 // foo::bar::baz (with 'baz =' implicitly on the left)
952 view_path_simple(ident, Path, NodeId),
955 view_path_glob(Path, NodeId),
958 view_path_list(Path, ~[path_list_ident], NodeId)
961 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
962 pub struct view_item {
969 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
970 pub enum view_item_ {
971 // ident: name used to refer to this crate in the code
972 // optional @str: if present, this is a location (containing
973 // arbitrary characters) from which to fetch the crate sources
974 // For example, extern mod whatever = "github.com/mozilla/rust"
975 view_item_extern_mod(ident, Option<@str>, ~[@MetaItem], NodeId),
976 view_item_use(~[@view_path]),
979 // Meta-data associated with an item
980 pub type Attribute = spanned<Attribute_>;
982 // Distinguishes between Attributes that decorate items and Attributes that
983 // are contained as statements within items. These two cases need to be
984 // distinguished for pretty-printing.
985 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
991 // doc-comments are promoted to attributes that have is_sugared_doc = true
992 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
993 pub struct Attribute_ {
996 is_sugared_doc: bool,
1000 trait_refs appear in impls.
1001 resolve maps each trait_ref's ref_id to its defining trait; that's all
1002 that the ref_id is for. The impl_id maps to the "self type" of this impl.
1003 If this impl is an item_impl, the impl_id is redundant (it could be the
1004 same as the impl's node id).
1006 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1007 pub struct trait_ref {
1012 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1013 pub enum visibility {
1020 pub fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1022 &inherited => parent_visibility,
1023 &public | &private => *self
1028 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1029 pub struct struct_field_ {
1030 kind: struct_field_kind,
1033 attrs: ~[Attribute],
1036 pub type struct_field = spanned<struct_field_>;
1038 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1039 pub enum struct_field_kind {
1040 named_field(ident, visibility),
1041 unnamed_field // element of a tuple-like struct
1044 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1045 pub struct struct_def {
1046 fields: ~[@struct_field], /* fields, not including ctor */
1047 /* ID of the constructor. This is only used for tuple- or enum-like
1049 ctor_id: Option<NodeId>
1053 FIXME (#3300): Should allow items to be anonymous. Right now
1054 we just use dummy names for anon items.
1056 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1059 attrs: ~[Attribute],
1066 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1068 item_static(Ty, mutability, @expr),
1069 item_fn(fn_decl, purity, AbiSet, Generics, Block),
1071 item_foreign_mod(foreign_mod),
1072 item_ty(Ty, Generics),
1073 item_enum(enum_def, Generics),
1074 item_struct(@struct_def, Generics),
1075 item_trait(Generics, ~[trait_ref], ~[trait_method]),
1077 Option<trait_ref>, // (optional) trait this impl implements
1080 // a macro invocation (which includes macro definition)
1084 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1085 pub struct foreign_item {
1087 attrs: ~[Attribute],
1088 node: foreign_item_,
1094 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1095 pub enum foreign_item_ {
1096 foreign_item_fn(fn_decl, Generics),
1097 foreign_item_static(Ty, /* is_mutbl */ bool),
1100 // The data we save and restore about an inlined item or method. This is not
1101 // part of the AST that we parse from a file, but it becomes part of the tree
1103 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1104 pub enum inlined_item {
1106 ii_method(def_id /* impl id */, bool /* is provided */, @method),
1107 ii_foreign(@foreign_item),
1110 /* hold off on tests ... they appear in a later merge.
1113 use std::option::{None, Option, Some};
1120 #[test] fn xorpush_test () {
1123 assert_eq!(s,~[14]);
1127 assert_eq!(s,~[14]);
1129 assert_eq!(s,~[14,15]);
1130 xorPush (&mut s,16);
1131 assert_eq! (s,~[14,15,16]);
1132 xorPush (&mut s,16);
1133 assert_eq! (s,~[14,15]);
1134 xorPush (&mut s,15);
1135 assert_eq! (s,~[14]);
1138 #[test] fn test_marksof () {
1139 let stopname = uints_to_name(&~[12,14,78]);
1142 assert_eq!(s,~[14]);
1144 assert_eq!(s,~[14,15]);
1145 xorPush (&mut s,16);
1146 assert_eq! (s,~[14,15,16]);
1147 xorPush (&mut s,16);
1148 assert_eq! (s,~[14,15]);
1149 xorPush (&mut s,15);
1150 assert_eq! (s,~[14]);
1153 #[test] fn test_marksof () {
1154 let stopname = uints_to_name(&~[12,14,78]);
1155 let name1 = uints_to_name(&~[4,9,7]);
1156 assert_eq!(marksof (MT,stopname),~[]);
1157 assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1158 // does xoring work?
1159 assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1161 // does nested xoring work?
1162 assert_eq! (marksof (Mark (5,
1169 // stop has no effect on marks
1170 assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1172 // rename where stop doesn't match:
1173 assert_eq! (marksof (Mark (9, @Rename
1176 uints_to_name(&~[100,101,102]),
1180 // rename where stop does match
1182 assert_eq! (marksof (Mark(9, @Rename (name1,
1190 // are ASTs encodable?
1191 #[test] fn check_asts_encodable() {
1192 let bogus_span = span {lo:BytePos(10),
1198 module: _mod {view_items: ~[], items: ~[]},
1203 // doesn't matter which encoder we use....
1204 let _f = (@e as @extra::serialize::Encodable<extra::json::Encoder>);
1215 // indent-tabs-mode: nil
1216 // c-basic-offset: 4
1217 // buffer-file-coding-system: utf-8-unix