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};
18 use core::option::{None, Option, Some};
21 use core::to_str::ToStr;
22 use std::serialize::{Encodable, Decodable, Encoder, Decoder};
25 // an identifier contains an index into the interner
26 // table and a SyntaxContext to track renaming and
27 // macro expansion per Flatt et al., "Macros
28 // That Work Together"
30 pub struct ident { repr: Name, ctxt: SyntaxContext }
32 // a SyntaxContext represents a chain of macro-expandings
33 // and renamings. Each macro expansion corresponds to
36 // I'm representing this syntax context as an index into
37 // a table, in order to work around a compiler bug
38 // that's causing unreleased memory to cause core dumps
39 // and also perhaps to save some work in destructor checks.
40 // the special uint '0' will be used to indicate an empty
43 // this uint is a reference to a table stored in thread-local
45 pub type SyntaxContext = uint;
47 pub type SCTable = ~[SyntaxContext_];
48 pub static empty_ctxt : uint = 0;
53 pub enum SyntaxContext_ {
55 Mark (Mrk,SyntaxContext),
56 // flattening the name and syntaxcontext into the rename...
58 // 1) the first name in a Rename node
59 // can only be a programmer-supplied name.
60 // 2) Every Rename node with a given Name in the
61 // "to" slot must have the same name and context
62 // in the "from" slot. In essence, they're all
63 // pointers to a single "rename" event node.
64 Rename (ident,Name,SyntaxContext)
67 // a name represents an identifier
69 // a mark represents a unique id associated
70 // with a macro expansion
73 impl<S:Encoder> Encodable<S> for ident {
74 fn encode(&self, s: &S) {
75 let intr = match unsafe {
76 task::local_data::local_data_get(interner_key!())
78 None => fail!(~"encode: TLS interner not set up"),
82 s.emit_str(*(*intr).get(*self));
86 impl<D:Decoder> Decodable<D> for ident {
87 fn decode(d: &D) -> ident {
88 let intr = match unsafe {
89 task::local_data::local_data_get(interner_key!())
91 None => fail!(~"decode: TLS interner not set up"),
95 (*intr).intern(@d.read_str())
99 impl to_bytes::IterBytes for ident {
100 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
101 self.repr.iter_bytes(lsb0, f)
105 // Functions may or may not have names.
106 pub type fn_ident = Option<ident>;
111 pub struct Lifetime {
117 // a "Path" is essentially Rust's notion of a name;
118 // for instance: core::cmp::Eq . It's represented
119 // as a sequence of identifiers, along with a bunch
120 // of supporting information.
128 rp: Option<@Lifetime>,
132 pub type crate_num = int;
134 pub type node_id = int;
144 pub static local_crate: crate_num = 0;
145 pub static crate_node_id: node_id = 0;
150 // The AST represents all type param bounds as types.
151 // typeck::collect::compute_bounds matches these against
152 // the "special" built-in traits (see middle::lang_items) and
153 // detects Copy, Send, Owned, and Const.
154 pub enum TyParamBound {
155 TraitTyParamBound(@trait_ref),
165 bounds: @OptVec<TyParamBound>
171 pub struct Generics {
172 lifetimes: OptVec<Lifetime>,
173 ty_params: OptVec<TyParam>
177 fn is_parameterized(&self) -> bool {
178 self.lifetimes.len() + self.ty_params.len() > 0
180 fn is_lt_parameterized(&self) -> bool {
181 self.lifetimes.len() > 0
183 fn is_type_parameterized(&self) -> bool {
184 self.ty_params.len() > 0
192 def_fn(def_id, purity),
193 def_static_method(/* method */ def_id,
194 /* trait */ Option<def_id>,
196 def_self(node_id, bool /* is_implicit */),
197 def_self_ty(/* trait id */ node_id),
199 def_foreign_mod(def_id),
201 def_arg(node_id, bool /* is_mutbl */),
202 def_local(node_id, bool /* is_mutbl */),
203 def_variant(def_id /* enum */, def_id /* variant */),
206 def_prim_ty(prim_ty),
207 def_ty_param(def_id, uint),
208 def_binding(node_id, binding_mode),
210 def_upvar(node_id, // id of closed over var
211 @def, // closed over def
212 node_id, // expr node that creates the closure
213 node_id), // id for the block/body of the closure expr
215 def_typaram_binder(node_id), /* struct, impl or trait with ty params */
221 // The set of meta_items that define the compilation environment of the crate,
222 // used to drive conditional compilation
223 pub type crate_cfg = ~[@meta_item];
225 pub type crate = spanned<crate_>;
236 pub type meta_item = spanned<meta_item_>;
241 pub enum meta_item_ {
243 meta_list(@~str, ~[@meta_item]),
244 meta_name_value(@~str, lit),
247 pub type blk = spanned<blk_>;
253 view_items: ~[@view_item],
257 rules: blk_check_mode,
272 pub struct field_pat {
280 pub enum binding_mode {
282 bind_by_ref(mutability),
286 impl to_bytes::IterBytes for binding_mode {
287 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
289 bind_by_copy => 0u8.iter_bytes(lsb0, f),
291 bind_by_ref(ref m) =>
292 to_bytes::iter_bytes_2(&1u8, m, lsb0, f),
295 2u8.iter_bytes(lsb0, f),
305 // A pat_ident may either be a new bound variable,
306 // or a nullary enum (in which case the second field
308 // In the nullary enum case, the parser can't determine
309 // which it is. The resolver determines this, and
310 // records this pattern's node_id in an auxiliary
311 // set (of "pat_idents that refer to nullary enums")
312 pat_ident(binding_mode, @Path, Option<@pat>),
313 pat_enum(@Path, Option<~[@pat]>), /* "none" means a * pattern where
314 * we don't bind the fields to names */
315 pat_struct(@Path, ~[field_pat], bool),
319 pat_region(@pat), // borrowed pointer pattern
321 pat_range(@expr, @expr),
322 // [a, b, ..i, y, z] is represented as
323 // pat_vec(~[a, b], Some(i), ~[y, z])
324 pat_vec(~[@pat], Option<@pat>, ~[@pat])
330 pub enum mutability { m_mutbl, m_imm, m_const, }
332 impl to_bytes::IterBytes for mutability {
333 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
334 (*self as u8).iter_bytes(lsb0, f)
347 impl to_bytes::IterBytes for Sigil {
348 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
349 (*self as uint).iter_bytes(lsb0, f)
353 impl ToStr for Sigil {
354 fn to_str(&self) -> ~str {
356 BorrowedSigil => ~"&",
367 // FIXME (#3469): Change uint to @expr (actually only constant exprs)
368 vstore_fixed(Option<uint>), // [1,2,3,4]
369 vstore_uniq, // ~[1,2,3,4]
370 vstore_box, // @[1,2,3,4]
371 vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4]
377 pub enum expr_vstore {
378 expr_vstore_uniq, // ~[1,2,3,4]
379 expr_vstore_box, // @[1,2,3,4]
380 expr_vstore_mut_box, // @mut [1,2,3,4]
381 expr_vstore_slice, // &[1,2,3,4]
382 expr_vstore_mut_slice, // &mut [1,2,3,4]
420 pub type stmt = spanned<stmt_>;
426 stmt_decl(@decl, node_id),
428 // expr without trailing semi-colon (must have unit type):
429 stmt_expr(@expr, node_id),
431 // expr with trailing semi-colon (may have any type):
432 stmt_semi(@expr, node_id),
434 // bool: is there a trailing sem-colon?
438 // FIXME (pending discussion of #1697, #2178...): local should really be
439 // a refinement on pat.
451 pub type local = spanned<local_>;
453 pub type decl = spanned<decl_>;
458 pub enum decl_ { decl_local(~[@local]), decl_item(@item), }
465 guard: Option<@expr>,
478 pub type field = spanned<field_>;
483 pub enum blk_check_mode { default_blk, unsafe_blk, }
490 // Extra node ID is only used for index, assign_op, unary, binary, method
510 expr_vstore(@expr, expr_vstore),
511 expr_vec(~[@expr], mutability),
512 expr_call(@expr, ~[@expr], CallSugar),
513 expr_method_call(@expr, ident, ~[@Ty], ~[@expr], CallSugar),
515 expr_binary(binop, @expr, @expr),
516 expr_unary(unop, @expr),
518 expr_cast(@expr, @Ty),
519 expr_if(@expr, blk, Option<@expr>),
520 expr_while(@expr, blk),
521 /* Conditionless loop (can be exited with break, cont, or ret)
522 Same semantics as while(true) { body }, but typestate knows that the
523 (implicit) condition is always true. */
524 expr_loop(blk, Option<ident>),
525 expr_match(@expr, ~[arm]),
526 expr_fn_block(fn_decl, blk),
527 // Inner expr is always an expr_fn_block. We need the wrapping node to
528 // easily type this (a function returning nil on the inside but bool on
530 expr_loop_body(@expr),
531 // Like expr_loop_body but for 'do' blocks
536 expr_assign(@expr, @expr),
537 expr_swap(@expr, @expr),
538 expr_assign_op(binop, @expr, @expr),
539 expr_field(@expr, ident, ~[@Ty]),
540 expr_index(@expr, @expr),
542 expr_addr_of(mutability, @expr),
543 expr_break(Option<ident>),
544 expr_again(Option<ident>),
545 expr_ret(Option<@expr>),
546 expr_log(@expr, @expr),
548 expr_inline_asm(inline_asm),
552 // A struct literal expression.
553 expr_struct(@Path, ~[field], Option<@expr>),
555 // A vector literal constructed from one repeated element.
556 expr_repeat(@expr /* element */, @expr /* count */, mutability),
558 // No-op: used solely so we can pretty-print faithfully
562 // When the main rust parser encounters a syntax-extension invocation, it
563 // parses the arguments to the invocation as a token-tree. This is a very
564 // loose structure, such that all sorts of different AST-fragments can
565 // be passed to syntax extensions using a uniform type.
567 // If the syntax extension is an MBE macro, it will attempt to match its
568 // LHS "matchers" against the provided token tree, and if it finds a
569 // match, will transcribe the RHS token tree, splicing in any captured
570 // macro_parser::matched_nonterminals into the tt_nonterminals it finds.
572 // The RHS of an MBE macro is the only place a tt_nonterminal or tt_seq
573 // makes any real sense. You could write them elsewhere but nothing
574 // else knows what to do with them, so you'll probably get a syntax
580 #[doc="For macro invocations; parsing is delegated to the macro"]
581 pub enum token_tree {
583 tt_tok(span, ::parse::token::Token),
584 // a delimited sequence (the delimiters appear as the first
585 // and last elements of the vector)
586 tt_delim(~[token_tree]),
587 // These only make sense for right-hand-sides of MBE macros:
589 // a kleene-style repetition sequence with a span, a tt_forest,
590 // an optional separator (?), and a boolean where true indicates
591 // zero or more (*), and false indicates one or more (+).
592 tt_seq(span, ~[token_tree], Option<::parse::token::Token>, bool),
594 // a syntactic variable that will be filled in by macro expansion.
595 tt_nonterminal(span, ident)
599 // Matchers are nodes defined-by and recognized-by the main rust parser and
600 // language, but they're only ever found inside syntax-extension invocations;
601 // indeed, the only thing that ever _activates_ the rules in the rust parser
602 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
603 // itself. Matchers represent a small sub-language for pattern-matching
604 // token-trees, and are thus primarily used by the macro-defining extension
610 // A matcher that matches a single token, denoted by the token itself. So
611 // long as there's no $ involved.
617 // A matcher that matches a sequence of sub-matchers, denoted various
620 // $(M)* zero or more Ms
621 // $(M)+ one or more Ms
622 // $(M),+ one or more comma-separated Ms
623 // $(A B C);* zero or more semi-separated 'A B C' seqs
629 // A matcher that matches one of a few interesting named rust
630 // nonterminals, such as types, expressions, items, or raw token-trees. A
631 // black-box matcher on expr, for example, binds an expr to a given ident,
632 // and that ident can re-occur as an interpolation in the RHS of a
633 // macro-by-example rule. For example:
635 // $foo:expr => 1 + $foo // interpolate an expr
636 // $foo:tt => $foo // interpolate a token-tree
637 // $foo:tt => bar! $foo // only other valid interpolation
638 // // is in arg position for another
641 // As a final, horrifying aside, note that macro-by-example's input is
642 // also matched by one of these matchers. Holy self-referential! It is matched
643 // by an match_seq, specifically this one:
645 // $( $lhs:matchers => $rhs:tt );+
647 // If you understand that, you have closed to loop and understand the whole
648 // macro system. Congratulations.
650 pub type matcher = spanned<matcher_>;
657 match_tok(::parse::token::Token),
658 // match repetitions of a sequence: body, separator, zero ok?,
659 // lo, hi position-in-match-array used:
660 match_seq(~[matcher], Option<::parse::token::Token>, bool, uint, uint),
661 // parse a Rust NT: name to bind, name of NT, position in match array:
662 match_nonterminal(ident, ident, uint)
665 pub type mac = spanned<mac_>;
671 mac_invoc_tt(@Path,~[token_tree]), // new macro-invocation
674 pub type lit = spanned<lit_>;
681 lit_int(i64, int_ty),
682 lit_uint(u64, uint_ty),
683 lit_int_unsuffixed(i64),
684 lit_float(@~str, float_ty),
685 lit_float_unsuffixed(@~str),
690 // NB: If you change this, you'll probably want to change the corresponding
691 // type structure in middle/ty.rs as well.
703 pub struct ty_field_ {
708 pub type ty_field = spanned<ty_field_>;
713 pub struct ty_method {
727 // A trait method is either required (meaning it doesn't have an
728 // implementation, just a signature) or provided (meaning it has a default
730 pub enum trait_method {
738 pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
740 impl ToStr for int_ty {
741 fn to_str(&self) -> ~str {
742 ::ast_util::int_ty_to_str(*self)
746 impl to_bytes::IterBytes for int_ty {
747 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
748 (*self as u8).iter_bytes(lsb0, f)
755 pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
757 impl ToStr for uint_ty {
758 fn to_str(&self) -> ~str {
759 ::ast_util::uint_ty_to_str(*self)
763 impl to_bytes::IterBytes for uint_ty {
764 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
765 (*self as u8).iter_bytes(lsb0, f)
772 pub enum float_ty { ty_f, ty_f32, ty_f64, }
774 impl ToStr for float_ty {
775 fn to_str(&self) -> ~str {
776 ::ast_util::float_ty_to_str(*self)
780 impl to_bytes::IterBytes for float_ty {
781 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
782 (*self as u8).iter_bytes(lsb0, f)
786 // NB Eq method appears below.
796 // Not represented directly in the AST, referred to by name through a ty_path.
816 impl ToStr for Onceness {
817 fn to_str(&self) -> ~str {
825 impl to_bytes::IterBytes for Onceness {
826 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
827 (*self as uint).iter_bytes(lsb0, f);
834 pub struct TyClosure {
836 region: Option<@Lifetime>,
837 lifetimes: OptVec<Lifetime>,
846 pub struct TyBareFn {
849 lifetimes: OptVec<Lifetime>,
858 ty_bot, /* bottom type */
862 ty_fixed_length_vec(mt, @expr),
864 ty_rptr(Option<@Lifetime>, mt),
865 ty_closure(@TyClosure),
866 ty_bare_fn(@TyBareFn),
868 ty_path(@Path, node_id),
870 // ty_infer means the type should be inferred instead of it having been
871 // specified. This should only appear at the "top level" of a type and not
876 impl to_bytes::IterBytes for Ty {
877 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
878 to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f);
885 pub enum asm_dialect {
893 pub struct inline_asm {
896 inputs: ~[(@~str, @expr)],
897 outputs: ~[(@~str, @expr)],
926 pure_fn, // declared with "pure fn"
927 unsafe_fn, // declared with "unsafe fn"
928 impure_fn, // declared with "fn"
929 extern_fn, // declared with "extern fn"
932 impl ToStr for purity {
933 fn to_str(&self) -> ~str {
935 impure_fn => ~"impure",
936 unsafe_fn => ~"unsafe",
938 extern_fn => ~"extern"
943 impl to_bytes::IterBytes for purity {
944 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
945 (*self as u8).iter_bytes(lsb0, f)
953 noreturn, // functions with return type _|_ that always
954 // raise an error or exit (i.e. never return to the caller)
955 return_val, // everything else
958 impl to_bytes::IterBytes for ret_style {
959 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
960 (*self as u8).iter_bytes(lsb0, f)
968 sty_static, // no self
970 sty_region(Option<@Lifetime>, mutability), // `&'lt self`
971 sty_box(mutability), // `@self`
972 sty_uniq(mutability) // `~self`
975 pub type self_ty = spanned<self_ty_>;
998 view_items: ~[@view_item],
1002 // Foreign mods can be named or anonymous
1006 pub enum foreign_mod_sort { named, anonymous }
1011 pub struct foreign_mod {
1012 sort: foreign_mod_sort,
1014 view_items: ~[@view_item],
1015 items: ~[@foreign_item],
1021 pub struct variant_arg {
1029 pub enum variant_kind {
1030 tuple_variant_kind(~[variant_arg]),
1031 struct_variant_kind(@struct_def),
1037 pub struct enum_def {
1038 variants: ~[variant],
1044 pub struct variant_ {
1046 attrs: ~[attribute],
1049 disr_expr: Option<@expr>,
1053 pub type variant = spanned<variant_>;
1058 pub struct path_list_ident_ {
1063 pub type path_list_ident = spanned<path_list_ident_>;
1065 pub type view_path = spanned<view_path_>;
1070 pub enum view_path_ {
1072 // quux = foo::bar::baz
1076 // foo::bar::baz (with 'baz =' implicitly on the left)
1077 view_path_simple(ident, @Path, node_id),
1080 view_path_glob(@Path, node_id),
1082 // foo::bar::{a,b,c}
1083 view_path_list(@Path, ~[path_list_ident], node_id)
1089 pub struct view_item {
1091 attrs: ~[attribute],
1099 pub enum view_item_ {
1100 view_item_extern_mod(ident, ~[@meta_item], node_id),
1101 view_item_use(~[@view_path]),
1104 // Meta-data associated with an item
1105 pub type attribute = spanned<attribute_>;
1107 // Distinguishes between attributes that decorate items and attributes that
1108 // are contained as statements within items. These two cases need to be
1109 // distinguished for pretty-printing.
1113 pub enum attr_style { attr_outer, attr_inner, }
1115 // doc-comments are promoted to attributes that have is_sugared_doc = true
1119 pub struct attribute_ {
1122 is_sugared_doc: bool,
1126 trait_refs appear in impls.
1127 resolve maps each trait_ref's ref_id to its defining trait; that's all
1128 that the ref_id is for. The impl_id maps to the "self type" of this impl.
1129 If this impl is an item_impl, the impl_id is redundant (it could be the
1130 same as the impl's node id).
1135 pub struct trait_ref {
1143 pub enum visibility { public, private, inherited }
1146 fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1148 &inherited => parent_visibility,
1149 &public | &private => *self
1157 pub struct struct_field_ {
1158 kind: struct_field_kind,
1161 attrs: ~[attribute],
1164 pub type struct_field = spanned<struct_field_>;
1169 pub enum struct_field_kind {
1170 named_field(ident, struct_mutability, visibility),
1171 unnamed_field // element of a tuple-like struct
1177 pub struct struct_def {
1178 fields: ~[@struct_field], /* fields, not including ctor */
1179 /* ID of the constructor. This is only used for tuple- or enum-like
1181 ctor_id: Option<node_id>
1185 FIXME (#3300): Should allow items to be anonymous. Right now
1186 we just use dummy names for anon items.
1193 attrs: ~[attribute],
1204 item_const(@Ty, @expr),
1205 item_fn(fn_decl, purity, AbiSet, Generics, blk),
1207 item_foreign_mod(foreign_mod),
1208 item_ty(@Ty, Generics),
1209 item_enum(enum_def, Generics),
1210 item_struct(@struct_def, Generics),
1211 item_trait(Generics, ~[@trait_ref], ~[trait_method]),
1213 Option<@trait_ref>, // (optional) trait this impl implements
1216 // a macro invocation (which includes macro definition)
1223 pub enum struct_mutability { struct_mutable, struct_immutable }
1225 impl to_bytes::IterBytes for struct_mutability {
1226 fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
1227 (*self as u8).iter_bytes(lsb0, f)
1234 pub struct foreign_item {
1236 attrs: ~[attribute],
1237 node: foreign_item_,
1246 pub enum foreign_item_ {
1247 foreign_item_fn(fn_decl, purity, Generics),
1248 foreign_item_const(@Ty)
1251 // The data we save and restore about an inlined item or method. This is not
1252 // part of the AST that we parse from a file, but it becomes part of the tree
1257 pub enum inlined_item {
1259 ii_method(def_id /* impl id */, @method),
1260 ii_foreign(@foreign_item),
1263 /* hold off on tests ... they appear in a later merge.
1266 use core::option::{None, Option, Some};
1273 #[test] fn xorpush_test () {
1276 assert_eq!(s,~[14]);
1280 assert_eq!(s,~[14]);
1282 assert_eq!(s,~[14,15]);
1283 xorPush (&mut s,16);
1284 assert_eq! (s,~[14,15,16]);
1285 xorPush (&mut s,16);
1286 assert_eq! (s,~[14,15]);
1287 xorPush (&mut s,15);
1288 assert_eq! (s,~[14]);
1291 #[test] fn test_marksof () {
1292 let stopname = uints_to_name(&~[12,14,78]);
1293 let name1 = uints_to_name(&~[4,9,7]);
1294 assert_eq!(marksof (MT,stopname),~[]);
1295 assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1296 // does xoring work?
1297 assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1299 // does nested xoring work?
1300 assert_eq! (marksof (Mark (5,
1307 // stop has no effect on marks
1308 assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1310 // rename where stop doesn't match:
1311 assert_eq! (marksof (Mark (9, @Rename
1314 uints_to_name(&~[100,101,102]),
1318 // rename where stop does match
1320 assert_eq! (marksof (Mark(9, @Rename (name1,
1328 // are ASTs encodable?
1329 #[test] fn check_asts_encodable() {
1330 let bogus_span = span {lo:BytePos(10),
1336 module: _mod {view_items: ~[], items: ~[]},
1341 // doesn't matter which encoder we use....
1342 let _f = (@e as @std::serialize::Encodable<std::json::Encoder>);