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};
16 use owned_slice::OwnedSlice;
17 use parse::token::{InternedString, str_to_ident};
22 use std::option::Option;
24 use std::gc::{Gc, GC};
25 use serialize::{Encodable, Decodable, Encoder, Decoder};
27 /// A pointer abstraction.
28 // FIXME(eddyb) #10676 use Rc<T> in the future.
29 pub type P<T> = Gc<T>;
31 #[allow(non_snake_case_functions)]
32 /// Construct a P<T> from a T value.
33 pub fn P<T: 'static>(value: T) -> P<T> {
37 // FIXME #6993: in librustc, uses of "ident" should be replaced
40 /// An identifier contains a Name (index into the interner
41 /// table) and a SyntaxContext to track renaming and
42 /// macro expansion per Flatt et al., "Macros
43 /// That Work Together"
44 #[deriving(Clone, Hash, PartialOrd, Eq, Ord)]
47 pub ctxt: SyntaxContext
51 /// Construct an identifier with the given name and an empty context:
52 pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
54 pub fn as_str<'a>(&'a self) -> &'a str {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 write!(f, "{}#{}", self.name, self.ctxt)
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 write!(f, "\"{}\"({})", token::get_name(*self).get(), nm)
72 impl PartialEq for Ident {
73 fn eq(&self, other: &Ident) -> bool {
74 if self.ctxt == other.ctxt {
75 self.name == other.name
77 // IF YOU SEE ONE OF THESE FAILS: it means that you're comparing
78 // idents that have different contexts. You can't fix this without
79 // knowing whether the comparison should be hygienic or non-hygienic.
80 // if it should be non-hygienic (most things are), just compare the
81 // 'name' fields of the idents. Or, even better, replace the idents
84 // On the other hand, if the comparison does need to be hygienic,
85 // one example and its non-hygienic counterpart would be:
86 // syntax::parse::token::mtwt_token_eq
87 // syntax::ext::tt::macro_parser::token_name_eq
88 fail!("not allowed to compare these idents: {:?}, {:?}. \
89 Probably related to issue \\#6993", self, other);
92 fn ne(&self, other: &Ident) -> bool {
97 /// A SyntaxContext represents a chain of macro-expandings
98 /// and renamings. Each macro expansion corresponds to
101 // I'm representing this syntax context as an index into
102 // a table, in order to work around a compiler bug
103 // that's causing unreleased memory to cause core dumps
104 // and also perhaps to save some work in destructor checks.
105 // the special uint '0' will be used to indicate an empty
108 // this uint is a reference to a table stored in thread-local
110 pub type SyntaxContext = u32;
111 pub static EMPTY_CTXT : SyntaxContext = 0;
112 pub static ILLEGAL_CTXT : SyntaxContext = 1;
114 /// A name is a part of an identifier, representing a string or gensym. It's
115 /// the result of interning.
116 #[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
117 pub struct Name(pub u32);
120 pub fn as_str<'a>(&'a self) -> &'a str {
122 // FIXME #12938: can't use copy_lifetime since &str isn't a &T
123 ::std::mem::transmute(token::get_name(*self).get())
127 pub fn uint(&self) -> uint {
128 let Name(nm) = *self;
132 pub fn ident(&self) -> Ident {
133 Ident { name: *self, ctxt: 0 }
137 /// A mark represents a unique id associated with a macro expansion
140 impl<S: Encoder<E>, E> Encodable<S, E> for Ident {
141 fn encode(&self, s: &mut S) -> Result<(), E> {
142 s.emit_str(token::get_ident(*self).get())
146 impl<D:Decoder<E>, E> Decodable<D, E> for Ident {
147 fn decode(d: &mut D) -> Result<Ident, E> {
148 Ok(str_to_ident(try!(d.read_str()).as_slice()))
152 /// Function name (not all functions have names)
153 pub type FnIdent = Option<Ident>;
155 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
156 pub struct Lifetime {
162 /// A "Path" is essentially Rust's notion of a name; for instance:
163 /// std::cmp::PartialEq . It's represented as a sequence of identifiers,
164 /// along with a bunch of supporting information.
165 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
168 /// A `::foo` path, is relative to the crate root rather than current
169 /// module (like paths in an import).
171 /// The segments in the path: the things separated by `::`.
172 pub segments: Vec<PathSegment> ,
175 /// A segment of a path: an identifier, an optional lifetime, and a set of
177 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
178 pub struct PathSegment {
179 /// The identifier portion of this path segment.
180 pub identifier: Ident,
181 /// The lifetime parameters for this path segment.
182 pub lifetimes: Vec<Lifetime>,
183 /// The type parameters for this path segment, if present.
184 pub types: OwnedSlice<P<Ty>>,
187 pub type CrateNum = u32;
189 pub type NodeId = u32;
191 #[deriving(Clone, Eq, Ord, PartialOrd, PartialEq, Encodable, Decodable, Hash, Show)]
197 /// Item definitions in the currently-compiled crate would have the CrateNum
198 /// LOCAL_CRATE in their DefId.
199 pub static LOCAL_CRATE: CrateNum = 0;
200 pub static CRATE_NODE_ID: NodeId = 0;
202 /// When parsing and doing expansions, we initially give all AST nodes this AST
203 /// node value. Then later, in the renumber pass, we renumber them to have
204 /// small, positive ids.
205 pub static DUMMY_NODE_ID: NodeId = -1;
207 /// The AST represents all type param bounds as types.
208 /// typeck::collect::compute_bounds matches these against
209 /// the "special" built-in traits (see middle::lang_items) and
210 /// detects Copy, Send and Share.
211 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
212 pub enum TyParamBound {
213 TraitTyParamBound(TraitRef),
214 StaticRegionTyParamBound,
215 UnboxedFnTyParamBound(UnboxedFnTy),
216 OtherRegionTyParamBound(Span) // FIXME -- just here until work for #5723 lands
219 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
223 pub bounds: OwnedSlice<TyParamBound>,
224 pub unbound: Option<TyParamBound>,
225 pub default: Option<P<Ty>>,
229 /// Represents lifetimes and type parameters attached to a declaration
230 /// of a function, enum, trait, etc.
231 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
232 pub struct Generics {
233 pub lifetimes: Vec<Lifetime>,
234 pub ty_params: OwnedSlice<TyParam>,
238 pub fn is_parameterized(&self) -> bool {
239 self.lifetimes.len() + self.ty_params.len() > 0
241 pub fn is_lt_parameterized(&self) -> bool {
242 self.lifetimes.len() > 0
244 pub fn is_type_parameterized(&self) -> bool {
245 self.ty_params.len() > 0
249 /// The set of MetaItems that define the compilation environment of the crate,
250 /// used to drive conditional compilation
251 pub type CrateConfig = Vec<Gc<MetaItem>> ;
253 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
256 pub attrs: Vec<Attribute>,
257 pub config: CrateConfig,
259 pub exported_macros: Vec<Span>
262 pub type MetaItem = Spanned<MetaItem_>;
264 #[deriving(Clone, Encodable, Decodable, Eq, Hash)]
266 MetaWord(InternedString),
267 MetaList(InternedString, Vec<Gc<MetaItem>>),
268 MetaNameValue(InternedString, Lit),
271 // can't be derived because the MetaList requires an unordered comparison
272 impl PartialEq for MetaItem_ {
273 fn eq(&self, other: &MetaItem_) -> bool {
275 MetaWord(ref ns) => match *other {
276 MetaWord(ref no) => (*ns) == (*no),
279 MetaNameValue(ref ns, ref vs) => match *other {
280 MetaNameValue(ref no, ref vo) => {
281 (*ns) == (*no) && vs.node == vo.node
285 MetaList(ref ns, ref miss) => match *other {
286 MetaList(ref no, ref miso) => {
288 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
296 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
298 pub view_items: Vec<ViewItem>,
299 pub stmts: Vec<Gc<Stmt>>,
300 pub expr: Option<Gc<Expr>>,
302 pub rules: BlockCheckMode,
306 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
313 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
314 pub struct FieldPat {
319 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
320 pub enum BindingMode {
321 BindByRef(Mutability),
322 BindByValue(Mutability),
325 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
329 /// A PatIdent may either be a new bound variable,
330 /// or a nullary enum (in which case the third field
332 /// In the nullary enum case, the parser can't determine
333 /// which it is. The resolver determines this, and
334 /// records this pattern's NodeId in an auxiliary
335 /// set (of "PatIdents that refer to nullary enums")
336 PatIdent(BindingMode, SpannedIdent, Option<Gc<Pat>>),
337 PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
338 * we don't bind the fields to names */
339 PatStruct(Path, Vec<FieldPat>, bool),
340 PatTup(Vec<Gc<Pat>>),
342 PatRegion(Gc<Pat>), // reference pattern
344 PatRange(Gc<Expr>, Gc<Expr>),
345 /// [a, b, ..i, y, z] is represented as:
346 /// PatVec(~[a, b], Some(i), ~[y, z])
347 PatVec(Vec<Gc<Pat>>, Option<Gc<Pat>>, Vec<Gc<Pat>>),
351 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
352 pub enum Mutability {
357 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
358 pub enum ExprVstore {
363 /// &mut [1, 2, 3, 4]
367 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
389 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
398 pub type Stmt = Spanned<Stmt_>;
400 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
402 /// Could be an item or a local (let) binding:
403 StmtDecl(Gc<Decl>, NodeId),
405 /// Expr without trailing semi-colon (must have unit type):
406 StmtExpr(Gc<Expr>, NodeId),
408 /// Expr with trailing semi-colon (may have any type):
409 StmtSemi(Gc<Expr>, NodeId),
411 /// bool: is there a trailing sem-colon?
415 /// Where a local declaration came from: either a true `let ... =
416 /// ...;`, or one desugared from the pattern of a for loop.
417 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
418 pub enum LocalSource {
423 // FIXME (pending discussion of #1697, #2178...): local should really be
424 // a refinement on pat.
425 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
426 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
430 pub init: Option<Gc<Expr>>,
433 pub source: LocalSource,
436 pub type Decl = Spanned<Decl_>;
438 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
440 /// A local (let) binding:
441 DeclLocal(Gc<Local>),
446 /// represents one arm of a 'match'
447 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
449 pub attrs: Vec<Attribute>,
450 pub pats: Vec<Gc<Pat>>,
451 pub guard: Option<Gc<Expr>>,
455 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
457 pub ident: SpannedIdent,
462 pub type SpannedIdent = Spanned<Ident>;
464 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
465 pub enum BlockCheckMode {
467 UnsafeBlock(UnsafeSource),
470 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
471 pub enum UnsafeSource {
476 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
483 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
485 ExprVstore(Gc<Expr>, ExprVstore),
486 /// First expr is the place; second expr is the value.
487 ExprBox(Gc<Expr>, Gc<Expr>),
488 ExprVec(Vec<Gc<Expr>>),
489 ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
490 ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<Gc<Expr>>),
491 ExprTup(Vec<Gc<Expr>>),
492 ExprBinary(BinOp, Gc<Expr>, Gc<Expr>),
493 ExprUnary(UnOp, Gc<Expr>),
495 ExprCast(Gc<Expr>, P<Ty>),
496 ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
497 ExprWhile(Gc<Expr>, P<Block>),
498 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
499 ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
500 // Conditionless loop (can be exited with break, cont, or ret)
501 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
502 ExprLoop(P<Block>, Option<Ident>),
503 ExprMatch(Gc<Expr>, Vec<Arm>),
504 ExprFnBlock(P<FnDecl>, P<Block>),
505 ExprProc(P<FnDecl>, P<Block>),
508 ExprAssign(Gc<Expr>, Gc<Expr>),
509 ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
510 ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
511 ExprIndex(Gc<Expr>, Gc<Expr>),
513 /// Variable reference, possibly containing `::` and/or
514 /// type parameters, e.g. foo::bar::<baz>
517 ExprAddrOf(Mutability, Gc<Expr>),
518 ExprBreak(Option<Ident>),
519 ExprAgain(Option<Ident>),
520 ExprRet(Option<Gc<Expr>>),
522 ExprInlineAsm(InlineAsm),
526 /// A struct literal expression.
527 ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
529 /// A vector literal constructed from one repeated element.
530 ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
532 /// No-op: used solely so we can pretty-print faithfully
536 /// When the main rust parser encounters a syntax-extension invocation, it
537 /// parses the arguments to the invocation as a token-tree. This is a very
538 /// loose structure, such that all sorts of different AST-fragments can
539 /// be passed to syntax extensions using a uniform type.
541 /// If the syntax extension is an MBE macro, it will attempt to match its
542 /// LHS "matchers" against the provided token tree, and if it finds a
543 /// match, will transcribe the RHS token tree, splicing in any captured
544 /// macro_parser::matched_nonterminals into the TTNonterminals it finds.
546 /// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
547 /// makes any real sense. You could write them elsewhere but nothing
548 /// else knows what to do with them, so you'll probably get a syntax
550 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
551 #[doc="For macro invocations; parsing is delegated to the macro"]
554 TTTok(Span, ::parse::token::Token),
555 /// A delimited sequence (the delimiters appear as the first
556 /// and last elements of the vector)
557 // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
558 TTDelim(Rc<Vec<TokenTree>>),
560 // These only make sense for right-hand-sides of MBE macros:
562 /// A kleene-style repetition sequence with a span, a TTForest,
563 /// an optional separator, and a boolean where true indicates
564 /// zero or more (..), and false indicates one or more (+).
565 // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
566 TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
568 /// A syntactic variable that will be filled in by macro expansion.
569 TTNonterminal(Span, Ident)
572 // Matchers are nodes defined-by and recognized-by the main rust parser and
573 // language, but they're only ever found inside syntax-extension invocations;
574 // indeed, the only thing that ever _activates_ the rules in the rust parser
575 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
576 // itself. Matchers represent a small sub-language for pattern-matching
577 // token-trees, and are thus primarily used by the macro-defining extension
583 // A matcher that matches a single token, denoted by the token itself. So
584 // long as there's no $ involved.
590 // A matcher that matches a sequence of sub-matchers, denoted various
593 // $(M)* zero or more Ms
594 // $(M)+ one or more Ms
595 // $(M),+ one or more comma-separated Ms
596 // $(A B C);* zero or more semi-separated 'A B C' seqs
602 // A matcher that matches one of a few interesting named rust
603 // nonterminals, such as types, expressions, items, or raw token-trees. A
604 // black-box matcher on expr, for example, binds an expr to a given ident,
605 // and that ident can re-occur as an interpolation in the RHS of a
606 // macro-by-example rule. For example:
608 // $foo:expr => 1 + $foo // interpolate an expr
609 // $foo:tt => $foo // interpolate a token-tree
610 // $foo:tt => bar! $foo // only other valid interpolation
611 // // is in arg position for another
614 // As a final, horrifying aside, note that macro-by-example's input is
615 // also matched by one of these matchers. Holy self-referential! It is matched
616 // by a MatchSeq, specifically this one:
618 // $( $lhs:matchers => $rhs:tt );+
620 // If you understand that, you have closed the loop and understand the whole
621 // macro system. Congratulations.
622 pub type Matcher = Spanned<Matcher_>;
624 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
627 MatchTok(::parse::token::Token),
628 /// Match repetitions of a sequence: body, separator, zero ok?,
629 /// lo, hi position-in-match-array used:
630 MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
631 /// Parse a Rust NT: name to bind, name of NT, position in match array:
632 MatchNonterminal(Ident, Ident, uint)
635 pub type Mac = Spanned<Mac_>;
637 /// Represents a macro invocation. The Path indicates which macro
638 /// is being invoked, and the vector of token-trees contains the source
639 /// of the macro invocation.
640 /// There's only one flavor, now, so this could presumably be simplified.
641 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
643 MacInvocTT(Path, Vec<TokenTree> , SyntaxContext), // new macro-invocation
646 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
652 pub type Lit = Spanned<Lit_>;
654 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
656 LitStr(InternedString, StrStyle),
657 LitBinary(Rc<Vec<u8> >),
661 LitUint(u64, UintTy),
662 LitIntUnsuffixed(i64),
663 LitFloat(InternedString, FloatTy),
664 LitFloatUnsuffixed(InternedString),
669 // NB: If you change this, you'll probably want to change the corresponding
670 // type structure in middle/ty.rs as well.
671 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
674 pub mutbl: Mutability,
677 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
678 pub struct TypeField {
684 /// Represents a required method in a trait declaration,
685 /// one without a default implementation
686 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
687 pub struct TypeMethod {
689 pub attrs: Vec<Attribute>,
690 pub fn_style: FnStyle,
692 pub generics: Generics,
693 pub explicit_self: ExplicitSelf,
699 /// Represents a method declaration in a trait declaration, possibly including
700 /// a default implementation A trait method is either required (meaning it
701 /// doesn't have an implementation, just a signature) or provided (meaning it
702 /// has a default implementation).
703 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
704 pub enum TraitMethod {
705 Required(TypeMethod),
706 Provided(Gc<Method>),
709 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
718 impl fmt::Show for IntTy {
719 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
720 write!(f, "{}", ast_util::int_ty_to_string(*self, None))
725 pub fn suffix_len(&self) -> uint {
729 TyI16 | TyI32 | TyI64 => 3,
734 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
744 pub fn suffix_len(&self) -> uint {
748 TyU16 | TyU32 | TyU64 => 3,
753 impl fmt::Show for UintTy {
754 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
755 write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
759 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
765 impl fmt::Show for FloatTy {
766 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
767 write!(f, "{}", ast_util::float_ty_to_string(*self))
772 pub fn suffix_len(&self) -> uint {
774 TyF32 | TyF64 => 3, // add F128 handling here
779 // NB PartialEq method appears below.
780 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
787 /// Not represented directly in the AST, referred to by name through a ty_path.
788 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
798 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
804 impl fmt::Show for Onceness {
805 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
807 Once => "once".fmt(f),
808 Many => "many".fmt(f),
813 /// Represents the type of a closure
814 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
815 pub struct ClosureTy {
816 pub lifetimes: Vec<Lifetime>,
817 pub fn_style: FnStyle,
818 pub onceness: Onceness,
820 /// Optional optvec distinguishes between "fn()" and "fn:()" so we can
821 /// implement issue #7264. None means "fn()", which means infer a default
822 /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
823 /// which means use no bounds (e.g., not even Owned on a ~fn()).
824 pub bounds: Option<OwnedSlice<TyParamBound>>,
827 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
828 pub struct BareFnTy {
829 pub fn_style: FnStyle,
831 pub lifetimes: Vec<Lifetime>,
835 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
836 pub struct UnboxedFnTy {
840 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
843 TyBot, /* bottom type */
847 TyFixedLengthVec(P<Ty>, Gc<Expr>),
849 TyRptr(Option<Lifetime>, MutTy),
850 TyClosure(Gc<ClosureTy>, Option<Lifetime>),
851 TyProc(Gc<ClosureTy>),
852 TyBareFn(Gc<BareFnTy>),
853 TyUnboxedFn(Gc<UnboxedFnTy>),
855 TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
856 /// No-op; kept solely so that we can pretty-print faithfully
859 /// TyInfer means the type should be inferred instead of it having been
860 /// specified. This can appear anywhere in a type.
864 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
865 pub enum AsmDialect {
870 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
871 pub struct InlineAsm {
872 pub asm: InternedString,
873 pub asm_str_style: StrStyle,
874 pub clobbers: InternedString,
875 pub inputs: Vec<(InternedString, Gc<Expr>)>,
876 pub outputs: Vec<(InternedString, Gc<Expr>)>,
878 pub alignstack: bool,
879 pub dialect: AsmDialect
882 /// represents an argument in a function header
883 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
891 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
892 let path = Spanned{span:span,node:self_ident};
894 // HACK(eddyb) fake type for the self argument.
902 node: PatIdent(BindByValue(mutability), path, None),
910 /// represents the header (not the body) of a function declaration
911 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
913 pub inputs: Vec<Arg>,
919 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
921 /// Declared with "unsafe fn"
923 /// Declared with "fn"
927 impl fmt::Show for FnStyle {
928 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
930 NormalFn => "normal".fmt(f),
931 UnsafeFn => "unsafe".fmt(f),
936 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
938 /// Functions with return type ! that always
939 /// raise an error or exit (i.e. never return to the caller)
945 /// Represents the kind of 'self' associated with a method
946 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
947 pub enum ExplicitSelf_ {
952 /// `&'lt self`, `&'lt mut self`
953 SelfRegion(Option<Lifetime>, Mutability, Ident),
958 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
960 // Represents a method declaration
961 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
964 pub attrs: Vec<Attribute>,
965 pub generics: Generics,
966 pub explicit_self: ExplicitSelf,
967 pub fn_style: FnStyle,
975 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
977 /// A span from the first token past `{` to the last token until `}`.
978 /// For `mod foo;`, the inner span ranges from the first token
979 /// to the last token in the external file.
981 pub view_items: Vec<ViewItem>,
982 pub items: Vec<Gc<Item>>,
985 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
986 pub struct ForeignMod {
988 pub view_items: Vec<ViewItem>,
989 pub items: Vec<Gc<ForeignItem>>,
992 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
993 pub struct VariantArg {
998 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
999 pub enum VariantKind {
1000 TupleVariantKind(Vec<VariantArg>),
1001 StructVariantKind(Gc<StructDef>),
1004 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1005 pub struct EnumDef {
1006 pub variants: Vec<P<Variant>>,
1009 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1010 pub struct Variant_ {
1012 pub attrs: Vec<Attribute>,
1013 pub kind: VariantKind,
1015 pub disr_expr: Option<Gc<Expr>>,
1016 pub vis: Visibility,
1019 pub type Variant = Spanned<Variant_>;
1021 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1022 pub struct PathListIdent_ {
1027 pub type PathListIdent = Spanned<PathListIdent_>;
1029 pub type ViewPath = Spanned<ViewPath_>;
1031 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1032 pub enum ViewPath_ {
1034 /// `quux = foo::bar::baz`
1038 /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
1039 ViewPathSimple(Ident, Path, NodeId),
1042 ViewPathGlob(Path, NodeId),
1044 /// `foo::bar::{a,b,c}`
1045 ViewPathList(Path, Vec<PathListIdent> , NodeId)
1048 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1049 pub struct ViewItem {
1050 pub node: ViewItem_,
1051 pub attrs: Vec<Attribute>,
1052 pub vis: Visibility,
1056 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1057 pub enum ViewItem_ {
1058 /// Ident: name used to refer to this crate in the code
1059 /// optional (InternedString,StrStyle): if present, this is a location
1060 /// (containing arbitrary characters) from which to fetch the crate sources
1061 /// For example, extern crate whatever = "github.com/rust-lang/rust"
1062 ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
1063 ViewItemUse(Gc<ViewPath>),
1066 /// Meta-data associated with an item
1067 pub type Attribute = Spanned<Attribute_>;
1069 /// Distinguishes between Attributes that decorate items and Attributes that
1070 /// are contained as statements within items. These two cases need to be
1071 /// distinguished for pretty-printing.
1072 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1073 pub enum AttrStyle {
1078 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1079 pub struct AttrId(pub uint);
1081 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1082 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1083 pub struct Attribute_ {
1085 pub style: AttrStyle,
1086 pub value: Gc<MetaItem>,
1087 pub is_sugared_doc: bool,
1091 /// TraitRef's appear in impls.
1092 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1093 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1094 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1095 /// same as the impl's node id).
1096 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1097 pub struct TraitRef {
1102 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1103 pub enum Visibility {
1109 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1111 &Inherited => parent_visibility,
1117 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1118 pub struct StructField_ {
1119 pub kind: StructFieldKind,
1122 pub attrs: Vec<Attribute>,
1126 pub fn ident(&self) -> Option<Ident> {
1128 NamedField(ref ident, _) => Some(ident.clone()),
1129 UnnamedField(_) => None
1134 pub type StructField = Spanned<StructField_>;
1136 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1137 pub enum StructFieldKind {
1138 NamedField(Ident, Visibility),
1139 /// Element of a tuple-like struct
1140 UnnamedField(Visibility),
1143 impl StructFieldKind {
1144 pub fn is_unnamed(&self) -> bool {
1146 UnnamedField(..) => true,
1147 NamedField(..) => false,
1152 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1153 pub struct StructDef {
1154 /// Fields, not including ctor
1155 pub fields: Vec<StructField>,
1156 /// ID of the constructor. This is only used for tuple- or enum-like
1158 pub ctor_id: Option<NodeId>,
1159 /// Super struct, if specified.
1160 pub super_struct: Option<P<Ty>>,
1161 /// True iff the struct may be inherited from.
1162 pub is_virtual: bool,
1166 FIXME (#3300): Should allow items to be anonymous. Right now
1167 we just use dummy names for anon items.
1169 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1172 pub attrs: Vec<Attribute>,
1175 pub vis: Visibility,
1179 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
1181 ItemStatic(P<Ty>, Mutability, Gc<Expr>),
1182 ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
1184 ItemForeignMod(ForeignMod),
1185 ItemTy(P<Ty>, Generics),
1186 ItemEnum(EnumDef, Generics),
1187 ItemStruct(Gc<StructDef>, Generics),
1188 /// Represents a Trait Declaration
1190 Option<TyParamBound>, // (optional) default bound not required for Self.
1191 // Currently, only Sized makes sense here.
1195 Option<TraitRef>, // (optional) trait this impl implements
1198 /// A macro invocation (which includes macro definition)
1202 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1203 pub struct ForeignItem {
1205 pub attrs: Vec<Attribute>,
1206 pub node: ForeignItem_,
1209 pub vis: Visibility,
1212 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1213 pub enum ForeignItem_ {
1214 ForeignItemFn(P<FnDecl>, Generics),
1215 ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1218 /// The data we save and restore about an inlined item or method. This is not
1219 /// part of the AST that we parse from a file, but it becomes part of the tree
1221 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
1222 pub enum InlinedItem {
1224 IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
1225 IIForeign(Gc<ForeignItem>),
1230 use serialize::json;
1235 // are ASTs encodable?
1237 fn check_asts_encodable() {
1246 view_items: Vec::new(),
1256 exported_macros: Vec::new(),
1258 // doesn't matter which encoder we use....
1259 let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;