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