]> git.proxmox.com Git - rustc.git/blame - src/libsyntax/ast.rs
* Introduce some changes by Angus Lees
[rustc.git] / src / libsyntax / ast.rs
CommitLineData
1a4d82fc 1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
11// The Rust abstract syntax tree.
12
1a4d82fc
JJ
13pub use self::AsmDialect::*;
14pub use self::AttrStyle::*;
15pub use self::BindingMode::*;
16pub use self::BinOp::*;
17pub use self::BlockCheckMode::*;
18pub use self::CaptureClause::*;
19pub use self::Decl_::*;
20pub use self::ExplicitSelf_::*;
21pub use self::Expr_::*;
22pub use self::FloatTy::*;
23pub use self::FunctionRetTy::*;
24pub use self::ForeignItem_::*;
25pub use self::ImplItem::*;
26pub use self::InlinedItem::*;
27pub use self::IntTy::*;
28pub use self::Item_::*;
29pub use self::KleeneOp::*;
30pub use self::Lit_::*;
31pub use self::LitIntType::*;
32pub use self::LocalSource::*;
33pub use self::Mac_::*;
34pub use self::MacStmtStyle::*;
35pub use self::MetaItem_::*;
36pub use self::Method_::*;
37pub use self::Mutability::*;
38pub use self::Onceness::*;
39pub use self::Pat_::*;
40pub use self::PathListItem_::*;
41pub use self::PatWildKind::*;
42pub use self::PrimTy::*;
43pub use self::Sign::*;
44pub use self::Stmt_::*;
45pub use self::StrStyle::*;
46pub use self::StructFieldKind::*;
47pub use self::TokenTree::*;
48pub use self::TraitItem::*;
49pub use self::Ty_::*;
50pub use self::TyParamBound::*;
51pub use self::UintTy::*;
52pub use self::UnboxedClosureKind::*;
53pub use self::UnOp::*;
54pub use self::UnsafeSource::*;
55pub use self::VariantKind::*;
56pub use self::ViewItem_::*;
57pub use self::ViewPath_::*;
58pub use self::Visibility::*;
59pub use self::PathParameters::*;
60
61use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
62use abi::Abi;
63use ast_util;
64use owned_slice::OwnedSlice;
65use parse::token::{InternedString, str_to_ident};
66use parse::token;
67use ptr::P;
68
69use std::fmt;
70use std::fmt::Show;
71use std::num::Int;
72use std::rc::Rc;
73use serialize::{Encodable, Decodable, Encoder, Decoder};
74
75// FIXME #6993: in librustc, uses of "ident" should be replaced
76// by just "Name".
77
78/// An identifier contains a Name (index into the interner
79/// table) and a SyntaxContext to track renaming and
80/// macro expansion per Flatt et al., "Macros
81/// That Work Together"
82#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
83pub struct Ident {
84 pub name: Name,
85 pub ctxt: SyntaxContext
86}
87
88impl Ident {
89 /// Construct an identifier with the given name and an empty context:
90 pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
91
92 pub fn as_str<'a>(&'a self) -> &'a str {
93 self.name.as_str()
94 }
223e47cc 95
1a4d82fc
JJ
96 pub fn encode_with_hygiene(&self) -> String {
97 format!("\x00name_{},ctxt_{}\x00",
98 self.name.uint(),
99 self.ctxt)
100 }
101}
223e47cc 102
1a4d82fc
JJ
103impl fmt::Show for Ident {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "{}#{}", self.name, self.ctxt)
106 }
107}
970d7e83 108
1a4d82fc
JJ
109impl fmt::String for Ident {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111 fmt::String::fmt(&self.name, f)
112 }
113}
223e47cc 114
1a4d82fc
JJ
115impl fmt::Show for Name {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 let Name(nm) = *self;
118 write!(f, "{:?}({})", token::get_name(*self).get(), nm)
119 }
120}
121
122impl fmt::String for Name {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 fmt::String::fmt(token::get_name(*self).get(), f)
125 }
126}
127
128impl PartialEq for Ident {
129 fn eq(&self, other: &Ident) -> bool {
130 if self.ctxt == other.ctxt {
131 self.name == other.name
132 } else {
133 // IF YOU SEE ONE OF THESE FAILS: it means that you're comparing
134 // idents that have different contexts. You can't fix this without
135 // knowing whether the comparison should be hygienic or non-hygienic.
136 // if it should be non-hygienic (most things are), just compare the
137 // 'name' fields of the idents. Or, even better, replace the idents
138 // with Name's.
139 //
140 // On the other hand, if the comparison does need to be hygienic,
141 // one example and its non-hygienic counterpart would be:
142 // syntax::parse::token::Token::mtwt_eq
143 // syntax::ext::tt::macro_parser::token_name_eq
144 panic!("not allowed to compare these idents: {}, {}. \
145 Probably related to issue \\#6993", self, other);
146 }
147 }
148 fn ne(&self, other: &Ident) -> bool {
149 ! self.eq(other)
150 }
151}
152
153/// A SyntaxContext represents a chain of macro-expandings
154/// and renamings. Each macro expansion corresponds to
155/// a fresh uint
223e47cc 156
970d7e83
LB
157// I'm representing this syntax context as an index into
158// a table, in order to work around a compiler bug
159// that's causing unreleased memory to cause core dumps
160// and also perhaps to save some work in destructor checks.
161// the special uint '0' will be used to indicate an empty
162// syntax context.
163
164// this uint is a reference to a table stored in thread-local
165// storage.
1a4d82fc
JJ
166pub type SyntaxContext = u32;
167pub const EMPTY_CTXT : SyntaxContext = 0;
168pub const ILLEGAL_CTXT : SyntaxContext = 1;
169
170/// A name is a part of an identifier, representing a string or gensym. It's
171/// the result of interning.
172#[derive(Eq, Ord, PartialEq, PartialOrd, Hash,
173 RustcEncodable, RustcDecodable, Clone, Copy)]
174pub struct Name(pub u32);
175
176impl Name {
177 pub fn as_str<'a>(&'a self) -> &'a str {
178 unsafe {
179 // FIXME #12938: can't use copy_lifetime since &str isn't a &T
180 ::std::mem::transmute::<&str,&str>(token::get_name(*self).get())
181 }
182 }
183
184 pub fn uint(&self) -> uint {
185 let Name(nm) = *self;
186 nm as uint
187 }
188
189 pub fn ident(&self) -> Ident {
190 Ident { name: *self, ctxt: 0 }
223e47cc
LB
191 }
192}
193
1a4d82fc
JJ
194/// A mark represents a unique id associated with a macro expansion
195pub type Mrk = u32;
196
197impl Encodable for Ident {
198 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
199 s.emit_str(token::get_ident(*self).get())
223e47cc
LB
200 }
201}
202
1a4d82fc
JJ
203impl Decodable for Ident {
204 fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
205 Ok(str_to_ident(&try!(d.read_str())[]))
206 }
207}
223e47cc 208
1a4d82fc
JJ
209/// Function name (not all functions have names)
210pub type FnIdent = Option<Ident>;
211
212#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,
213 Show, Copy)]
223e47cc 214pub struct Lifetime {
1a4d82fc
JJ
215 pub id: NodeId,
216 pub span: Span,
217 pub name: Name
218}
219
220#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
221pub struct LifetimeDef {
222 pub lifetime: Lifetime,
223 pub bounds: Vec<Lifetime>
223e47cc
LB
224}
225
1a4d82fc
JJ
226/// A "Path" is essentially Rust's notion of a name; for instance:
227/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
228/// along with a bunch of supporting information.
229#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
970d7e83 230pub struct Path {
1a4d82fc
JJ
231 pub span: Span,
232 /// A `::foo` path, is relative to the crate root rather than current
233 /// module (like paths in an import).
234 pub global: bool,
235 /// The segments in the path: the things separated by `::`.
236 pub segments: Vec<PathSegment>,
237}
238
239/// A segment of a path: an identifier, an optional lifetime, and a set of
240/// types.
241#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
242pub struct PathSegment {
243 /// The identifier portion of this path segment.
244 pub identifier: Ident,
245
246 /// Type/lifetime parameters attached to this path. They come in
247 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
248 /// this is more than just simple syntactic sugar; the use of
249 /// parens affects the region binding rules, so we preserve the
250 /// distinction.
251 pub parameters: PathParameters,
252}
253
254#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
255pub enum PathParameters {
256 AngleBracketedParameters(AngleBracketedParameterData),
257 ParenthesizedParameters(ParenthesizedParameterData),
258}
259
260impl PathParameters {
261 pub fn none() -> PathParameters {
262 AngleBracketedParameters(AngleBracketedParameterData {
263 lifetimes: Vec::new(),
264 types: OwnedSlice::empty(),
265 bindings: OwnedSlice::empty(),
266 })
267 }
268
269 pub fn is_empty(&self) -> bool {
270 match *self {
271 AngleBracketedParameters(ref data) => data.is_empty(),
272
273 // Even if the user supplied no types, something like
274 // `X()` is equivalent to `X<(),()>`.
275 ParenthesizedParameters(..) => false,
276 }
277 }
278
279 pub fn has_lifetimes(&self) -> bool {
280 match *self {
281 AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
282 ParenthesizedParameters(_) => false,
283 }
284 }
285
286 pub fn has_types(&self) -> bool {
287 match *self {
288 AngleBracketedParameters(ref data) => !data.types.is_empty(),
289 ParenthesizedParameters(..) => true,
290 }
291 }
292
293 /// Returns the types that the user wrote. Note that these do not necessarily map to the type
294 /// parameters in the parenthesized case.
295 pub fn types(&self) -> Vec<&P<Ty>> {
296 match *self {
297 AngleBracketedParameters(ref data) => {
298 data.types.iter().collect()
299 }
300 ParenthesizedParameters(ref data) => {
301 data.inputs.iter()
302 .chain(data.output.iter())
303 .collect()
304 }
305 }
306 }
307
308 pub fn lifetimes(&self) -> Vec<&Lifetime> {
309 match *self {
310 AngleBracketedParameters(ref data) => {
311 data.lifetimes.iter().collect()
312 }
313 ParenthesizedParameters(_) => {
314 Vec::new()
315 }
316 }
317 }
318
319 pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
320 match *self {
321 AngleBracketedParameters(ref data) => {
322 data.bindings.iter().collect()
323 }
324 ParenthesizedParameters(_) => {
325 Vec::new()
326 }
327 }
328 }
329}
330
331/// A path like `Foo<'a, T>`
332#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
333pub struct AngleBracketedParameterData {
334 /// The lifetime parameters for this path segment.
335 pub lifetimes: Vec<Lifetime>,
336 /// The type parameters for this path segment, if present.
337 pub types: OwnedSlice<P<Ty>>,
338 /// Bindings (equality constraints) on associated types, if present.
339 /// E.g., `Foo<A=Bar>`.
340 pub bindings: OwnedSlice<P<TypeBinding>>,
223e47cc
LB
341}
342
1a4d82fc
JJ
343impl AngleBracketedParameterData {
344 fn is_empty(&self) -> bool {
345 self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
346 }
347}
348
349/// A path like `Foo(A,B) -> C`
350#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
351pub struct ParenthesizedParameterData {
352 /// `(A,B)`
353 pub inputs: Vec<P<Ty>>,
354
355 /// `C`
356 pub output: Option<P<Ty>>,
357}
358
359pub type CrateNum = u32;
223e47cc 360
1a4d82fc 361pub type NodeId = u32;
223e47cc 362
1a4d82fc
JJ
363#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
364 RustcDecodable, Hash, Show, Copy)]
365pub struct DefId {
366 pub krate: CrateNum,
367 pub node: NodeId,
223e47cc
LB
368}
369
1a4d82fc
JJ
370/// Item definitions in the currently-compiled crate would have the CrateNum
371/// LOCAL_CRATE in their DefId.
372pub const LOCAL_CRATE: CrateNum = 0;
373pub const CRATE_NODE_ID: NodeId = 0;
223e47cc 374
1a4d82fc
JJ
375/// When parsing and doing expansions, we initially give all AST nodes this AST
376/// node value. Then later, in the renumber pass, we renumber them to have
377/// small, positive ids.
378pub const DUMMY_NODE_ID: NodeId = -1;
379
380/// The AST represents all type param bounds as types.
381/// typeck::collect::compute_bounds matches these against
382/// the "special" built-in traits (see middle::lang_items) and
383/// detects Copy, Send and Sync.
384#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
223e47cc 385pub enum TyParamBound {
1a4d82fc
JJ
386 TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
387 RegionTyParamBound(Lifetime)
223e47cc
LB
388}
389
1a4d82fc
JJ
390/// A modifier on a bound, currently this is only used for `?Sized`, where the
391/// modifier is `Maybe`. Negative bounds should also be handled here.
392#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
393pub enum TraitBoundModifier {
394 None,
395 Maybe,
396}
397
398pub type TyParamBounds = OwnedSlice<TyParamBound>;
399
400#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
223e47cc 401pub struct TyParam {
1a4d82fc
JJ
402 pub ident: Ident,
403 pub id: NodeId,
404 pub bounds: TyParamBounds,
405 pub default: Option<P<Ty>>,
406 pub span: Span
223e47cc
LB
407}
408
1a4d82fc
JJ
409/// Represents lifetimes and type parameters attached to a declaration
410/// of a function, enum, trait, etc.
411#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
223e47cc 412pub struct Generics {
1a4d82fc
JJ
413 pub lifetimes: Vec<LifetimeDef>,
414 pub ty_params: OwnedSlice<TyParam>,
415 pub where_clause: WhereClause,
223e47cc
LB
416}
417
970d7e83
LB
418impl Generics {
419 pub fn is_parameterized(&self) -> bool {
223e47cc
LB
420 self.lifetimes.len() + self.ty_params.len() > 0
421 }
970d7e83 422 pub fn is_lt_parameterized(&self) -> bool {
223e47cc
LB
423 self.lifetimes.len() > 0
424 }
970d7e83 425 pub fn is_type_parameterized(&self) -> bool {
223e47cc
LB
426 self.ty_params.len() > 0
427 }
428}
429
1a4d82fc
JJ
430#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
431pub struct WhereClause {
432 pub id: NodeId,
433 pub predicates: Vec<WherePredicate>,
223e47cc
LB
434}
435
1a4d82fc
JJ
436#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
437pub enum WherePredicate {
438 BoundPredicate(WhereBoundPredicate),
439 RegionPredicate(WhereRegionPredicate),
440 EqPredicate(WhereEqPredicate)
223e47cc
LB
441}
442
1a4d82fc
JJ
443#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
444pub struct WhereBoundPredicate {
445 pub span: Span,
446 pub bounded_ty: P<Ty>,
447 pub bounds: OwnedSlice<TyParamBound>,
223e47cc
LB
448}
449
1a4d82fc
JJ
450#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
451pub struct WhereRegionPredicate {
452 pub span: Span,
453 pub lifetime: Lifetime,
454 pub bounds: Vec<Lifetime>,
455}
223e47cc 456
1a4d82fc
JJ
457#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
458pub struct WhereEqPredicate {
459 pub id: NodeId,
460 pub span: Span,
461 pub path: Path,
462 pub ty: P<Ty>,
463}
464
465/// The set of MetaItems that define the compilation environment of the crate,
466/// used to drive conditional compilation
467pub type CrateConfig = Vec<P<MetaItem>> ;
223e47cc 468
1a4d82fc
JJ
469#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
470pub struct Crate {
471 pub module: Mod,
472 pub attrs: Vec<Attribute>,
473 pub config: CrateConfig,
474 pub span: Span,
475 pub exported_macros: Vec<MacroDef>,
970d7e83 476}
223e47cc 477
1a4d82fc
JJ
478pub type MetaItem = Spanned<MetaItem_>;
479
480#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
481pub enum MetaItem_ {
482 MetaWord(InternedString),
483 MetaList(InternedString, Vec<P<MetaItem>>),
484 MetaNameValue(InternedString, Lit),
485}
486
487// can't be derived because the MetaList requires an unordered comparison
488impl PartialEq for MetaItem_ {
489 fn eq(&self, other: &MetaItem_) -> bool {
490 match *self {
491 MetaWord(ref ns) => match *other {
492 MetaWord(ref no) => (*ns) == (*no),
493 _ => false
494 },
495 MetaNameValue(ref ns, ref vs) => match *other {
496 MetaNameValue(ref no, ref vo) => {
497 (*ns) == (*no) && vs.node == vo.node
498 }
499 _ => false
500 },
501 MetaList(ref ns, ref miss) => match *other {
502 MetaList(ref no, ref miso) => {
503 ns == no &&
504 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
505 }
506 _ => false
507 }
508 }
509 }
223e47cc
LB
510}
511
1a4d82fc
JJ
512#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
513pub struct Block {
514 pub view_items: Vec<ViewItem>,
515 pub stmts: Vec<P<Stmt>>,
516 pub expr: Option<P<Expr>>,
517 pub id: NodeId,
518 pub rules: BlockCheckMode,
519 pub span: Span,
520}
521
522#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
523pub struct Pat {
524 pub id: NodeId,
525 pub node: Pat_,
526 pub span: Span,
527}
528
529#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
530pub struct FieldPat {
531 pub ident: Ident,
532 pub pat: P<Pat>,
533 pub is_shorthand: bool,
534}
535
536#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
537pub enum BindingMode {
538 BindByRef(Mutability),
539 BindByValue(Mutability),
540}
541
542#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
543pub enum PatWildKind {
544 /// Represents the wildcard pattern `_`
545 PatWildSingle,
546
547 /// Represents the wildcard pattern `..`
548 PatWildMulti,
549}
550
551#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
552pub enum Pat_ {
553 /// Represents a wildcard pattern (either `_` or `..`)
554 PatWild(PatWildKind),
555
556 /// A PatIdent may either be a new bound variable,
557 /// or a nullary enum (in which case the third field
558 /// is None).
559 /// In the nullary enum case, the parser can't determine
560 /// which it is. The resolver determines this, and
561 /// records this pattern's NodeId in an auxiliary
562 /// set (of "PatIdents that refer to nullary enums")
563 PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>),
564
565 /// "None" means a * pattern where we don't bind the fields to names.
566 PatEnum(Path, Option<Vec<P<Pat>>>),
567
568 PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
569 PatTup(Vec<P<Pat>>),
570 PatBox(P<Pat>),
571 PatRegion(P<Pat>, Mutability), // reference pattern
572 PatLit(P<Expr>),
573 PatRange(P<Expr>, P<Expr>),
574 /// [a, b, ..i, y, z] is represented as:
575 /// PatVec(box [a, b], Some(i), box [y, z])
576 PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
577 PatMac(Mac),
578}
579
580#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
581pub enum Mutability {
582 MutMutable,
583 MutImmutable,
584}
585
586#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
587pub enum BinOp {
588 BiAdd,
589 BiSub,
590 BiMul,
591 BiDiv,
592 BiRem,
593 BiAnd,
594 BiOr,
595 BiBitXor,
596 BiBitAnd,
597 BiBitOr,
598 BiShl,
599 BiShr,
600 BiEq,
601 BiLt,
602 BiLe,
603 BiNe,
604 BiGe,
605 BiGt,
606}
607
608#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
609pub enum UnOp {
610 UnUniq,
611 UnDeref,
612 UnNot,
613 UnNeg
614}
615
616pub type Stmt = Spanned<Stmt_>;
617
618#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
619pub enum Stmt_ {
620 /// Could be an item or a local (let) binding:
621 StmtDecl(P<Decl>, NodeId),
622
623 /// Expr without trailing semi-colon (must have unit type):
624 StmtExpr(P<Expr>, NodeId),
625
626 /// Expr with trailing semi-colon (may have any type):
627 StmtSemi(P<Expr>, NodeId),
628
629 StmtMac(P<Mac>, MacStmtStyle),
630}
631
632#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
633pub enum MacStmtStyle {
634 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
635 /// `foo!(...);`, `foo![...];`
636 MacStmtWithSemicolon,
637 /// The macro statement had braces; e.g. foo! { ... }
638 MacStmtWithBraces,
639 /// The macro statement had parentheses or brackets and no semicolon; e.g.
640 /// `foo!(...)`. All of these will end up being converted into macro
641 /// expressions.
642 MacStmtWithoutBraces,
643}
644
645/// Where a local declaration came from: either a true `let ... =
646/// ...;`, or one desugared from the pattern of a for loop.
647#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
648pub enum LocalSource {
649 LocalLet,
650 LocalFor,
223e47cc
LB
651}
652
1a4d82fc
JJ
653// FIXME (pending discussion of #1697, #2178...): local should really be
654// a refinement on pat.
655/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
656#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
657pub struct Local {
658 pub pat: P<Pat>,
659 pub ty: Option<P<Ty>>,
660 pub init: Option<P<Expr>>,
661 pub id: NodeId,
662 pub span: Span,
663 pub source: LocalSource,
664}
665
666pub type Decl = Spanned<Decl_>;
667
668#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
669pub enum Decl_ {
670 /// A local (let) binding:
671 DeclLocal(P<Local>),
672 /// An item binding:
673 DeclItem(P<Item>),
674}
675
676/// represents one arm of a 'match'
677#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
678pub struct Arm {
679 pub attrs: Vec<Attribute>,
680 pub pats: Vec<P<Pat>>,
681 pub guard: Option<P<Expr>>,
682 pub body: P<Expr>,
683}
684
685#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
686pub struct Field {
687 pub ident: SpannedIdent,
688 pub expr: P<Expr>,
689 pub span: Span,
690}
691
692pub type SpannedIdent = Spanned<Ident>;
693
694#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
695pub enum BlockCheckMode {
696 DefaultBlock,
697 UnsafeBlock(UnsafeSource),
698}
699
700#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
701pub enum UnsafeSource {
702 CompilerGenerated,
703 UserProvided,
704}
705
706#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
707pub struct Expr {
708 pub id: NodeId,
709 pub node: Expr_,
710 pub span: Span,
711}
712
713#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
714pub enum Expr_ {
715 /// First expr is the place; second expr is the value.
716 ExprBox(Option<P<Expr>>, P<Expr>),
717 ExprVec(Vec<P<Expr>>),
718 ExprCall(P<Expr>, Vec<P<Expr>>),
719 ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
720 ExprTup(Vec<P<Expr>>),
721 ExprBinary(BinOp, P<Expr>, P<Expr>),
722 ExprUnary(UnOp, P<Expr>),
723 ExprLit(P<Lit>),
724 ExprCast(P<Expr>, P<Ty>),
725 ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
726 ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
727 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
728 ExprWhile(P<Expr>, P<Block>, Option<Ident>),
729 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
730 ExprWhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
731 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
732 ExprForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
733 // Conditionless loop (can be exited with break, cont, or ret)
734 // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
735 ExprLoop(P<Block>, Option<Ident>),
736 ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
737 ExprClosure(CaptureClause, Option<UnboxedClosureKind>, P<FnDecl>, P<Block>),
738 ExprBlock(P<Block>),
739
740 ExprAssign(P<Expr>, P<Expr>),
741 ExprAssignOp(BinOp, P<Expr>, P<Expr>),
742 ExprField(P<Expr>, SpannedIdent),
743 ExprTupField(P<Expr>, Spanned<uint>),
744 ExprIndex(P<Expr>, P<Expr>),
745 ExprRange(Option<P<Expr>>, Option<P<Expr>>),
746
747 /// Variable reference, possibly containing `::` and/or
748 /// type parameters, e.g. foo::bar::<baz>
749 ExprPath(Path),
750
751 ExprAddrOf(Mutability, P<Expr>),
752 ExprBreak(Option<Ident>),
753 ExprAgain(Option<Ident>),
754 ExprRet(Option<P<Expr>>),
755
756 ExprInlineAsm(InlineAsm),
757
758 ExprMac(Mac),
759
760 /// A struct literal expression.
761 ExprStruct(Path, Vec<Field>, Option<P<Expr>> /* base */),
762
763 /// A vector literal constructed from one repeated element.
764 ExprRepeat(P<Expr> /* element */, P<Expr> /* count */),
765
766 /// No-op: used solely so we can pretty-print faithfully
767 ExprParen(P<Expr>)
768}
769
770/// A "qualified path":
771///
772/// <Vec<T> as SomeTrait>::SomeAssociatedItem
773/// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~
774/// self_type trait_name item_name
775#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
776pub struct QPath {
777 pub self_type: P<Ty>,
778 pub trait_ref: P<TraitRef>,
779 pub item_name: Ident, // FIXME(#20301) -- should use Name
780}
781
782#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
783pub enum MatchSource {
784 Normal,
785 IfLetDesugar { contains_else_clause: bool },
786 WhileLetDesugar,
787}
788
789#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
790pub enum CaptureClause {
791 CaptureByValue,
792 CaptureByRef,
793}
794
795/// A delimited sequence of token trees
796#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
797pub struct Delimited {
798 /// The type of delimiter
799 pub delim: token::DelimToken,
800 /// The span covering the opening delimiter
801 pub open_span: Span,
802 /// The delimited sequence of token trees
803 pub tts: Vec<TokenTree>,
804 /// The span covering the closing delimiter
805 pub close_span: Span,
806}
807
808impl Delimited {
809 /// Returns the opening delimiter as a token.
810 pub fn open_token(&self) -> token::Token {
811 token::OpenDelim(self.delim)
812 }
223e47cc 813
1a4d82fc
JJ
814 /// Returns the closing delimiter as a token.
815 pub fn close_token(&self) -> token::Token {
816 token::CloseDelim(self.delim)
817 }
223e47cc 818
1a4d82fc
JJ
819 /// Returns the opening delimiter as a token tree.
820 pub fn open_tt(&self) -> TokenTree {
821 TtToken(self.open_span, self.open_token())
822 }
823
824 /// Returns the closing delimiter as a token tree.
825 pub fn close_tt(&self) -> TokenTree {
826 TtToken(self.close_span, self.close_token())
827 }
828}
829
830/// A sequence of token treesee
831#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
832pub struct SequenceRepetition {
833 /// The sequence of token trees
834 pub tts: Vec<TokenTree>,
835 /// The optional separator
836 pub separator: Option<token::Token>,
837 /// Whether the sequence can be repeated zero (*), or one or more times (+)
838 pub op: KleeneOp,
839 /// The number of `MatchNt`s that appear in the sequence (and subsequences)
840 pub num_captures: uint,
841}
842
843/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
844/// for token sequences.
845#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
846pub enum KleeneOp {
847 ZeroOrMore,
848 OneOrMore,
849}
850
851/// When the main rust parser encounters a syntax-extension invocation, it
852/// parses the arguments to the invocation as a token-tree. This is a very
853/// loose structure, such that all sorts of different AST-fragments can
854/// be passed to syntax extensions using a uniform type.
855///
856/// If the syntax extension is an MBE macro, it will attempt to match its
857/// LHS token tree against the provided token tree, and if it finds a
858/// match, will transcribe the RHS token tree, splicing in any captured
859/// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
860///
861/// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
862/// Nothing special happens to misnamed or misplaced `SubstNt`s.
863#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
864#[doc="For macro invocations; parsing is delegated to the macro"]
865pub enum TokenTree {
866 /// A single token
867 TtToken(Span, token::Token),
868 /// A delimited sequence of token trees
869 TtDelimited(Span, Rc<Delimited>),
870
871 // This only makes sense in MBE macros.
872
873 /// A kleene-style repetition sequence with a span
874 // FIXME(eddyb) #12938 Use DST.
875 TtSequence(Span, Rc<SequenceRepetition>),
223e47cc
LB
876}
877
1a4d82fc
JJ
878impl TokenTree {
879 pub fn len(&self) -> uint {
880 match *self {
881 TtToken(_, token::DocComment(_)) => 2,
882 TtToken(_, token::SpecialVarNt(..)) => 2,
883 TtToken(_, token::MatchNt(..)) => 3,
884 TtDelimited(_, ref delimed) => {
885 delimed.tts.len() + 2
886 }
887 TtSequence(_, ref seq) => {
888 seq.tts.len()
889 }
890 TtToken(..) => 0
891 }
892 }
893
894 pub fn get_tt(&self, index: uint) -> TokenTree {
895 match (self, index) {
896 (&TtToken(sp, token::DocComment(_)), 0) => {
897 TtToken(sp, token::Pound)
898 }
899 (&TtToken(sp, token::DocComment(name)), 1) => {
900 TtDelimited(sp, Rc::new(Delimited {
901 delim: token::Bracket,
902 open_span: sp,
903 tts: vec![TtToken(sp, token::Ident(token::str_to_ident("doc"),
904 token::Plain)),
905 TtToken(sp, token::Eq),
906 TtToken(sp, token::Literal(token::Str_(name), None))],
907 close_span: sp,
908 }))
909 }
910 (&TtDelimited(_, ref delimed), _) => {
911 if index == 0 {
912 return delimed.open_tt();
913 }
914 if index == delimed.tts.len() + 1 {
915 return delimed.close_tt();
916 }
917 delimed.tts[index - 1].clone()
918 }
919 (&TtToken(sp, token::SpecialVarNt(var)), _) => {
920 let v = [TtToken(sp, token::Dollar),
921 TtToken(sp, token::Ident(token::str_to_ident(var.as_str()),
922 token::Plain))];
923 v[index]
924 }
925 (&TtToken(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
926 let v = [TtToken(sp, token::SubstNt(name, name_st)),
927 TtToken(sp, token::Colon),
928 TtToken(sp, token::Ident(kind, kind_st))];
929 v[index]
930 }
931 (&TtSequence(_, ref seq), _) => {
932 seq.tts[index].clone()
933 }
934 _ => panic!("Cannot expand a token tree")
935 }
936 }
937
938 /// Returns the `Span` corresponding to this token tree.
939 pub fn get_span(&self) -> Span {
940 match *self {
941 TtToken(span, _) => span,
942 TtDelimited(span, _) => span,
943 TtSequence(span, _) => span,
970d7e83
LB
944 }
945 }
946}
947
1a4d82fc 948pub type Mac = Spanned<Mac_>;
223e47cc 949
1a4d82fc
JJ
950/// Represents a macro invocation. The Path indicates which macro
951/// is being invoked, and the vector of token-trees contains the source
952/// of the macro invocation.
953/// There's only one flavor, now, so this could presumably be simplified.
954#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
955pub enum Mac_ {
956 // NB: the additional ident for a macro_rules-style macro is actually
957 // stored in the enclosing item. Oog.
958 MacInvocTT(Path, Vec<TokenTree> , SyntaxContext), // new macro-invocation
959}
223e47cc 960
1a4d82fc
JJ
961#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
962pub enum StrStyle {
963 CookedStr,
964 RawStr(uint)
223e47cc
LB
965}
966
1a4d82fc 967pub type Lit = Spanned<Lit_>;
223e47cc 968
1a4d82fc
JJ
969#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
970pub enum Sign {
971 Minus,
972 Plus
223e47cc
LB
973}
974
1a4d82fc
JJ
975impl Sign {
976 pub fn new<T:Int>(n: T) -> Sign {
977 if n < Int::zero() {
978 Minus
979 } else {
980 Plus
981 }
982 }
983}
223e47cc 984
1a4d82fc
JJ
985#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
986pub enum LitIntType {
987 SignedIntLit(IntTy, Sign),
988 UnsignedIntLit(UintTy),
989 UnsuffixedIntLit(Sign)
223e47cc
LB
990}
991
1a4d82fc
JJ
992impl LitIntType {
993 pub fn suffix_len(&self) -> uint {
994 match *self {
995 UnsuffixedIntLit(_) => 0,
996 SignedIntLit(s, _) => s.suffix_len(),
997 UnsignedIntLit(u) => u.suffix_len()
998 }
999 }
1000}
223e47cc 1001
1a4d82fc
JJ
1002#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1003pub enum Lit_ {
1004 LitStr(InternedString, StrStyle),
1005 LitBinary(Rc<Vec<u8>>),
1006 LitByte(u8),
1007 LitChar(char),
1008 LitInt(u64, LitIntType),
1009 LitFloat(InternedString, FloatTy),
1010 LitFloatUnsuffixed(InternedString),
1011 LitBool(bool),
223e47cc
LB
1012}
1013
1014// NB: If you change this, you'll probably want to change the corresponding
1015// type structure in middle/ty.rs as well.
1a4d82fc
JJ
1016#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1017pub struct MutTy {
1018 pub ty: P<Ty>,
1019 pub mutbl: Mutability,
1020}
1021
1022#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1023pub struct TypeField {
1024 pub ident: Ident,
1025 pub mt: MutTy,
1026 pub span: Span,
1027}
1028
1029/// Represents a required method in a trait declaration,
1030/// one without a default implementation
1031#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1032pub struct TypeMethod {
1033 pub ident: Ident,
1034 pub attrs: Vec<Attribute>,
1035 pub unsafety: Unsafety,
1036 pub abi: Abi,
1037 pub decl: P<FnDecl>,
1038 pub generics: Generics,
1039 pub explicit_self: ExplicitSelf,
1040 pub id: NodeId,
1041 pub span: Span,
1042 pub vis: Visibility,
1043}
1044
1045/// Represents a method declaration in a trait declaration, possibly including
1046/// a default implementation A trait method is either required (meaning it
1047/// doesn't have an implementation, just a signature) or provided (meaning it
1048/// has a default implementation).
1049#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1050pub enum TraitItem {
1051 RequiredMethod(TypeMethod),
1052 ProvidedMethod(P<Method>),
1053 TypeTraitItem(P<AssociatedType>),
1054}
1055
1056#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1057pub enum ImplItem {
1058 MethodImplItem(P<Method>),
1059 TypeImplItem(P<Typedef>),
1060}
1061
1062#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1063pub struct AssociatedType {
1064 pub attrs: Vec<Attribute>,
1065 pub ty_param: TyParam,
1066}
1067
1068#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1069pub struct Typedef {
1070 pub id: NodeId,
1071 pub span: Span,
1072 pub ident: Ident,
1073 pub vis: Visibility,
1074 pub attrs: Vec<Attribute>,
1075 pub typ: P<Ty>,
1076}
1077
1078#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1079pub enum IntTy {
1080 TyIs(bool /* is this deprecated `int`? */),
1081 TyI8,
1082 TyI16,
1083 TyI32,
1084 TyI64,
1085}
1086
1087impl PartialEq for IntTy {
1088 fn eq(&self, other: &IntTy) -> bool {
1089 match (*self, *other) {
1090 // true/false need to compare the same, so this can't be derived
1091 (TyIs(_), TyIs(_)) |
1092 (TyI8, TyI8) |
1093 (TyI16, TyI16) |
1094 (TyI32, TyI32) |
1095 (TyI64, TyI64) => true,
1096 _ => false
1097 }
1098 }
223e47cc
LB
1099}
1100
1a4d82fc
JJ
1101impl fmt::Show for IntTy {
1102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1103 fmt::String::fmt(self, f)
1104 }
223e47cc
LB
1105}
1106
1a4d82fc
JJ
1107impl fmt::String for IntTy {
1108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1109 write!(f, "{}", ast_util::int_ty_to_string(*self, None))
1110 }
1111}
223e47cc 1112
1a4d82fc
JJ
1113impl IntTy {
1114 pub fn suffix_len(&self) -> uint {
1115 match *self {
1116 TyIs(true) /* i */ => 1,
1117 TyIs(false) /* is */ | TyI8 => 2,
1118 TyI16 | TyI32 | TyI64 => 3,
1119 }
1120 }
223e47cc
LB
1121}
1122
1a4d82fc
JJ
1123#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1124pub enum UintTy {
1125 TyUs(bool /* is this deprecated uint? */),
1126 TyU8,
1127 TyU16,
1128 TyU32,
1129 TyU64,
1130}
1131
1132impl PartialEq for UintTy {
1133 fn eq(&self, other: &UintTy) -> bool {
1134 match (*self, *other) {
1135 // true/false need to compare the same, so this can't be derived
1136 (TyUs(_), TyUs(_)) |
1137 (TyU8, TyU8) |
1138 (TyU16, TyU16) |
1139 (TyU32, TyU32) |
1140 (TyU64, TyU64) => true,
1141 _ => false
1142 }
1143 }
223e47cc
LB
1144}
1145
1a4d82fc
JJ
1146impl UintTy {
1147 pub fn suffix_len(&self) -> uint {
1148 match *self {
1149 TyUs(true) /* u */ => 1,
1150 TyUs(false) /* us */ | TyU8 => 2,
1151 TyU16 | TyU32 | TyU64 => 3,
1152 }
1153 }
1154}
223e47cc 1155
1a4d82fc
JJ
1156impl fmt::Show for UintTy {
1157 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1158 fmt::String::fmt(self, f)
223e47cc
LB
1159 }
1160}
1161
1a4d82fc
JJ
1162impl fmt::String for UintTy {
1163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1164 write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
1165 }
1166}
1167
1168#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1169pub enum FloatTy {
1170 TyF32,
1171 TyF64,
1172}
223e47cc 1173
1a4d82fc
JJ
1174impl fmt::Show for FloatTy {
1175 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1176 fmt::String::fmt(self, f)
223e47cc
LB
1177 }
1178}
1179
1a4d82fc
JJ
1180impl fmt::String for FloatTy {
1181 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1182 write!(f, "{}", ast_util::float_ty_to_string(*self))
1183 }
1184}
223e47cc 1185
1a4d82fc
JJ
1186impl FloatTy {
1187 pub fn suffix_len(&self) -> uint {
1188 match *self {
1189 TyF32 | TyF64 => 3, // add F128 handling here
1190 }
223e47cc
LB
1191 }
1192}
1193
1a4d82fc
JJ
1194// Bind a type to an associated type: `A=Foo`.
1195#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1196pub struct TypeBinding {
1197 pub id: NodeId,
1198 pub ident: Ident,
1199 pub ty: P<Ty>,
1200 pub span: Span,
1201}
1202
1203
1204// NB PartialEq method appears below.
1205#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
223e47cc 1206pub struct Ty {
1a4d82fc
JJ
1207 pub id: NodeId,
1208 pub node: Ty_,
1209 pub span: Span,
223e47cc
LB
1210}
1211
1a4d82fc
JJ
1212/// Not represented directly in the AST, referred to by name through a ty_path.
1213#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1214pub enum PrimTy {
1215 TyInt(IntTy),
1216 TyUint(UintTy),
1217 TyFloat(FloatTy),
1218 TyStr,
1219 TyBool,
1220 TyChar
223e47cc
LB
1221}
1222
1a4d82fc 1223#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
223e47cc
LB
1224pub enum Onceness {
1225 Once,
1226 Many
1227}
1228
1a4d82fc
JJ
1229impl fmt::Show for Onceness {
1230 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1231 fmt::String::fmt(match *self {
1232 Once => "once",
1233 Many => "many",
1234 }, f)
1235 }
1236}
1237
1238impl fmt::String for Onceness {
1239 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1240 fmt::String::fmt(match *self {
1241 Once => "once",
1242 Many => "many",
1243 }, f)
1244 }
1245}
1246
1247/// Represents the type of a closure
1248#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1249pub struct ClosureTy {
1250 pub lifetimes: Vec<LifetimeDef>,
1251 pub unsafety: Unsafety,
1252 pub onceness: Onceness,
1253 pub decl: P<FnDecl>,
1254 pub bounds: TyParamBounds,
1255}
1256
1257#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1258pub struct BareFnTy {
1259 pub unsafety: Unsafety,
1260 pub abi: Abi,
1261 pub lifetimes: Vec<LifetimeDef>,
1262 pub decl: P<FnDecl>
1263}
1264
1265#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1266/// The different kinds of types recognized by the compiler
1267pub enum Ty_ {
1268 TyVec(P<Ty>),
1269 /// A fixed length array (`[T, ..n]`)
1270 TyFixedLengthVec(P<Ty>, P<Expr>),
1271 /// A raw pointer (`*const T` or `*mut T`)
1272 TyPtr(MutTy),
1273 /// A reference (`&'a T` or `&'a mut T`)
1274 TyRptr(Option<Lifetime>, MutTy),
1275 /// A bare function (e.g. `fn(uint) -> bool`)
1276 TyBareFn(P<BareFnTy>),
1277 /// A tuple (`(A, B, C, D,...)`)
1278 TyTup(Vec<P<Ty>> ),
1279 /// A path (`module::module::...::Type`) or primitive
1280 ///
1281 /// Type parameters are stored in the Path itself
1282 TyPath(Path, NodeId),
1283 /// Something like `A+B`. Note that `B` must always be a path.
1284 TyObjectSum(P<Ty>, TyParamBounds),
1285 /// A type like `for<'a> Foo<&'a Bar>`
1286 TyPolyTraitRef(TyParamBounds),
1287 /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
1288 TyQPath(P<QPath>),
1289 /// No-op; kept solely so that we can pretty-print faithfully
1290 TyParen(P<Ty>),
1291 /// Unused for now
1292 TyTypeof(P<Expr>),
1293 /// TyInfer means the type should be inferred instead of it having been
1294 /// specified. This can appear anywhere in a type.
1295 TyInfer,
1296}
1297
1298#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1299pub enum AsmDialect {
1300 AsmAtt,
1301 AsmIntel
1302}
1303
1304#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1305pub struct InlineAsm {
1306 pub asm: InternedString,
1307 pub asm_str_style: StrStyle,
1308 pub outputs: Vec<(InternedString, P<Expr>, bool)>,
1309 pub inputs: Vec<(InternedString, P<Expr>)>,
1310 pub clobbers: Vec<InternedString>,
1311 pub volatile: bool,
1312 pub alignstack: bool,
1313 pub dialect: AsmDialect,
1314 pub expn_id: ExpnId,
1315}
1316
1317/// represents an argument in a function header
1318#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1319pub struct Arg {
1320 pub ty: P<Ty>,
1321 pub pat: P<Pat>,
1322 pub id: NodeId,
1323}
1324
1325impl Arg {
1326 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1327 let path = Spanned{span:span,node:self_ident};
1328 Arg {
1329 // HACK(eddyb) fake type for the self argument.
1330 ty: P(Ty {
1331 id: DUMMY_NODE_ID,
1332 node: TyInfer,
1333 span: DUMMY_SP,
1334 }),
1335 pat: P(Pat {
1336 id: DUMMY_NODE_ID,
1337 node: PatIdent(BindByValue(mutability), path, None),
1338 span: span
1339 }),
1340 id: DUMMY_NODE_ID
223e47cc
LB
1341 }
1342 }
1343}
1344
1a4d82fc
JJ
1345/// represents the header (not the body) of a function declaration
1346#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1347pub struct FnDecl {
1348 pub inputs: Vec<Arg>,
1349 pub output: FunctionRetTy,
1350 pub variadic: bool
1351}
1352
1353#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1354pub enum Unsafety {
1355 Unsafe,
1356 Normal,
1357}
1358
1359impl fmt::String for Unsafety {
1360 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1361 fmt::String::fmt(match *self {
1362 Unsafety::Normal => "normal",
1363 Unsafety::Unsafe => "unsafe",
1364 }, f)
1365 }
1366}
1367
1368#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1369pub enum ImplPolarity {
1370 /// impl Trait for Type
1371 Positive,
1372 /// impl !Trait for Type
1373 Negative,
1374}
1375
1376impl fmt::Show for ImplPolarity {
1377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
223e47cc 1378 match *self {
1a4d82fc
JJ
1379 ImplPolarity::Positive => "positive".fmt(f),
1380 ImplPolarity::Negative => "negative".fmt(f),
223e47cc
LB
1381 }
1382 }
1383}
1384
1a4d82fc
JJ
1385
1386#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1387pub enum FunctionRetTy {
1388 /// Functions with return type ! that always
1389 /// raise an error or exit (i.e. never return to the caller)
1390 NoReturn(Span),
1391 /// Everything else
1392 Return(P<Ty>),
1393}
1394
1395impl FunctionRetTy {
1396 pub fn span(&self) -> Span {
1397 match *self {
1398 NoReturn(span) => span,
1399 Return(ref ty) => ty.span
1400 }
1401 }
223e47cc
LB
1402}
1403
1a4d82fc
JJ
1404/// Represents the kind of 'self' associated with a method
1405#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1406pub enum ExplicitSelf_ {
1407 /// No self
1408 SelfStatic,
1409 /// `self`
1410 SelfValue(Ident),
1411 /// `&'lt self`, `&'lt mut self`
1412 SelfRegion(Option<Lifetime>, Mutability, Ident),
1413 /// `self: TYPE`
1414 SelfExplicit(P<Ty>, Ident),
223e47cc
LB
1415}
1416
1a4d82fc 1417pub type ExplicitSelf = Spanned<ExplicitSelf_>;
223e47cc 1418
1a4d82fc
JJ
1419#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1420pub struct Method {
1421 pub attrs: Vec<Attribute>,
1422 pub id: NodeId,
1423 pub span: Span,
1424 pub node: Method_,
223e47cc
LB
1425}
1426
1a4d82fc
JJ
1427#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1428pub enum Method_ {
1429 /// Represents a method declaration
1430 MethDecl(Ident,
1431 Generics,
1432 Abi,
1433 ExplicitSelf,
1434 Unsafety,
1435 P<FnDecl>,
1436 P<Block>,
1437 Visibility),
1438 /// Represents a macro in method position
1439 MethMac(Mac),
223e47cc
LB
1440}
1441
1a4d82fc
JJ
1442#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1443pub struct Mod {
1444 /// A span from the first token past `{` to the last token until `}`.
1445 /// For `mod foo;`, the inner span ranges from the first token
1446 /// to the last token in the external file.
1447 pub inner: Span,
1448 pub view_items: Vec<ViewItem>,
1449 pub items: Vec<P<Item>>,
1450}
223e47cc 1451
1a4d82fc
JJ
1452#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1453pub struct ForeignMod {
1454 pub abi: Abi,
1455 pub view_items: Vec<ViewItem>,
1456 pub items: Vec<P<ForeignItem>>,
223e47cc
LB
1457}
1458
1a4d82fc
JJ
1459#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1460pub struct VariantArg {
1461 pub ty: P<Ty>,
1462 pub id: NodeId,
223e47cc
LB
1463}
1464
1a4d82fc
JJ
1465#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1466pub enum VariantKind {
1467 TupleVariantKind(Vec<VariantArg>),
1468 StructVariantKind(P<StructDef>),
223e47cc
LB
1469}
1470
1a4d82fc
JJ
1471#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1472pub struct EnumDef {
1473 pub variants: Vec<P<Variant>>,
223e47cc
LB
1474}
1475
1a4d82fc
JJ
1476#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1477pub struct Variant_ {
1478 pub name: Ident,
1479 pub attrs: Vec<Attribute>,
1480 pub kind: VariantKind,
1481 pub id: NodeId,
1482 pub disr_expr: Option<P<Expr>>,
1483 pub vis: Visibility,
223e47cc
LB
1484}
1485
1a4d82fc 1486pub type Variant = Spanned<Variant_>;
223e47cc 1487
1a4d82fc
JJ
1488#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1489pub enum PathListItem_ {
1490 PathListIdent { name: Ident, id: NodeId },
1491 PathListMod { id: NodeId }
223e47cc
LB
1492}
1493
1a4d82fc
JJ
1494impl PathListItem_ {
1495 pub fn id(&self) -> NodeId {
1496 match *self {
1497 PathListIdent { id, .. } | PathListMod { id } => id
1498 }
1499 }
1500}
223e47cc 1501
1a4d82fc 1502pub type PathListItem = Spanned<PathListItem_>;
223e47cc 1503
1a4d82fc 1504pub type ViewPath = Spanned<ViewPath_>;
223e47cc 1505
1a4d82fc
JJ
1506#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1507pub enum ViewPath_ {
223e47cc 1508
1a4d82fc
JJ
1509 /// `foo::bar::baz as quux`
1510 ///
1511 /// or just
1512 ///
1513 /// `foo::bar::baz` (with `as baz` implicitly on the right)
1514 ViewPathSimple(Ident, Path, NodeId),
223e47cc 1515
1a4d82fc
JJ
1516 /// `foo::bar::*`
1517 ViewPathGlob(Path, NodeId),
1518
1519 /// `foo::bar::{a,b,c}`
1520 ViewPathList(Path, Vec<PathListItem> , NodeId)
223e47cc
LB
1521}
1522
1a4d82fc
JJ
1523#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1524pub struct ViewItem {
1525 pub node: ViewItem_,
1526 pub attrs: Vec<Attribute>,
1527 pub vis: Visibility,
1528 pub span: Span,
223e47cc
LB
1529}
1530
1a4d82fc
JJ
1531#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1532pub enum ViewItem_ {
1533 /// Ident: name used to refer to this crate in the code
1534 /// optional (InternedString,StrStyle): if present, this is a location
1535 /// (containing arbitrary characters) from which to fetch the crate sources
1536 /// For example, extern crate whatever = "github.com/rust-lang/rust"
1537 ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
1538 ViewItemUse(P<ViewPath>),
223e47cc
LB
1539}
1540
1a4d82fc
JJ
1541/// Meta-data associated with an item
1542pub type Attribute = Spanned<Attribute_>;
223e47cc 1543
1a4d82fc
JJ
1544/// Distinguishes between Attributes that decorate items and Attributes that
1545/// are contained as statements within items. These two cases need to be
1546/// distinguished for pretty-printing.
1547#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1548pub enum AttrStyle {
1549 AttrOuter,
1550 AttrInner,
1551}
223e47cc 1552
1a4d82fc
JJ
1553#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1554pub struct AttrId(pub uint);
1555
1556/// Doc-comments are promoted to attributes that have is_sugared_doc = true
1557#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1558pub struct Attribute_ {
1559 pub id: AttrId,
1560 pub style: AttrStyle,
1561 pub value: P<MetaItem>,
1562 pub is_sugared_doc: bool,
223e47cc
LB
1563}
1564
1a4d82fc
JJ
1565/// TraitRef's appear in impls.
1566/// resolve maps each TraitRef's ref_id to its defining trait; that's all
1567/// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1568/// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1569/// same as the impl's node id).
1570#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1571pub struct TraitRef {
1572 pub path: Path,
1573 pub ref_id: NodeId,
223e47cc
LB
1574}
1575
1a4d82fc
JJ
1576#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1577pub struct PolyTraitRef {
1578 /// The `'a` in `<'a> Foo<&'a T>`
1579 pub bound_lifetimes: Vec<LifetimeDef>,
223e47cc 1580
1a4d82fc
JJ
1581 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1582 pub trait_ref: TraitRef,
1583}
1584
1585#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1586pub enum Visibility {
1587 Public,
1588 Inherited,
1589}
1590
1591impl Visibility {
1592 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
970d7e83 1593 match self {
1a4d82fc
JJ
1594 &Inherited => parent_visibility,
1595 &Public => *self
970d7e83
LB
1596 }
1597 }
1598}
1599
1a4d82fc
JJ
1600#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1601pub struct StructField_ {
1602 pub kind: StructFieldKind,
1603 pub id: NodeId,
1604 pub ty: P<Ty>,
1605 pub attrs: Vec<Attribute>,
1606}
1607
1608impl StructField_ {
1609 pub fn ident(&self) -> Option<Ident> {
1610 match self.kind {
1611 NamedField(ref ident, _) => Some(ident.clone()),
1612 UnnamedField(_) => None
1613 }
1614 }
223e47cc
LB
1615}
1616
1a4d82fc 1617pub type StructField = Spanned<StructField_>;
223e47cc 1618
1a4d82fc
JJ
1619#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1620pub enum StructFieldKind {
1621 NamedField(Ident, Visibility),
1622 /// Element of a tuple-like struct
1623 UnnamedField(Visibility),
223e47cc
LB
1624}
1625
1a4d82fc
JJ
1626impl StructFieldKind {
1627 pub fn is_unnamed(&self) -> bool {
1628 match *self {
1629 UnnamedField(..) => true,
1630 NamedField(..) => false,
1631 }
1632 }
1633}
1634
1635#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1636pub struct StructDef {
1637 /// Fields, not including ctor
1638 pub fields: Vec<StructField>,
1639 /// ID of the constructor. This is only used for tuple- or enum-like
1640 /// structs.
1641 pub ctor_id: Option<NodeId>,
223e47cc
LB
1642}
1643
1644/*
1645 FIXME (#3300): Should allow items to be anonymous. Right now
1646 we just use dummy names for anon items.
1647 */
1a4d82fc
JJ
1648#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1649pub struct Item {
1650 pub ident: Ident,
1651 pub attrs: Vec<Attribute>,
1652 pub id: NodeId,
1653 pub node: Item_,
1654 pub vis: Visibility,
1655 pub span: Span,
1656}
1657
1658#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1659pub enum Item_ {
1660 ItemStatic(P<Ty>, Mutability, P<Expr>),
1661 ItemConst(P<Ty>, P<Expr>),
1662 ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
1663 ItemMod(Mod),
1664 ItemForeignMod(ForeignMod),
1665 ItemTy(P<Ty>, Generics),
1666 ItemEnum(EnumDef, Generics),
1667 ItemStruct(P<StructDef>, Generics),
1668 /// Represents a Trait Declaration
1669 ItemTrait(Unsafety,
1670 Generics,
1671 TyParamBounds,
1672 Vec<TraitItem>),
1673 ItemImpl(Unsafety,
1674 ImplPolarity,
1675 Generics,
1676 Option<TraitRef>, // (optional) trait this impl implements
1677 P<Ty>, // self
1678 Vec<ImplItem>),
1679 /// A macro invocation (which includes macro definition)
1680 ItemMac(Mac),
1681}
1682
1683impl Item_ {
1684 pub fn descriptive_variant(&self) -> &str {
1685 match *self {
1686 ItemStatic(..) => "static item",
1687 ItemConst(..) => "constant item",
1688 ItemFn(..) => "function",
1689 ItemMod(..) => "module",
1690 ItemForeignMod(..) => "foreign module",
1691 ItemTy(..) => "type alias",
1692 ItemEnum(..) => "enum",
1693 ItemStruct(..) => "struct",
1694 ItemTrait(..) => "trait",
1695 ItemMac(..) |
1696 ItemImpl(..) => "item"
1697 }
970d7e83 1698 }
1a4d82fc 1699}
970d7e83 1700
1a4d82fc
JJ
1701#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1702pub struct ForeignItem {
1703 pub ident: Ident,
1704 pub attrs: Vec<Attribute>,
1705 pub node: ForeignItem_,
1706 pub id: NodeId,
1707 pub span: Span,
1708 pub vis: Visibility,
1709}
970d7e83 1710
1a4d82fc
JJ
1711#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1712pub enum ForeignItem_ {
1713 ForeignItemFn(P<FnDecl>, Generics),
1714 ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
1715}
970d7e83 1716
1a4d82fc
JJ
1717impl ForeignItem_ {
1718 pub fn descriptive_variant(&self) -> &str {
1719 match *self {
1720 ForeignItemFn(..) => "foreign function",
1721 ForeignItemStatic(..) => "foreign static item"
1722 }
223e47cc 1723 }
1a4d82fc 1724}
970d7e83 1725
1a4d82fc
JJ
1726#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
1727pub enum UnboxedClosureKind {
1728 FnUnboxedClosureKind,
1729 FnMutUnboxedClosureKind,
1730 FnOnceUnboxedClosureKind,
1731}
970d7e83 1732
1a4d82fc
JJ
1733/// The data we save and restore about an inlined item or method. This is not
1734/// part of the AST that we parse from a file, but it becomes part of the tree
1735/// that we trans.
1736#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1737pub enum InlinedItem {
1738 IIItem(P<Item>),
1739 IITraitItem(DefId /* impl id */, TraitItem),
1740 IIImplItem(DefId /* impl id */, ImplItem),
1741 IIForeign(P<ForeignItem>),
223e47cc 1742}
970d7e83 1743
1a4d82fc
JJ
1744/// A macro definition, in this crate or imported from another.
1745///
1746/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
1747#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
1748pub struct MacroDef {
1749 pub ident: Ident,
1750 pub attrs: Vec<Attribute>,
1751 pub id: NodeId,
1752 pub span: Span,
1753 pub imported_from: Option<Ident>,
1754 pub export: bool,
1755 pub use_locally: bool,
1756 pub body: Vec<TokenTree>,
1757}
1758
1759#[cfg(test)]
1760mod test {
1761 use serialize;
1762 use super::*;
1763
1764 // are ASTs encodable?
1765 #[test]
1766 fn check_asts_encodable() {
1767 fn assert_encodable<T: serialize::Encodable>() {}
1768 assert_encodable::<Crate>();
1769 }
1770}