1 // Copyright 2012-2014 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, DUMMY_SP};
17 use parse::token::{InternedString, special_idents, str_to_ident};
20 use std::cell::RefCell;
21 use std::hashmap::HashMap;
22 use std::option::Option;
23 use std::to_str::ToStr;
24 use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
26 /// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
29 /// Construct a P<T> from a T value.
30 pub fn P<T: 'static>(value: T) -> P<T> {
34 // FIXME #6993: in librustc, uses of "ident" should be replaced
37 // an identifier contains a Name (index into the interner
38 // table) and a SyntaxContext to track renaming and
39 // macro expansion per Flatt et al., "Macros
40 // That Work Together"
41 #[deriving(Clone, IterBytes, ToStr, TotalEq, TotalOrd)]
42 pub struct Ident { name: Name, ctxt: SyntaxContext }
45 /// Construct an identifier with the given name and an empty context:
46 pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
50 fn eq(&self, other: &Ident) -> bool {
51 if self.ctxt == other.ctxt {
52 self.name == other.name
54 // IF YOU SEE ONE OF THESE FAILS: it means that you're comparing
55 // idents that have different contexts. You can't fix this without
56 // knowing whether the comparison should be hygienic or non-hygienic.
57 // if it should be non-hygienic (most things are), just compare the
58 // 'name' fields of the idents. Or, even better, replace the idents
60 fail!("not allowed to compare these idents: {:?}, {:?}.
61 Probably related to issue \\#6993", self, other);
64 fn ne(&self, other: &Ident) -> bool {
69 /// A SyntaxContext represents a chain of macro-expandings
70 /// and renamings. Each macro expansion corresponds to
73 // I'm representing this syntax context as an index into
74 // a table, in order to work around a compiler bug
75 // that's causing unreleased memory to cause core dumps
76 // and also perhaps to save some work in destructor checks.
77 // the special uint '0' will be used to indicate an empty
80 // this uint is a reference to a table stored in thread-local
82 pub type SyntaxContext = u32;
84 // the SCTable contains a table of SyntaxContext_'s. It
85 // represents a flattened tree structure, to avoid having
86 // managed pointers everywhere (that caused an ICE).
87 // the mark_memo and rename_memo fields are side-tables
88 // that ensure that adding the same mark to the same context
89 // gives you back the same context as before. This shouldn't
90 // change the semantics--everything here is immutable--but
91 // it should cut down on memory use *a lot*; applying a mark
92 // to a tree containing 50 identifiers would otherwise generate
94 table: RefCell<~[SyntaxContext_]>,
95 mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
96 rename_memo: RefCell<HashMap<(SyntaxContext,Ident,Name),SyntaxContext>>,
99 // NB: these must be placed in any SCTable...
100 pub static EMPTY_CTXT : SyntaxContext = 0;
101 pub static ILLEGAL_CTXT : SyntaxContext = 1;
103 #[deriving(Eq, Encodable, Decodable,IterBytes)]
104 pub enum SyntaxContext_ {
106 Mark (Mrk,SyntaxContext),
107 // flattening the name and syntaxcontext into the rename...
108 // HIDDEN INVARIANTS:
109 // 1) the first name in a Rename node
110 // can only be a programmer-supplied name.
111 // 2) Every Rename node with a given Name in the
112 // "to" slot must have the same name and context
113 // in the "from" slot. In essence, they're all
114 // pointers to a single "rename" event node.
115 Rename (Ident,Name,SyntaxContext),
116 // actually, IllegalCtxt may not be necessary.
120 /// A name is a part of an identifier, representing a string or gensym. It's
121 /// the result of interning.
124 /// A mark represents a unique id associated with a macro expansion
127 impl<S:Encoder> Encodable<S> for Ident {
128 fn encode(&self, s: &mut S) {
129 let string = token::get_ident(self.name);
130 s.emit_str(string.get());
134 impl<D:Decoder> Decodable<D> for Ident {
135 fn decode(d: &mut D) -> Ident {
136 str_to_ident(d.read_str())
140 /// Function name (not all functions have names)
141 pub type FnIdent = Option<Ident>;
143 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
144 pub struct Lifetime {
147 // FIXME #7743 : change this to Name!
151 // a "Path" is essentially Rust's notion of a name;
152 // for instance: std::cmp::Eq . It's represented
153 // as a sequence of identifiers, along with a bunch
154 // of supporting information.
155 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
158 /// A `::foo` path, is relative to the crate root rather than current
159 /// module (like paths in an import).
161 /// The segments in the path: the things separated by `::`.
162 segments: ~[PathSegment],
165 /// A segment of a path: an identifier, an optional lifetime, and a set of
167 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
168 pub struct PathSegment {
169 /// The identifier portion of this path segment.
171 /// The lifetime parameters for this path segment.
172 lifetimes: OptVec<Lifetime>,
173 /// The type parameters for this path segment, if present.
174 types: OptVec<P<Ty>>,
177 pub type CrateNum = u32;
179 pub type NodeId = u32;
181 #[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, IterBytes, ToStr)]
187 /// Item definitions in the currently-compiled crate would have the CrateNum
188 /// LOCAL_CRATE in their DefId.
189 pub static LOCAL_CRATE: CrateNum = 0;
190 pub static CRATE_NODE_ID: NodeId = 0;
192 // When parsing and doing expansions, we initially give all AST nodes this AST
193 // node value. Then later, in the renumber pass, we renumber them to have
194 // small, positive ids.
195 pub static DUMMY_NODE_ID: NodeId = -1;
197 // The AST represents all type param bounds as types.
198 // typeck::collect::compute_bounds matches these against
199 // the "special" built-in traits (see middle::lang_items) and
200 // detects Copy, Send, Send, and Freeze.
201 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
202 pub enum TyParamBound {
203 TraitTyParamBound(TraitRef),
207 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
211 bounds: OptVec<TyParamBound>,
212 default: Option<P<Ty>>
215 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
216 pub struct Generics {
217 lifetimes: OptVec<Lifetime>,
218 ty_params: OptVec<TyParam>,
222 pub fn is_parameterized(&self) -> bool {
223 self.lifetimes.len() + self.ty_params.len() > 0
225 pub fn is_lt_parameterized(&self) -> bool {
226 self.lifetimes.len() > 0
228 pub fn is_type_parameterized(&self) -> bool {
229 self.ty_params.len() > 0
233 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
234 pub enum MethodProvenance {
239 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
241 DefFn(DefId, Purity),
242 DefStaticMethod(/* method */ DefId, MethodProvenance, Purity),
243 DefSelfTy(/* trait id */ NodeId),
245 DefForeignMod(DefId),
246 DefStatic(DefId, bool /* is_mutbl */),
247 DefArg(NodeId, BindingMode),
248 DefLocal(NodeId, BindingMode),
249 DefVariant(DefId /* enum */, DefId /* variant */, bool /* is_structure */),
253 DefTyParam(DefId, uint),
254 DefBinding(NodeId, BindingMode),
256 DefUpvar(NodeId, // id of closed over var
257 @Def, // closed over def
258 NodeId, // expr node that creates the closure
259 NodeId), // id for the block/body of the closure expr
261 /// Note that if it's a tuple struct's definition, the node id of the DefId
262 /// may either refer to the item definition's id or the StructDef.ctor_id.
264 /// The cases that I have encountered so far are (this is not exhaustive):
265 /// - If it's a ty_path referring to some tuple struct, then DefMap maps
266 /// it to a def whose id is the item definition's id.
267 /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
268 /// it to a def whose id is the StructDef.ctor_id.
270 DefTyParamBinder(NodeId), /* struct, impl or trait with ty params */
273 DefMethod(DefId /* method */, Option<DefId> /* trait */),
276 #[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
279 DefEarlyBoundRegion(/* index */ uint, /* lifetime decl */ NodeId),
280 DefLateBoundRegion(/* binder_id */ NodeId, /* depth */ uint, /* lifetime decl */ NodeId),
281 DefFreeRegion(/* block scope */ NodeId, /* lifetime decl */ NodeId),
284 // The set of MetaItems that define the compilation environment of the crate,
285 // used to drive conditional compilation
286 pub type CrateConfig = ~[@MetaItem];
288 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
296 pub type MetaItem = Spanned<MetaItem_>;
298 #[deriving(Clone, Encodable, Decodable, IterBytes)]
300 MetaWord(InternedString),
301 MetaList(InternedString, ~[@MetaItem]),
302 MetaNameValue(InternedString, Lit),
305 // can't be derived because the MetaList requires an unordered comparison
306 impl Eq for MetaItem_ {
307 fn eq(&self, other: &MetaItem_) -> bool {
309 MetaWord(ref ns) => match *other {
310 MetaWord(ref no) => (*ns) == (*no),
313 MetaNameValue(ref ns, ref vs) => match *other {
314 MetaNameValue(ref no, ref vo) => {
315 (*ns) == (*no) && vs.node == vo.node
319 MetaList(ref ns, ref miss) => match *other {
320 MetaList(ref no, ref miso) => {
322 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
330 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
332 view_items: ~[ViewItem],
336 rules: BlockCheckMode,
340 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
347 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
348 pub struct FieldPat {
353 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
354 pub enum BindingMode {
355 BindByRef(Mutability),
356 BindByValue(Mutability),
359 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
363 // A PatIdent may either be a new bound variable,
364 // or a nullary enum (in which case the second field
366 // In the nullary enum case, the parser can't determine
367 // which it is. The resolver determines this, and
368 // records this pattern's NodeId in an auxiliary
369 // set (of "pat_idents that refer to nullary enums")
370 PatIdent(BindingMode, Path, Option<@Pat>),
371 PatEnum(Path, Option<~[@Pat]>), /* "none" means a * pattern where
372 * we don't bind the fields to names */
373 PatStruct(Path, ~[FieldPat], bool),
376 PatRegion(@Pat), // reference pattern
378 PatRange(@Expr, @Expr),
379 // [a, b, ..i, y, z] is represented as
380 // PatVec(~[a, b], Some(i), ~[y, z])
381 PatVec(~[@Pat], Option<@Pat>, ~[@Pat])
384 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
385 pub enum Mutability {
390 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
397 impl ToStr for Sigil {
398 fn to_str(&self) -> ~str {
400 BorrowedSigil => ~"&",
407 #[deriving(Eq, Encodable, Decodable, IterBytes)]
409 // FIXME (#3469): Change uint to @expr (actually only constant exprs)
410 VstoreFixed(Option<uint>), // [1,2,3,4]
411 VstoreUniq, // ~[1,2,3,4]
412 VstoreBox, // @[1,2,3,4]
413 VstoreSlice(Option<Lifetime>) // &'foo? [1,2,3,4]
416 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
417 pub enum ExprVstore {
418 ExprVstoreUniq, // ~[1,2,3,4]
419 ExprVstoreBox, // @[1,2,3,4]
420 ExprVstoreSlice, // &[1,2,3,4]
421 ExprVstoreMutSlice, // &mut [1,2,3,4]
424 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
446 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
455 pub type Stmt = Spanned<Stmt_>;
457 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
459 // could be an item or a local (let) binding:
460 StmtDecl(@Decl, NodeId),
462 // expr without trailing semi-colon (must have unit type):
463 StmtExpr(@Expr, NodeId),
465 // expr with trailing semi-colon (may have any type):
466 StmtSemi(@Expr, NodeId),
468 // bool: is there a trailing sem-colon?
472 // FIXME (pending discussion of #1697, #2178...): local should really be
473 // a refinement on pat.
474 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
475 #[deriving(Eq, Encodable, Decodable,IterBytes)]
484 pub type Decl = Spanned<Decl_>;
486 #[deriving(Eq, Encodable, Decodable,IterBytes)]
488 // a local (let) binding:
494 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
497 guard: Option<@Expr>,
501 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
508 pub type SpannedIdent = Spanned<Ident>;
510 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
511 pub enum BlockCheckMode {
513 UnsafeBlock(UnsafeSource),
516 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
517 pub enum UnsafeSource {
522 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
530 pub fn get_callee_id(&self) -> Option<NodeId> {
532 ExprMethodCall(callee_id, _, _, _, _) |
533 ExprIndex(callee_id, _, _) |
534 ExprBinary(callee_id, _, _, _) |
535 ExprAssignOp(callee_id, _, _, _) |
536 ExprUnary(callee_id, _, _) => Some(callee_id),
542 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
548 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
550 ExprVstore(@Expr, ExprVstore),
551 // First expr is the place; second expr is the value.
552 ExprBox(@Expr, @Expr),
553 ExprVec(~[@Expr], Mutability),
554 ExprCall(@Expr, ~[@Expr], CallSugar),
555 ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
557 ExprBinary(NodeId, BinOp, @Expr, @Expr),
558 ExprUnary(NodeId, UnOp, @Expr),
560 ExprCast(@Expr, P<Ty>),
561 ExprIf(@Expr, P<Block>, Option<@Expr>),
562 ExprWhile(@Expr, P<Block>),
563 // FIXME #6993: change to Option<Name>
564 ExprForLoop(@Pat, @Expr, P<Block>, Option<Ident>),
565 // Conditionless loop (can be exited with break, cont, or ret)
566 // FIXME #6993: change to Option<Name>
567 ExprLoop(P<Block>, Option<Ident>),
568 ExprMatch(@Expr, ~[Arm]),
569 ExprFnBlock(P<FnDecl>, P<Block>),
570 ExprProc(P<FnDecl>, P<Block>),
573 ExprAssign(@Expr, @Expr),
574 ExprAssignOp(NodeId, BinOp, @Expr, @Expr),
575 ExprField(@Expr, Ident, ~[P<Ty>]),
576 ExprIndex(NodeId, @Expr, @Expr),
578 /// Expression that looks like a "name". For example,
579 /// `std::vec::from_elem::<uint>` is an ExprPath that's the "name" part
580 /// of a function call.
583 ExprAddrOf(Mutability, @Expr),
584 ExprBreak(Option<Name>),
585 ExprAgain(Option<Name>),
586 ExprRet(Option<@Expr>),
588 /// Gets the log level for the enclosing module
591 ExprInlineAsm(InlineAsm),
595 // A struct literal expression.
596 ExprStruct(Path, ~[Field], Option<@Expr> /* base */),
598 // A vector literal constructed from one repeated element.
599 ExprRepeat(@Expr /* element */, @Expr /* count */, Mutability),
601 // No-op: used solely so we can pretty-print faithfully
605 // When the main rust parser encounters a syntax-extension invocation, it
606 // parses the arguments to the invocation as a token-tree. This is a very
607 // loose structure, such that all sorts of different AST-fragments can
608 // be passed to syntax extensions using a uniform type.
610 // If the syntax extension is an MBE macro, it will attempt to match its
611 // LHS "matchers" against the provided token tree, and if it finds a
612 // match, will transcribe the RHS token tree, splicing in any captured
613 // macro_parser::matched_nonterminals into the TTNonterminals it finds.
615 // The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
616 // makes any real sense. You could write them elsewhere but nothing
617 // else knows what to do with them, so you'll probably get a syntax
620 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
621 #[doc="For macro invocations; parsing is delegated to the macro"]
624 TTTok(Span, ::parse::token::Token),
625 // a delimited sequence (the delimiters appear as the first
626 // and last elements of the vector)
627 TTDelim(@~[TokenTree]),
629 // These only make sense for right-hand-sides of MBE macros:
631 // a kleene-style repetition sequence with a span, a TTForest,
632 // an optional separator, and a boolean where true indicates
633 // zero or more (..), and false indicates one or more (+).
634 TTSeq(Span, @~[TokenTree], Option<::parse::token::Token>, bool),
636 // a syntactic variable that will be filled in by macro expansion.
637 TTNonterminal(Span, Ident)
641 // Matchers are nodes defined-by and recognized-by the main rust parser and
642 // language, but they're only ever found inside syntax-extension invocations;
643 // indeed, the only thing that ever _activates_ the rules in the rust parser
644 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
645 // itself. Matchers represent a small sub-language for pattern-matching
646 // token-trees, and are thus primarily used by the macro-defining extension
652 // A matcher that matches a single token, denoted by the token itself. So
653 // long as there's no $ involved.
659 // A matcher that matches a sequence of sub-matchers, denoted various
662 // $(M)* zero or more Ms
663 // $(M)+ one or more Ms
664 // $(M),+ one or more comma-separated Ms
665 // $(A B C);* zero or more semi-separated 'A B C' seqs
671 // A matcher that matches one of a few interesting named rust
672 // nonterminals, such as types, expressions, items, or raw token-trees. A
673 // black-box matcher on expr, for example, binds an expr to a given ident,
674 // and that ident can re-occur as an interpolation in the RHS of a
675 // macro-by-example rule. For example:
677 // $foo:expr => 1 + $foo // interpolate an expr
678 // $foo:tt => $foo // interpolate a token-tree
679 // $foo:tt => bar! $foo // only other valid interpolation
680 // // is in arg position for another
683 // As a final, horrifying aside, note that macro-by-example's input is
684 // also matched by one of these matchers. Holy self-referential! It is matched
685 // by a MatchSeq, specifically this one:
687 // $( $lhs:matchers => $rhs:tt );+
689 // If you understand that, you have closed to loop and understand the whole
690 // macro system. Congratulations.
692 pub type Matcher = Spanned<Matcher_>;
694 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
697 MatchTok(::parse::token::Token),
698 // match repetitions of a sequence: body, separator, zero ok?,
699 // lo, hi position-in-match-array used:
700 MatchSeq(~[Matcher], Option<::parse::token::Token>, bool, uint, uint),
701 // parse a Rust NT: name to bind, name of NT, position in match array:
702 MatchNonterminal(Ident, Ident, uint)
705 pub type Mac = Spanned<Mac_>;
707 // represents a macro invocation. The Path indicates which macro
708 // is being invoked, and the vector of token-trees contains the source
709 // of the macro invocation.
710 // There's only one flavor, now, so this could presumably be simplified.
711 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
713 MacInvocTT(Path, ~[TokenTree], SyntaxContext), // new macro-invocation
716 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
722 pub type Lit = Spanned<Lit_>;
724 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
726 LitStr(InternedString, StrStyle),
730 LitUint(u64, UintTy),
731 LitIntUnsuffixed(i64),
732 LitFloat(InternedString, FloatTy),
733 LitFloatUnsuffixed(InternedString),
738 // NB: If you change this, you'll probably want to change the corresponding
739 // type structure in middle/ty.rs as well.
740 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
746 #[deriving(Eq, Encodable, Decodable,IterBytes)]
747 pub struct TypeField {
753 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
754 pub struct TypeMethod {
760 explicit_self: ExplicitSelf,
765 // A trait method is either required (meaning it doesn't have an
766 // implementation, just a signature) or provided (meaning it has a default
768 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
769 pub enum TraitMethod {
770 Required(TypeMethod),
774 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
783 impl ToStr for IntTy {
784 fn to_str(&self) -> ~str {
785 ast_util::int_ty_to_str(*self)
789 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
798 impl ToStr for UintTy {
799 fn to_str(&self) -> ~str {
800 ast_util::uint_ty_to_str(*self)
804 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
810 impl ToStr for FloatTy {
811 fn to_str(&self) -> ~str {
812 ast_util::float_ty_to_str(*self)
816 // NB Eq method appears below.
817 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
824 // Not represented directly in the AST, referred to by name through a ty_path.
825 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
835 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
841 impl ToStr for Onceness {
842 fn to_str(&self) -> ~str {
850 #[deriving(Eq, Encodable, Decodable,IterBytes)]
851 pub struct ClosureTy {
853 region: Option<Lifetime>,
854 lifetimes: OptVec<Lifetime>,
858 // Optional optvec distinguishes between "fn()" and "fn:()" so we can
859 // implement issue #7264. None means "fn()", which means infer a default
860 // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
861 // which means use no bounds (e.g., not even Owned on a ~fn()).
862 bounds: Option<OptVec<TyParamBound>>,
865 #[deriving(Eq, Encodable, Decodable,IterBytes)]
866 pub struct BareFnTy {
869 lifetimes: OptVec<Lifetime>,
873 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
876 TyBot, /* bottom type */
880 TyFixedLengthVec(P<Ty>, @Expr),
882 TyRptr(Option<Lifetime>, MutTy),
883 TyClosure(@ClosureTy),
886 TyPath(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
888 // TyInfer means the type should be inferred instead of it having been
889 // specified. This should only appear at the "top level" of a type and not
894 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
895 pub enum AsmDialect {
900 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
901 pub struct InlineAsm {
903 asm_str_style: StrStyle,
904 clobbers: InternedString,
905 inputs: ~[(InternedString, @Expr)],
906 outputs: ~[(InternedString, @Expr)],
912 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
920 pub fn new_self(span: Span, mutability: Mutability) -> Arg {
921 let path = ast_util::ident_to_path(span, special_idents::self_);
923 // HACK(eddyb) fake type for the self argument.
931 node: PatIdent(BindByValue(mutability), path, None),
939 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
947 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
949 UnsafeFn, // declared with "unsafe fn"
950 ImpureFn, // declared with "fn"
951 ExternFn, // declared with "extern fn"
954 impl ToStr for Purity {
955 fn to_str(&self) -> ~str {
957 ImpureFn => ~"impure",
958 UnsafeFn => ~"unsafe",
959 ExternFn => ~"extern"
964 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
966 NoReturn, // functions with return type _|_ that always
967 // raise an error or exit (i.e. never return to the caller)
968 Return, // everything else
971 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
972 pub enum ExplicitSelf_ {
973 SelfStatic, // no self
975 SelfRegion(Option<Lifetime>, Mutability), // `&'lt self`, `&'lt mut self`
980 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
982 #[deriving(Eq, Encodable, Decodable,IterBytes)]
987 explicit_self: ExplicitSelf,
996 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
998 view_items: ~[ViewItem],
1002 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1003 pub struct ForeignMod {
1005 view_items: ~[ViewItem],
1006 items: ~[@ForeignItem],
1009 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1010 pub struct VariantArg {
1015 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1016 pub enum VariantKind {
1017 TupleVariantKind(~[VariantArg]),
1018 StructVariantKind(@StructDef),
1021 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1022 pub struct EnumDef {
1023 variants: ~[P<Variant>],
1026 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1027 pub struct Variant_ {
1029 attrs: ~[Attribute],
1032 disr_expr: Option<@Expr>,
1036 pub type Variant = Spanned<Variant_>;
1038 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1039 pub struct PathListIdent_ {
1044 pub type PathListIdent = Spanned<PathListIdent_>;
1046 pub type ViewPath = Spanned<ViewPath_>;
1048 #[deriving(Eq, Encodable, Decodable, IterBytes)]
1049 pub enum ViewPath_ {
1051 // quux = foo::bar::baz
1055 // foo::bar::baz (with 'baz =' implicitly on the left)
1056 ViewPathSimple(Ident, Path, NodeId),
1059 ViewPathGlob(Path, NodeId),
1061 // foo::bar::{a,b,c}
1062 ViewPathList(Path, ~[PathListIdent], NodeId)
1065 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1066 pub struct ViewItem {
1068 attrs: ~[Attribute],
1073 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1074 pub enum ViewItem_ {
1075 // ident: name used to refer to this crate in the code
1076 // optional @str: if present, this is a location (containing
1077 // arbitrary characters) from which to fetch the crate sources
1078 // For example, extern mod whatever = "github.com/mozilla/rust"
1079 ViewItemExternMod(Ident, Option<(InternedString,StrStyle)>, NodeId),
1080 ViewItemUse(~[@ViewPath]),
1083 // Meta-data associated with an item
1084 pub type Attribute = Spanned<Attribute_>;
1086 // Distinguishes between Attributes that decorate items and Attributes that
1087 // are contained as statements within items. These two cases need to be
1088 // distinguished for pretty-printing.
1089 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1090 pub enum AttrStyle {
1095 // doc-comments are promoted to attributes that have is_sugared_doc = true
1096 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1097 pub struct Attribute_ {
1100 is_sugared_doc: bool,
1104 TraitRef's appear in impls.
1105 resolve maps each TraitRef's ref_id to its defining trait; that's all
1106 that the ref_id is for. The impl_id maps to the "self type" of this impl.
1107 If this impl is an ItemImpl, the impl_id is redundant (it could be the
1108 same as the impl's node id).
1110 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1111 pub struct TraitRef {
1116 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1117 pub enum Visibility {
1124 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1126 &Inherited => parent_visibility,
1127 &Public | &Private => *self
1132 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1133 pub struct StructField_ {
1134 kind: StructFieldKind,
1137 attrs: ~[Attribute],
1140 pub type StructField = Spanned<StructField_>;
1142 #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
1143 pub enum StructFieldKind {
1144 NamedField(Ident, Visibility),
1145 UnnamedField // element of a tuple-like struct
1148 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1149 pub struct StructDef {
1150 fields: ~[StructField], /* fields, not including ctor */
1151 /* ID of the constructor. This is only used for tuple- or enum-like
1153 ctor_id: Option<NodeId>
1157 FIXME (#3300): Should allow items to be anonymous. Right now
1158 we just use dummy names for anon items.
1160 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1163 attrs: ~[Attribute],
1170 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
1172 ItemStatic(P<Ty>, Mutability, @Expr),
1173 ItemFn(P<FnDecl>, Purity, AbiSet, Generics, P<Block>),
1175 ItemForeignMod(ForeignMod),
1176 ItemTy(P<Ty>, Generics),
1177 ItemEnum(EnumDef, Generics),
1178 ItemStruct(@StructDef, Generics),
1179 ItemTrait(Generics, ~[TraitRef], ~[TraitMethod]),
1181 Option<TraitRef>, // (optional) trait this impl implements
1184 // a macro invocation (which includes macro definition)
1188 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1189 pub struct ForeignItem {
1191 attrs: ~[Attribute],
1198 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1199 pub enum ForeignItem_ {
1200 ForeignItemFn(P<FnDecl>, Generics),
1201 ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1204 // The data we save and restore about an inlined item or method. This is not
1205 // part of the AST that we parse from a file, but it becomes part of the tree
1207 #[deriving(Eq, Encodable, Decodable,IterBytes)]
1208 pub enum InlinedItem {
1210 IIMethod(DefId /* impl id */, bool /* is provided */, @Method),
1211 IIForeign(@ForeignItem),
1220 fn is_freeze<T: Freeze>() {}
1222 // Assert that the AST remains Freeze (#10693).
1224 fn ast_is_freeze() {
1225 is_freeze::<Item>();
1228 // are ASTs encodable?
1230 fn check_asts_encodable() {
1232 module: Mod {view_items: ~[], items: ~[]},
1241 // doesn't matter which encoder we use....
1242 let _f = (@e as @extra::serialize::Encodable<extra::json::Encoder>);