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 pub use self::TyParamBound
::*;
14 pub use self::UnsafeSource
::*;
15 pub use self::ViewPath_
::*;
16 pub use self::PathParameters
::*;
18 use attr
::ThinAttributes
;
19 use codemap
::{Span, Spanned, DUMMY_SP, ExpnId}
;
23 use ext
::tt
::macro_parser
;
24 use parse
::token
::InternedString
;
27 use parse
::lexer
::comments
::{doc_comment_style, strip_doc_comment_decoration}
;
34 use std
::hash
::{Hash, Hasher}
;
35 use serialize
::{Encodable, Decodable, Encoder, Decoder}
;
37 /// A name is a part of an identifier, representing a string or gensym. It's
38 /// the result of interning.
39 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
40 pub struct Name(pub u32);
42 /// A SyntaxContext represents a chain of macro-expandings
43 /// and renamings. Each macro expansion corresponds to
44 /// a fresh u32. This u32 is a reference to a table stored
45 /// in thread-local storage.
46 /// The special value EMPTY_CTXT is used to indicate an empty
48 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
49 pub struct SyntaxContext(pub u32);
51 /// An identifier contains a Name (index into the interner
52 /// table) and a SyntaxContext to track renaming and
53 /// macro expansion per Flatt et al., "Macros That Work Together"
54 #[derive(Clone, Copy, Eq)]
57 pub ctxt
: SyntaxContext
61 pub fn as_str(self) -> token
::InternedString
{
62 token
::InternedString
::new_from_name(self)
66 impl fmt
::Debug
for Name
{
67 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
68 write
!(f
, "{}({})", self, self.0)
72 impl fmt
::Display
for Name
{
73 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
74 fmt
::Display
::fmt(&self.as_str(), f
)
78 impl Encodable
for Name
{
79 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
80 s
.emit_str(&self.as_str())
84 impl Decodable
for Name
{
85 fn decode
<D
: Decoder
>(d
: &mut D
) -> Result
<Name
, D
::Error
> {
86 Ok(token
::intern(&d
.read_str()?
[..]))
90 pub const EMPTY_CTXT
: SyntaxContext
= SyntaxContext(0);
93 pub fn new(name
: Name
, ctxt
: SyntaxContext
) -> Ident
{
94 Ident {name: name, ctxt: ctxt}
96 pub fn with_empty_ctxt(name
: Name
) -> Ident
{
97 Ident {name: name, ctxt: EMPTY_CTXT}
101 impl PartialEq
for Ident
{
102 fn eq(&self, other
: &Ident
) -> bool
{
103 if self.ctxt
!= other
.ctxt
{
104 // There's no one true way to compare Idents. They can be compared
105 // non-hygienically `id1.name == id2.name`, hygienically
106 // `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
107 // `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
108 // Ideally, PartialEq should not be implemented for Ident at all, but that
109 // would be too impractical, because many larger structures (Token, in particular)
110 // including Idents as their parts derive PartialEq and use it for non-hygienic
111 // comparisons. That's why PartialEq is implemented and defaults to non-hygienic
112 // comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
113 // the name of Ident is hashed. Still try to avoid comparing idents in your code
114 // (especially as keys in hash maps), use one of the three methods listed above
117 // If you see this panic, then some idents from different contexts were compared
118 // non-hygienically. It's likely a bug. Use one of the three comparison methods
119 // listed above explicitly.
121 panic
!("idents with different contexts are compared with operator `==`: \
122 {:?}, {:?}.", self, other
);
125 self.name
== other
.name
129 impl Hash
for Ident
{
130 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
131 self.name
.hash(state
)
135 impl fmt
::Debug
for Ident
{
136 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
137 write
!(f
, "{}#{}", self.name
, self.ctxt
.0)
141 impl fmt
::Display
for Ident
{
142 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
143 fmt
::Display
::fmt(&self.name
, f
)
147 impl Encodable
for Ident
{
148 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
153 impl Decodable
for Ident
{
154 fn decode
<D
: Decoder
>(d
: &mut D
) -> Result
<Ident
, D
::Error
> {
155 Ok(Ident
::with_empty_ctxt(Name
::decode(d
)?
))
159 /// A mark represents a unique id associated with a macro expansion
162 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
163 pub struct Lifetime
{
169 impl fmt
::Debug
for Lifetime
{
170 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
171 write
!(f
, "lifetime({}: {})", self.id
, pprust
::lifetime_to_string(self))
175 /// A lifetime definition, eg `'a: 'b+'c+'d`
176 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
177 pub struct LifetimeDef
{
178 pub lifetime
: Lifetime
,
179 pub bounds
: Vec
<Lifetime
>
182 /// A "Path" is essentially Rust's notion of a name; for instance:
183 /// std::cmp::PartialEq . It's represented as a sequence of identifiers,
184 /// along with a bunch of supporting information.
185 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
188 /// A `::foo` path, is relative to the crate root rather than current
189 /// module (like paths in an import).
191 /// The segments in the path: the things separated by `::`.
192 pub segments
: Vec
<PathSegment
>,
195 impl fmt
::Debug
for Path
{
196 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
197 write
!(f
, "path({})", pprust
::path_to_string(self))
201 impl fmt
::Display
for Path
{
202 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
203 write
!(f
, "{}", pprust
::path_to_string(self))
208 // convert a span and an identifier to the corresponding
210 pub fn from_ident(s
: Span
, identifier
: Ident
) -> Path
{
216 identifier
: identifier
,
217 parameters
: PathParameters
::none()
224 /// A segment of a path: an identifier, an optional lifetime, and a set of
226 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
227 pub struct PathSegment
{
228 /// The identifier portion of this path segment.
229 pub identifier
: Ident
,
231 /// Type/lifetime parameters attached to this path. They come in
232 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
233 /// this is more than just simple syntactic sugar; the use of
234 /// parens affects the region binding rules, so we preserve the
236 pub parameters
: PathParameters
,
239 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
240 pub enum PathParameters
{
241 /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
242 AngleBracketed(AngleBracketedParameterData
),
243 /// The `(A,B)` and `C` in `Foo(A,B) -> C`
244 Parenthesized(ParenthesizedParameterData
),
247 impl PathParameters
{
248 pub fn none() -> PathParameters
{
249 PathParameters
::AngleBracketed(AngleBracketedParameterData
{
250 lifetimes
: Vec
::new(),
252 bindings
: P
::empty(),
256 pub fn is_empty(&self) -> bool
{
258 PathParameters
::AngleBracketed(ref data
) => data
.is_empty(),
260 // Even if the user supplied no types, something like
261 // `X()` is equivalent to `X<(),()>`.
262 PathParameters
::Parenthesized(..) => false,
266 pub fn has_lifetimes(&self) -> bool
{
268 PathParameters
::AngleBracketed(ref data
) => !data
.lifetimes
.is_empty(),
269 PathParameters
::Parenthesized(_
) => false,
273 pub fn has_types(&self) -> bool
{
275 PathParameters
::AngleBracketed(ref data
) => !data
.types
.is_empty(),
276 PathParameters
::Parenthesized(..) => true,
280 /// Returns the types that the user wrote. Note that these do not necessarily map to the type
281 /// parameters in the parenthesized case.
282 pub fn types(&self) -> Vec
<&P
<Ty
>> {
284 PathParameters
::AngleBracketed(ref data
) => {
285 data
.types
.iter().collect()
287 PathParameters
::Parenthesized(ref data
) => {
289 .chain(data
.output
.iter())
295 pub fn lifetimes(&self) -> Vec
<&Lifetime
> {
297 PathParameters
::AngleBracketed(ref data
) => {
298 data
.lifetimes
.iter().collect()
300 PathParameters
::Parenthesized(_
) => {
306 pub fn bindings(&self) -> Vec
<&TypeBinding
> {
308 PathParameters
::AngleBracketed(ref data
) => {
309 data
.bindings
.iter().collect()
311 PathParameters
::Parenthesized(_
) => {
318 /// A path like `Foo<'a, T>`
319 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
320 pub struct AngleBracketedParameterData
{
321 /// The lifetime parameters for this path segment.
322 pub lifetimes
: Vec
<Lifetime
>,
323 /// The type parameters for this path segment, if present.
324 pub types
: P
<[P
<Ty
>]>,
325 /// Bindings (equality constraints) on associated types, if present.
326 /// e.g., `Foo<A=Bar>`.
327 pub bindings
: P
<[TypeBinding
]>,
330 impl AngleBracketedParameterData
{
331 fn is_empty(&self) -> bool
{
332 self.lifetimes
.is_empty() && self.types
.is_empty() && self.bindings
.is_empty()
336 /// A path like `Foo(A,B) -> C`
337 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
338 pub struct ParenthesizedParameterData
{
343 pub inputs
: Vec
<P
<Ty
>>,
346 pub output
: Option
<P
<Ty
>>,
349 pub type CrateNum
= u32;
351 pub type NodeId
= u32;
353 /// Node id used to represent the root of the crate.
354 pub const CRATE_NODE_ID
: NodeId
= 0;
356 /// When parsing and doing expansions, we initially give all AST nodes this AST
357 /// node value. Then later, in the renumber pass, we renumber them to have
358 /// small, positive ids.
359 pub const DUMMY_NODE_ID
: NodeId
= !0;
361 pub trait NodeIdAssigner
{
362 fn next_node_id(&self) -> NodeId
;
363 fn peek_node_id(&self) -> NodeId
;
365 fn diagnostic(&self) -> &errors
::Handler
{
366 panic
!("this ID assigner cannot emit diagnostics")
370 /// The AST represents all type param bounds as types.
371 /// typeck::collect::compute_bounds matches these against
372 /// the "special" built-in traits (see middle::lang_items) and
373 /// detects Copy, Send and Sync.
374 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
375 pub enum TyParamBound
{
376 TraitTyParamBound(PolyTraitRef
, TraitBoundModifier
),
377 RegionTyParamBound(Lifetime
)
380 /// A modifier on a bound, currently this is only used for `?Sized`, where the
381 /// modifier is `Maybe`. Negative bounds should also be handled here.
382 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
383 pub enum TraitBoundModifier
{
388 pub type TyParamBounds
= P
<[TyParamBound
]>;
390 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
394 pub bounds
: TyParamBounds
,
395 pub default: Option
<P
<Ty
>>,
399 /// Represents lifetimes and type parameters attached to a declaration
400 /// of a function, enum, trait, etc.
401 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
402 pub struct Generics
{
403 pub lifetimes
: Vec
<LifetimeDef
>,
404 pub ty_params
: P
<[TyParam
]>,
405 pub where_clause
: WhereClause
,
409 pub fn is_lt_parameterized(&self) -> bool
{
410 !self.lifetimes
.is_empty()
412 pub fn is_type_parameterized(&self) -> bool
{
413 !self.ty_params
.is_empty()
415 pub fn is_parameterized(&self) -> bool
{
416 self.is_lt_parameterized() || self.is_type_parameterized()
420 impl Default
for Generics
{
421 fn default() -> Generics
{
423 lifetimes
: Vec
::new(),
424 ty_params
: P
::empty(),
425 where_clause
: WhereClause
{
427 predicates
: Vec
::new(),
433 /// A `where` clause in a definition
434 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
435 pub struct WhereClause
{
437 pub predicates
: Vec
<WherePredicate
>,
440 /// A single predicate in a `where` clause
441 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
442 pub enum WherePredicate
{
443 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
444 BoundPredicate(WhereBoundPredicate
),
445 /// A lifetime predicate, e.g. `'a: 'b+'c`
446 RegionPredicate(WhereRegionPredicate
),
447 /// An equality predicate (unsupported)
448 EqPredicate(WhereEqPredicate
),
451 /// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
452 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
453 pub struct WhereBoundPredicate
{
455 /// Any lifetimes from a `for` binding
456 pub bound_lifetimes
: Vec
<LifetimeDef
>,
457 /// The type being bounded
458 pub bounded_ty
: P
<Ty
>,
459 /// Trait and lifetime bounds (`Clone+Send+'static`)
460 pub bounds
: TyParamBounds
,
463 /// A lifetime predicate, e.g. `'a: 'b+'c`
464 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
465 pub struct WhereRegionPredicate
{
467 pub lifetime
: Lifetime
,
468 pub bounds
: Vec
<Lifetime
>,
471 /// An equality predicate (unsupported), e.g. `T=int`
472 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
473 pub struct WhereEqPredicate
{
480 /// The set of MetaItems that define the compilation environment of the crate,
481 /// used to drive conditional compilation
482 pub type CrateConfig
= Vec
<P
<MetaItem
>>;
484 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
487 pub attrs
: Vec
<Attribute
>,
488 pub config
: CrateConfig
,
490 pub exported_macros
: Vec
<MacroDef
>,
493 pub type MetaItem
= Spanned
<MetaItemKind
>;
495 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
496 pub enum MetaItemKind
{
497 Word(InternedString
),
498 List(InternedString
, Vec
<P
<MetaItem
>>),
499 NameValue(InternedString
, Lit
),
502 // can't be derived because the MetaItemKind::List requires an unordered comparison
503 impl PartialEq
for MetaItemKind
{
504 fn eq(&self, other
: &MetaItemKind
) -> bool
{
505 use self::MetaItemKind
::*;
507 Word(ref ns
) => match *other
{
508 Word(ref no
) => (*ns
) == (*no
),
511 NameValue(ref ns
, ref vs
) => match *other
{
512 NameValue(ref no
, ref vo
) => {
513 (*ns
) == (*no
) && vs
.node
== vo
.node
517 List(ref ns
, ref miss
) => match *other
{
518 List(ref no
, ref miso
) => {
520 miss
.iter().all(|mi
| miso
.iter().any(|x
| x
.node
== mi
.node
))
528 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
530 /// Statements in a block
531 pub stmts
: Vec
<Stmt
>,
532 /// An expression at the end of the block
533 /// without a semicolon, if any
534 pub expr
: Option
<P
<Expr
>>,
536 /// Distinguishes between `unsafe { ... }` and `{ ... }`
537 pub rules
: BlockCheckMode
,
541 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
548 impl fmt
::Debug
for Pat
{
549 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
550 write
!(f
, "pat({}: {})", self.id
, pprust
::pat_to_string(self))
554 /// A single field in a struct pattern
556 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
557 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
558 /// except is_shorthand is true
559 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
560 pub struct FieldPat
{
561 /// The identifier for the field
563 /// The pattern the field is destructured to
565 pub is_shorthand
: bool
,
568 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
569 pub enum BindingMode
{
574 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
576 /// Represents a wildcard pattern (`_`)
579 /// A `PatKind::Ident` may either be a new bound variable,
580 /// or a unit struct/variant pattern, or a const pattern (in the last two cases
581 /// the third field must be `None`).
583 /// In the unit or const pattern case, the parser can't determine
584 /// which it is. The resolver determines this, and
585 /// records this pattern's `NodeId` in an auxiliary
586 /// set (of "PatIdents that refer to unit patterns or constants").
587 Ident(BindingMode
, SpannedIdent
, Option
<P
<Pat
>>),
589 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
590 /// The `bool` is `true` in the presence of a `..`.
591 Struct(Path
, Vec
<Spanned
<FieldPat
>>, bool
),
593 /// A tuple struct/variant pattern `Variant(x, y, z)`.
594 /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
595 TupleStruct(Path
, Option
<Vec
<P
<Pat
>>>),
598 /// Such pattern can be resolved to a unit struct/variant or a constant.
601 /// An associated const named using the qualified path `<T>::CONST` or
602 /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
603 /// referred to as simply `T::CONST`, in which case they will end up as
604 /// PatKind::Path, and the resolver will have to sort that out.
607 /// A tuple pattern `(a, b)`
611 /// A reference pattern, e.g. `&mut (a, b)`
612 Ref(P
<Pat
>, Mutability
),
615 /// A range pattern, e.g. `1...2`
616 Range(P
<Expr
>, P
<Expr
>),
617 /// `[a, b, ..i, y, z]` is represented as:
618 /// `PatKind::Vec(box [a, b], Some(i), box [y, z])`
619 Vec(Vec
<P
<Pat
>>, Option
<P
<Pat
>>, Vec
<P
<Pat
>>),
620 /// A macro pattern; pre-expansion
624 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
625 pub enum Mutability
{
630 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
632 /// The `+` operator (addition)
634 /// The `-` operator (subtraction)
636 /// The `*` operator (multiplication)
638 /// The `/` operator (division)
640 /// The `%` operator (modulus)
642 /// The `&&` operator (logical and)
644 /// The `||` operator (logical or)
646 /// The `^` operator (bitwise xor)
648 /// The `&` operator (bitwise and)
650 /// The `|` operator (bitwise or)
652 /// The `<<` operator (shift left)
654 /// The `>>` operator (shift right)
656 /// The `==` operator (equality)
658 /// The `<` operator (less than)
660 /// The `<=` operator (less than or equal to)
662 /// The `!=` operator (not equal to)
664 /// The `>=` operator (greater than or equal to)
666 /// The `>` operator (greater than)
671 pub fn to_string(&self) -> &'
static str {
672 use self::BinOpKind
::*;
694 pub fn lazy(&self) -> bool
{
696 BinOpKind
::And
| BinOpKind
::Or
=> true,
701 pub fn is_shift(&self) -> bool
{
703 BinOpKind
::Shl
| BinOpKind
::Shr
=> true,
707 pub fn is_comparison(&self) -> bool
{
708 use self::BinOpKind
::*;
710 Eq
| Lt
| Le
| Ne
| Gt
| Ge
=>
712 And
| Or
| Add
| Sub
| Mul
| Div
| Rem
|
713 BitXor
| BitAnd
| BitOr
| Shl
| Shr
=>
717 /// Returns `true` if the binary operator takes its arguments by value
718 pub fn is_by_value(&self) -> bool
{
719 !self.is_comparison()
723 pub type BinOp
= Spanned
<BinOpKind
>;
725 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
727 /// The `*` operator for dereferencing
729 /// The `!` operator for logical inversion
731 /// The `-` operator for negation
736 /// Returns `true` if the unary operator takes its argument by value
737 pub fn is_by_value(u
: UnOp
) -> bool
{
739 UnOp
::Neg
| UnOp
::Not
=> true,
744 pub fn to_string(op
: UnOp
) -> &'
static str {
754 pub type Stmt
= Spanned
<StmtKind
>;
756 impl fmt
::Debug
for Stmt
{
757 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
758 write
!(f
, "stmt({}: {})",
760 .map_or(Cow
::Borrowed("<macro>"),|id
|Cow
::Owned(id
.to_string())),
761 pprust
::stmt_to_string(self))
766 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
768 /// Could be an item or a local (let) binding:
769 Decl(P
<Decl
>, NodeId
),
771 /// Expr without trailing semi-colon (must have unit type):
772 Expr(P
<Expr
>, NodeId
),
774 /// Expr with trailing semi-colon (may have any type):
775 Semi(P
<Expr
>, NodeId
),
777 Mac(P
<Mac
>, MacStmtStyle
, ThinAttributes
),
781 pub fn id(&self) -> Option
<NodeId
> {
783 StmtKind
::Decl(_
, id
) => Some(id
),
784 StmtKind
::Expr(_
, id
) => Some(id
),
785 StmtKind
::Semi(_
, id
) => Some(id
),
786 StmtKind
::Mac(..) => None
,
790 pub fn attrs(&self) -> &[Attribute
] {
792 StmtKind
::Decl(ref d
, _
) => d
.attrs(),
793 StmtKind
::Expr(ref e
, _
) |
794 StmtKind
::Semi(ref e
, _
) => e
.attrs(),
795 StmtKind
::Mac(_
, _
, Some(ref b
)) => b
,
796 StmtKind
::Mac(_
, _
, None
) => &[],
801 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
802 pub enum MacStmtStyle
{
803 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
804 /// `foo!(...);`, `foo![...];`
806 /// The macro statement had braces; e.g. foo! { ... }
808 /// The macro statement had parentheses or brackets and no semicolon; e.g.
809 /// `foo!(...)`. All of these will end up being converted into macro
814 // FIXME (pending discussion of #1697, #2178...): local should really be
815 // a refinement on pat.
816 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
817 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
820 pub ty
: Option
<P
<Ty
>>,
821 /// Initializer expression to set the value, if any
822 pub init
: Option
<P
<Expr
>>,
825 pub attrs
: ThinAttributes
,
829 pub fn attrs(&self) -> &[Attribute
] {
837 pub type Decl
= Spanned
<DeclKind
>;
839 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
841 /// A local (let) binding:
848 pub fn attrs(&self) -> &[Attribute
] {
850 DeclKind
::Local(ref l
) => l
.attrs(),
851 DeclKind
::Item(ref i
) => i
.attrs(),
856 /// represents one arm of a 'match'
857 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
859 pub attrs
: Vec
<Attribute
>,
860 pub pats
: Vec
<P
<Pat
>>,
861 pub guard
: Option
<P
<Expr
>>,
865 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
867 pub ident
: SpannedIdent
,
872 pub type SpannedIdent
= Spanned
<Ident
>;
874 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
875 pub enum BlockCheckMode
{
877 Unsafe(UnsafeSource
),
880 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
881 pub enum UnsafeSource
{
887 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
892 pub attrs
: ThinAttributes
896 pub fn attrs(&self) -> &[Attribute
] {
904 impl fmt
::Debug
for Expr
{
905 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
906 write
!(f
, "expr({}: {})", self.id
, pprust
::expr_to_string(self))
910 /// Limit types of a range (inclusive or exclusive)
911 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
912 pub enum RangeLimits
{
913 /// Inclusive at the beginning, exclusive at the end
915 /// Inclusive at the beginning and end
919 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
921 /// A `box x` expression.
923 /// First expr is the place; second expr is the value.
924 InPlace(P
<Expr
>, P
<Expr
>),
925 /// An array (`[a, b, c, d]`)
929 /// The first field resolves to the function itself,
930 /// and the second field is the list of arguments
931 Call(P
<Expr
>, Vec
<P
<Expr
>>),
932 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
934 /// The `SpannedIdent` is the identifier for the method name.
935 /// The vector of `Ty`s are the ascripted type parameters for the method
936 /// (within the angle brackets).
938 /// The first element of the vector of `Expr`s is the expression that evaluates
939 /// to the object on which the method is being called on (the receiver),
940 /// and the remaining elements are the rest of the arguments.
942 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
943 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
944 MethodCall(SpannedIdent
, Vec
<P
<Ty
>>, Vec
<P
<Expr
>>),
945 /// A tuple (`(a, b, c ,d)`)
947 /// A binary operation (For example: `a + b`, `a * b`)
948 Binary(BinOp
, P
<Expr
>, P
<Expr
>),
949 /// A unary operation (For example: `!x`, `*x`)
950 Unary(UnOp
, P
<Expr
>),
951 /// A literal (For example: `1`, `"foo"`)
953 /// A cast (`foo as f64`)
954 Cast(P
<Expr
>, P
<Ty
>),
955 Type(P
<Expr
>, P
<Ty
>),
956 /// An `if` block, with an optional else block
958 /// `if expr { block } else { expr }`
959 If(P
<Expr
>, P
<Block
>, Option
<P
<Expr
>>),
960 /// An `if let` expression with an optional else block
962 /// `if let pat = expr { block } else { expr }`
964 /// This is desugared to a `match` expression.
965 IfLet(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<P
<Expr
>>),
966 /// A while loop, with an optional label
968 /// `'label: while expr { block }`
969 While(P
<Expr
>, P
<Block
>, Option
<Ident
>),
970 /// A while-let loop, with an optional label
972 /// `'label: while let pat = expr { block }`
974 /// This is desugared to a combination of `loop` and `match` expressions.
975 WhileLet(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<Ident
>),
976 /// A for loop, with an optional label
978 /// `'label: for pat in expr { block }`
980 /// This is desugared to a combination of `loop` and `match` expressions.
981 ForLoop(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<Ident
>),
982 /// Conditionless loop (can be exited with break, continue, or return)
984 /// `'label: loop { block }`
985 Loop(P
<Block
>, Option
<Ident
>),
987 Match(P
<Expr
>, Vec
<Arm
>),
988 /// A closure (for example, `move |a, b, c| {a + b + c}`)
989 Closure(CaptureBy
, P
<FnDecl
>, P
<Block
>),
990 /// A block (`{ ... }`)
993 /// An assignment (`a = foo()`)
994 Assign(P
<Expr
>, P
<Expr
>),
995 /// An assignment with an operator
997 /// For example, `a += 1`.
998 AssignOp(BinOp
, P
<Expr
>, P
<Expr
>),
999 /// Access of a named struct field (`obj.foo`)
1000 Field(P
<Expr
>, SpannedIdent
),
1001 /// Access of an unnamed field of a struct or tuple-struct
1003 /// For example, `foo.0`.
1004 TupField(P
<Expr
>, Spanned
<usize>),
1005 /// An indexing operation (`foo[2]`)
1006 Index(P
<Expr
>, P
<Expr
>),
1007 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
1008 Range(Option
<P
<Expr
>>, Option
<P
<Expr
>>, RangeLimits
),
1010 /// Variable reference, possibly containing `::` and/or type
1011 /// parameters, e.g. foo::bar::<baz>.
1013 /// Optionally "qualified",
1014 /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
1015 Path(Option
<QSelf
>, Path
),
1017 /// A referencing operation (`&a` or `&mut a`)
1018 AddrOf(Mutability
, P
<Expr
>),
1019 /// A `break`, with an optional label to break
1020 Break(Option
<SpannedIdent
>),
1021 /// A `continue`, with an optional label
1022 Again(Option
<SpannedIdent
>),
1023 /// A `return`, with an optional value to be returned
1024 Ret(Option
<P
<Expr
>>),
1026 /// Output of the `asm!()` macro
1027 InlineAsm(InlineAsm
),
1029 /// A macro invocation; pre-expansion
1032 /// A struct literal expression.
1034 /// For example, `Foo {x: 1, y: 2}`, or
1035 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1036 Struct(Path
, Vec
<Field
>, Option
<P
<Expr
>>),
1038 /// An array literal constructed from one repeated element.
1040 /// For example, `[1; 5]`. The first expression is the element
1041 /// to be repeated; the second is the number of times to repeat it.
1042 Repeat(P
<Expr
>, P
<Expr
>),
1044 /// No-op: used solely so we can pretty-print faithfully
1051 /// The explicit Self type in a "qualified path". The actual
1052 /// path, including the trait and the associated item, is stored
1053 /// separately. `position` represents the index of the associated
1054 /// item qualified with this Self type.
1057 /// <Vec<T> as a::b::Trait>::AssociatedItem
1058 /// ^~~~~ ~~~~~~~~~~~~~~^
1061 /// <Vec<T>>::AssociatedItem
1065 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1071 /// A capture clause
1072 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1073 pub enum CaptureBy
{
1078 /// A delimited sequence of token trees
1079 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1080 pub struct Delimited
{
1081 /// The type of delimiter
1082 pub delim
: token
::DelimToken
,
1083 /// The span covering the opening delimiter
1084 pub open_span
: Span
,
1085 /// The delimited sequence of token trees
1086 pub tts
: Vec
<TokenTree
>,
1087 /// The span covering the closing delimiter
1088 pub close_span
: Span
,
1092 /// Returns the opening delimiter as a token.
1093 pub fn open_token(&self) -> token
::Token
{
1094 token
::OpenDelim(self.delim
)
1097 /// Returns the closing delimiter as a token.
1098 pub fn close_token(&self) -> token
::Token
{
1099 token
::CloseDelim(self.delim
)
1102 /// Returns the opening delimiter as a token tree.
1103 pub fn open_tt(&self) -> TokenTree
{
1104 TokenTree
::Token(self.open_span
, self.open_token())
1107 /// Returns the closing delimiter as a token tree.
1108 pub fn close_tt(&self) -> TokenTree
{
1109 TokenTree
::Token(self.close_span
, self.close_token())
1113 /// A sequence of token trees
1114 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1115 pub struct SequenceRepetition
{
1116 /// The sequence of token trees
1117 pub tts
: Vec
<TokenTree
>,
1118 /// The optional separator
1119 pub separator
: Option
<token
::Token
>,
1120 /// Whether the sequence can be repeated zero (*), or one or more times (+)
1122 /// The number of `MatchNt`s that appear in the sequence (and subsequences)
1123 pub num_captures
: usize,
1126 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
1127 /// for token sequences.
1128 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1134 /// When the main rust parser encounters a syntax-extension invocation, it
1135 /// parses the arguments to the invocation as a token-tree. This is a very
1136 /// loose structure, such that all sorts of different AST-fragments can
1137 /// be passed to syntax extensions using a uniform type.
1139 /// If the syntax extension is an MBE macro, it will attempt to match its
1140 /// LHS token tree against the provided token tree, and if it finds a
1141 /// match, will transcribe the RHS token tree, splicing in any captured
1142 /// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
1144 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
1145 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
1146 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1147 pub enum TokenTree
{
1149 Token(Span
, token
::Token
),
1150 /// A delimited sequence of token trees
1151 Delimited(Span
, Rc
<Delimited
>),
1153 // This only makes sense in MBE macros.
1155 /// A kleene-style repetition sequence with a span
1156 // FIXME(eddyb) #12938 Use DST.
1157 Sequence(Span
, Rc
<SequenceRepetition
>),
1161 pub fn len(&self) -> usize {
1163 TokenTree
::Token(_
, token
::DocComment(name
)) => {
1164 match doc_comment_style(&name
.as_str()) {
1165 AttrStyle
::Outer
=> 2,
1166 AttrStyle
::Inner
=> 3
1169 TokenTree
::Token(_
, token
::SpecialVarNt(..)) => 2,
1170 TokenTree
::Token(_
, token
::MatchNt(..)) => 3,
1171 TokenTree
::Delimited(_
, ref delimed
) => {
1172 delimed
.tts
.len() + 2
1174 TokenTree
::Sequence(_
, ref seq
) => {
1177 TokenTree
::Token(..) => 0
1181 pub fn get_tt(&self, index
: usize) -> TokenTree
{
1182 match (self, index
) {
1183 (&TokenTree
::Token(sp
, token
::DocComment(_
)), 0) => {
1184 TokenTree
::Token(sp
, token
::Pound
)
1186 (&TokenTree
::Token(sp
, token
::DocComment(name
)), 1)
1187 if doc_comment_style(&name
.as_str()) == AttrStyle
::Inner
=> {
1188 TokenTree
::Token(sp
, token
::Not
)
1190 (&TokenTree
::Token(sp
, token
::DocComment(name
)), _
) => {
1191 let stripped
= strip_doc_comment_decoration(&name
.as_str());
1193 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
1194 // required to wrap the text.
1195 let num_of_hashes
= stripped
.chars().scan(0, |cnt
, x
| {
1196 *cnt
= if x
== '
"' {
1198 } else if *cnt != 0 && x == '#' {
1204 }).max().unwrap_or(0);
1206 TokenTree::Delimited(sp, Rc::new(Delimited {
1207 delim: token::Bracket,
1209 tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc
"),
1211 TokenTree::Token(sp, token::Eq),
1212 TokenTree::Token(sp, token::Literal(
1213 token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
1217 (&TokenTree::Delimited(_, ref delimed), _) => {
1219 return delimed.open_tt();
1221 if index == delimed.tts.len() + 1 {
1222 return delimed.close_tt();
1224 delimed.tts[index - 1].clone()
1226 (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
1227 let v = [TokenTree::Token(sp, token::Dollar),
1228 TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str()),
1232 (&TokenTree::Token(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
1233 let v = [TokenTree::Token(sp, token::SubstNt(name, name_st)),
1234 TokenTree::Token(sp, token::Colon),
1235 TokenTree::Token(sp, token::Ident(kind, kind_st))];
1238 (&TokenTree::Sequence(_, ref seq), _) => {
1239 seq.tts[index].clone()
1241 _ => panic!("Cannot expand a token tree
")
1245 /// Returns the `Span` corresponding to this token tree.
1246 pub fn get_span(&self) -> Span {
1248 TokenTree::Token(span, _) => span,
1249 TokenTree::Delimited(span, _) => span,
1250 TokenTree::Sequence(span, _) => span,
1254 /// Use this token tree as a matcher to parse given tts.
1255 pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
1256 -> macro_parser::NamedParseResult {
1257 // `None` is because we're not interpolating
1258 let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
1261 tts.iter().cloned().collect(),
1263 macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
1267 pub type Mac = Spanned<Mac_>;
1269 /// Represents a macro invocation. The Path indicates which macro
1270 /// is being invoked, and the vector of token-trees contains the source
1271 /// of the macro invocation.
1273 /// NB: the additional ident for a macro_rules-style macro is actually
1274 /// stored in the enclosing item. Oog.
1275 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1278 pub tts: Vec<TokenTree>,
1279 pub ctxt: SyntaxContext,
1282 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1284 /// A regular string, like `"foo
"`
1286 /// A raw string, like `r##"foo
"##`
1288 /// The uint is the number of `#` symbols used
1293 pub type Lit = Spanned<LitKind>;
1295 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1296 pub enum LitIntType {
1302 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1304 /// A string literal (`"foo
"`)
1305 Str(InternedString, StrStyle),
1306 /// A byte string (`b"foo
"`)
1307 ByteStr(Rc<Vec<u8>>),
1308 /// A byte char (`b'f'`)
1310 /// A character literal (`'a'`)
1312 /// An integer literal (`1`)
1313 Int(u64, LitIntType),
1314 /// A float literal (`1f64` or `1E10f64`)
1315 Float(InternedString, FloatTy),
1316 /// A float literal without a suffix (`1.0 or 1.0E10`)
1317 FloatUnsuffixed(InternedString),
1318 /// A boolean literal
1323 /// Returns true if this literal is a string and false otherwise.
1324 pub fn is_str(&self) -> bool {
1326 LitKind::Str(..) => true,
1332 // NB: If you change this, you'll probably want to change the corresponding
1333 // type structure in middle/ty.rs as well.
1334 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1337 pub mutbl: Mutability,
1340 /// Represents a method's signature in a trait declaration,
1341 /// or in an implementation.
1342 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1343 pub struct MethodSig {
1344 pub unsafety: Unsafety,
1345 pub constness: Constness,
1347 pub decl: P<FnDecl>,
1348 pub generics: Generics,
1349 pub explicit_self: ExplicitSelf,
1352 /// Represents an item declaration within a trait declaration,
1353 /// possibly including a default implementation. A trait item is
1354 /// either required (meaning it doesn't have an implementation, just a
1355 /// signature) or provided (meaning it has a default implementation).
1356 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1357 pub struct TraitItem {
1360 pub attrs: Vec<Attribute>,
1361 pub node: TraitItemKind,
1365 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1366 pub enum TraitItemKind {
1367 Const(P<Ty>, Option<P<Expr>>),
1368 Method(MethodSig, Option<P<Block>>),
1369 Type(TyParamBounds, Option<P<Ty>>),
1372 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1373 pub struct ImplItem {
1376 pub vis: Visibility,
1377 pub defaultness: Defaultness,
1378 pub attrs: Vec<Attribute>,
1379 pub node: ImplItemKind,
1383 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1384 pub enum ImplItemKind {
1385 Const(P<Ty>, P<Expr>),
1386 Method(MethodSig, P<Block>),
1391 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1400 impl fmt::Debug for IntTy {
1401 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1402 fmt::Display::fmt(self, f)
1406 impl fmt::Display for IntTy {
1407 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1408 write!(f, "{}
", self.ty_to_string())
1413 pub fn ty_to_string(&self) -> &'static str {
1415 IntTy::Is => "isize",
1417 IntTy::I16 => "i16",
1418 IntTy::I32 => "i32",
1423 pub fn val_to_string(&self, val: i64) -> String {
1424 // cast to a u64 so we can correctly print INT64_MIN. All integral types
1425 // are parsed as u64, so we wouldn't want to print an extra negative
1427 format!("{}{}
", val as u64, self.ty_to_string())
1430 pub fn ty_max(&self) -> u64 {
1433 IntTy::I16 => 0x8000,
1434 IntTy::Is | IntTy::I32 => 0x80000000, // FIXME: actually ni about Is
1435 IntTy::I64 => 0x8000000000000000
1439 pub fn bit_width(&self) -> Option<usize> {
1441 IntTy::Is => return None,
1450 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1460 pub fn ty_to_string(&self) -> &'static str {
1462 UintTy::Us => "usize",
1464 UintTy::U16 => "u16",
1465 UintTy::U32 => "u32",
1466 UintTy::U64 => "u64"
1470 pub fn val_to_string(&self, val: u64) -> String {
1471 format!("{}{}
", val, self.ty_to_string())
1474 pub fn ty_max(&self) -> u64 {
1477 UintTy::U16 => 0xffff,
1478 UintTy::Us | UintTy::U32 => 0xffffffff, // FIXME: actually ni about Us
1479 UintTy::U64 => 0xffffffffffffffff
1483 pub fn bit_width(&self) -> Option<usize> {
1485 UintTy::Us => return None,
1494 impl fmt::Debug for UintTy {
1495 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1496 fmt::Display::fmt(self, f)
1500 impl fmt::Display for UintTy {
1501 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1502 write!(f, "{}
", self.ty_to_string())
1506 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1512 impl fmt::Debug for FloatTy {
1513 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1514 fmt::Display::fmt(self, f)
1518 impl fmt::Display for FloatTy {
1519 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1520 write!(f, "{}
", self.ty_to_string())
1525 pub fn ty_to_string(&self) -> &'static str {
1527 FloatTy::F32 => "f32",
1528 FloatTy::F64 => "f64",
1532 pub fn bit_width(&self) -> usize {
1540 // Bind a type to an associated type: `A=Foo`.
1541 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1542 pub struct TypeBinding {
1549 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1556 impl fmt::Debug for Ty {
1557 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1558 write!(f, "type({}
)", pprust::ty_to_string(self))
1562 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1563 pub struct BareFnTy {
1564 pub unsafety: Unsafety,
1566 pub lifetimes: Vec<LifetimeDef>,
1570 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1571 /// The different kinds of types recognized by the compiler
1574 /// A fixed length array (`[T; n]`)
1575 FixedLengthVec(P<Ty>, P<Expr>),
1576 /// A raw pointer (`*const T` or `*mut T`)
1578 /// A reference (`&'a T` or `&'a mut T`)
1579 Rptr(Option<Lifetime>, MutTy),
1580 /// A bare function (e.g. `fn(usize) -> bool`)
1581 BareFn(P<BareFnTy>),
1582 /// A tuple (`(A, B, C, D,...)`)
1584 /// A path (`module::module::...::Type`), optionally
1585 /// "qualified
", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1587 /// Type parameters are stored in the Path itself
1588 Path(Option<QSelf>, Path),
1589 /// Something like `A+B`. Note that `B` must always be a path.
1590 ObjectSum(P<Ty>, TyParamBounds),
1591 /// A type like `for<'a> Foo<&'a Bar>`
1592 PolyTraitRef(TyParamBounds),
1593 /// No-op; kept solely so that we can pretty-print faithfully
1597 /// TyKind::Infer means the type should be inferred instead of it having been
1598 /// specified. This can appear anywhere in a type.
1600 // A macro in the type position.
1604 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1605 pub enum AsmDialect {
1610 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1611 pub struct InlineAsmOutput {
1612 pub constraint: InternedString,
1615 pub is_indirect: bool,
1618 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1619 pub struct InlineAsm {
1620 pub asm: InternedString,
1621 pub asm_str_style: StrStyle,
1622 pub outputs: Vec<InlineAsmOutput>,
1623 pub inputs: Vec<(InternedString, P<Expr>)>,
1624 pub clobbers: Vec<InternedString>,
1626 pub alignstack: bool,
1627 pub dialect: AsmDialect,
1628 pub expn_id: ExpnId,
1631 /// represents an argument in a function header
1632 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1640 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1641 let path = Spanned{span:span,node:self_ident};
1643 // HACK(eddyb) fake type for the self argument.
1646 node: TyKind::Infer,
1651 node: PatKind::Ident(BindingMode::ByValue(mutability), path, None),
1659 /// Represents the header (not the body) of a function declaration
1660 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1662 pub inputs: Vec<Arg>,
1663 pub output: FunctionRetTy,
1667 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1673 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1674 pub enum Constness {
1679 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1680 pub enum Defaultness {
1685 impl fmt::Display for Unsafety {
1686 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1687 fmt::Display::fmt(match *self {
1688 Unsafety::Normal => "normal
",
1689 Unsafety::Unsafe => "unsafe",
1694 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1695 pub enum ImplPolarity {
1696 /// `impl Trait for Type`
1698 /// `impl !Trait for Type`
1702 impl fmt::Debug for ImplPolarity {
1703 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1705 ImplPolarity::Positive => "positive
".fmt(f),
1706 ImplPolarity::Negative => "negative
".fmt(f),
1712 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1713 pub enum FunctionRetTy {
1714 /// Functions with return type `!`that always
1715 /// raise an error or exit (i.e. never return to the caller)
1717 /// Return type is not specified.
1719 /// Functions default to `()` and
1720 /// closures default to inference. Span points to where return
1721 /// type would be inserted.
1727 impl FunctionRetTy {
1728 pub fn span(&self) -> Span {
1730 FunctionRetTy::None(span) => span,
1731 FunctionRetTy::Default(span) => span,
1732 FunctionRetTy::Ty(ref ty) => ty.span,
1737 /// Represents the kind of 'self' associated with a method
1738 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1744 /// `&'lt self`, `&'lt mut self`
1745 Region(Option<Lifetime>, Mutability, Ident),
1747 Explicit(P<Ty>, Ident),
1750 pub type ExplicitSelf = Spanned<SelfKind>;
1752 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1754 /// A span from the first token past `{` to the last token until `}`.
1755 /// For `mod foo;`, the inner span ranges from the first token
1756 /// to the last token in the external file.
1758 pub items: Vec<P<Item>>,
1761 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1762 pub struct ForeignMod {
1764 pub items: Vec<ForeignItem>,
1767 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1768 pub struct EnumDef {
1769 pub variants: Vec<Variant>,
1772 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1773 pub struct Variant_ {
1775 pub attrs: Vec<Attribute>,
1776 pub data: VariantData,
1777 /// Explicit discriminant, eg `Foo = 1`
1778 pub disr_expr: Option<P<Expr>>,
1781 pub type Variant = Spanned<Variant_>;
1783 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1784 pub enum PathListItemKind {
1787 /// renamed in list, eg `use foo::{bar as baz};`
1788 rename: Option<Ident>,
1792 /// renamed in list, eg `use foo::{self as baz};`
1793 rename: Option<Ident>,
1798 impl PathListItemKind {
1799 pub fn id(&self) -> NodeId {
1801 PathListItemKind::Ident { id, .. } | PathListItemKind::Mod { id, .. } => id
1805 pub fn name(&self) -> Option<Ident> {
1807 PathListItemKind::Ident { name, .. } => Some(name),
1808 PathListItemKind::Mod { .. } => None,
1812 pub fn rename(&self) -> Option<Ident> {
1814 PathListItemKind::Ident { rename, .. } | PathListItemKind::Mod { rename, .. } => rename
1819 pub type PathListItem = Spanned<PathListItemKind>;
1821 pub type ViewPath = Spanned<ViewPath_>;
1823 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1824 pub enum ViewPath_ {
1826 /// `foo::bar::baz as quux`
1830 /// `foo::bar::baz` (with `as baz` implicitly on the right)
1831 ViewPathSimple(Ident, Path),
1836 /// `foo::bar::{a,b,c}`
1837 ViewPathList(Path, Vec<PathListItem>)
1840 /// Meta-data associated with an item
1841 pub type Attribute = Spanned<Attribute_>;
1843 /// Distinguishes between Attributes that decorate items and Attributes that
1844 /// are contained as statements within items. These two cases need to be
1845 /// distinguished for pretty-printing.
1846 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1847 pub enum AttrStyle {
1852 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1853 pub struct AttrId(pub usize);
1855 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1856 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1857 pub struct Attribute_ {
1859 pub style: AttrStyle,
1860 pub value: P<MetaItem>,
1861 pub is_sugared_doc: bool,
1864 /// TraitRef's appear in impls.
1866 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1867 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1868 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
1869 /// same as the impl's node id).
1870 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1871 pub struct TraitRef {
1876 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1877 pub struct PolyTraitRef {
1878 /// The `'a` in `<'a> Foo<&'a T>`
1879 pub bound_lifetimes: Vec<LifetimeDef>,
1881 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1882 pub trait_ref: TraitRef,
1887 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1888 pub enum Visibility {
1891 Restricted { path: P<Path>, id: NodeId },
1895 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1896 pub struct StructField {
1898 pub ident: Option<Ident>,
1899 pub vis: Visibility,
1902 pub attrs: Vec<Attribute>,
1905 /// Fields and Ids of enum variants and structs
1907 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1908 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1909 /// One shared Id can be successfully used for these two purposes.
1910 /// Id of the whole enum lives in `Item`.
1912 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1913 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1914 /// the variant itself" from enum variants.
1915 /// Id of the whole struct lives in `Item`.
1916 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1917 pub enum VariantData
{
1918 Struct(Vec
<StructField
>, NodeId
),
1919 Tuple(Vec
<StructField
>, NodeId
),
1924 pub fn fields(&self) -> &[StructField
] {
1926 VariantData
::Struct(ref fields
, _
) | VariantData
::Tuple(ref fields
, _
) => fields
,
1930 pub fn id(&self) -> NodeId
{
1932 VariantData
::Struct(_
, id
) | VariantData
::Tuple(_
, id
) | VariantData
::Unit(id
) => id
1935 pub fn is_struct(&self) -> bool
{
1936 if let VariantData
::Struct(..) = *self { true }
else { false }
1938 pub fn is_tuple(&self) -> bool
{
1939 if let VariantData
::Tuple(..) = *self { true }
else { false }
1941 pub fn is_unit(&self) -> bool
{
1942 if let VariantData
::Unit(..) = *self { true }
else { false }
1947 FIXME (#3300): Should allow items to be anonymous. Right now
1948 we just use dummy names for anon items.
1952 /// The name might be a dummy name in case of anonymous items
1953 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1956 pub attrs
: Vec
<Attribute
>,
1959 pub vis
: Visibility
,
1964 pub fn attrs(&self) -> &[Attribute
] {
1969 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1971 /// An`extern crate` item, with optional original crate name,
1973 /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1974 ExternCrate(Option
<Name
>),
1975 /// A `use` or `pub use` item
1979 Static(P
<Ty
>, Mutability
, P
<Expr
>),
1981 Const(P
<Ty
>, P
<Expr
>),
1982 /// A function declaration
1983 Fn(P
<FnDecl
>, Unsafety
, Constness
, Abi
, Generics
, P
<Block
>),
1986 /// An external module
1987 ForeignMod(ForeignMod
),
1988 /// A type alias, e.g. `type Foo = Bar<u8>`
1989 Ty(P
<Ty
>, Generics
),
1990 /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1991 Enum(EnumDef
, Generics
),
1992 /// A struct definition, e.g. `struct Foo<A> {x: A}`
1993 Struct(VariantData
, Generics
),
1994 /// Represents a Trait Declaration
2000 // Default trait implementations
2002 // `impl Trait for .. {}`
2003 DefaultImpl(Unsafety
, TraitRef
),
2004 /// An implementation, eg `impl<A> Trait for Foo { .. }`
2008 Option
<TraitRef
>, // (optional) trait this impl implements
2011 /// A macro invocation (which includes macro definition)
2016 pub fn descriptive_variant(&self) -> &str {
2018 ItemKind
::ExternCrate(..) => "extern crate",
2019 ItemKind
::Use(..) => "use",
2020 ItemKind
::Static(..) => "static item",
2021 ItemKind
::Const(..) => "constant item",
2022 ItemKind
::Fn(..) => "function",
2023 ItemKind
::Mod(..) => "module",
2024 ItemKind
::ForeignMod(..) => "foreign module",
2025 ItemKind
::Ty(..) => "type alias",
2026 ItemKind
::Enum(..) => "enum",
2027 ItemKind
::Struct(..) => "struct",
2028 ItemKind
::Trait(..) => "trait",
2030 ItemKind
::Impl(..) |
2031 ItemKind
::DefaultImpl(..) => "item"
2036 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2037 pub struct ForeignItem
{
2039 pub attrs
: Vec
<Attribute
>,
2040 pub node
: ForeignItemKind
,
2043 pub vis
: Visibility
,
2046 /// An item within an `extern` block
2047 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2048 pub enum ForeignItemKind
{
2049 /// A foreign function
2050 Fn(P
<FnDecl
>, Generics
),
2051 /// A foreign static item (`static ext: u8`), with optional mutability
2052 /// (the boolean is true when mutable)
2053 Static(P
<Ty
>, bool
),
2056 impl ForeignItemKind
{
2057 pub fn descriptive_variant(&self) -> &str {
2059 ForeignItemKind
::Fn(..) => "foreign function",
2060 ForeignItemKind
::Static(..) => "foreign static item"
2065 /// A macro definition, in this crate or imported from another.
2067 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
2068 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2069 pub struct MacroDef
{
2071 pub attrs
: Vec
<Attribute
>,
2074 pub imported_from
: Option
<Ident
>,
2076 pub use_locally
: bool
,
2077 pub allow_internal_unstable
: bool
,
2078 pub body
: Vec
<TokenTree
>,
2086 // are ASTs encodable?
2088 fn check_asts_encodable() {
2089 fn assert_encodable
<T
: serialize
::Encodable
>() {}
2090 assert_encodable
::<Crate
>();