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