]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
Auto merge of #55356 - Aaron1011:fix/rustdoc-negative-auto, r=nikomatsakis
[rust.git] / src / libsyntax / ast.rs
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.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // The Rust abstract syntax tree.
12
13 pub use self::GenericArgs::*;
14 pub use self::UnsafeSource::*;
15 pub use symbol::{Ident, Symbol as Name};
16 pub use util::parser::ExprPrecedence;
17
18 use ext::hygiene::{Mark, SyntaxContext};
19 use print::pprust;
20 use ptr::P;
21 use rustc_data_structures::indexed_vec;
22 use rustc_data_structures::indexed_vec::Idx;
23 use rustc_target::spec::abi::Abi;
24 use source_map::{dummy_spanned, respan, Spanned};
25 use symbol::{keywords, Symbol};
26 use syntax_pos::{Span, DUMMY_SP};
27 use tokenstream::{ThinTokenStream, TokenStream};
28 use ThinVec;
29
30 use rustc_data_structures::fx::FxHashSet;
31 use rustc_data_structures::sync::Lrc;
32 use serialize::{self, Decoder, Encoder};
33 use std::fmt;
34 use std::u32;
35
36 pub use rustc_target::abi::FloatTy;
37
38 #[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
39 pub struct Label {
40     pub ident: Ident,
41 }
42
43 impl fmt::Debug for Label {
44     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45         write!(f, "label({:?})", self.ident)
46     }
47 }
48
49 #[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
50 pub struct Lifetime {
51     pub id: NodeId,
52     pub ident: Ident,
53 }
54
55 impl fmt::Debug for Lifetime {
56     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57         write!(
58             f,
59             "lifetime({}: {})",
60             self.id,
61             pprust::lifetime_to_string(self)
62         )
63     }
64 }
65
66 /// A "Path" is essentially Rust's notion of a name.
67 ///
68 /// It's represented as a sequence of identifiers,
69 /// along with a bunch of supporting information.
70 ///
71 /// E.g. `std::cmp::PartialEq`
72 #[derive(Clone, RustcEncodable, RustcDecodable)]
73 pub struct Path {
74     pub span: Span,
75     /// The segments in the path: the things separated by `::`.
76     /// Global paths begin with `keywords::CrateRoot`.
77     pub segments: Vec<PathSegment>,
78 }
79
80 impl<'a> PartialEq<&'a str> for Path {
81     fn eq(&self, string: &&'a str) -> bool {
82         self.segments.len() == 1 && self.segments[0].ident.name == *string
83     }
84 }
85
86 impl fmt::Debug for Path {
87     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88         write!(f, "path({})", pprust::path_to_string(self))
89     }
90 }
91
92 impl fmt::Display for Path {
93     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94         write!(f, "{}", pprust::path_to_string(self))
95     }
96 }
97
98 impl Path {
99     // convert a span and an identifier to the corresponding
100     // 1-segment path
101     pub fn from_ident(ident: Ident) -> Path {
102         Path {
103             segments: vec![PathSegment::from_ident(ident)],
104             span: ident.span,
105         }
106     }
107
108     // Make a "crate root" segment for this path unless it already has it
109     // or starts with something like `self`/`super`/`$crate`/etc.
110     pub fn make_root(&self) -> Option<PathSegment> {
111         if let Some(ident) = self.segments.get(0).map(|seg| seg.ident) {
112             if ident.is_path_segment_keyword() {
113                 return None;
114             }
115         }
116         Some(PathSegment::crate_root(self.span.shrink_to_lo()))
117     }
118
119     pub fn is_global(&self) -> bool {
120         !self.segments.is_empty() && self.segments[0].ident.name == keywords::CrateRoot.name()
121     }
122 }
123
124 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
125 ///
126 /// E.g. `std`, `String` or `Box<T>`
127 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
128 pub struct PathSegment {
129     /// The identifier portion of this path segment.
130     pub ident: Ident,
131
132     pub id: NodeId,
133
134     /// Type/lifetime parameters attached to this path. They come in
135     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
136     /// `None` means that no parameter list is supplied (`Path`),
137     /// `Some` means that parameter list is supplied (`Path<X, Y>`)
138     /// but it can be empty (`Path<>`).
139     /// `P` is used as a size optimization for the common case with no parameters.
140     pub args: Option<P<GenericArgs>>,
141 }
142
143 impl PathSegment {
144     pub fn from_ident(ident: Ident) -> Self {
145         PathSegment { ident, id: DUMMY_NODE_ID, args: None }
146     }
147     pub fn crate_root(span: Span) -> Self {
148         PathSegment::from_ident(Ident::new(keywords::CrateRoot.name(), span))
149     }
150 }
151
152 /// Arguments of a path segment.
153 ///
154 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
155 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
156 pub enum GenericArgs {
157     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
158     AngleBracketed(AngleBracketedArgs),
159     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
160     Parenthesized(ParenthesisedArgs),
161 }
162
163 impl GenericArgs {
164     pub fn span(&self) -> Span {
165         match *self {
166             AngleBracketed(ref data) => data.span,
167             Parenthesized(ref data) => data.span,
168         }
169     }
170 }
171
172 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
173 pub enum GenericArg {
174     Lifetime(Lifetime),
175     Type(P<Ty>),
176 }
177
178 /// A path like `Foo<'a, T>`
179 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
180 pub struct AngleBracketedArgs {
181     /// Overall span
182     pub span: Span,
183     /// The arguments for this path segment.
184     pub args: Vec<GenericArg>,
185     /// Bindings (equality constraints) on associated types, if present.
186     ///
187     /// E.g., `Foo<A=Bar>`.
188     pub bindings: Vec<TypeBinding>,
189 }
190
191 impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
192     fn into(self) -> Option<P<GenericArgs>> {
193         Some(P(GenericArgs::AngleBracketed(self)))
194     }
195 }
196
197 impl Into<Option<P<GenericArgs>>> for ParenthesisedArgs {
198     fn into(self) -> Option<P<GenericArgs>> {
199         Some(P(GenericArgs::Parenthesized(self)))
200     }
201 }
202
203 /// A path like `Foo(A,B) -> C`
204 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
205 pub struct ParenthesisedArgs {
206     /// Overall span
207     pub span: Span,
208
209     /// `(A,B)`
210     pub inputs: Vec<P<Ty>>,
211
212     /// `C`
213     pub output: Option<P<Ty>>,
214 }
215
216 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
217 pub struct NodeId(u32);
218
219 impl NodeId {
220     pub fn new(x: usize) -> NodeId {
221         assert!(x < (u32::MAX as usize));
222         NodeId(x as u32)
223     }
224
225     pub fn from_u32(x: u32) -> NodeId {
226         NodeId(x)
227     }
228
229     pub fn as_usize(&self) -> usize {
230         self.0 as usize
231     }
232
233     pub fn as_u32(&self) -> u32 {
234         self.0
235     }
236
237     pub fn placeholder_from_mark(mark: Mark) -> Self {
238         NodeId(mark.as_u32())
239     }
240
241     pub fn placeholder_to_mark(self) -> Mark {
242         Mark::from_u32(self.0)
243     }
244 }
245
246 impl fmt::Display for NodeId {
247     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248         fmt::Display::fmt(&self.0, f)
249     }
250 }
251
252 impl serialize::UseSpecializedEncodable for NodeId {
253     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
254         s.emit_u32(self.0)
255     }
256 }
257
258 impl serialize::UseSpecializedDecodable for NodeId {
259     fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
260         d.read_u32().map(NodeId)
261     }
262 }
263
264 impl indexed_vec::Idx for NodeId {
265     fn new(idx: usize) -> Self {
266         NodeId::new(idx)
267     }
268
269     fn index(self) -> usize {
270         self.as_usize()
271     }
272 }
273
274 /// Node id used to represent the root of the crate.
275 pub const CRATE_NODE_ID: NodeId = NodeId(0);
276
277 /// When parsing and doing expansions, we initially give all AST nodes this AST
278 /// node value. Then later, in the renumber pass, we renumber them to have
279 /// small, positive ids.
280 pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
281
282 /// A modifier on a bound, currently this is only used for `?Sized`, where the
283 /// modifier is `Maybe`. Negative bounds should also be handled here.
284 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
285 pub enum TraitBoundModifier {
286     None,
287     Maybe,
288 }
289
290 /// The AST represents all type param bounds as types.
291 /// `typeck::collect::compute_bounds` matches these against
292 /// the "special" built-in traits (see `middle::lang_items`) and
293 /// detects `Copy`, `Send` and `Sync`.
294 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
295 pub enum GenericBound {
296     Trait(PolyTraitRef, TraitBoundModifier),
297     Outlives(Lifetime),
298 }
299
300 impl GenericBound {
301     pub fn span(&self) -> Span {
302         match self {
303             &GenericBound::Trait(ref t, ..) => t.span,
304             &GenericBound::Outlives(ref l) => l.ident.span,
305         }
306     }
307 }
308
309 pub type GenericBounds = Vec<GenericBound>;
310
311 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
312 pub enum GenericParamKind {
313     /// A lifetime definition, e.g. `'a: 'b+'c+'d`.
314     Lifetime,
315     Type {
316         default: Option<P<Ty>>,
317     },
318 }
319
320 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
321 pub struct GenericParam {
322     pub id: NodeId,
323     pub ident: Ident,
324     pub attrs: ThinVec<Attribute>,
325     pub bounds: GenericBounds,
326
327     pub kind: GenericParamKind,
328 }
329
330 /// Represents lifetime, type and const parameters attached to a declaration of
331 /// a function, enum, trait, etc.
332 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
333 pub struct Generics {
334     pub params: Vec<GenericParam>,
335     pub where_clause: WhereClause,
336     pub span: Span,
337 }
338
339 impl Default for Generics {
340     /// Creates an instance of `Generics`.
341     fn default() -> Generics {
342         Generics {
343             params: Vec::new(),
344             where_clause: WhereClause {
345                 id: DUMMY_NODE_ID,
346                 predicates: Vec::new(),
347                 span: DUMMY_SP,
348             },
349             span: DUMMY_SP,
350         }
351     }
352 }
353
354 /// A `where` clause in a definition
355 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
356 pub struct WhereClause {
357     pub id: NodeId,
358     pub predicates: Vec<WherePredicate>,
359     pub span: Span,
360 }
361
362 /// A single predicate in a `where` clause
363 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
364 pub enum WherePredicate {
365     /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
366     BoundPredicate(WhereBoundPredicate),
367     /// A lifetime predicate, e.g. `'a: 'b+'c`
368     RegionPredicate(WhereRegionPredicate),
369     /// An equality predicate (unsupported)
370     EqPredicate(WhereEqPredicate),
371 }
372
373 impl WherePredicate {
374     pub fn span(&self) -> Span {
375         match self {
376             &WherePredicate::BoundPredicate(ref p) => p.span,
377             &WherePredicate::RegionPredicate(ref p) => p.span,
378             &WherePredicate::EqPredicate(ref p) => p.span,
379         }
380     }
381 }
382
383 /// A type bound.
384 ///
385 /// E.g. `for<'c> Foo: Send+Clone+'c`
386 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
387 pub struct WhereBoundPredicate {
388     pub span: Span,
389     /// Any generics from a `for` binding
390     pub bound_generic_params: Vec<GenericParam>,
391     /// The type being bounded
392     pub bounded_ty: P<Ty>,
393     /// Trait and lifetime bounds (`Clone+Send+'static`)
394     pub bounds: GenericBounds,
395 }
396
397 /// A lifetime predicate.
398 ///
399 /// E.g. `'a: 'b+'c`
400 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
401 pub struct WhereRegionPredicate {
402     pub span: Span,
403     pub lifetime: Lifetime,
404     pub bounds: GenericBounds,
405 }
406
407 /// An equality predicate (unsupported).
408 ///
409 /// E.g. `T=int`
410 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
411 pub struct WhereEqPredicate {
412     pub id: NodeId,
413     pub span: Span,
414     pub lhs_ty: P<Ty>,
415     pub rhs_ty: P<Ty>,
416 }
417
418 /// The set of MetaItems that define the compilation environment of the crate,
419 /// used to drive conditional compilation
420 pub type CrateConfig = FxHashSet<(Name, Option<Symbol>)>;
421
422 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
423 pub struct Crate {
424     pub module: Mod,
425     pub attrs: Vec<Attribute>,
426     pub span: Span,
427 }
428
429 /// A spanned compile-time attribute list item.
430 pub type NestedMetaItem = Spanned<NestedMetaItemKind>;
431
432 /// Possible values inside of compile-time attribute lists.
433 ///
434 /// E.g. the '..' in `#[name(..)]`.
435 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
436 pub enum NestedMetaItemKind {
437     /// A full MetaItem, for recursive meta items.
438     MetaItem(MetaItem),
439     /// A literal.
440     ///
441     /// E.g. "foo", 64, true
442     Literal(Lit),
443 }
444
445 /// A spanned compile-time attribute item.
446 ///
447 /// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
448 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
449 pub struct MetaItem {
450     pub ident: Path,
451     pub node: MetaItemKind,
452     pub span: Span,
453 }
454
455 /// A compile-time attribute item.
456 ///
457 /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
458 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
459 pub enum MetaItemKind {
460     /// Word meta item.
461     ///
462     /// E.g. `test` as in `#[test]`
463     Word,
464     /// List meta item.
465     ///
466     /// E.g. `derive(..)` as in `#[derive(..)]`
467     List(Vec<NestedMetaItem>),
468     /// Name value meta item.
469     ///
470     /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
471     NameValue(Lit),
472 }
473
474 /// A Block (`{ .. }`).
475 ///
476 /// E.g. `{ .. }` as in `fn foo() { .. }`
477 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
478 pub struct Block {
479     /// Statements in a block
480     pub stmts: Vec<Stmt>,
481     pub id: NodeId,
482     /// Distinguishes between `unsafe { ... }` and `{ ... }`
483     pub rules: BlockCheckMode,
484     pub span: Span,
485     pub recovered: bool,
486 }
487
488 #[derive(Clone, RustcEncodable, RustcDecodable)]
489 pub struct Pat {
490     pub id: NodeId,
491     pub node: PatKind,
492     pub span: Span,
493 }
494
495 impl fmt::Debug for Pat {
496     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
497         write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
498     }
499 }
500
501 impl Pat {
502     pub(super) fn to_ty(&self) -> Option<P<Ty>> {
503         let node = match &self.node {
504             PatKind::Wild => TyKind::Infer,
505             PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) => {
506                 TyKind::Path(None, Path::from_ident(*ident))
507             }
508             PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
509             PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
510             PatKind::Ref(pat, mutbl) => pat
511                 .to_ty()
512                 .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
513             PatKind::Slice(pats, None, _) if pats.len() == 1 => {
514                 pats[0].to_ty().map(TyKind::Slice)?
515             }
516             PatKind::Tuple(pats, None) => {
517                 let mut tys = Vec::with_capacity(pats.len());
518                 // FIXME(#48994) - could just be collected into an Option<Vec>
519                 for pat in pats {
520                     tys.push(pat.to_ty()?);
521                 }
522                 TyKind::Tup(tys)
523             }
524             _ => return None,
525         };
526
527         Some(P(Ty {
528             node,
529             id: self.id,
530             span: self.span,
531         }))
532     }
533
534     pub fn walk<F>(&self, it: &mut F) -> bool
535     where
536         F: FnMut(&Pat) -> bool,
537     {
538         if !it(self) {
539             return false;
540         }
541
542         match self.node {
543             PatKind::Ident(_, _, Some(ref p)) => p.walk(it),
544             PatKind::Struct(_, ref fields, _) => fields.iter().all(|field| field.node.pat.walk(it)),
545             PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
546                 s.iter().all(|p| p.walk(it))
547             }
548             PatKind::Box(ref s) | PatKind::Ref(ref s, _) | PatKind::Paren(ref s) => s.walk(it),
549             PatKind::Slice(ref before, ref slice, ref after) => {
550                 before.iter().all(|p| p.walk(it))
551                     && slice.iter().all(|p| p.walk(it))
552                     && after.iter().all(|p| p.walk(it))
553             }
554             PatKind::Wild
555             | PatKind::Lit(_)
556             | PatKind::Range(..)
557             | PatKind::Ident(..)
558             | PatKind::Path(..)
559             | PatKind::Mac(_) => true,
560         }
561     }
562 }
563
564 /// A single field in a struct pattern
565 ///
566 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
567 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
568 /// except is_shorthand is true
569 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
570 pub struct FieldPat {
571     /// The identifier for the field
572     pub ident: Ident,
573     /// The pattern the field is destructured to
574     pub pat: P<Pat>,
575     pub is_shorthand: bool,
576     pub attrs: ThinVec<Attribute>,
577 }
578
579 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
580 pub enum BindingMode {
581     ByRef(Mutability),
582     ByValue(Mutability),
583 }
584
585 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
586 pub enum RangeEnd {
587     Included(RangeSyntax),
588     Excluded,
589 }
590
591 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
592 pub enum RangeSyntax {
593     DotDotDot,
594     DotDotEq,
595 }
596
597 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
598 pub enum PatKind {
599     /// Represents a wildcard pattern (`_`)
600     Wild,
601
602     /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
603     /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
604     /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
605     /// during name resolution.
606     Ident(BindingMode, Ident, Option<P<Pat>>),
607
608     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
609     /// The `bool` is `true` in the presence of a `..`.
610     Struct(Path, Vec<Spanned<FieldPat>>, bool),
611
612     /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
613     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
614     /// 0 <= position <= subpats.len()
615     TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
616
617     /// A possibly qualified path pattern.
618     /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
619     /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
620     /// only legally refer to associated constants.
621     Path(Option<QSelf>, Path),
622
623     /// A tuple pattern `(a, b)`.
624     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
625     /// 0 <= position <= subpats.len()
626     Tuple(Vec<P<Pat>>, Option<usize>),
627     /// A `box` pattern
628     Box(P<Pat>),
629     /// A reference pattern, e.g. `&mut (a, b)`
630     Ref(P<Pat>, Mutability),
631     /// A literal
632     Lit(P<Expr>),
633     /// A range pattern, e.g. `1...2`, `1..=2` or `1..2`
634     Range(P<Expr>, P<Expr>, Spanned<RangeEnd>),
635     /// `[a, b, ..i, y, z]` is represented as:
636     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
637     Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
638     /// Parentheses in patterns used for grouping, i.e. `(PAT)`.
639     Paren(P<Pat>),
640     /// A macro pattern; pre-expansion
641     Mac(Mac),
642 }
643
644 #[derive(
645     Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy,
646 )]
647 pub enum Mutability {
648     Mutable,
649     Immutable,
650 }
651
652 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
653 pub enum BinOpKind {
654     /// The `+` operator (addition)
655     Add,
656     /// The `-` operator (subtraction)
657     Sub,
658     /// The `*` operator (multiplication)
659     Mul,
660     /// The `/` operator (division)
661     Div,
662     /// The `%` operator (modulus)
663     Rem,
664     /// The `&&` operator (logical and)
665     And,
666     /// The `||` operator (logical or)
667     Or,
668     /// The `^` operator (bitwise xor)
669     BitXor,
670     /// The `&` operator (bitwise and)
671     BitAnd,
672     /// The `|` operator (bitwise or)
673     BitOr,
674     /// The `<<` operator (shift left)
675     Shl,
676     /// The `>>` operator (shift right)
677     Shr,
678     /// The `==` operator (equality)
679     Eq,
680     /// The `<` operator (less than)
681     Lt,
682     /// The `<=` operator (less than or equal to)
683     Le,
684     /// The `!=` operator (not equal to)
685     Ne,
686     /// The `>=` operator (greater than or equal to)
687     Ge,
688     /// The `>` operator (greater than)
689     Gt,
690 }
691
692 impl BinOpKind {
693     pub fn to_string(&self) -> &'static str {
694         use self::BinOpKind::*;
695         match *self {
696             Add => "+",
697             Sub => "-",
698             Mul => "*",
699             Div => "/",
700             Rem => "%",
701             And => "&&",
702             Or => "||",
703             BitXor => "^",
704             BitAnd => "&",
705             BitOr => "|",
706             Shl => "<<",
707             Shr => ">>",
708             Eq => "==",
709             Lt => "<",
710             Le => "<=",
711             Ne => "!=",
712             Ge => ">=",
713             Gt => ">",
714         }
715     }
716     pub fn lazy(&self) -> bool {
717         match *self {
718             BinOpKind::And | BinOpKind::Or => true,
719             _ => false,
720         }
721     }
722
723     pub fn is_shift(&self) -> bool {
724         match *self {
725             BinOpKind::Shl | BinOpKind::Shr => true,
726             _ => false,
727         }
728     }
729
730     pub fn is_comparison(&self) -> bool {
731         use self::BinOpKind::*;
732         match *self {
733             Eq | Lt | Le | Ne | Gt | Ge => true,
734             And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
735         }
736     }
737
738     /// Returns `true` if the binary operator takes its arguments by value
739     pub fn is_by_value(&self) -> bool {
740         !self.is_comparison()
741     }
742 }
743
744 pub type BinOp = Spanned<BinOpKind>;
745
746 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
747 pub enum UnOp {
748     /// The `*` operator for dereferencing
749     Deref,
750     /// The `!` operator for logical inversion
751     Not,
752     /// The `-` operator for negation
753     Neg,
754 }
755
756 impl UnOp {
757     /// Returns `true` if the unary operator takes its argument by value
758     pub fn is_by_value(u: UnOp) -> bool {
759         match u {
760             UnOp::Neg | UnOp::Not => true,
761             _ => false,
762         }
763     }
764
765     pub fn to_string(op: UnOp) -> &'static str {
766         match op {
767             UnOp::Deref => "*",
768             UnOp::Not => "!",
769             UnOp::Neg => "-",
770         }
771     }
772 }
773
774 /// A statement
775 #[derive(Clone, RustcEncodable, RustcDecodable)]
776 pub struct Stmt {
777     pub id: NodeId,
778     pub node: StmtKind,
779     pub span: Span,
780 }
781
782 impl Stmt {
783     pub fn add_trailing_semicolon(mut self) -> Self {
784         self.node = match self.node {
785             StmtKind::Expr(expr) => StmtKind::Semi(expr),
786             StmtKind::Mac(mac) => {
787                 StmtKind::Mac(mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)))
788             }
789             node => node,
790         };
791         self
792     }
793
794     pub fn is_item(&self) -> bool {
795         match self.node {
796             StmtKind::Item(_) => true,
797             _ => false,
798         }
799     }
800
801     pub fn is_expr(&self) -> bool {
802         match self.node {
803             StmtKind::Expr(_) => true,
804             _ => false,
805         }
806     }
807 }
808
809 impl fmt::Debug for Stmt {
810     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
811         write!(
812             f,
813             "stmt({}: {})",
814             self.id.to_string(),
815             pprust::stmt_to_string(self)
816         )
817     }
818 }
819
820 #[derive(Clone, RustcEncodable, RustcDecodable)]
821 pub enum StmtKind {
822     /// A local (let) binding.
823     Local(P<Local>),
824
825     /// An item definition.
826     Item(P<Item>),
827
828     /// Expr without trailing semi-colon.
829     Expr(P<Expr>),
830     /// Expr with a trailing semi-colon.
831     Semi(P<Expr>),
832     /// Macro.
833     Mac(P<(Mac, MacStmtStyle, ThinVec<Attribute>)>),
834 }
835
836 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
837 pub enum MacStmtStyle {
838     /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
839     /// `foo!(...);`, `foo![...];`
840     Semicolon,
841     /// The macro statement had braces; e.g. foo! { ... }
842     Braces,
843     /// The macro statement had parentheses or brackets and no semicolon; e.g.
844     /// `foo!(...)`. All of these will end up being converted into macro
845     /// expressions.
846     NoBraces,
847 }
848
849 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
850 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
851 pub struct Local {
852     pub pat: P<Pat>,
853     pub ty: Option<P<Ty>>,
854     /// Initializer expression to set the value, if any
855     pub init: Option<P<Expr>>,
856     pub id: NodeId,
857     pub span: Span,
858     pub attrs: ThinVec<Attribute>,
859 }
860
861 /// An arm of a 'match'.
862 ///
863 /// E.g. `0..=10 => { println!("match!") }` as in
864 ///
865 /// ```
866 /// match 123 {
867 ///     0..=10 => { println!("match!") },
868 ///     _ => { println!("no match!") },
869 /// }
870 /// ```
871 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
872 pub struct Arm {
873     pub attrs: Vec<Attribute>,
874     pub pats: Vec<P<Pat>>,
875     pub guard: Option<Guard>,
876     pub body: P<Expr>,
877 }
878
879 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
880 pub enum Guard {
881     If(P<Expr>),
882 }
883
884 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
885 pub struct Field {
886     pub ident: Ident,
887     pub expr: P<Expr>,
888     pub span: Span,
889     pub is_shorthand: bool,
890     pub attrs: ThinVec<Attribute>,
891 }
892
893 pub type SpannedIdent = Spanned<Ident>;
894
895 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
896 pub enum BlockCheckMode {
897     Default,
898     Unsafe(UnsafeSource),
899 }
900
901 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
902 pub enum UnsafeSource {
903     CompilerGenerated,
904     UserProvided,
905 }
906
907 /// A constant (expression) that's not an item or associated item,
908 /// but needs its own `DefId` for type-checking, const-eval, etc.
909 /// These are usually found nested inside types (e.g. array lengths)
910 /// or expressions (e.g. repeat counts), and also used to define
911 /// explicit discriminant values for enum variants.
912 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
913 pub struct AnonConst {
914     pub id: NodeId,
915     pub value: P<Expr>,
916 }
917
918 /// An expression
919 #[derive(Clone, RustcEncodable, RustcDecodable)]
920 pub struct Expr {
921     pub id: NodeId,
922     pub node: ExprKind,
923     pub span: Span,
924     pub attrs: ThinVec<Attribute>,
925 }
926
927 impl Expr {
928     /// Whether this expression would be valid somewhere that expects a value, for example, an `if`
929     /// condition.
930     pub fn returns(&self) -> bool {
931         if let ExprKind::Block(ref block, _) = self.node {
932             match block.stmts.last().map(|last_stmt| &last_stmt.node) {
933                 // implicit return
934                 Some(&StmtKind::Expr(_)) => true,
935                 Some(&StmtKind::Semi(ref expr)) => {
936                     if let ExprKind::Ret(_) = expr.node {
937                         // last statement is explicit return
938                         true
939                     } else {
940                         false
941                     }
942                 }
943                 // This is a block that doesn't end in either an implicit or explicit return
944                 _ => false,
945             }
946         } else {
947             // This is not a block, it is a value
948             true
949         }
950     }
951
952     fn to_bound(&self) -> Option<GenericBound> {
953         match &self.node {
954             ExprKind::Path(None, path) => Some(GenericBound::Trait(
955                 PolyTraitRef::new(Vec::new(), path.clone(), self.span),
956                 TraitBoundModifier::None,
957             )),
958             _ => None,
959         }
960     }
961
962     pub(super) fn to_ty(&self) -> Option<P<Ty>> {
963         let node = match &self.node {
964             ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
965             ExprKind::Mac(mac) => TyKind::Mac(mac.clone()),
966             ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
967             ExprKind::AddrOf(mutbl, expr) => expr
968                 .to_ty()
969                 .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
970             ExprKind::Repeat(expr, expr_len) => {
971                 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
972             }
973             ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
974             ExprKind::Tup(exprs) => {
975                 let tys = exprs
976                     .iter()
977                     .map(|expr| expr.to_ty())
978                     .collect::<Option<Vec<_>>>()?;
979                 TyKind::Tup(tys)
980             }
981             ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
982                 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
983                     TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
984                 } else {
985                     return None;
986                 }
987             }
988             _ => return None,
989         };
990
991         Some(P(Ty {
992             node,
993             id: self.id,
994             span: self.span,
995         }))
996     }
997
998     pub fn precedence(&self) -> ExprPrecedence {
999         match self.node {
1000             ExprKind::Box(_) => ExprPrecedence::Box,
1001             ExprKind::ObsoleteInPlace(..) => ExprPrecedence::ObsoleteInPlace,
1002             ExprKind::Array(_) => ExprPrecedence::Array,
1003             ExprKind::Call(..) => ExprPrecedence::Call,
1004             ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
1005             ExprKind::Tup(_) => ExprPrecedence::Tup,
1006             ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
1007             ExprKind::Unary(..) => ExprPrecedence::Unary,
1008             ExprKind::Lit(_) => ExprPrecedence::Lit,
1009             ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
1010             ExprKind::If(..) => ExprPrecedence::If,
1011             ExprKind::IfLet(..) => ExprPrecedence::IfLet,
1012             ExprKind::While(..) => ExprPrecedence::While,
1013             ExprKind::WhileLet(..) => ExprPrecedence::WhileLet,
1014             ExprKind::ForLoop(..) => ExprPrecedence::ForLoop,
1015             ExprKind::Loop(..) => ExprPrecedence::Loop,
1016             ExprKind::Match(..) => ExprPrecedence::Match,
1017             ExprKind::Closure(..) => ExprPrecedence::Closure,
1018             ExprKind::Block(..) => ExprPrecedence::Block,
1019             ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
1020             ExprKind::Async(..) => ExprPrecedence::Async,
1021             ExprKind::Assign(..) => ExprPrecedence::Assign,
1022             ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
1023             ExprKind::Field(..) => ExprPrecedence::Field,
1024             ExprKind::Index(..) => ExprPrecedence::Index,
1025             ExprKind::Range(..) => ExprPrecedence::Range,
1026             ExprKind::Path(..) => ExprPrecedence::Path,
1027             ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
1028             ExprKind::Break(..) => ExprPrecedence::Break,
1029             ExprKind::Continue(..) => ExprPrecedence::Continue,
1030             ExprKind::Ret(..) => ExprPrecedence::Ret,
1031             ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
1032             ExprKind::Mac(..) => ExprPrecedence::Mac,
1033             ExprKind::Struct(..) => ExprPrecedence::Struct,
1034             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
1035             ExprKind::Paren(..) => ExprPrecedence::Paren,
1036             ExprKind::Try(..) => ExprPrecedence::Try,
1037             ExprKind::Yield(..) => ExprPrecedence::Yield,
1038         }
1039     }
1040 }
1041
1042 impl fmt::Debug for Expr {
1043     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1044         write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
1045     }
1046 }
1047
1048 /// Limit types of a range (inclusive or exclusive)
1049 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1050 pub enum RangeLimits {
1051     /// Inclusive at the beginning, exclusive at the end
1052     HalfOpen,
1053     /// Inclusive at the beginning and end
1054     Closed,
1055 }
1056
1057 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1058 pub enum ExprKind {
1059     /// A `box x` expression.
1060     Box(P<Expr>),
1061     /// First expr is the place; second expr is the value.
1062     ObsoleteInPlace(P<Expr>, P<Expr>),
1063     /// An array (`[a, b, c, d]`)
1064     Array(Vec<P<Expr>>),
1065     /// A function call
1066     ///
1067     /// The first field resolves to the function itself,
1068     /// and the second field is the list of arguments.
1069     /// This also represents calling the constructor of
1070     /// tuple-like ADTs such as tuple structs and enum variants.
1071     Call(P<Expr>, Vec<P<Expr>>),
1072     /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
1073     ///
1074     /// The `PathSegment` represents the method name and its generic arguments
1075     /// (within the angle brackets).
1076     /// The first element of the vector of `Expr`s is the expression that evaluates
1077     /// to the object on which the method is being called on (the receiver),
1078     /// and the remaining elements are the rest of the arguments.
1079     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
1080     /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
1081     MethodCall(PathSegment, Vec<P<Expr>>),
1082     /// A tuple (`(a, b, c ,d)`)
1083     Tup(Vec<P<Expr>>),
1084     /// A binary operation (For example: `a + b`, `a * b`)
1085     Binary(BinOp, P<Expr>, P<Expr>),
1086     /// A unary operation (For example: `!x`, `*x`)
1087     Unary(UnOp, P<Expr>),
1088     /// A literal (For example: `1`, `"foo"`)
1089     Lit(Lit),
1090     /// A cast (`foo as f64`)
1091     Cast(P<Expr>, P<Ty>),
1092     Type(P<Expr>, P<Ty>),
1093     /// An `if` block, with an optional else block
1094     ///
1095     /// `if expr { block } else { expr }`
1096     If(P<Expr>, P<Block>, Option<P<Expr>>),
1097     /// An `if let` expression with an optional else block
1098     ///
1099     /// `if let pat = expr { block } else { expr }`
1100     ///
1101     /// This is desugared to a `match` expression.
1102     IfLet(Vec<P<Pat>>, P<Expr>, P<Block>, Option<P<Expr>>),
1103     /// A while loop, with an optional label
1104     ///
1105     /// `'label: while expr { block }`
1106     While(P<Expr>, P<Block>, Option<Label>),
1107     /// A while-let loop, with an optional label
1108     ///
1109     /// `'label: while let pat = expr { block }`
1110     ///
1111     /// This is desugared to a combination of `loop` and `match` expressions.
1112     WhileLet(Vec<P<Pat>>, P<Expr>, P<Block>, Option<Label>),
1113     /// A for loop, with an optional label
1114     ///
1115     /// `'label: for pat in expr { block }`
1116     ///
1117     /// This is desugared to a combination of `loop` and `match` expressions.
1118     ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>),
1119     /// Conditionless loop (can be exited with break, continue, or return)
1120     ///
1121     /// `'label: loop { block }`
1122     Loop(P<Block>, Option<Label>),
1123     /// A `match` block.
1124     Match(P<Expr>, Vec<Arm>),
1125     /// A closure (for example, `move |a, b, c| a + b + c`)
1126     ///
1127     /// The final span is the span of the argument block `|...|`
1128     Closure(CaptureBy, IsAsync, Movability, P<FnDecl>, P<Expr>, Span),
1129     /// A block (`'label: { ... }`)
1130     Block(P<Block>, Option<Label>),
1131     /// An async block (`async move { ... }`)
1132     ///
1133     /// The `NodeId` is the `NodeId` for the closure that results from
1134     /// desugaring an async block, just like the NodeId field in the
1135     /// `IsAsync` enum. This is necessary in order to create a def for the
1136     /// closure which can be used as a parent of any child defs. Defs
1137     /// created during lowering cannot be made the parent of any other
1138     /// preexisting defs.
1139     Async(CaptureBy, NodeId, P<Block>),
1140     /// A try block (`try { ... }`)
1141     TryBlock(P<Block>),
1142
1143     /// An assignment (`a = foo()`)
1144     Assign(P<Expr>, P<Expr>),
1145     /// An assignment with an operator
1146     ///
1147     /// For example, `a += 1`.
1148     AssignOp(BinOp, P<Expr>, P<Expr>),
1149     /// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct field
1150     Field(P<Expr>, Ident),
1151     /// An indexing operation (`foo[2]`)
1152     Index(P<Expr>, P<Expr>),
1153     /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
1154     Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1155
1156     /// Variable reference, possibly containing `::` and/or type
1157     /// parameters, e.g. foo::bar::<baz>.
1158     ///
1159     /// Optionally "qualified",
1160     /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
1161     Path(Option<QSelf>, Path),
1162
1163     /// A referencing operation (`&a` or `&mut a`)
1164     AddrOf(Mutability, P<Expr>),
1165     /// A `break`, with an optional label to break, and an optional expression
1166     Break(Option<Label>, Option<P<Expr>>),
1167     /// A `continue`, with an optional label
1168     Continue(Option<Label>),
1169     /// A `return`, with an optional value to be returned
1170     Ret(Option<P<Expr>>),
1171
1172     /// Output of the `asm!()` macro
1173     InlineAsm(P<InlineAsm>),
1174
1175     /// A macro invocation; pre-expansion
1176     Mac(Mac),
1177
1178     /// A struct literal expression.
1179     ///
1180     /// For example, `Foo {x: 1, y: 2}`, or
1181     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1182     Struct(Path, Vec<Field>, Option<P<Expr>>),
1183
1184     /// An array literal constructed from one repeated element.
1185     ///
1186     /// For example, `[1; 5]`. The expression is the element to be
1187     /// repeated; the constant is the number of times to repeat it.
1188     Repeat(P<Expr>, AnonConst),
1189
1190     /// No-op: used solely so we can pretty-print faithfully
1191     Paren(P<Expr>),
1192
1193     /// `expr?`
1194     Try(P<Expr>),
1195
1196     /// A `yield`, with an optional value to be yielded
1197     Yield(Option<P<Expr>>),
1198 }
1199
1200 /// The explicit Self type in a "qualified path". The actual
1201 /// path, including the trait and the associated item, is stored
1202 /// separately. `position` represents the index of the associated
1203 /// item qualified with this Self type.
1204 ///
1205 /// ```ignore (only-for-syntax-highlight)
1206 /// <Vec<T> as a::b::Trait>::AssociatedItem
1207 ///  ^~~~~     ~~~~~~~~~~~~~~^
1208 ///  ty        position = 3
1209 ///
1210 /// <Vec<T>>::AssociatedItem
1211 ///  ^~~~~    ^
1212 ///  ty       position = 0
1213 /// ```
1214 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1215 pub struct QSelf {
1216     pub ty: P<Ty>,
1217
1218     /// The span of `a::b::Trait` in a path like `<Vec<T> as
1219     /// a::b::Trait>::AssociatedItem`; in the case where `position ==
1220     /// 0`, this is an empty span.
1221     pub path_span: Span,
1222     pub position: usize,
1223 }
1224
1225 /// A capture clause
1226 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1227 pub enum CaptureBy {
1228     Value,
1229     Ref,
1230 }
1231
1232 /// The movability of a generator / closure literal
1233 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1234 pub enum Movability {
1235     Static,
1236     Movable,
1237 }
1238
1239 pub type Mac = Spanned<Mac_>;
1240
1241 /// Represents a macro invocation. The Path indicates which macro
1242 /// is being invoked, and the vector of token-trees contains the source
1243 /// of the macro invocation.
1244 ///
1245 /// NB: the additional ident for a macro_rules-style macro is actually
1246 /// stored in the enclosing item. Oog.
1247 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1248 pub struct Mac_ {
1249     pub path: Path,
1250     pub delim: MacDelimiter,
1251     pub tts: ThinTokenStream,
1252 }
1253
1254 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
1255 pub enum MacDelimiter {
1256     Parenthesis,
1257     Bracket,
1258     Brace,
1259 }
1260
1261 impl Mac_ {
1262     pub fn stream(&self) -> TokenStream {
1263         self.tts.clone().into()
1264     }
1265 }
1266
1267 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1268 pub struct MacroDef {
1269     pub tokens: ThinTokenStream,
1270     pub legacy: bool,
1271 }
1272
1273 impl MacroDef {
1274     pub fn stream(&self) -> TokenStream {
1275         self.tokens.clone().into()
1276     }
1277 }
1278
1279 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
1280 pub enum StrStyle {
1281     /// A regular string, like `"foo"`
1282     Cooked,
1283     /// A raw string, like `r##"foo"##`
1284     ///
1285     /// The value is the number of `#` symbols used.
1286     Raw(u16),
1287 }
1288
1289 /// A literal
1290 pub type Lit = Spanned<LitKind>;
1291
1292 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
1293 pub enum LitIntType {
1294     Signed(IntTy),
1295     Unsigned(UintTy),
1296     Unsuffixed,
1297 }
1298
1299 /// Literal kind.
1300 ///
1301 /// E.g. `"foo"`, `42`, `12.34` or `bool`
1302 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
1303 pub enum LitKind {
1304     /// A string literal (`"foo"`)
1305     Str(Symbol, StrStyle),
1306     /// A byte string (`b"foo"`)
1307     ByteStr(Lrc<Vec<u8>>),
1308     /// A byte char (`b'f'`)
1309     Byte(u8),
1310     /// A character literal (`'a'`)
1311     Char(char),
1312     /// An integer literal (`1`)
1313     Int(u128, LitIntType),
1314     /// A float literal (`1f64` or `1E10f64`)
1315     Float(Symbol, FloatTy),
1316     /// A float literal without a suffix (`1.0 or 1.0E10`)
1317     FloatUnsuffixed(Symbol),
1318     /// A boolean literal
1319     Bool(bool),
1320 }
1321
1322 impl LitKind {
1323     /// Returns true if this literal is a string and false otherwise.
1324     pub fn is_str(&self) -> bool {
1325         match *self {
1326             LitKind::Str(..) => true,
1327             _ => false,
1328         }
1329     }
1330
1331     /// Returns true if this literal is byte literal string false otherwise.
1332     pub fn is_bytestr(&self) -> bool {
1333         match self {
1334             LitKind::ByteStr(_) => true,
1335             _ => false,
1336         }
1337     }
1338
1339     /// Returns true if this is a numeric literal.
1340     pub fn is_numeric(&self) -> bool {
1341         match *self {
1342             LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true,
1343             _ => false,
1344         }
1345     }
1346
1347     /// Returns true if this literal has no suffix. Note: this will return true
1348     /// for literals with prefixes such as raw strings and byte strings.
1349     pub fn is_unsuffixed(&self) -> bool {
1350         match *self {
1351             // unsuffixed variants
1352             LitKind::Str(..)
1353             | LitKind::ByteStr(..)
1354             | LitKind::Byte(..)
1355             | LitKind::Char(..)
1356             | LitKind::Int(_, LitIntType::Unsuffixed)
1357             | LitKind::FloatUnsuffixed(..)
1358             | LitKind::Bool(..) => true,
1359             // suffixed variants
1360             LitKind::Int(_, LitIntType::Signed(..))
1361             | LitKind::Int(_, LitIntType::Unsigned(..))
1362             | LitKind::Float(..) => false,
1363         }
1364     }
1365
1366     /// Returns true if this literal has a suffix.
1367     pub fn is_suffixed(&self) -> bool {
1368         !self.is_unsuffixed()
1369     }
1370 }
1371
1372 // NB: If you change this, you'll probably want to change the corresponding
1373 // type structure in middle/ty.rs as well.
1374 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1375 pub struct MutTy {
1376     pub ty: P<Ty>,
1377     pub mutbl: Mutability,
1378 }
1379
1380 /// Represents a method's signature in a trait declaration,
1381 /// or in an implementation.
1382 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1383 pub struct MethodSig {
1384     pub header: FnHeader,
1385     pub decl: P<FnDecl>,
1386 }
1387
1388 /// Represents an item declaration within a trait declaration,
1389 /// possibly including a default implementation. A trait item is
1390 /// either required (meaning it doesn't have an implementation, just a
1391 /// signature) or provided (meaning it has a default implementation).
1392 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1393 pub struct TraitItem {
1394     pub id: NodeId,
1395     pub ident: Ident,
1396     pub attrs: Vec<Attribute>,
1397     pub generics: Generics,
1398     pub node: TraitItemKind,
1399     pub span: Span,
1400     /// See `Item::tokens` for what this is
1401     pub tokens: Option<TokenStream>,
1402 }
1403
1404 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1405 pub enum TraitItemKind {
1406     Const(P<Ty>, Option<P<Expr>>),
1407     Method(MethodSig, Option<P<Block>>),
1408     Type(GenericBounds, Option<P<Ty>>),
1409     Macro(Mac),
1410 }
1411
1412 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1413 pub struct ImplItem {
1414     pub id: NodeId,
1415     pub ident: Ident,
1416     pub vis: Visibility,
1417     pub defaultness: Defaultness,
1418     pub attrs: Vec<Attribute>,
1419     pub generics: Generics,
1420     pub node: ImplItemKind,
1421     pub span: Span,
1422     /// See `Item::tokens` for what this is
1423     pub tokens: Option<TokenStream>,
1424 }
1425
1426 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1427 pub enum ImplItemKind {
1428     Const(P<Ty>, P<Expr>),
1429     Method(MethodSig, P<Block>),
1430     Type(P<Ty>),
1431     Existential(GenericBounds),
1432     Macro(Mac),
1433 }
1434
1435 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
1436 pub enum IntTy {
1437     Isize,
1438     I8,
1439     I16,
1440     I32,
1441     I64,
1442     I128,
1443 }
1444
1445 impl fmt::Debug for IntTy {
1446     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1447         fmt::Display::fmt(self, f)
1448     }
1449 }
1450
1451 impl fmt::Display for IntTy {
1452     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1453         write!(f, "{}", self.ty_to_string())
1454     }
1455 }
1456
1457 impl IntTy {
1458     pub fn ty_to_string(&self) -> &'static str {
1459         match *self {
1460             IntTy::Isize => "isize",
1461             IntTy::I8 => "i8",
1462             IntTy::I16 => "i16",
1463             IntTy::I32 => "i32",
1464             IntTy::I64 => "i64",
1465             IntTy::I128 => "i128",
1466         }
1467     }
1468
1469     pub fn val_to_string(&self, val: i128) -> String {
1470         // cast to a u128 so we can correctly print INT128_MIN. All integral types
1471         // are parsed as u128, so we wouldn't want to print an extra negative
1472         // sign.
1473         format!("{}{}", val as u128, self.ty_to_string())
1474     }
1475
1476     pub fn bit_width(&self) -> Option<usize> {
1477         Some(match *self {
1478             IntTy::Isize => return None,
1479             IntTy::I8 => 8,
1480             IntTy::I16 => 16,
1481             IntTy::I32 => 32,
1482             IntTy::I64 => 64,
1483             IntTy::I128 => 128,
1484         })
1485     }
1486 }
1487
1488 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
1489 pub enum UintTy {
1490     Usize,
1491     U8,
1492     U16,
1493     U32,
1494     U64,
1495     U128,
1496 }
1497
1498 impl UintTy {
1499     pub fn ty_to_string(&self) -> &'static str {
1500         match *self {
1501             UintTy::Usize => "usize",
1502             UintTy::U8 => "u8",
1503             UintTy::U16 => "u16",
1504             UintTy::U32 => "u32",
1505             UintTy::U64 => "u64",
1506             UintTy::U128 => "u128",
1507         }
1508     }
1509
1510     pub fn val_to_string(&self, val: u128) -> String {
1511         format!("{}{}", val, self.ty_to_string())
1512     }
1513
1514     pub fn bit_width(&self) -> Option<usize> {
1515         Some(match *self {
1516             UintTy::Usize => return None,
1517             UintTy::U8 => 8,
1518             UintTy::U16 => 16,
1519             UintTy::U32 => 32,
1520             UintTy::U64 => 64,
1521             UintTy::U128 => 128,
1522         })
1523     }
1524 }
1525
1526 impl fmt::Debug for UintTy {
1527     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1528         fmt::Display::fmt(self, f)
1529     }
1530 }
1531
1532 impl fmt::Display for UintTy {
1533     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1534         write!(f, "{}", self.ty_to_string())
1535     }
1536 }
1537
1538 // Bind a type to an associated type: `A=Foo`.
1539 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1540 pub struct TypeBinding {
1541     pub id: NodeId,
1542     pub ident: Ident,
1543     pub ty: P<Ty>,
1544     pub span: Span,
1545 }
1546
1547 #[derive(Clone, RustcEncodable, RustcDecodable)]
1548 pub struct Ty {
1549     pub id: NodeId,
1550     pub node: TyKind,
1551     pub span: Span,
1552 }
1553
1554 impl fmt::Debug for Ty {
1555     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1556         write!(f, "type({})", pprust::ty_to_string(self))
1557     }
1558 }
1559
1560 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1561 pub struct BareFnTy {
1562     pub unsafety: Unsafety,
1563     pub abi: Abi,
1564     pub generic_params: Vec<GenericParam>,
1565     pub decl: P<FnDecl>,
1566 }
1567
1568 /// The different kinds of types recognized by the compiler
1569 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1570 pub enum TyKind {
1571     /// A variable-length slice (`[T]`)
1572     Slice(P<Ty>),
1573     /// A fixed length array (`[T; n]`)
1574     Array(P<Ty>, AnonConst),
1575     /// A raw pointer (`*const T` or `*mut T`)
1576     Ptr(MutTy),
1577     /// A reference (`&'a T` or `&'a mut T`)
1578     Rptr(Option<Lifetime>, MutTy),
1579     /// A bare function (e.g. `fn(usize) -> bool`)
1580     BareFn(P<BareFnTy>),
1581     /// The never type (`!`)
1582     Never,
1583     /// A tuple (`(A, B, C, D,...)`)
1584     Tup(Vec<P<Ty>>),
1585     /// A path (`module::module::...::Type`), optionally
1586     /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1587     ///
1588     /// Type parameters are stored in the Path itself
1589     Path(Option<QSelf>, Path),
1590     /// A trait object type `Bound1 + Bound2 + Bound3`
1591     /// where `Bound` is a trait or a lifetime.
1592     TraitObject(GenericBounds, TraitObjectSyntax),
1593     /// An `impl Bound1 + Bound2 + Bound3` type
1594     /// where `Bound` is a trait or a lifetime.
1595     ///
1596     /// The `NodeId` exists to prevent lowering from having to
1597     /// generate `NodeId`s on the fly, which would complicate
1598     /// the generation of `existential type` items significantly
1599     ImplTrait(NodeId, GenericBounds),
1600     /// No-op; kept solely so that we can pretty-print faithfully
1601     Paren(P<Ty>),
1602     /// Unused for now
1603     Typeof(AnonConst),
1604     /// TyKind::Infer means the type should be inferred instead of it having been
1605     /// specified. This can appear anywhere in a type.
1606     Infer,
1607     /// Inferred type of a `self` or `&self` argument in a method.
1608     ImplicitSelf,
1609     // A macro in the type position.
1610     Mac(Mac),
1611     /// Placeholder for a kind that has failed to be defined.
1612     Err,
1613 }
1614
1615 impl TyKind {
1616     pub fn is_implicit_self(&self) -> bool {
1617         if let TyKind::ImplicitSelf = *self {
1618             true
1619         } else {
1620             false
1621         }
1622     }
1623
1624     pub fn is_unit(&self) -> bool {
1625         if let TyKind::Tup(ref tys) = *self {
1626             tys.is_empty()
1627         } else {
1628             false
1629         }
1630     }
1631 }
1632
1633 /// Syntax used to declare a trait object.
1634 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1635 pub enum TraitObjectSyntax {
1636     Dyn,
1637     None,
1638 }
1639
1640 /// Inline assembly dialect.
1641 ///
1642 /// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`
1643 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1644 pub enum AsmDialect {
1645     Att,
1646     Intel,
1647 }
1648
1649 /// Inline assembly.
1650 ///
1651 /// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`
1652 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1653 pub struct InlineAsmOutput {
1654     pub constraint: Symbol,
1655     pub expr: P<Expr>,
1656     pub is_rw: bool,
1657     pub is_indirect: bool,
1658 }
1659
1660 /// Inline assembly.
1661 ///
1662 /// E.g. `asm!("NOP");`
1663 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1664 pub struct InlineAsm {
1665     pub asm: Symbol,
1666     pub asm_str_style: StrStyle,
1667     pub outputs: Vec<InlineAsmOutput>,
1668     pub inputs: Vec<(Symbol, P<Expr>)>,
1669     pub clobbers: Vec<Symbol>,
1670     pub volatile: bool,
1671     pub alignstack: bool,
1672     pub dialect: AsmDialect,
1673     pub ctxt: SyntaxContext,
1674 }
1675
1676 /// An argument in a function header.
1677 ///
1678 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
1679 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1680 pub struct Arg {
1681     pub ty: P<Ty>,
1682     pub pat: P<Pat>,
1683     pub id: NodeId,
1684 }
1685
1686 /// Alternative representation for `Arg`s describing `self` parameter of methods.
1687 ///
1688 /// E.g. `&mut self` as in `fn foo(&mut self)`
1689 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1690 pub enum SelfKind {
1691     /// `self`, `mut self`
1692     Value(Mutability),
1693     /// `&'lt self`, `&'lt mut self`
1694     Region(Option<Lifetime>, Mutability),
1695     /// `self: TYPE`, `mut self: TYPE`
1696     Explicit(P<Ty>, Mutability),
1697 }
1698
1699 pub type ExplicitSelf = Spanned<SelfKind>;
1700
1701 impl Arg {
1702     pub fn to_self(&self) -> Option<ExplicitSelf> {
1703         if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
1704             if ident.name == keywords::SelfValue.name() {
1705                 return match self.ty.node {
1706                     TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
1707                     TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.node.is_implicit_self() => {
1708                         Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
1709                     }
1710                     _ => Some(respan(
1711                         self.pat.span.to(self.ty.span),
1712                         SelfKind::Explicit(self.ty.clone(), mutbl),
1713                     )),
1714                 };
1715             }
1716         }
1717         None
1718     }
1719
1720     pub fn is_self(&self) -> bool {
1721         if let PatKind::Ident(_, ident, _) = self.pat.node {
1722             ident.name == keywords::SelfValue.name()
1723         } else {
1724             false
1725         }
1726     }
1727
1728     pub fn from_self(eself: ExplicitSelf, eself_ident: Ident) -> Arg {
1729         let span = eself.span.to(eself_ident.span);
1730         let infer_ty = P(Ty {
1731             id: DUMMY_NODE_ID,
1732             node: TyKind::ImplicitSelf,
1733             span,
1734         });
1735         let arg = |mutbl, ty| Arg {
1736             pat: P(Pat {
1737                 id: DUMMY_NODE_ID,
1738                 node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
1739                 span,
1740             }),
1741             ty,
1742             id: DUMMY_NODE_ID,
1743         };
1744         match eself.node {
1745             SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
1746             SelfKind::Value(mutbl) => arg(mutbl, infer_ty),
1747             SelfKind::Region(lt, mutbl) => arg(
1748                 Mutability::Immutable,
1749                 P(Ty {
1750                     id: DUMMY_NODE_ID,
1751                     node: TyKind::Rptr(
1752                         lt,
1753                         MutTy {
1754                             ty: infer_ty,
1755                             mutbl: mutbl,
1756                         },
1757                     ),
1758                     span,
1759                 }),
1760             ),
1761         }
1762     }
1763 }
1764
1765 /// Header (not the body) of a function declaration.
1766 ///
1767 /// E.g. `fn foo(bar: baz)`
1768 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1769 pub struct FnDecl {
1770     pub inputs: Vec<Arg>,
1771     pub output: FunctionRetTy,
1772     pub variadic: bool,
1773 }
1774
1775 impl FnDecl {
1776     pub fn get_self(&self) -> Option<ExplicitSelf> {
1777         self.inputs.get(0).and_then(Arg::to_self)
1778     }
1779     pub fn has_self(&self) -> bool {
1780         self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
1781     }
1782 }
1783
1784 /// Is the trait definition an auto trait?
1785 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1786 pub enum IsAuto {
1787     Yes,
1788     No,
1789 }
1790
1791 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1792 pub enum Unsafety {
1793     Unsafe,
1794     Normal,
1795 }
1796
1797 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
1798 pub enum IsAsync {
1799     Async {
1800         closure_id: NodeId,
1801         return_impl_trait_id: NodeId,
1802     },
1803     NotAsync,
1804 }
1805
1806 impl IsAsync {
1807     pub fn is_async(self) -> bool {
1808         if let IsAsync::Async { .. } = self {
1809             true
1810         } else {
1811             false
1812         }
1813     }
1814     /// In case this is an `Async` return the `NodeId` for the generated impl Trait item
1815     pub fn opt_return_id(self) -> Option<NodeId> {
1816         match self {
1817             IsAsync::Async {
1818                 return_impl_trait_id,
1819                 ..
1820             } => Some(return_impl_trait_id),
1821             IsAsync::NotAsync => None,
1822         }
1823     }
1824 }
1825
1826 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1827 pub enum Constness {
1828     Const,
1829     NotConst,
1830 }
1831
1832 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1833 pub enum Defaultness {
1834     Default,
1835     Final,
1836 }
1837
1838 impl fmt::Display for Unsafety {
1839     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1840         fmt::Display::fmt(
1841             match *self {
1842                 Unsafety::Normal => "normal",
1843                 Unsafety::Unsafe => "unsafe",
1844             },
1845             f,
1846         )
1847     }
1848 }
1849
1850 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)]
1851 pub enum ImplPolarity {
1852     /// `impl Trait for Type`
1853     Positive,
1854     /// `impl !Trait for Type`
1855     Negative,
1856 }
1857
1858 impl fmt::Debug for ImplPolarity {
1859     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1860         match *self {
1861             ImplPolarity::Positive => "positive".fmt(f),
1862             ImplPolarity::Negative => "negative".fmt(f),
1863         }
1864     }
1865 }
1866
1867 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1868 pub enum FunctionRetTy {
1869     /// Return type is not specified.
1870     ///
1871     /// Functions default to `()` and
1872     /// closures default to inference. Span points to where return
1873     /// type would be inserted.
1874     Default(Span),
1875     /// Everything else
1876     Ty(P<Ty>),
1877 }
1878
1879 impl FunctionRetTy {
1880     pub fn span(&self) -> Span {
1881         match *self {
1882             FunctionRetTy::Default(span) => span,
1883             FunctionRetTy::Ty(ref ty) => ty.span,
1884         }
1885     }
1886 }
1887
1888 /// Module declaration.
1889 ///
1890 /// E.g. `mod foo;` or `mod foo { .. }`
1891 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1892 pub struct Mod {
1893     /// A span from the first token past `{` to the last token until `}`.
1894     /// For `mod foo;`, the inner span ranges from the first token
1895     /// to the last token in the external file.
1896     pub inner: Span,
1897     pub items: Vec<P<Item>>,
1898     /// For `mod foo;` inline is false, for `mod foo { .. }` it is true.
1899     pub inline: bool,
1900 }
1901
1902 /// Foreign module declaration.
1903 ///
1904 /// E.g. `extern { .. }` or `extern C { .. }`
1905 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1906 pub struct ForeignMod {
1907     pub abi: Abi,
1908     pub items: Vec<ForeignItem>,
1909 }
1910
1911 /// Global inline assembly
1912 ///
1913 /// aka module-level assembly or file-scoped assembly
1914 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
1915 pub struct GlobalAsm {
1916     pub asm: Symbol,
1917     pub ctxt: SyntaxContext,
1918 }
1919
1920 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1921 pub struct EnumDef {
1922     pub variants: Vec<Variant>,
1923 }
1924
1925 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1926 pub struct Variant_ {
1927     pub ident: Ident,
1928     pub attrs: Vec<Attribute>,
1929     pub data: VariantData,
1930     /// Explicit discriminant, e.g. `Foo = 1`
1931     pub disr_expr: Option<AnonConst>,
1932 }
1933
1934 pub type Variant = Spanned<Variant_>;
1935
1936 /// Part of `use` item to the right of its prefix.
1937 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1938 pub enum UseTreeKind {
1939     /// `use prefix` or `use prefix as rename`
1940     ///
1941     /// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
1942     /// namespace.
1943     Simple(Option<Ident>, NodeId, NodeId),
1944     /// `use prefix::{...}`
1945     Nested(Vec<(UseTree, NodeId)>),
1946     /// `use prefix::*`
1947     Glob,
1948 }
1949
1950 /// A tree of paths sharing common prefixes.
1951 /// Used in `use` items both at top-level and inside of braces in import groups.
1952 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1953 pub struct UseTree {
1954     pub prefix: Path,
1955     pub kind: UseTreeKind,
1956     pub span: Span,
1957 }
1958
1959 impl UseTree {
1960     pub fn ident(&self) -> Ident {
1961         match self.kind {
1962             UseTreeKind::Simple(Some(rename), ..) => rename,
1963             UseTreeKind::Simple(None, ..) => {
1964                 self.prefix
1965                     .segments
1966                     .last()
1967                     .expect("empty prefix in a simple import")
1968                     .ident
1969             }
1970             _ => panic!("`UseTree::ident` can only be used on a simple import"),
1971         }
1972     }
1973 }
1974
1975 /// Distinguishes between Attributes that decorate items and Attributes that
1976 /// are contained as statements within items. These two cases need to be
1977 /// distinguished for pretty-printing.
1978 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1979 pub enum AttrStyle {
1980     Outer,
1981     Inner,
1982 }
1983
1984 #[derive(
1985     Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy,
1986 )]
1987 pub struct AttrId(pub usize);
1988
1989 impl Idx for AttrId {
1990     fn new(idx: usize) -> Self {
1991         AttrId(idx)
1992     }
1993     fn index(self) -> usize {
1994         self.0
1995     }
1996 }
1997
1998 /// Meta-data associated with an item
1999 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
2000 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2001 pub struct Attribute {
2002     pub id: AttrId,
2003     pub style: AttrStyle,
2004     pub path: Path,
2005     pub tokens: TokenStream,
2006     pub is_sugared_doc: bool,
2007     pub span: Span,
2008 }
2009
2010 /// TraitRef's appear in impls.
2011 ///
2012 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
2013 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
2014 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
2015 /// same as the impl's node id).
2016 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2017 pub struct TraitRef {
2018     pub path: Path,
2019     pub ref_id: NodeId,
2020 }
2021
2022 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2023 pub struct PolyTraitRef {
2024     /// The `'a` in `<'a> Foo<&'a T>`
2025     pub bound_generic_params: Vec<GenericParam>,
2026
2027     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
2028     pub trait_ref: TraitRef,
2029
2030     pub span: Span,
2031 }
2032
2033 impl PolyTraitRef {
2034     pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
2035         PolyTraitRef {
2036             bound_generic_params: generic_params,
2037             trait_ref: TraitRef {
2038                 path: path,
2039                 ref_id: DUMMY_NODE_ID,
2040             },
2041             span,
2042         }
2043     }
2044 }
2045
2046 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
2047 pub enum CrateSugar {
2048     /// Source is `pub(crate)`
2049     PubCrate,
2050
2051     /// Source is (just) `crate`
2052     JustCrate,
2053 }
2054
2055 pub type Visibility = Spanned<VisibilityKind>;
2056
2057 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2058 pub enum VisibilityKind {
2059     Public,
2060     Crate(CrateSugar),
2061     Restricted { path: P<Path>, id: NodeId },
2062     Inherited,
2063 }
2064
2065 impl VisibilityKind {
2066     pub fn is_pub(&self) -> bool {
2067         if let VisibilityKind::Public = *self {
2068             true
2069         } else {
2070             false
2071         }
2072     }
2073 }
2074
2075 /// Field of a struct.
2076 ///
2077 /// E.g. `bar: usize` as in `struct Foo { bar: usize }`
2078 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2079 pub struct StructField {
2080     pub span: Span,
2081     pub ident: Option<Ident>,
2082     pub vis: Visibility,
2083     pub id: NodeId,
2084     pub ty: P<Ty>,
2085     pub attrs: Vec<Attribute>,
2086 }
2087
2088 /// Fields and Ids of enum variants and structs
2089 ///
2090 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
2091 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
2092 /// One shared Id can be successfully used for these two purposes.
2093 /// Id of the whole enum lives in `Item`.
2094 ///
2095 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
2096 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
2097 /// the variant itself" from enum variants.
2098 /// Id of the whole struct lives in `Item`.
2099 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2100 pub enum VariantData {
2101     /// Struct variant.
2102     ///
2103     /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
2104     Struct(Vec<StructField>, NodeId),
2105     /// Tuple variant.
2106     ///
2107     /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
2108     Tuple(Vec<StructField>, NodeId),
2109     /// Unit variant.
2110     ///
2111     /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
2112     Unit(NodeId),
2113 }
2114
2115 impl VariantData {
2116     pub fn fields(&self) -> &[StructField] {
2117         match *self {
2118             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
2119             _ => &[],
2120         }
2121     }
2122     pub fn id(&self) -> NodeId {
2123         match *self {
2124             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
2125         }
2126     }
2127     pub fn is_struct(&self) -> bool {
2128         if let VariantData::Struct(..) = *self {
2129             true
2130         } else {
2131             false
2132         }
2133     }
2134     pub fn is_tuple(&self) -> bool {
2135         if let VariantData::Tuple(..) = *self {
2136             true
2137         } else {
2138             false
2139         }
2140     }
2141     pub fn is_unit(&self) -> bool {
2142         if let VariantData::Unit(..) = *self {
2143             true
2144         } else {
2145             false
2146         }
2147     }
2148 }
2149
2150 /// An item
2151 ///
2152 /// The name might be a dummy name in case of anonymous items
2153 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2154 pub struct Item {
2155     pub ident: Ident,
2156     pub attrs: Vec<Attribute>,
2157     pub id: NodeId,
2158     pub node: ItemKind,
2159     pub vis: Visibility,
2160     pub span: Span,
2161
2162     /// Original tokens this item was parsed from. This isn't necessarily
2163     /// available for all items, although over time more and more items should
2164     /// have this be `Some`. Right now this is primarily used for procedural
2165     /// macros, notably custom attributes.
2166     ///
2167     /// Note that the tokens here do not include the outer attributes, but will
2168     /// include inner attributes.
2169     pub tokens: Option<TokenStream>,
2170 }
2171
2172 /// A function header
2173 ///
2174 /// All the information between the visibility & the name of the function is
2175 /// included in this struct (e.g. `async unsafe fn` or `const extern "C" fn`)
2176 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
2177 pub struct FnHeader {
2178     pub unsafety: Unsafety,
2179     pub asyncness: IsAsync,
2180     pub constness: Spanned<Constness>,
2181     pub abi: Abi,
2182 }
2183
2184 impl Default for FnHeader {
2185     fn default() -> FnHeader {
2186         FnHeader {
2187             unsafety: Unsafety::Normal,
2188             asyncness: IsAsync::NotAsync,
2189             constness: dummy_spanned(Constness::NotConst),
2190             abi: Abi::Rust,
2191         }
2192     }
2193 }
2194
2195 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2196 pub enum ItemKind {
2197     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
2198     ///
2199     /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
2200     ExternCrate(Option<Name>),
2201     /// A use declaration (`use` or `pub use`) item.
2202     ///
2203     /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
2204     Use(P<UseTree>),
2205     /// A static item (`static` or `pub static`).
2206     ///
2207     /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
2208     Static(P<Ty>, Mutability, P<Expr>),
2209     /// A constant item (`const` or `pub const`).
2210     ///
2211     /// E.g. `const FOO: i32 = 42;`
2212     Const(P<Ty>, P<Expr>),
2213     /// A function declaration (`fn` or `pub fn`).
2214     ///
2215     /// E.g. `fn foo(bar: usize) -> usize { .. }`
2216     Fn(P<FnDecl>, FnHeader, Generics, P<Block>),
2217     /// A module declaration (`mod` or `pub mod`).
2218     ///
2219     /// E.g. `mod foo;` or `mod foo { .. }`
2220     Mod(Mod),
2221     /// An external module (`extern` or `pub extern`).
2222     ///
2223     /// E.g. `extern {}` or `extern "C" {}`
2224     ForeignMod(ForeignMod),
2225     /// Module-level inline assembly (from `global_asm!()`)
2226     GlobalAsm(P<GlobalAsm>),
2227     /// A type alias (`type` or `pub type`).
2228     ///
2229     /// E.g. `type Foo = Bar<u8>;`
2230     Ty(P<Ty>, Generics),
2231     /// An existential type declaration (`existential type`).
2232     ///
2233     /// E.g. `existential type Foo: Bar + Boo;`
2234     Existential(GenericBounds, Generics),
2235     /// An enum definition (`enum` or `pub enum`).
2236     ///
2237     /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
2238     Enum(EnumDef, Generics),
2239     /// A struct definition (`struct` or `pub struct`).
2240     ///
2241     /// E.g. `struct Foo<A> { x: A }`
2242     Struct(VariantData, Generics),
2243     /// A union definition (`union` or `pub union`).
2244     ///
2245     /// E.g. `union Foo<A, B> { x: A, y: B }`
2246     Union(VariantData, Generics),
2247     /// A Trait declaration (`trait` or `pub trait`).
2248     ///
2249     /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
2250     Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec<TraitItem>),
2251     /// Trait alias
2252     ///
2253     /// E.g. `trait Foo = Bar + Quux;`
2254     TraitAlias(Generics, GenericBounds),
2255     /// An implementation.
2256     ///
2257     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
2258     Impl(
2259         Unsafety,
2260         ImplPolarity,
2261         Defaultness,
2262         Generics,
2263         Option<TraitRef>, // (optional) trait this impl implements
2264         P<Ty>,            // self
2265         Vec<ImplItem>,
2266     ),
2267     /// A macro invocation.
2268     ///
2269     /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
2270     Mac(Mac),
2271
2272     /// A macro definition.
2273     MacroDef(MacroDef),
2274 }
2275
2276 impl ItemKind {
2277     pub fn descriptive_variant(&self) -> &str {
2278         match *self {
2279             ItemKind::ExternCrate(..) => "extern crate",
2280             ItemKind::Use(..) => "use",
2281             ItemKind::Static(..) => "static item",
2282             ItemKind::Const(..) => "constant item",
2283             ItemKind::Fn(..) => "function",
2284             ItemKind::Mod(..) => "module",
2285             ItemKind::ForeignMod(..) => "foreign module",
2286             ItemKind::GlobalAsm(..) => "global asm",
2287             ItemKind::Ty(..) => "type alias",
2288             ItemKind::Existential(..) => "existential type",
2289             ItemKind::Enum(..) => "enum",
2290             ItemKind::Struct(..) => "struct",
2291             ItemKind::Union(..) => "union",
2292             ItemKind::Trait(..) => "trait",
2293             ItemKind::TraitAlias(..) => "trait alias",
2294             ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item",
2295         }
2296     }
2297 }
2298
2299 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2300 pub struct ForeignItem {
2301     pub ident: Ident,
2302     pub attrs: Vec<Attribute>,
2303     pub node: ForeignItemKind,
2304     pub id: NodeId,
2305     pub span: Span,
2306     pub vis: Visibility,
2307 }
2308
2309 /// An item within an `extern` block
2310 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2311 pub enum ForeignItemKind {
2312     /// A foreign function
2313     Fn(P<FnDecl>, Generics),
2314     /// A foreign static item (`static ext: u8`), with optional mutability
2315     /// (the boolean is true when mutable)
2316     Static(P<Ty>, bool),
2317     /// A foreign type
2318     Ty,
2319     /// A macro invocation
2320     Macro(Mac),
2321 }
2322
2323 impl ForeignItemKind {
2324     pub fn descriptive_variant(&self) -> &str {
2325         match *self {
2326             ForeignItemKind::Fn(..) => "foreign function",
2327             ForeignItemKind::Static(..) => "foreign static item",
2328             ForeignItemKind::Ty => "foreign type",
2329             ForeignItemKind::Macro(..) => "macro in foreign module",
2330         }
2331     }
2332 }
2333
2334 #[cfg(test)]
2335 mod tests {
2336     use super::*;
2337     use serialize;
2338
2339     // are ASTs encodable?
2340     #[test]
2341     fn check_asts_encodable() {
2342         fn assert_encodable<T: serialize::Encodable>() {}
2343         assert_encodable::<Crate>();
2344     }
2345 }