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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
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, Show)]
256 pub attrs: Vec<Attribute>,
257 pub config: CrateConfig,
259 pub exported_macros: Vec<Gc<Item>>
262 pub type MetaItem = Spanned<MetaItem_>;
264 #[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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, Show)]
313 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
314 pub struct FieldPat {
319 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
320 pub enum BindingMode {
321 BindByRef(Mutability),
322 BindByValue(Mutability),
325 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
358 pub enum ExprVstore {
363 /// &mut [1, 2, 3, 4]
367 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
389 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
398 pub type Stmt = Spanned<Stmt_>;
400 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
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(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
430 pub init: Option<Gc<Expr>>,
433 pub source: LocalSource,
436 pub type Decl = Spanned<Decl_>;
438 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
440 /// A local (let) binding:
441 DeclLocal(Gc<Local>),
446 /// represents one arm of a 'match'
447 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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, Show)]
457 pub ident: SpannedIdent,
462 pub type SpannedIdent = Spanned<Ident>;
464 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
465 pub enum BlockCheckMode {
467 UnsafeBlock(UnsafeSource),
470 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
471 pub enum UnsafeSource {
476 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
483 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
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>),
506 ExprUnboxedFn(P<FnDecl>, P<Block>),
509 ExprAssign(Gc<Expr>, Gc<Expr>),
510 ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
511 ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
512 ExprIndex(Gc<Expr>, Gc<Expr>),
514 /// Variable reference, possibly containing `::` and/or
515 /// type parameters, e.g. foo::bar::<baz>
518 ExprAddrOf(Mutability, Gc<Expr>),
519 ExprBreak(Option<Ident>),
520 ExprAgain(Option<Ident>),
521 ExprRet(Option<Gc<Expr>>),
523 ExprInlineAsm(InlineAsm),
527 /// A struct literal expression.
528 ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
530 /// A vector literal constructed from one repeated element.
531 ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
533 /// No-op: used solely so we can pretty-print faithfully
537 /// When the main rust parser encounters a syntax-extension invocation, it
538 /// parses the arguments to the invocation as a token-tree. This is a very
539 /// loose structure, such that all sorts of different AST-fragments can
540 /// be passed to syntax extensions using a uniform type.
542 /// If the syntax extension is an MBE macro, it will attempt to match its
543 /// LHS "matchers" against the provided token tree, and if it finds a
544 /// match, will transcribe the RHS token tree, splicing in any captured
545 /// macro_parser::matched_nonterminals into the TTNonterminals it finds.
547 /// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
548 /// makes any real sense. You could write them elsewhere but nothing
549 /// else knows what to do with them, so you'll probably get a syntax
551 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
552 #[doc="For macro invocations; parsing is delegated to the macro"]
555 TTTok(Span, ::parse::token::Token),
556 /// A delimited sequence (the delimiters appear as the first
557 /// and last elements of the vector)
558 // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
559 TTDelim(Rc<Vec<TokenTree>>),
561 // These only make sense for right-hand-sides of MBE macros:
563 /// A kleene-style repetition sequence with a span, a TTForest,
564 /// an optional separator, and a boolean where true indicates
565 /// zero or more (..), and false indicates one or more (+).
566 // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
567 TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
569 /// A syntactic variable that will be filled in by macro expansion.
570 TTNonterminal(Span, Ident)
573 // Matchers are nodes defined-by and recognized-by the main rust parser and
574 // language, but they're only ever found inside syntax-extension invocations;
575 // indeed, the only thing that ever _activates_ the rules in the rust parser
576 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
577 // itself. Matchers represent a small sub-language for pattern-matching
578 // token-trees, and are thus primarily used by the macro-defining extension
584 // A matcher that matches a single token, denoted by the token itself. So
585 // long as there's no $ involved.
591 // A matcher that matches a sequence of sub-matchers, denoted various
594 // $(M)* zero or more Ms
595 // $(M)+ one or more Ms
596 // $(M),+ one or more comma-separated Ms
597 // $(A B C);* zero or more semi-separated 'A B C' seqs
603 // A matcher that matches one of a few interesting named rust
604 // nonterminals, such as types, expressions, items, or raw token-trees. A
605 // black-box matcher on expr, for example, binds an expr to a given ident,
606 // and that ident can re-occur as an interpolation in the RHS of a
607 // macro-by-example rule. For example:
609 // $foo:expr => 1 + $foo // interpolate an expr
610 // $foo:tt => $foo // interpolate a token-tree
611 // $foo:tt => bar! $foo // only other valid interpolation
612 // // is in arg position for another
615 // As a final, horrifying aside, note that macro-by-example's input is
616 // also matched by one of these matchers. Holy self-referential! It is matched
617 // by a MatchSeq, specifically this one:
619 // $( $lhs:matchers => $rhs:tt );+
621 // If you understand that, you have closed the loop and understand the whole
622 // macro system. Congratulations.
623 pub type Matcher = Spanned<Matcher_>;
625 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
628 MatchTok(::parse::token::Token),
629 /// Match repetitions of a sequence: body, separator, zero ok?,
630 /// lo, hi position-in-match-array used:
631 MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
632 /// Parse a Rust NT: name to bind, name of NT, position in match array:
633 MatchNonterminal(Ident, Ident, uint)
636 pub type Mac = Spanned<Mac_>;
638 /// Represents a macro invocation. The Path indicates which macro
639 /// is being invoked, and the vector of token-trees contains the source
640 /// of the macro invocation.
641 /// There's only one flavor, now, so this could presumably be simplified.
642 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
644 // NB: the additional ident for a macro_rules-style macro is actually
645 // stored in the enclosing item. Oog.
646 MacInvocTT(Path, Vec<TokenTree> , SyntaxContext), // new macro-invocation
649 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
655 pub type Lit = Spanned<Lit_>;
657 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
659 LitStr(InternedString, StrStyle),
660 LitBinary(Rc<Vec<u8> >),
664 LitUint(u64, UintTy),
665 LitIntUnsuffixed(i64),
666 LitFloat(InternedString, FloatTy),
667 LitFloatUnsuffixed(InternedString),
672 // NB: If you change this, you'll probably want to change the corresponding
673 // type structure in middle/ty.rs as well.
674 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
677 pub mutbl: Mutability,
680 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
681 pub struct TypeField {
687 /// Represents a required method in a trait declaration,
688 /// one without a default implementation
689 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
690 pub struct TypeMethod {
692 pub attrs: Vec<Attribute>,
693 pub fn_style: FnStyle,
696 pub generics: Generics,
697 pub explicit_self: ExplicitSelf,
703 /// Represents a method declaration in a trait declaration, possibly including
704 /// a default implementation A trait method is either required (meaning it
705 /// doesn't have an implementation, just a signature) or provided (meaning it
706 /// has a default implementation).
707 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
708 pub enum TraitMethod {
709 Required(TypeMethod),
710 Provided(Gc<Method>),
713 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
722 impl fmt::Show for IntTy {
723 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
724 write!(f, "{}", ast_util::int_ty_to_string(*self, None))
729 pub fn suffix_len(&self) -> uint {
733 TyI16 | TyI32 | TyI64 => 3,
738 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
748 pub fn suffix_len(&self) -> uint {
752 TyU16 | TyU32 | TyU64 => 3,
757 impl fmt::Show for UintTy {
758 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
759 write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
763 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
769 impl fmt::Show for FloatTy {
770 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
771 write!(f, "{}", ast_util::float_ty_to_string(*self))
776 pub fn suffix_len(&self) -> uint {
778 TyF32 | TyF64 => 3, // add F128 handling here
783 // NB PartialEq method appears below.
784 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
791 /// Not represented directly in the AST, referred to by name through a ty_path.
792 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
802 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
808 impl fmt::Show for Onceness {
809 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
811 Once => "once".fmt(f),
812 Many => "many".fmt(f),
817 /// Represents the type of a closure
818 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)]
819 pub struct ClosureTy {
820 pub lifetimes: Vec<Lifetime>,
821 pub fn_style: FnStyle,
822 pub onceness: Onceness,
824 /// Optional optvec distinguishes between "fn()" and "fn:()" so we can
825 /// implement issue #7264. None means "fn()", which means infer a default
826 /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
827 /// which means use no bounds (e.g., not even Owned on a ~fn()).
828 pub bounds: Option<OwnedSlice<TyParamBound>>,
831 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)]
832 pub struct BareFnTy {
833 pub fn_style: FnStyle,
835 pub lifetimes: Vec<Lifetime>,
839 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
840 pub struct UnboxedFnTy {
844 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
847 TyBot, /* bottom type */
851 TyFixedLengthVec(P<Ty>, Gc<Expr>),
853 TyRptr(Option<Lifetime>, MutTy),
854 TyClosure(Gc<ClosureTy>, Option<Lifetime>),
855 TyProc(Gc<ClosureTy>),
856 TyBareFn(Gc<BareFnTy>),
857 TyUnboxedFn(Gc<UnboxedFnTy>),
859 TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
860 /// No-op; kept solely so that we can pretty-print faithfully
863 /// TyInfer means the type should be inferred instead of it having been
864 /// specified. This can appear anywhere in a type.
868 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
869 pub enum AsmDialect {
874 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
875 pub struct InlineAsm {
876 pub asm: InternedString,
877 pub asm_str_style: StrStyle,
878 pub clobbers: InternedString,
879 pub inputs: Vec<(InternedString, Gc<Expr>)>,
880 pub outputs: Vec<(InternedString, Gc<Expr>)>,
882 pub alignstack: bool,
883 pub dialect: AsmDialect
886 /// represents an argument in a function header
887 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
895 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
896 let path = Spanned{span:span,node:self_ident};
898 // HACK(eddyb) fake type for the self argument.
906 node: PatIdent(BindByValue(mutability), path, None),
914 /// represents the header (not the body) of a function declaration
915 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
917 pub inputs: Vec<Arg>,
923 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
925 /// Declared with "unsafe fn"
927 /// Declared with "fn"
931 impl fmt::Show for FnStyle {
932 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
934 NormalFn => "normal".fmt(f),
935 UnsafeFn => "unsafe".fmt(f),
940 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
942 /// Functions with return type ! that always
943 /// raise an error or exit (i.e. never return to the caller)
949 /// Represents the kind of 'self' associated with a method
950 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
951 pub enum ExplicitSelf_ {
956 /// `&'lt self`, `&'lt mut self`
957 SelfRegion(Option<Lifetime>, Mutability, Ident),
959 SelfExplicit(P<Ty>, Ident),
962 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
964 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
966 pub attrs: Vec<Attribute>,
972 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
974 /// Represents a method declaration
983 /// Represents a macro in method position
987 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
989 /// A span from the first token past `{` to the last token until `}`.
990 /// For `mod foo;`, the inner span ranges from the first token
991 /// to the last token in the external file.
993 pub view_items: Vec<ViewItem>,
994 pub items: Vec<Gc<Item>>,
997 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
998 pub struct ForeignMod {
1000 pub view_items: Vec<ViewItem>,
1001 pub items: Vec<Gc<ForeignItem>>,
1004 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1005 pub struct VariantArg {
1010 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1011 pub enum VariantKind {
1012 TupleVariantKind(Vec<VariantArg>),
1013 StructVariantKind(Gc<StructDef>),
1016 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1017 pub struct EnumDef {
1018 pub variants: Vec<P<Variant>>,
1021 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1022 pub struct Variant_ {
1024 pub attrs: Vec<Attribute>,
1025 pub kind: VariantKind,
1027 pub disr_expr: Option<Gc<Expr>>,
1028 pub vis: Visibility,
1031 pub type Variant = Spanned<Variant_>;
1033 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1034 pub enum PathListItem_ {
1035 PathListIdent { pub name: Ident, pub id: NodeId },
1036 PathListMod { pub id: NodeId }
1039 impl PathListItem_ {
1040 pub fn id(&self) -> NodeId {
1042 PathListIdent { id, .. } | PathListMod { id } => id
1047 pub type PathListItem = Spanned<PathListItem_>;
1049 pub type ViewPath = Spanned<ViewPath_>;
1051 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1052 pub enum ViewPath_ {
1054 /// `quux = foo::bar::baz`
1058 /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
1059 ViewPathSimple(Ident, Path, NodeId),
1062 ViewPathGlob(Path, NodeId),
1064 /// `foo::bar::{a,b,c}`
1065 ViewPathList(Path, Vec<PathListItem> , NodeId)
1068 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1069 pub struct ViewItem {
1070 pub node: ViewItem_,
1071 pub attrs: Vec<Attribute>,
1072 pub vis: Visibility,
1076 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1077 pub enum ViewItem_ {
1078 /// Ident: name used to refer to this crate in the code
1079 /// optional (InternedString,StrStyle): if present, this is a location
1080 /// (containing arbitrary characters) from which to fetch the crate sources
1081 /// For example, extern crate whatever = "github.com/rust-lang/rust"
1082 ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
1083 ViewItemUse(Gc<ViewPath>),
1086 /// Meta-data associated with an item
1087 pub type Attribute = Spanned<Attribute_>;
1089 /// Distinguishes between Attributes that decorate items and Attributes that
1090 /// are contained as statements within items. These two cases need to be
1091 /// distinguished for pretty-printing.
1092 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1093 pub enum AttrStyle {
1098 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1099 pub struct AttrId(pub uint);
1101 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1102 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1103 pub struct Attribute_ {
1105 pub style: AttrStyle,
1106 pub value: Gc<MetaItem>,
1107 pub is_sugared_doc: bool,
1111 /// TraitRef's appear in impls.
1112 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1113 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1114 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1115 /// same as the impl's node id).
1116 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1117 pub struct TraitRef {
1122 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1123 pub enum Visibility {
1129 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1131 &Inherited => parent_visibility,
1137 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1138 pub struct StructField_ {
1139 pub kind: StructFieldKind,
1142 pub attrs: Vec<Attribute>,
1146 pub fn ident(&self) -> Option<Ident> {
1148 NamedField(ref ident, _) => Some(ident.clone()),
1149 UnnamedField(_) => None
1154 pub type StructField = Spanned<StructField_>;
1156 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1157 pub enum StructFieldKind {
1158 NamedField(Ident, Visibility),
1159 /// Element of a tuple-like struct
1160 UnnamedField(Visibility),
1163 impl StructFieldKind {
1164 pub fn is_unnamed(&self) -> bool {
1166 UnnamedField(..) => true,
1167 NamedField(..) => false,
1172 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1173 pub struct StructDef {
1174 /// Fields, not including ctor
1175 pub fields: Vec<StructField>,
1176 /// ID of the constructor. This is only used for tuple- or enum-like
1178 pub ctor_id: Option<NodeId>,
1179 /// Super struct, if specified.
1180 pub super_struct: Option<P<Ty>>,
1181 /// True iff the struct may be inherited from.
1182 pub is_virtual: bool,
1186 FIXME (#3300): Should allow items to be anonymous. Right now
1187 we just use dummy names for anon items.
1189 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1192 pub attrs: Vec<Attribute>,
1195 pub vis: Visibility,
1199 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1201 ItemStatic(P<Ty>, Mutability, Gc<Expr>),
1202 ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
1204 ItemForeignMod(ForeignMod),
1205 ItemTy(P<Ty>, Generics),
1206 ItemEnum(EnumDef, Generics),
1207 ItemStruct(Gc<StructDef>, Generics),
1208 /// Represents a Trait Declaration
1210 Option<TyParamBound>, // (optional) default bound not required for Self.
1211 // Currently, only Sized makes sense here.
1215 Option<TraitRef>, // (optional) trait this impl implements
1218 /// A macro invocation (which includes macro definition)
1222 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1223 pub struct ForeignItem {
1225 pub attrs: Vec<Attribute>,
1226 pub node: ForeignItem_,
1229 pub vis: Visibility,
1232 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1233 pub enum ForeignItem_ {
1234 ForeignItemFn(P<FnDecl>, Generics),
1235 ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1238 /// The data we save and restore about an inlined item or method. This is not
1239 /// part of the AST that we parse from a file, but it becomes part of the tree
1241 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1242 pub enum InlinedItem {
1244 IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
1245 IIForeign(Gc<ForeignItem>),
1250 use serialize::json;
1255 // are ASTs encodable?
1257 fn check_asts_encodable() {
1266 view_items: Vec::new(),
1276 exported_macros: Vec::new(),
1278 // doesn't matter which encoder we use....
1279 let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;