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