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