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
::{mk_sp, respan, Span, Spanned, DUMMY_SP, ExpnId}
;
23 use ext
::tt
::macro_parser
;
24 use parse
::token
::{self, keywords, InternedString}
;
26 use parse
::lexer
::comments
::{doc_comment_style, strip_doc_comment_decoration}
;
33 use std
::hash
::{Hash, Hasher}
;
34 use serialize
::{Encodable, Decodable, Encoder, Decoder}
;
36 /// A name is a part of an identifier, representing a string or gensym. It's
37 /// the result of interning.
38 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
39 pub struct Name(pub u32);
41 /// A SyntaxContext represents a chain of macro-expandings
42 /// and renamings. Each macro expansion corresponds to
43 /// a fresh u32. This u32 is a reference to a table stored
44 /// in thread-local storage.
45 /// The special value EMPTY_CTXT is used to indicate an empty
47 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
48 pub struct SyntaxContext(pub u32);
50 /// An identifier contains a Name (index into the interner
51 /// table) and a SyntaxContext to track renaming and
52 /// macro expansion per Flatt et al., "Macros That Work Together"
53 #[derive(Clone, Copy, Eq)]
56 pub ctxt
: SyntaxContext
60 pub fn as_str(self) -> token
::InternedString
{
61 token
::InternedString
::new_from_name(self)
64 pub fn unhygienize(self) -> Name
{
65 token
::intern(&self.as_str())
69 impl fmt
::Debug
for Name
{
70 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
71 write
!(f
, "{}({})", self, self.0)
75 impl fmt
::Display
for Name
{
76 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
77 fmt
::Display
::fmt(&self.as_str(), f
)
81 impl Encodable
for Name
{
82 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
83 s
.emit_str(&self.as_str())
87 impl Decodable
for Name
{
88 fn decode
<D
: Decoder
>(d
: &mut D
) -> Result
<Name
, D
::Error
> {
89 Ok(token
::intern(&d
.read_str()?
[..]))
93 pub const EMPTY_CTXT
: SyntaxContext
= SyntaxContext(0);
96 pub fn new(name
: Name
, ctxt
: SyntaxContext
) -> Ident
{
97 Ident {name: name, ctxt: ctxt}
99 pub const fn with_empty_ctxt(name
: Name
) -> Ident
{
100 Ident {name: name, ctxt: EMPTY_CTXT}
104 impl PartialEq
for Ident
{
105 fn eq(&self, other
: &Ident
) -> bool
{
106 if self.ctxt
!= other
.ctxt
{
107 // There's no one true way to compare Idents. They can be compared
108 // non-hygienically `id1.name == id2.name`, hygienically
109 // `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
110 // `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
111 // Ideally, PartialEq should not be implemented for Ident at all, but that
112 // would be too impractical, because many larger structures (Token, in particular)
113 // including Idents as their parts derive PartialEq and use it for non-hygienic
114 // comparisons. That's why PartialEq is implemented and defaults to non-hygienic
115 // comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
116 // the name of Ident is hashed. Still try to avoid comparing idents in your code
117 // (especially as keys in hash maps), use one of the three methods listed above
120 // If you see this panic, then some idents from different contexts were compared
121 // non-hygienically. It's likely a bug. Use one of the three comparison methods
122 // listed above explicitly.
124 panic
!("idents with different contexts are compared with operator `==`: \
125 {:?}, {:?}.", self, other
);
128 self.name
== other
.name
132 impl Hash
for Ident
{
133 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
134 self.name
.hash(state
)
138 impl fmt
::Debug
for Ident
{
139 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
140 write
!(f
, "{}#{}", self.name
, self.ctxt
.0)
144 impl fmt
::Display
for Ident
{
145 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
146 fmt
::Display
::fmt(&self.name
, f
)
150 impl Encodable
for Ident
{
151 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
156 impl Decodable
for Ident
{
157 fn decode
<D
: Decoder
>(d
: &mut D
) -> Result
<Ident
, D
::Error
> {
158 Ok(Ident
::with_empty_ctxt(Name
::decode(d
)?
))
162 /// A mark represents a unique id associated with a macro expansion
165 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
166 pub struct Lifetime
{
172 impl fmt
::Debug
for Lifetime
{
173 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
174 write
!(f
, "lifetime({}: {})", self.id
, pprust
::lifetime_to_string(self))
178 /// A lifetime definition, eg `'a: 'b+'c+'d`
179 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
180 pub struct LifetimeDef
{
181 pub lifetime
: Lifetime
,
182 pub bounds
: Vec
<Lifetime
>
185 /// A "Path" is essentially Rust's notion of a name; for instance:
186 /// std::cmp::PartialEq . It's represented as a sequence of identifiers,
187 /// along with a bunch of supporting information.
188 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
191 /// A `::foo` path, is relative to the crate root rather than current
192 /// module (like paths in an import).
194 /// The segments in the path: the things separated by `::`.
195 pub segments
: Vec
<PathSegment
>,
198 impl fmt
::Debug
for Path
{
199 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
200 write
!(f
, "path({})", pprust
::path_to_string(self))
204 impl fmt
::Display
for Path
{
205 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
206 write
!(f
, "{}", pprust
::path_to_string(self))
211 // convert a span and an identifier to the corresponding
213 pub fn from_ident(s
: Span
, identifier
: Ident
) -> Path
{
219 identifier
: identifier
,
220 parameters
: PathParameters
::none()
227 /// A segment of a path: an identifier, an optional lifetime, and a set of
229 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
230 pub struct PathSegment
{
231 /// The identifier portion of this path segment.
232 pub identifier
: Ident
,
234 /// Type/lifetime parameters attached to this path. They come in
235 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
236 /// this is more than just simple syntactic sugar; the use of
237 /// parens affects the region binding rules, so we preserve the
239 pub parameters
: PathParameters
,
242 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
243 pub enum PathParameters
{
244 /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
245 AngleBracketed(AngleBracketedParameterData
),
246 /// The `(A,B)` and `C` in `Foo(A,B) -> C`
247 Parenthesized(ParenthesizedParameterData
),
250 impl PathParameters
{
251 pub fn none() -> PathParameters
{
252 PathParameters
::AngleBracketed(AngleBracketedParameterData
{
253 lifetimes
: Vec
::new(),
259 pub fn is_empty(&self) -> bool
{
261 PathParameters
::AngleBracketed(ref data
) => data
.is_empty(),
263 // Even if the user supplied no types, something like
264 // `X()` is equivalent to `X<(),()>`.
265 PathParameters
::Parenthesized(..) => false,
269 pub fn has_lifetimes(&self) -> bool
{
271 PathParameters
::AngleBracketed(ref data
) => !data
.lifetimes
.is_empty(),
272 PathParameters
::Parenthesized(_
) => false,
276 pub fn has_types(&self) -> bool
{
278 PathParameters
::AngleBracketed(ref data
) => !data
.types
.is_empty(),
279 PathParameters
::Parenthesized(..) => true,
283 /// Returns the types that the user wrote. Note that these do not necessarily map to the type
284 /// parameters in the parenthesized case.
285 pub fn types(&self) -> Vec
<&P
<Ty
>> {
287 PathParameters
::AngleBracketed(ref data
) => {
288 data
.types
.iter().collect()
290 PathParameters
::Parenthesized(ref data
) => {
292 .chain(data
.output
.iter())
298 pub fn lifetimes(&self) -> Vec
<&Lifetime
> {
300 PathParameters
::AngleBracketed(ref data
) => {
301 data
.lifetimes
.iter().collect()
303 PathParameters
::Parenthesized(_
) => {
309 pub fn bindings(&self) -> Vec
<&TypeBinding
> {
311 PathParameters
::AngleBracketed(ref data
) => {
312 data
.bindings
.iter().collect()
314 PathParameters
::Parenthesized(_
) => {
321 /// A path like `Foo<'a, T>`
322 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
323 pub struct AngleBracketedParameterData
{
324 /// The lifetime parameters for this path segment.
325 pub lifetimes
: Vec
<Lifetime
>,
326 /// The type parameters for this path segment, if present.
327 pub types
: P
<[P
<Ty
>]>,
328 /// Bindings (equality constraints) on associated types, if present.
329 /// e.g., `Foo<A=Bar>`.
330 pub bindings
: P
<[TypeBinding
]>,
333 impl AngleBracketedParameterData
{
334 fn is_empty(&self) -> bool
{
335 self.lifetimes
.is_empty() && self.types
.is_empty() && self.bindings
.is_empty()
339 /// A path like `Foo(A,B) -> C`
340 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
341 pub struct ParenthesizedParameterData
{
346 pub inputs
: Vec
<P
<Ty
>>,
349 pub output
: Option
<P
<Ty
>>,
352 pub type CrateNum
= u32;
354 pub type NodeId
= u32;
356 /// Node id used to represent the root of the crate.
357 pub const CRATE_NODE_ID
: NodeId
= 0;
359 /// When parsing and doing expansions, we initially give all AST nodes this AST
360 /// node value. Then later, in the renumber pass, we renumber them to have
361 /// small, positive ids.
362 pub const DUMMY_NODE_ID
: NodeId
= !0;
364 pub trait NodeIdAssigner
{
365 fn next_node_id(&self) -> NodeId
;
366 fn peek_node_id(&self) -> NodeId
;
368 fn diagnostic(&self) -> &errors
::Handler
{
369 panic
!("this ID assigner cannot emit diagnostics")
373 /// The AST represents all type param bounds as types.
374 /// typeck::collect::compute_bounds matches these against
375 /// the "special" built-in traits (see middle::lang_items) and
376 /// detects Copy, Send and Sync.
377 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
378 pub enum TyParamBound
{
379 TraitTyParamBound(PolyTraitRef
, TraitBoundModifier
),
380 RegionTyParamBound(Lifetime
)
383 /// A modifier on a bound, currently this is only used for `?Sized`, where the
384 /// modifier is `Maybe`. Negative bounds should also be handled here.
385 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
386 pub enum TraitBoundModifier
{
391 pub type TyParamBounds
= P
<[TyParamBound
]>;
393 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
397 pub bounds
: TyParamBounds
,
398 pub default: Option
<P
<Ty
>>,
402 /// Represents lifetimes and type parameters attached to a declaration
403 /// of a function, enum, trait, etc.
404 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
405 pub struct Generics
{
406 pub lifetimes
: Vec
<LifetimeDef
>,
407 pub ty_params
: P
<[TyParam
]>,
408 pub where_clause
: WhereClause
,
412 pub fn is_lt_parameterized(&self) -> bool
{
413 !self.lifetimes
.is_empty()
415 pub fn is_type_parameterized(&self) -> bool
{
416 !self.ty_params
.is_empty()
418 pub fn is_parameterized(&self) -> bool
{
419 self.is_lt_parameterized() || self.is_type_parameterized()
423 impl Default
for Generics
{
424 fn default() -> Generics
{
426 lifetimes
: Vec
::new(),
428 where_clause
: WhereClause
{
430 predicates
: Vec
::new(),
436 /// A `where` clause in a definition
437 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
438 pub struct WhereClause
{
440 pub predicates
: Vec
<WherePredicate
>,
443 /// A single predicate in a `where` clause
444 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
445 pub enum WherePredicate
{
446 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
447 BoundPredicate(WhereBoundPredicate
),
448 /// A lifetime predicate, e.g. `'a: 'b+'c`
449 RegionPredicate(WhereRegionPredicate
),
450 /// An equality predicate (unsupported)
451 EqPredicate(WhereEqPredicate
),
454 /// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
455 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
456 pub struct WhereBoundPredicate
{
458 /// Any lifetimes from a `for` binding
459 pub bound_lifetimes
: Vec
<LifetimeDef
>,
460 /// The type being bounded
461 pub bounded_ty
: P
<Ty
>,
462 /// Trait and lifetime bounds (`Clone+Send+'static`)
463 pub bounds
: TyParamBounds
,
466 /// A lifetime predicate, e.g. `'a: 'b+'c`
467 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
468 pub struct WhereRegionPredicate
{
470 pub lifetime
: Lifetime
,
471 pub bounds
: Vec
<Lifetime
>,
474 /// An equality predicate (unsupported), e.g. `T=int`
475 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
476 pub struct WhereEqPredicate
{
483 /// The set of MetaItems that define the compilation environment of the crate,
484 /// used to drive conditional compilation
485 pub type CrateConfig
= Vec
<P
<MetaItem
>>;
487 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
490 pub attrs
: Vec
<Attribute
>,
491 pub config
: CrateConfig
,
493 pub exported_macros
: Vec
<MacroDef
>,
496 pub type MetaItem
= Spanned
<MetaItemKind
>;
498 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
499 pub enum MetaItemKind
{
500 Word(InternedString
),
501 List(InternedString
, Vec
<P
<MetaItem
>>),
502 NameValue(InternedString
, Lit
),
505 // can't be derived because the MetaItemKind::List requires an unordered comparison
506 impl PartialEq
for MetaItemKind
{
507 fn eq(&self, other
: &MetaItemKind
) -> bool
{
508 use self::MetaItemKind
::*;
510 Word(ref ns
) => match *other
{
511 Word(ref no
) => (*ns
) == (*no
),
514 NameValue(ref ns
, ref vs
) => match *other
{
515 NameValue(ref no
, ref vo
) => {
516 (*ns
) == (*no
) && vs
.node
== vo
.node
520 List(ref ns
, ref miss
) => match *other
{
521 List(ref no
, ref miso
) => {
523 miss
.iter().all(|mi
| miso
.iter().any(|x
| x
.node
== mi
.node
))
531 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
533 /// Statements in a block
534 pub stmts
: Vec
<Stmt
>,
535 /// An expression at the end of the block
536 /// without a semicolon, if any
537 pub expr
: Option
<P
<Expr
>>,
539 /// Distinguishes between `unsafe { ... }` and `{ ... }`
540 pub rules
: BlockCheckMode
,
544 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
551 impl fmt
::Debug
for Pat
{
552 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
553 write
!(f
, "pat({}: {})", self.id
, pprust
::pat_to_string(self))
558 pub fn walk
<F
>(&self, it
: &mut F
) -> bool
559 where F
: FnMut(&Pat
) -> bool
566 PatKind
::Ident(_
, _
, Some(ref p
)) => p
.walk(it
),
567 PatKind
::Struct(_
, ref fields
, _
) => {
568 fields
.iter().all(|field
| field
.node
.pat
.walk(it
))
570 PatKind
::TupleStruct(_
, Some(ref s
)) | PatKind
::Tup(ref s
) => {
571 s
.iter().all(|p
| p
.walk(it
))
573 PatKind
::Box(ref s
) | PatKind
::Ref(ref s
, _
) => {
576 PatKind
::Vec(ref before
, ref slice
, ref after
) => {
577 before
.iter().all(|p
| p
.walk(it
)) &&
578 slice
.iter().all(|p
| p
.walk(it
)) &&
579 after
.iter().all(|p
| p
.walk(it
))
583 PatKind
::Range(_
, _
) |
584 PatKind
::Ident(_
, _
, _
) |
585 PatKind
::TupleStruct(..) |
587 PatKind
::QPath(_
, _
) |
595 /// A single field in a struct pattern
597 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
598 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
599 /// except is_shorthand is true
600 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
601 pub struct FieldPat
{
602 /// The identifier for the field
604 /// The pattern the field is destructured to
606 pub is_shorthand
: bool
,
609 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
610 pub enum BindingMode
{
615 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
617 /// Represents a wildcard pattern (`_`)
620 /// A `PatKind::Ident` may either be a new bound variable,
621 /// or a unit struct/variant pattern, or a const pattern (in the last two cases
622 /// the third field must be `None`).
624 /// In the unit or const pattern case, the parser can't determine
625 /// which it is. The resolver determines this, and
626 /// records this pattern's `NodeId` in an auxiliary
627 /// set (of "PatIdents that refer to unit patterns or constants").
628 Ident(BindingMode
, SpannedIdent
, Option
<P
<Pat
>>),
630 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
631 /// The `bool` is `true` in the presence of a `..`.
632 Struct(Path
, Vec
<Spanned
<FieldPat
>>, bool
),
634 /// A tuple struct/variant pattern `Variant(x, y, z)`.
635 /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
636 TupleStruct(Path
, Option
<Vec
<P
<Pat
>>>),
639 /// Such pattern can be resolved to a unit struct/variant or a constant.
642 /// An associated const named using the qualified path `<T>::CONST` or
643 /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
644 /// referred to as simply `T::CONST`, in which case they will end up as
645 /// PatKind::Path, and the resolver will have to sort that out.
648 /// A tuple pattern `(a, b)`
652 /// A reference pattern, e.g. `&mut (a, b)`
653 Ref(P
<Pat
>, Mutability
),
656 /// A range pattern, e.g. `1...2`
657 Range(P
<Expr
>, P
<Expr
>),
658 /// `[a, b, ..i, y, z]` is represented as:
659 /// `PatKind::Vec(box [a, b], Some(i), box [y, z])`
660 Vec(Vec
<P
<Pat
>>, Option
<P
<Pat
>>, Vec
<P
<Pat
>>),
661 /// A macro pattern; pre-expansion
665 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
666 pub enum Mutability
{
671 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
673 /// The `+` operator (addition)
675 /// The `-` operator (subtraction)
677 /// The `*` operator (multiplication)
679 /// The `/` operator (division)
681 /// The `%` operator (modulus)
683 /// The `&&` operator (logical and)
685 /// The `||` operator (logical or)
687 /// The `^` operator (bitwise xor)
689 /// The `&` operator (bitwise and)
691 /// The `|` operator (bitwise or)
693 /// The `<<` operator (shift left)
695 /// The `>>` operator (shift right)
697 /// The `==` operator (equality)
699 /// The `<` operator (less than)
701 /// The `<=` operator (less than or equal to)
703 /// The `!=` operator (not equal to)
705 /// The `>=` operator (greater than or equal to)
707 /// The `>` operator (greater than)
712 pub fn to_string(&self) -> &'
static str {
713 use self::BinOpKind
::*;
735 pub fn lazy(&self) -> bool
{
737 BinOpKind
::And
| BinOpKind
::Or
=> true,
742 pub fn is_shift(&self) -> bool
{
744 BinOpKind
::Shl
| BinOpKind
::Shr
=> true,
748 pub fn is_comparison(&self) -> bool
{
749 use self::BinOpKind
::*;
751 Eq
| Lt
| Le
| Ne
| Gt
| Ge
=>
753 And
| Or
| Add
| Sub
| Mul
| Div
| Rem
|
754 BitXor
| BitAnd
| BitOr
| Shl
| Shr
=>
758 /// Returns `true` if the binary operator takes its arguments by value
759 pub fn is_by_value(&self) -> bool
{
760 !self.is_comparison()
764 pub type BinOp
= Spanned
<BinOpKind
>;
766 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
768 /// The `*` operator for dereferencing
770 /// The `!` operator for logical inversion
772 /// The `-` operator for negation
777 /// Returns `true` if the unary operator takes its argument by value
778 pub fn is_by_value(u
: UnOp
) -> bool
{
780 UnOp
::Neg
| UnOp
::Not
=> true,
785 pub fn to_string(op
: UnOp
) -> &'
static str {
795 pub type Stmt
= Spanned
<StmtKind
>;
797 impl fmt
::Debug
for Stmt
{
798 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
799 write
!(f
, "stmt({}: {})",
801 .map_or(Cow
::Borrowed("<macro>"),|id
|Cow
::Owned(id
.to_string())),
802 pprust
::stmt_to_string(self))
807 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
809 /// Could be an item or a local (let) binding:
810 Decl(P
<Decl
>, NodeId
),
812 /// Expr without trailing semi-colon (must have unit type):
813 Expr(P
<Expr
>, NodeId
),
815 /// Expr with trailing semi-colon (may have any type):
816 Semi(P
<Expr
>, NodeId
),
818 Mac(P
<Mac
>, MacStmtStyle
, ThinAttributes
),
822 pub fn id(&self) -> Option
<NodeId
> {
824 StmtKind
::Decl(_
, id
) => Some(id
),
825 StmtKind
::Expr(_
, id
) => Some(id
),
826 StmtKind
::Semi(_
, id
) => Some(id
),
827 StmtKind
::Mac(..) => None
,
831 pub fn attrs(&self) -> &[Attribute
] {
833 StmtKind
::Decl(ref d
, _
) => d
.attrs(),
834 StmtKind
::Expr(ref e
, _
) |
835 StmtKind
::Semi(ref e
, _
) => e
.attrs(),
836 StmtKind
::Mac(_
, _
, Some(ref b
)) => b
,
837 StmtKind
::Mac(_
, _
, None
) => &[],
842 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
843 pub enum MacStmtStyle
{
844 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
845 /// `foo!(...);`, `foo![...];`
847 /// The macro statement had braces; e.g. foo! { ... }
849 /// The macro statement had parentheses or brackets and no semicolon; e.g.
850 /// `foo!(...)`. All of these will end up being converted into macro
855 // FIXME (pending discussion of #1697, #2178...): local should really be
856 // a refinement on pat.
857 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
858 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
861 pub ty
: Option
<P
<Ty
>>,
862 /// Initializer expression to set the value, if any
863 pub init
: Option
<P
<Expr
>>,
866 pub attrs
: ThinAttributes
,
870 pub fn attrs(&self) -> &[Attribute
] {
878 pub type Decl
= Spanned
<DeclKind
>;
880 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
882 /// A local (let) binding:
889 pub fn attrs(&self) -> &[Attribute
] {
891 DeclKind
::Local(ref l
) => l
.attrs(),
892 DeclKind
::Item(ref i
) => i
.attrs(),
897 /// represents one arm of a 'match'
898 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
900 pub attrs
: Vec
<Attribute
>,
901 pub pats
: Vec
<P
<Pat
>>,
902 pub guard
: Option
<P
<Expr
>>,
906 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
908 pub ident
: SpannedIdent
,
913 pub type SpannedIdent
= Spanned
<Ident
>;
915 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
916 pub enum BlockCheckMode
{
918 Unsafe(UnsafeSource
),
921 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
922 pub enum UnsafeSource
{
928 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
933 pub attrs
: ThinAttributes
937 pub fn attrs(&self) -> &[Attribute
] {
945 impl fmt
::Debug
for Expr
{
946 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
947 write
!(f
, "expr({}: {})", self.id
, pprust
::expr_to_string(self))
951 /// Limit types of a range (inclusive or exclusive)
952 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
953 pub enum RangeLimits
{
954 /// Inclusive at the beginning, exclusive at the end
956 /// Inclusive at the beginning and end
960 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
962 /// A `box x` expression.
964 /// First expr is the place; second expr is the value.
965 InPlace(P
<Expr
>, P
<Expr
>),
966 /// An array (`[a, b, c, d]`)
970 /// The first field resolves to the function itself,
971 /// and the second field is the list of arguments
972 Call(P
<Expr
>, Vec
<P
<Expr
>>),
973 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
975 /// The `SpannedIdent` is the identifier for the method name.
976 /// The vector of `Ty`s are the ascripted type parameters for the method
977 /// (within the angle brackets).
979 /// The first element of the vector of `Expr`s is the expression that evaluates
980 /// to the object on which the method is being called on (the receiver),
981 /// and the remaining elements are the rest of the arguments.
983 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
984 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
985 MethodCall(SpannedIdent
, Vec
<P
<Ty
>>, Vec
<P
<Expr
>>),
986 /// A tuple (`(a, b, c ,d)`)
988 /// A binary operation (For example: `a + b`, `a * b`)
989 Binary(BinOp
, P
<Expr
>, P
<Expr
>),
990 /// A unary operation (For example: `!x`, `*x`)
991 Unary(UnOp
, P
<Expr
>),
992 /// A literal (For example: `1`, `"foo"`)
994 /// A cast (`foo as f64`)
995 Cast(P
<Expr
>, P
<Ty
>),
996 Type(P
<Expr
>, P
<Ty
>),
997 /// An `if` block, with an optional else block
999 /// `if expr { block } else { expr }`
1000 If(P
<Expr
>, P
<Block
>, Option
<P
<Expr
>>),
1001 /// An `if let` expression with an optional else block
1003 /// `if let pat = expr { block } else { expr }`
1005 /// This is desugared to a `match` expression.
1006 IfLet(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<P
<Expr
>>),
1007 /// A while loop, with an optional label
1009 /// `'label: while expr { block }`
1010 While(P
<Expr
>, P
<Block
>, Option
<Ident
>),
1011 /// A while-let loop, with an optional label
1013 /// `'label: while let pat = expr { block }`
1015 /// This is desugared to a combination of `loop` and `match` expressions.
1016 WhileLet(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<Ident
>),
1017 /// A for loop, with an optional label
1019 /// `'label: for pat in expr { block }`
1021 /// This is desugared to a combination of `loop` and `match` expressions.
1022 ForLoop(P
<Pat
>, P
<Expr
>, P
<Block
>, Option
<Ident
>),
1023 /// Conditionless loop (can be exited with break, continue, or return)
1025 /// `'label: loop { block }`
1026 Loop(P
<Block
>, Option
<Ident
>),
1027 /// A `match` block.
1028 Match(P
<Expr
>, Vec
<Arm
>),
1029 /// A closure (for example, `move |a, b, c| {a + b + c}`)
1031 /// The final span is the span of the argument block `|...|`
1032 Closure(CaptureBy
, P
<FnDecl
>, P
<Block
>, Span
),
1033 /// A block (`{ ... }`)
1036 /// An assignment (`a = foo()`)
1037 Assign(P
<Expr
>, P
<Expr
>),
1038 /// An assignment with an operator
1040 /// For example, `a += 1`.
1041 AssignOp(BinOp
, P
<Expr
>, P
<Expr
>),
1042 /// Access of a named struct field (`obj.foo`)
1043 Field(P
<Expr
>, SpannedIdent
),
1044 /// Access of an unnamed field of a struct or tuple-struct
1046 /// For example, `foo.0`.
1047 TupField(P
<Expr
>, Spanned
<usize>),
1048 /// An indexing operation (`foo[2]`)
1049 Index(P
<Expr
>, P
<Expr
>),
1050 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
1051 Range(Option
<P
<Expr
>>, Option
<P
<Expr
>>, RangeLimits
),
1053 /// Variable reference, possibly containing `::` and/or type
1054 /// parameters, e.g. foo::bar::<baz>.
1056 /// Optionally "qualified",
1057 /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
1058 Path(Option
<QSelf
>, Path
),
1060 /// A referencing operation (`&a` or `&mut a`)
1061 AddrOf(Mutability
, P
<Expr
>),
1062 /// A `break`, with an optional label to break
1063 Break(Option
<SpannedIdent
>),
1064 /// A `continue`, with an optional label
1065 Again(Option
<SpannedIdent
>),
1066 /// A `return`, with an optional value to be returned
1067 Ret(Option
<P
<Expr
>>),
1069 /// Output of the `asm!()` macro
1070 InlineAsm(InlineAsm
),
1072 /// A macro invocation; pre-expansion
1075 /// A struct literal expression.
1077 /// For example, `Foo {x: 1, y: 2}`, or
1078 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1079 Struct(Path
, Vec
<Field
>, Option
<P
<Expr
>>),
1081 /// An array literal constructed from one repeated element.
1083 /// For example, `[1; 5]`. The first expression is the element
1084 /// to be repeated; the second is the number of times to repeat it.
1085 Repeat(P
<Expr
>, P
<Expr
>),
1087 /// No-op: used solely so we can pretty-print faithfully
1094 /// The explicit Self type in a "qualified path". The actual
1095 /// path, including the trait and the associated item, is stored
1096 /// separately. `position` represents the index of the associated
1097 /// item qualified with this Self type.
1100 /// <Vec<T> as a::b::Trait>::AssociatedItem
1101 /// ^~~~~ ~~~~~~~~~~~~~~^
1104 /// <Vec<T>>::AssociatedItem
1108 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1114 /// A capture clause
1115 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1116 pub enum CaptureBy
{
1121 /// A delimited sequence of token trees
1122 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1123 pub struct Delimited
{
1124 /// The type of delimiter
1125 pub delim
: token
::DelimToken
,
1126 /// The span covering the opening delimiter
1127 pub open_span
: Span
,
1128 /// The delimited sequence of token trees
1129 pub tts
: Vec
<TokenTree
>,
1130 /// The span covering the closing delimiter
1131 pub close_span
: Span
,
1135 /// Returns the opening delimiter as a token.
1136 pub fn open_token(&self) -> token
::Token
{
1137 token
::OpenDelim(self.delim
)
1140 /// Returns the closing delimiter as a token.
1141 pub fn close_token(&self) -> token
::Token
{
1142 token
::CloseDelim(self.delim
)
1145 /// Returns the opening delimiter as a token tree.
1146 pub fn open_tt(&self) -> TokenTree
{
1147 TokenTree
::Token(self.open_span
, self.open_token())
1150 /// Returns the closing delimiter as a token tree.
1151 pub fn close_tt(&self) -> TokenTree
{
1152 TokenTree
::Token(self.close_span
, self.close_token())
1156 /// A sequence of token trees
1157 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1158 pub struct SequenceRepetition
{
1159 /// The sequence of token trees
1160 pub tts
: Vec
<TokenTree
>,
1161 /// The optional separator
1162 pub separator
: Option
<token
::Token
>,
1163 /// Whether the sequence can be repeated zero (*), or one or more times (+)
1165 /// The number of `MatchNt`s that appear in the sequence (and subsequences)
1166 pub num_captures
: usize,
1169 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
1170 /// for token sequences.
1171 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1177 /// When the main rust parser encounters a syntax-extension invocation, it
1178 /// parses the arguments to the invocation as a token-tree. This is a very
1179 /// loose structure, such that all sorts of different AST-fragments can
1180 /// be passed to syntax extensions using a uniform type.
1182 /// If the syntax extension is an MBE macro, it will attempt to match its
1183 /// LHS token tree against the provided token tree, and if it finds a
1184 /// match, will transcribe the RHS token tree, splicing in any captured
1185 /// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
1187 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
1188 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
1189 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1190 pub enum TokenTree
{
1192 Token(Span
, token
::Token
),
1193 /// A delimited sequence of token trees
1194 Delimited(Span
, Rc
<Delimited
>),
1196 // This only makes sense in MBE macros.
1198 /// A kleene-style repetition sequence with a span
1199 // FIXME(eddyb) #12938 Use DST.
1200 Sequence(Span
, Rc
<SequenceRepetition
>),
1204 pub fn len(&self) -> usize {
1206 TokenTree
::Token(_
, token
::DocComment(name
)) => {
1207 match doc_comment_style(&name
.as_str()) {
1208 AttrStyle
::Outer
=> 2,
1209 AttrStyle
::Inner
=> 3
1212 TokenTree
::Token(_
, token
::SpecialVarNt(..)) => 2,
1213 TokenTree
::Token(_
, token
::MatchNt(..)) => 3,
1214 TokenTree
::Delimited(_
, ref delimed
) => {
1215 delimed
.tts
.len() + 2
1217 TokenTree
::Sequence(_
, ref seq
) => {
1220 TokenTree
::Token(..) => 0
1224 pub fn get_tt(&self, index
: usize) -> TokenTree
{
1225 match (self, index
) {
1226 (&TokenTree
::Token(sp
, token
::DocComment(_
)), 0) => {
1227 TokenTree
::Token(sp
, token
::Pound
)
1229 (&TokenTree
::Token(sp
, token
::DocComment(name
)), 1)
1230 if doc_comment_style(&name
.as_str()) == AttrStyle
::Inner
=> {
1231 TokenTree
::Token(sp
, token
::Not
)
1233 (&TokenTree
::Token(sp
, token
::DocComment(name
)), _
) => {
1234 let stripped
= strip_doc_comment_decoration(&name
.as_str());
1236 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
1237 // required to wrap the text.
1238 let num_of_hashes
= stripped
.chars().scan(0, |cnt
, x
| {
1239 *cnt
= if x
== '
"' {
1241 } else if *cnt != 0 && x == '#' {
1247 }).max().unwrap_or(0);
1249 TokenTree::Delimited(sp, Rc::new(Delimited {
1250 delim: token::Bracket,
1252 tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc
"))),
1253 TokenTree::Token(sp, token::Eq),
1254 TokenTree::Token(sp, token::Literal(
1255 token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
1259 (&TokenTree::Delimited(_, ref delimed), _) => {
1261 return delimed.open_tt();
1263 if index == delimed.tts.len() + 1 {
1264 return delimed.close_tt();
1266 delimed.tts[index - 1].clone()
1268 (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
1269 let v = [TokenTree::Token(sp, token::Dollar),
1270 TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str())))];
1273 (&TokenTree::Token(sp, token::MatchNt(name, kind)), _) => {
1274 let v = [TokenTree::Token(sp, token::SubstNt(name)),
1275 TokenTree::Token(sp, token::Colon),
1276 TokenTree::Token(sp, token::Ident(kind))];
1279 (&TokenTree::Sequence(_, ref seq), _) => {
1280 seq.tts[index].clone()
1282 _ => panic!("Cannot expand a token tree
")
1286 /// Returns the `Span` corresponding to this token tree.
1287 pub fn get_span(&self) -> Span {
1289 TokenTree::Token(span, _) => span,
1290 TokenTree::Delimited(span, _) => span,
1291 TokenTree::Sequence(span, _) => span,
1295 /// Use this token tree as a matcher to parse given tts.
1296 pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
1297 -> macro_parser::NamedParseResult {
1298 // `None` is because we're not interpolating
1299 let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
1302 tts.iter().cloned().collect(),
1304 macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
1308 pub type Mac = Spanned<Mac_>;
1310 /// Represents a macro invocation. The Path indicates which macro
1311 /// is being invoked, and the vector of token-trees contains the source
1312 /// of the macro invocation.
1314 /// NB: the additional ident for a macro_rules-style macro is actually
1315 /// stored in the enclosing item. Oog.
1316 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1319 pub tts: Vec<TokenTree>,
1320 pub ctxt: SyntaxContext,
1323 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1325 /// A regular string, like `"foo
"`
1327 /// A raw string, like `r##"foo
"##`
1329 /// The uint is the number of `#` symbols used
1334 pub type Lit = Spanned<LitKind>;
1336 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1337 pub enum LitIntType {
1343 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1345 /// A string literal (`"foo
"`)
1346 Str(InternedString, StrStyle),
1347 /// A byte string (`b"foo
"`)
1348 ByteStr(Rc<Vec<u8>>),
1349 /// A byte char (`b'f'`)
1351 /// A character literal (`'a'`)
1353 /// An integer literal (`1`)
1354 Int(u64, LitIntType),
1355 /// A float literal (`1f64` or `1E10f64`)
1356 Float(InternedString, FloatTy),
1357 /// A float literal without a suffix (`1.0 or 1.0E10`)
1358 FloatUnsuffixed(InternedString),
1359 /// A boolean literal
1364 /// Returns true if this literal is a string and false otherwise.
1365 pub fn is_str(&self) -> bool {
1367 LitKind::Str(..) => true,
1373 // NB: If you change this, you'll probably want to change the corresponding
1374 // type structure in middle/ty.rs as well.
1375 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1378 pub mutbl: Mutability,
1381 /// Represents a method's signature in a trait declaration,
1382 /// or in an implementation.
1383 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1384 pub struct MethodSig {
1385 pub unsafety: Unsafety,
1386 pub constness: Constness,
1388 pub decl: P<FnDecl>,
1389 pub generics: Generics,
1390 pub explicit_self: ExplicitSelf,
1393 /// Represents an item declaration within a trait declaration,
1394 /// possibly including a default implementation. A trait item is
1395 /// either required (meaning it doesn't have an implementation, just a
1396 /// signature) or provided (meaning it has a default implementation).
1397 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1398 pub struct TraitItem {
1401 pub attrs: Vec<Attribute>,
1402 pub node: TraitItemKind,
1406 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1407 pub enum TraitItemKind {
1408 Const(P<Ty>, Option<P<Expr>>),
1409 Method(MethodSig, Option<P<Block>>),
1410 Type(TyParamBounds, Option<P<Ty>>),
1413 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1414 pub struct ImplItem {
1417 pub vis: Visibility,
1418 pub defaultness: Defaultness,
1419 pub attrs: Vec<Attribute>,
1420 pub node: ImplItemKind,
1424 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1425 pub enum ImplItemKind {
1426 Const(P<Ty>, P<Expr>),
1427 Method(MethodSig, P<Block>),
1432 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1441 impl fmt::Debug for IntTy {
1442 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1443 fmt::Display::fmt(self, f)
1447 impl fmt::Display for IntTy {
1448 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1449 write!(f, "{}
", self.ty_to_string())
1454 pub fn ty_to_string(&self) -> &'static str {
1456 IntTy::Is => "isize",
1458 IntTy::I16 => "i16",
1459 IntTy::I32 => "i32",
1464 pub fn val_to_string(&self, val: i64) -> String {
1465 // cast to a u64 so we can correctly print INT64_MIN. All integral types
1466 // are parsed as u64, so we wouldn't want to print an extra negative
1468 format!("{}{}
", val as u64, self.ty_to_string())
1471 pub fn ty_max(&self) -> u64 {
1474 IntTy::I16 => 0x8000,
1475 IntTy::Is | IntTy::I32 => 0x80000000, // FIXME: actually ni about Is
1476 IntTy::I64 => 0x8000000000000000
1480 pub fn bit_width(&self) -> Option<usize> {
1482 IntTy::Is => return None,
1491 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1501 pub fn ty_to_string(&self) -> &'static str {
1503 UintTy::Us => "usize",
1505 UintTy::U16 => "u16",
1506 UintTy::U32 => "u32",
1507 UintTy::U64 => "u64"
1511 pub fn val_to_string(&self, val: u64) -> String {
1512 format!("{}{}
", val, self.ty_to_string())
1515 pub fn ty_max(&self) -> u64 {
1518 UintTy::U16 => 0xffff,
1519 UintTy::Us | UintTy::U32 => 0xffffffff, // FIXME: actually ni about Us
1520 UintTy::U64 => 0xffffffffffffffff
1524 pub fn bit_width(&self) -> Option<usize> {
1526 UintTy::Us => return None,
1535 impl fmt::Debug for UintTy {
1536 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1537 fmt::Display::fmt(self, f)
1541 impl fmt::Display for UintTy {
1542 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1543 write!(f, "{}
", self.ty_to_string())
1547 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1553 impl fmt::Debug for FloatTy {
1554 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1555 fmt::Display::fmt(self, f)
1559 impl fmt::Display for FloatTy {
1560 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1561 write!(f, "{}
", self.ty_to_string())
1566 pub fn ty_to_string(&self) -> &'static str {
1568 FloatTy::F32 => "f32",
1569 FloatTy::F64 => "f64",
1573 pub fn bit_width(&self) -> usize {
1581 // Bind a type to an associated type: `A=Foo`.
1582 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1583 pub struct TypeBinding {
1590 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1597 impl fmt::Debug for Ty {
1598 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1599 write!(f, "type({}
)", pprust::ty_to_string(self))
1603 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1604 pub struct BareFnTy {
1605 pub unsafety: Unsafety,
1607 pub lifetimes: Vec<LifetimeDef>,
1611 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1612 /// The different kinds of types recognized by the compiler
1615 /// A fixed length array (`[T; n]`)
1616 FixedLengthVec(P<Ty>, P<Expr>),
1617 /// A raw pointer (`*const T` or `*mut T`)
1619 /// A reference (`&'a T` or `&'a mut T`)
1620 Rptr(Option<Lifetime>, MutTy),
1621 /// A bare function (e.g. `fn(usize) -> bool`)
1622 BareFn(P<BareFnTy>),
1623 /// A tuple (`(A, B, C, D,...)`)
1625 /// A path (`module::module::...::Type`), optionally
1626 /// "qualified
", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1628 /// Type parameters are stored in the Path itself
1629 Path(Option<QSelf>, Path),
1630 /// Something like `A+B`. Note that `B` must always be a path.
1631 ObjectSum(P<Ty>, TyParamBounds),
1632 /// A type like `for<'a> Foo<&'a Bar>`
1633 PolyTraitRef(TyParamBounds),
1634 /// No-op; kept solely so that we can pretty-print faithfully
1638 /// TyKind::Infer means the type should be inferred instead of it having been
1639 /// specified. This can appear anywhere in a type.
1641 // A macro in the type position.
1645 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1646 pub enum AsmDialect {
1651 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1652 pub struct InlineAsmOutput {
1653 pub constraint: InternedString,
1656 pub is_indirect: bool,
1659 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1660 pub struct InlineAsm {
1661 pub asm: InternedString,
1662 pub asm_str_style: StrStyle,
1663 pub outputs: Vec<InlineAsmOutput>,
1664 pub inputs: Vec<(InternedString, P<Expr>)>,
1665 pub clobbers: Vec<InternedString>,
1667 pub alignstack: bool,
1668 pub dialect: AsmDialect,
1669 pub expn_id: ExpnId,
1672 /// represents an argument in a function header
1673 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1680 /// Represents the kind of 'self' associated with a method.
1681 /// String representation of `Ident` here is always "self", but hygiene contexts may differ.
1682 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1686 /// `self`, `mut self`
1688 /// `&'lt self`, `&'lt mut self`
1689 Region(Option<Lifetime>, Mutability, Ident),
1690 /// `self: TYPE`, `mut self: TYPE`
1691 Explicit(P<Ty>, Ident),
1694 pub type ExplicitSelf = Spanned<SelfKind>;
1697 #[unstable(feature = "rustc_private
", issue = "27812")]
1698 #[rustc_deprecated(since = "1.10.0", reason = "use `from_self` instead
")]
1699 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1700 let path = Spanned{span:span,node:self_ident};
1702 // HACK(eddyb) fake type for the self argument.
1705 node: TyKind::Infer,
1710 node: PatKind::Ident(BindingMode::ByValue(mutability), path, None),
1717 pub fn to_self(&self) -> Option<ExplicitSelf> {
1718 if let PatKind::Ident(_, ident, _) = self.pat.node {
1719 if ident.node.name == keywords::SelfValue.name() {
1720 return match self.ty.node {
1721 TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(ident.node))),
1722 TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => {
1723 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl, ident.node)))
1725 _ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
1726 SelfKind::Explicit(self.ty.clone(), ident.node))),
1733 pub fn from_self(eself: ExplicitSelf, ident_sp: Span, mutbl: Mutability) -> Arg {
1734 let pat = |ident, span| P(Pat {
1736 node: PatKind::Ident(BindingMode::ByValue(mutbl), respan(ident_sp, ident), None),
1739 let infer_ty = P(Ty {
1741 node: TyKind::Infer,
1744 let arg = |ident, ty, span| Arg {
1745 pat: pat(ident, span),
1750 SelfKind::Static => panic!("bug
: `Arg
::from_self` is called
\
1751 with `SelfKind
::Static` argument
"),
1752 SelfKind::Explicit(ty, ident) => arg(ident, ty, mk_sp(eself.span.lo, ident_sp.hi)),
1753 SelfKind::Value(ident) => arg(ident, infer_ty, eself.span),
1754 SelfKind::Region(lt, mutbl, ident) => arg(ident, P(Ty {
1756 node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }),
1763 /// Represents the header (not the body) of a function declaration
1764 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1766 pub inputs: Vec<Arg>,
1767 pub output: FunctionRetTy,
1771 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1777 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1778 pub enum Constness {
1783 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1784 pub enum Defaultness {
1789 impl fmt::Display for Unsafety {
1790 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1791 fmt::Display::fmt(match *self {
1792 Unsafety::Normal => "normal
",
1793 Unsafety::Unsafe => "unsafe",
1798 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1799 pub enum ImplPolarity {
1800 /// `impl Trait for Type`
1802 /// `impl !Trait for Type`
1806 impl fmt::Debug for ImplPolarity {
1807 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1809 ImplPolarity::Positive => "positive
".fmt(f),
1810 ImplPolarity::Negative => "negative
".fmt(f),
1816 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1817 pub enum FunctionRetTy {
1818 /// Functions with return type `!`that always
1819 /// raise an error or exit (i.e. never return to the caller)
1821 /// Return type is not specified.
1823 /// Functions default to `()` and
1824 /// closures default to inference. Span points to where return
1825 /// type would be inserted.
1831 impl FunctionRetTy {
1832 pub fn span(&self) -> Span {
1834 FunctionRetTy::None(span) => span,
1835 FunctionRetTy::Default(span) => span,
1836 FunctionRetTy::Ty(ref ty) => ty.span,
1841 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1843 /// A span from the first token past `{` to the last token until `}`.
1844 /// For `mod foo;`, the inner span ranges from the first token
1845 /// to the last token in the external file.
1847 pub items: Vec<P<Item>>,
1850 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1851 pub struct ForeignMod {
1853 pub items: Vec<ForeignItem>,
1856 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1857 pub struct EnumDef {
1858 pub variants: Vec<Variant>,
1861 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1862 pub struct Variant_ {
1864 pub attrs: Vec<Attribute>,
1865 pub data: VariantData,
1866 /// Explicit discriminant, eg `Foo = 1`
1867 pub disr_expr: Option<P<Expr>>,
1870 pub type Variant = Spanned<Variant_>;
1872 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1873 pub enum PathListItemKind {
1876 /// renamed in list, eg `use foo::{bar as baz};`
1877 rename: Option<Ident>,
1881 /// renamed in list, eg `use foo::{self as baz};`
1882 rename: Option<Ident>,
1887 impl PathListItemKind {
1888 pub fn id(&self) -> NodeId {
1890 PathListItemKind::Ident { id, .. } | PathListItemKind::Mod { id, .. } => id
1894 pub fn name(&self) -> Option<Ident> {
1896 PathListItemKind::Ident { name, .. } => Some(name),
1897 PathListItemKind::Mod { .. } => None,
1901 pub fn rename(&self) -> Option<Ident> {
1903 PathListItemKind::Ident { rename, .. } | PathListItemKind::Mod { rename, .. } => rename
1908 pub type PathListItem = Spanned<PathListItemKind>;
1910 pub type ViewPath = Spanned<ViewPath_>;
1912 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1913 pub enum ViewPath_ {
1915 /// `foo::bar::baz as quux`
1919 /// `foo::bar::baz` (with `as baz` implicitly on the right)
1920 ViewPathSimple(Ident, Path),
1925 /// `foo::bar::{a,b,c}`
1926 ViewPathList(Path, Vec<PathListItem>)
1929 /// Meta-data associated with an item
1930 pub type Attribute = Spanned<Attribute_>;
1932 /// Distinguishes between Attributes that decorate items and Attributes that
1933 /// are contained as statements within items. These two cases need to be
1934 /// distinguished for pretty-printing.
1935 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1936 pub enum AttrStyle {
1941 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1942 pub struct AttrId(pub usize);
1944 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1945 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1946 pub struct Attribute_ {
1948 pub style: AttrStyle,
1949 pub value: P<MetaItem>,
1950 pub is_sugared_doc: bool,
1953 /// TraitRef's appear in impls.
1955 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1956 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1957 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
1958 /// same as the impl's node id).
1959 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1960 pub struct TraitRef {
1965 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1966 pub struct PolyTraitRef {
1967 /// The `'a` in `<'a> Foo<&'a T>`
1968 pub bound_lifetimes: Vec<LifetimeDef>,
1970 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1971 pub trait_ref: TraitRef,
1976 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1977 pub enum Visibility {
1980 Restricted { path: P<Path>, id: NodeId },
1984 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1985 pub struct StructField {
1987 pub ident: Option<Ident>,
1988 pub vis: Visibility,
1991 pub attrs: Vec<Attribute>,
1994 /// Fields and Ids of enum variants and structs
1996 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1997 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1998 /// One shared Id can be successfully used for these two purposes.
1999 /// Id of the whole enum lives in `Item`.
2001 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
2002 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
2003 /// the variant itself" from enum variants.
2004 /// Id of the whole struct lives in `Item`.
2005 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2006 pub enum VariantData
{
2007 Struct(Vec
<StructField
>, NodeId
),
2008 Tuple(Vec
<StructField
>, NodeId
),
2013 pub fn fields(&self) -> &[StructField
] {
2015 VariantData
::Struct(ref fields
, _
) | VariantData
::Tuple(ref fields
, _
) => fields
,
2019 pub fn id(&self) -> NodeId
{
2021 VariantData
::Struct(_
, id
) | VariantData
::Tuple(_
, id
) | VariantData
::Unit(id
) => id
2024 pub fn is_struct(&self) -> bool
{
2025 if let VariantData
::Struct(..) = *self { true }
else { false }
2027 pub fn is_tuple(&self) -> bool
{
2028 if let VariantData
::Tuple(..) = *self { true }
else { false }
2030 pub fn is_unit(&self) -> bool
{
2031 if let VariantData
::Unit(..) = *self { true }
else { false }
2036 FIXME (#3300): Should allow items to be anonymous. Right now
2037 we just use dummy names for anon items.
2041 /// The name might be a dummy name in case of anonymous items
2042 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2045 pub attrs
: Vec
<Attribute
>,
2048 pub vis
: Visibility
,
2053 pub fn attrs(&self) -> &[Attribute
] {
2058 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2060 /// An`extern crate` item, with optional original crate name,
2062 /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
2063 ExternCrate(Option
<Name
>),
2064 /// A `use` or `pub use` item
2068 Static(P
<Ty
>, Mutability
, P
<Expr
>),
2070 Const(P
<Ty
>, P
<Expr
>),
2071 /// A function declaration
2072 Fn(P
<FnDecl
>, Unsafety
, Constness
, Abi
, Generics
, P
<Block
>),
2075 /// An external module
2076 ForeignMod(ForeignMod
),
2077 /// A type alias, e.g. `type Foo = Bar<u8>`
2078 Ty(P
<Ty
>, Generics
),
2079 /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
2080 Enum(EnumDef
, Generics
),
2081 /// A struct definition, e.g. `struct Foo<A> {x: A}`
2082 Struct(VariantData
, Generics
),
2083 /// Represents a Trait Declaration
2084 Trait(Unsafety
, Generics
, TyParamBounds
, Vec
<TraitItem
>),
2086 // Default trait implementations
2088 // `impl Trait for .. {}`
2089 DefaultImpl(Unsafety
, TraitRef
),
2090 /// An implementation, eg `impl<A> Trait for Foo { .. }`
2094 Option
<TraitRef
>, // (optional) trait this impl implements
2097 /// A macro invocation (which includes macro definition)
2102 pub fn descriptive_variant(&self) -> &str {
2104 ItemKind
::ExternCrate(..) => "extern crate",
2105 ItemKind
::Use(..) => "use",
2106 ItemKind
::Static(..) => "static item",
2107 ItemKind
::Const(..) => "constant item",
2108 ItemKind
::Fn(..) => "function",
2109 ItemKind
::Mod(..) => "module",
2110 ItemKind
::ForeignMod(..) => "foreign module",
2111 ItemKind
::Ty(..) => "type alias",
2112 ItemKind
::Enum(..) => "enum",
2113 ItemKind
::Struct(..) => "struct",
2114 ItemKind
::Trait(..) => "trait",
2116 ItemKind
::Impl(..) |
2117 ItemKind
::DefaultImpl(..) => "item"
2122 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2123 pub struct ForeignItem
{
2125 pub attrs
: Vec
<Attribute
>,
2126 pub node
: ForeignItemKind
,
2129 pub vis
: Visibility
,
2132 /// An item within an `extern` block
2133 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2134 pub enum ForeignItemKind
{
2135 /// A foreign function
2136 Fn(P
<FnDecl
>, Generics
),
2137 /// A foreign static item (`static ext: u8`), with optional mutability
2138 /// (the boolean is true when mutable)
2139 Static(P
<Ty
>, bool
),
2142 impl ForeignItemKind
{
2143 pub fn descriptive_variant(&self) -> &str {
2145 ForeignItemKind
::Fn(..) => "foreign function",
2146 ForeignItemKind
::Static(..) => "foreign static item"
2151 /// A macro definition, in this crate or imported from another.
2153 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
2154 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2155 pub struct MacroDef
{
2157 pub attrs
: Vec
<Attribute
>,
2160 pub imported_from
: Option
<Ident
>,
2162 pub use_locally
: bool
,
2163 pub allow_internal_unstable
: bool
,
2164 pub body
: Vec
<TokenTree
>,
2172 // are ASTs encodable?
2174 fn check_asts_encodable() {
2175 fn assert_encodable
<T
: serialize
::Encodable
>() {}
2176 assert_encodable
::<Crate
>();