]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | // The Rust HIR. | |
12 | ||
e9174d1e SL |
13 | pub use self::BindingMode::*; |
14 | pub use self::BinOp_::*; | |
15 | pub use self::BlockCheckMode::*; | |
16 | pub use self::CaptureClause::*; | |
17 | pub use self::Decl_::*; | |
18 | pub use self::ExplicitSelf_::*; | |
19 | pub use self::Expr_::*; | |
e9174d1e SL |
20 | pub use self::FunctionRetTy::*; |
21 | pub use self::ForeignItem_::*; | |
e9174d1e | 22 | pub use self::Item_::*; |
e9174d1e | 23 | pub use self::Mutability::*; |
e9174d1e | 24 | pub use self::PathListItem_::*; |
e9174d1e | 25 | pub use self::PrimTy::*; |
e9174d1e | 26 | pub use self::Stmt_::*; |
e9174d1e SL |
27 | pub use self::StructFieldKind::*; |
28 | pub use self::TraitItem_::*; | |
29 | pub use self::Ty_::*; | |
30 | pub use self::TyParamBound::*; | |
e9174d1e SL |
31 | pub use self::UnOp::*; |
32 | pub use self::UnsafeSource::*; | |
e9174d1e SL |
33 | pub use self::ViewPath_::*; |
34 | pub use self::Visibility::*; | |
35 | pub use self::PathParameters::*; | |
36 | ||
92a42be0 SL |
37 | use intravisit::Visitor; |
38 | use std::collections::BTreeMap; | |
e9174d1e SL |
39 | use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; |
40 | use syntax::abi::Abi; | |
92a42be0 | 41 | use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; |
9cc50fc6 | 42 | use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; |
92a42be0 | 43 | use syntax::attr::ThinAttributes; |
e9174d1e SL |
44 | use syntax::parse::token::InternedString; |
45 | use syntax::ptr::P; | |
46 | ||
47 | use print::pprust; | |
48 | use util; | |
49 | ||
50 | use std::fmt; | |
92a42be0 SL |
51 | use std::hash::{Hash, Hasher}; |
52 | use serialize::{Encodable, Decodable, Encoder, Decoder}; | |
53 | ||
9cc50fc6 SL |
54 | /// HIR doesn't commit to a concrete storage type and have its own alias for a vector. |
55 | /// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar | |
56 | /// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead | |
57 | /// of `Vec` to avoid keeping extra capacity. | |
58 | pub type HirVec<T> = P<[T]>; | |
59 | ||
60 | macro_rules! hir_vec { | |
61 | ($elem:expr; $n:expr) => ( | |
62 | $crate::hir::HirVec::from(vec![$elem; $n]) | |
63 | ); | |
64 | ($($x:expr),*) => ( | |
65 | $crate::hir::HirVec::from(vec![$($x),*]) | |
66 | ); | |
67 | ($($x:expr,)*) => (vec![$($x),*]) | |
68 | } | |
69 | ||
92a42be0 SL |
70 | /// Identifier in HIR |
71 | #[derive(Clone, Copy, Eq)] | |
72 | pub struct Ident { | |
73 | /// Hygienic name (renamed), should be used by default | |
74 | pub name: Name, | |
75 | /// Unhygienic name (original, not renamed), needed in few places in name resolution | |
76 | pub unhygienic_name: Name, | |
77 | } | |
78 | ||
79 | impl Ident { | |
80 | /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with | |
81 | /// the argument. Hygiene properties of the created identifier depend entirely on this | |
82 | /// argument. If the argument is a plain interned string `intern("iter")`, then the result | |
83 | /// is unhygienic and can interfere with other entities named "iter". If the argument is | |
84 | /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't | |
85 | /// interfere with other entities having the same string as a name. | |
86 | pub fn from_name(name: Name) -> Ident { | |
87 | Ident { name: name, unhygienic_name: name } | |
88 | } | |
89 | } | |
90 | ||
91 | impl PartialEq for Ident { | |
92 | fn eq(&self, other: &Ident) -> bool { | |
93 | self.name == other.name | |
94 | } | |
95 | } | |
96 | ||
97 | impl Hash for Ident { | |
98 | fn hash<H: Hasher>(&self, state: &mut H) { | |
99 | self.name.hash(state) | |
100 | } | |
101 | } | |
102 | ||
103 | impl fmt::Debug for Ident { | |
104 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
105 | fmt::Debug::fmt(&self.name, f) | |
106 | } | |
107 | } | |
108 | ||
109 | impl fmt::Display for Ident { | |
110 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
111 | fmt::Display::fmt(&self.name, f) | |
112 | } | |
113 | } | |
114 | ||
115 | impl Encodable for Ident { | |
116 | fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
117 | self.name.encode(s) | |
118 | } | |
119 | } | |
120 | ||
121 | impl Decodable for Ident { | |
122 | fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> { | |
123 | Ok(Ident::from_name(try!(Name::decode(d)))) | |
124 | } | |
125 | } | |
e9174d1e | 126 | |
e9174d1e SL |
127 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] |
128 | pub struct Lifetime { | |
129 | pub id: NodeId, | |
130 | pub span: Span, | |
b039eaaf | 131 | pub name: Name, |
e9174d1e SL |
132 | } |
133 | ||
134 | impl fmt::Debug for Lifetime { | |
135 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
b039eaaf SL |
136 | write!(f, |
137 | "lifetime({}: {})", | |
138 | self.id, | |
139 | pprust::lifetime_to_string(self)) | |
e9174d1e SL |
140 | } |
141 | } | |
142 | ||
143 | /// A lifetime definition, eg `'a: 'b+'c+'d` | |
144 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
145 | pub struct LifetimeDef { | |
146 | pub lifetime: Lifetime, | |
9cc50fc6 | 147 | pub bounds: HirVec<Lifetime>, |
e9174d1e SL |
148 | } |
149 | ||
150 | /// A "Path" is essentially Rust's notion of a name; for instance: | |
151 | /// std::cmp::PartialEq . It's represented as a sequence of identifiers, | |
152 | /// along with a bunch of supporting information. | |
153 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
154 | pub struct Path { | |
155 | pub span: Span, | |
156 | /// A `::foo` path, is relative to the crate root rather than current | |
157 | /// module (like paths in an import). | |
158 | pub global: bool, | |
159 | /// The segments in the path: the things separated by `::`. | |
9cc50fc6 | 160 | pub segments: HirVec<PathSegment>, |
e9174d1e SL |
161 | } |
162 | ||
163 | impl fmt::Debug for Path { | |
164 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
165 | write!(f, "path({})", pprust::path_to_string(self)) | |
166 | } | |
167 | } | |
168 | ||
169 | impl fmt::Display for Path { | |
170 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
171 | write!(f, "{}", pprust::path_to_string(self)) | |
172 | } | |
173 | } | |
174 | ||
175 | /// A segment of a path: an identifier, an optional lifetime, and a set of | |
176 | /// types. | |
177 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
178 | pub struct PathSegment { | |
179 | /// The identifier portion of this path segment. | |
92a42be0 SL |
180 | /// |
181 | /// Hygiene properties of this identifier are worth noting. | |
182 | /// Most path segments are not hygienic and they are not renamed during | |
183 | /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from | |
184 | /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths) | |
185 | /// can be hygienic, so they are renamed. You should not normally care about this peculiarity | |
186 | /// and just use `identifier.name` unless you modify identifier resolution code | |
187 | /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`). | |
e9174d1e SL |
188 | pub identifier: Ident, |
189 | ||
190 | /// Type/lifetime parameters attached to this path. They come in | |
191 | /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that | |
192 | /// this is more than just simple syntactic sugar; the use of | |
193 | /// parens affects the region binding rules, so we preserve the | |
194 | /// distinction. | |
195 | pub parameters: PathParameters, | |
196 | } | |
197 | ||
198 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
199 | pub enum PathParameters { | |
200 | /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` | |
201 | AngleBracketedParameters(AngleBracketedParameterData), | |
202 | /// The `(A,B)` and `C` in `Foo(A,B) -> C` | |
203 | ParenthesizedParameters(ParenthesizedParameterData), | |
204 | } | |
205 | ||
206 | impl PathParameters { | |
207 | pub fn none() -> PathParameters { | |
208 | AngleBracketedParameters(AngleBracketedParameterData { | |
9cc50fc6 SL |
209 | lifetimes: HirVec::new(), |
210 | types: HirVec::new(), | |
211 | bindings: HirVec::new(), | |
e9174d1e SL |
212 | }) |
213 | } | |
214 | ||
215 | pub fn is_empty(&self) -> bool { | |
216 | match *self { | |
217 | AngleBracketedParameters(ref data) => data.is_empty(), | |
218 | ||
219 | // Even if the user supplied no types, something like | |
220 | // `X()` is equivalent to `X<(),()>`. | |
221 | ParenthesizedParameters(..) => false, | |
222 | } | |
223 | } | |
224 | ||
225 | pub fn has_lifetimes(&self) -> bool { | |
226 | match *self { | |
227 | AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), | |
228 | ParenthesizedParameters(_) => false, | |
229 | } | |
230 | } | |
231 | ||
232 | pub fn has_types(&self) -> bool { | |
233 | match *self { | |
234 | AngleBracketedParameters(ref data) => !data.types.is_empty(), | |
235 | ParenthesizedParameters(..) => true, | |
236 | } | |
237 | } | |
238 | ||
239 | /// Returns the types that the user wrote. Note that these do not necessarily map to the type | |
240 | /// parameters in the parenthesized case. | |
9cc50fc6 | 241 | pub fn types(&self) -> HirVec<&P<Ty>> { |
e9174d1e SL |
242 | match *self { |
243 | AngleBracketedParameters(ref data) => { | |
244 | data.types.iter().collect() | |
245 | } | |
246 | ParenthesizedParameters(ref data) => { | |
b039eaaf SL |
247 | data.inputs |
248 | .iter() | |
e9174d1e SL |
249 | .chain(data.output.iter()) |
250 | .collect() | |
251 | } | |
252 | } | |
253 | } | |
254 | ||
9cc50fc6 | 255 | pub fn lifetimes(&self) -> HirVec<&Lifetime> { |
e9174d1e SL |
256 | match *self { |
257 | AngleBracketedParameters(ref data) => { | |
258 | data.lifetimes.iter().collect() | |
259 | } | |
260 | ParenthesizedParameters(_) => { | |
9cc50fc6 | 261 | HirVec::new() |
e9174d1e SL |
262 | } |
263 | } | |
264 | } | |
265 | ||
9cc50fc6 | 266 | pub fn bindings(&self) -> HirVec<&TypeBinding> { |
e9174d1e SL |
267 | match *self { |
268 | AngleBracketedParameters(ref data) => { | |
269 | data.bindings.iter().collect() | |
270 | } | |
271 | ParenthesizedParameters(_) => { | |
9cc50fc6 | 272 | HirVec::new() |
e9174d1e SL |
273 | } |
274 | } | |
275 | } | |
276 | } | |
277 | ||
278 | /// A path like `Foo<'a, T>` | |
279 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
280 | pub struct AngleBracketedParameterData { | |
281 | /// The lifetime parameters for this path segment. | |
9cc50fc6 | 282 | pub lifetimes: HirVec<Lifetime>, |
e9174d1e | 283 | /// The type parameters for this path segment, if present. |
9cc50fc6 | 284 | pub types: HirVec<P<Ty>>, |
e9174d1e SL |
285 | /// Bindings (equality constraints) on associated types, if present. |
286 | /// E.g., `Foo<A=Bar>`. | |
9cc50fc6 | 287 | pub bindings: HirVec<TypeBinding>, |
e9174d1e SL |
288 | } |
289 | ||
290 | impl AngleBracketedParameterData { | |
291 | fn is_empty(&self) -> bool { | |
292 | self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty() | |
293 | } | |
294 | } | |
295 | ||
296 | /// A path like `Foo(A,B) -> C` | |
297 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
298 | pub struct ParenthesizedParameterData { | |
299 | /// Overall span | |
300 | pub span: Span, | |
301 | ||
302 | /// `(A,B)` | |
9cc50fc6 | 303 | pub inputs: HirVec<P<Ty>>, |
e9174d1e SL |
304 | |
305 | /// `C` | |
306 | pub output: Option<P<Ty>>, | |
307 | } | |
308 | ||
309 | /// The AST represents all type param bounds as types. | |
310 | /// typeck::collect::compute_bounds matches these against | |
311 | /// the "special" built-in traits (see middle::lang_items) and | |
312 | /// detects Copy, Send and Sync. | |
313 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
314 | pub enum TyParamBound { | |
315 | TraitTyParamBound(PolyTraitRef, TraitBoundModifier), | |
b039eaaf | 316 | RegionTyParamBound(Lifetime), |
e9174d1e SL |
317 | } |
318 | ||
319 | /// A modifier on a bound, currently this is only used for `?Sized`, where the | |
320 | /// modifier is `Maybe`. Negative bounds should also be handled here. | |
321 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
322 | pub enum TraitBoundModifier { | |
323 | None, | |
324 | Maybe, | |
325 | } | |
326 | ||
9cc50fc6 | 327 | pub type TyParamBounds = HirVec<TyParamBound>; |
e9174d1e SL |
328 | |
329 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
330 | pub struct TyParam { | |
b039eaaf | 331 | pub name: Name, |
e9174d1e SL |
332 | pub id: NodeId, |
333 | pub bounds: TyParamBounds, | |
334 | pub default: Option<P<Ty>>, | |
b039eaaf | 335 | pub span: Span, |
e9174d1e SL |
336 | } |
337 | ||
338 | /// Represents lifetimes and type parameters attached to a declaration | |
339 | /// of a function, enum, trait, etc. | |
340 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
341 | pub struct Generics { | |
9cc50fc6 SL |
342 | pub lifetimes: HirVec<LifetimeDef>, |
343 | pub ty_params: HirVec<TyParam>, | |
e9174d1e SL |
344 | pub where_clause: WhereClause, |
345 | } | |
346 | ||
347 | impl Generics { | |
348 | pub fn is_lt_parameterized(&self) -> bool { | |
349 | !self.lifetimes.is_empty() | |
350 | } | |
351 | pub fn is_type_parameterized(&self) -> bool { | |
352 | !self.ty_params.is_empty() | |
353 | } | |
354 | pub fn is_parameterized(&self) -> bool { | |
355 | self.is_lt_parameterized() || self.is_type_parameterized() | |
356 | } | |
357 | } | |
358 | ||
359 | /// A `where` clause in a definition | |
360 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
361 | pub struct WhereClause { | |
362 | pub id: NodeId, | |
9cc50fc6 | 363 | pub predicates: HirVec<WherePredicate>, |
e9174d1e SL |
364 | } |
365 | ||
366 | /// A single predicate in a `where` clause | |
367 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
368 | pub enum WherePredicate { | |
369 | /// A type binding, eg `for<'c> Foo: Send+Clone+'c` | |
370 | BoundPredicate(WhereBoundPredicate), | |
371 | /// A lifetime predicate, e.g. `'a: 'b+'c` | |
372 | RegionPredicate(WhereRegionPredicate), | |
373 | /// An equality predicate (unsupported) | |
b039eaaf | 374 | EqPredicate(WhereEqPredicate), |
e9174d1e SL |
375 | } |
376 | ||
377 | /// A type bound, eg `for<'c> Foo: Send+Clone+'c` | |
378 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
379 | pub struct WhereBoundPredicate { | |
380 | pub span: Span, | |
381 | /// Any lifetimes from a `for` binding | |
9cc50fc6 | 382 | pub bound_lifetimes: HirVec<LifetimeDef>, |
e9174d1e SL |
383 | /// The type being bounded |
384 | pub bounded_ty: P<Ty>, | |
385 | /// Trait and lifetime bounds (`Clone+Send+'static`) | |
9cc50fc6 | 386 | pub bounds: TyParamBounds, |
e9174d1e SL |
387 | } |
388 | ||
389 | /// A lifetime predicate, e.g. `'a: 'b+'c` | |
390 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
391 | pub struct WhereRegionPredicate { | |
392 | pub span: Span, | |
393 | pub lifetime: Lifetime, | |
9cc50fc6 | 394 | pub bounds: HirVec<Lifetime>, |
e9174d1e SL |
395 | } |
396 | ||
397 | /// An equality predicate (unsupported), e.g. `T=int` | |
398 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
399 | pub struct WhereEqPredicate { | |
400 | pub id: NodeId, | |
401 | pub span: Span, | |
402 | pub path: Path, | |
403 | pub ty: P<Ty>, | |
404 | } | |
405 | ||
9cc50fc6 SL |
406 | pub type CrateConfig = HirVec<P<MetaItem>>; |
407 | ||
92a42be0 | 408 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] |
e9174d1e SL |
409 | pub struct Crate { |
410 | pub module: Mod, | |
9cc50fc6 | 411 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
412 | pub config: CrateConfig, |
413 | pub span: Span, | |
9cc50fc6 | 414 | pub exported_macros: HirVec<MacroDef>, |
92a42be0 SL |
415 | |
416 | // NB: We use a BTreeMap here so that `visit_all_items` iterates | |
417 | // over the ids in increasing order. In principle it should not | |
418 | // matter what order we visit things in, but in *practice* it | |
419 | // does, because it can affect the order in which errors are | |
420 | // detected, which in turn can make compile-fail tests yield | |
421 | // slightly different results. | |
422 | pub items: BTreeMap<NodeId, Item>, | |
423 | } | |
424 | ||
425 | impl Crate { | |
426 | pub fn item(&self, id: NodeId) -> &Item { | |
427 | &self.items[&id] | |
428 | } | |
429 | ||
430 | /// Visits all items in the crate in some determinstic (but | |
431 | /// unspecified) order. If you just need to process every item, | |
432 | /// but don't care about nesting, this method is the best choice. | |
433 | /// | |
434 | /// If you do care about nesting -- usually because your algorithm | |
435 | /// follows lexical scoping rules -- then you want a different | |
436 | /// approach. You should override `visit_nested_item` in your | |
437 | /// visitor and then call `intravisit::walk_crate` instead. | |
438 | pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) { | |
439 | for (_, item) in &self.items { | |
440 | visitor.visit_item(item); | |
441 | } | |
442 | } | |
e9174d1e SL |
443 | } |
444 | ||
445 | /// A macro definition, in this crate or imported from another. | |
446 | /// | |
447 | /// Not parsed directly, but created on macro import or `macro_rules!` expansion. | |
448 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
449 | pub struct MacroDef { | |
b039eaaf | 450 | pub name: Name, |
9cc50fc6 | 451 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
452 | pub id: NodeId, |
453 | pub span: Span, | |
b039eaaf | 454 | pub imported_from: Option<Name>, |
e9174d1e SL |
455 | pub export: bool, |
456 | pub use_locally: bool, | |
457 | pub allow_internal_unstable: bool, | |
9cc50fc6 | 458 | pub body: HirVec<TokenTree>, |
e9174d1e SL |
459 | } |
460 | ||
e9174d1e SL |
461 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
462 | pub struct Block { | |
463 | /// Statements in a block | |
9cc50fc6 | 464 | pub stmts: HirVec<Stmt>, |
e9174d1e SL |
465 | /// An expression at the end of the block |
466 | /// without a semicolon, if any | |
467 | pub expr: Option<P<Expr>>, | |
468 | pub id: NodeId, | |
469 | /// Distinguishes between `unsafe { ... }` and `{ ... }` | |
470 | pub rules: BlockCheckMode, | |
471 | pub span: Span, | |
472 | } | |
473 | ||
474 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
475 | pub struct Pat { | |
476 | pub id: NodeId, | |
7453a54e | 477 | pub node: PatKind, |
e9174d1e SL |
478 | pub span: Span, |
479 | } | |
480 | ||
481 | impl fmt::Debug for Pat { | |
482 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
483 | write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self)) | |
484 | } | |
485 | } | |
486 | ||
487 | /// A single field in a struct pattern | |
488 | /// | |
489 | /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` | |
490 | /// are treated the same as` x: x, y: ref y, z: ref mut z`, | |
491 | /// except is_shorthand is true | |
492 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
493 | pub struct FieldPat { | |
494 | /// The identifier for the field | |
b039eaaf | 495 | pub name: Name, |
e9174d1e SL |
496 | /// The pattern the field is destructured to |
497 | pub pat: P<Pat>, | |
498 | pub is_shorthand: bool, | |
499 | } | |
500 | ||
501 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
502 | pub enum BindingMode { | |
503 | BindByRef(Mutability), | |
504 | BindByValue(Mutability), | |
505 | } | |
506 | ||
e9174d1e | 507 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
7453a54e | 508 | pub enum PatKind { |
92a42be0 | 509 | /// Represents a wildcard pattern (`_`) |
7453a54e | 510 | Wild, |
e9174d1e | 511 | |
7453a54e SL |
512 | /// A `PatKind::Ident` may either be a new bound variable, |
513 | /// or a unit struct/variant pattern, or a const pattern (in the last two cases | |
514 | /// the third field must be `None`). | |
e9174d1e | 515 | /// |
7453a54e | 516 | /// In the unit or const pattern case, the parser can't determine |
e9174d1e | 517 | /// which it is. The resolver determines this, and |
7453a54e SL |
518 | /// records this pattern's `NodeId` in an auxiliary |
519 | /// set (of "PatIdents that refer to unit patterns or constants"). | |
520 | Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>), | |
e9174d1e | 521 | |
7453a54e SL |
522 | /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. |
523 | /// The `bool` is `true` in the presence of a `..`. | |
524 | Struct(Path, HirVec<Spanned<FieldPat>>, bool), | |
525 | ||
526 | /// A tuple struct/variant pattern `Variant(x, y, z)`. | |
92a42be0 | 527 | /// "None" means a `Variant(..)` pattern where we don't bind the fields to names. |
7453a54e SL |
528 | TupleStruct(Path, Option<HirVec<P<Pat>>>), |
529 | ||
530 | /// A path pattern. | |
531 | /// Such pattern can be resolved to a unit struct/variant or a constant. | |
532 | Path(Path), | |
e9174d1e SL |
533 | |
534 | /// An associated const named using the qualified path `<T>::CONST` or | |
535 | /// `<T as Trait>::CONST`. Associated consts from inherent impls can be | |
536 | /// referred to as simply `T::CONST`, in which case they will end up as | |
7453a54e SL |
537 | /// PatKind::Path, and the resolver will have to sort that out. |
538 | QPath(QSelf, Path), | |
e9174d1e | 539 | |
e9174d1e | 540 | /// A tuple pattern `(a, b)` |
7453a54e | 541 | Tup(HirVec<P<Pat>>), |
e9174d1e | 542 | /// A `box` pattern |
7453a54e | 543 | Box(P<Pat>), |
e9174d1e | 544 | /// A reference pattern, e.g. `&mut (a, b)` |
7453a54e | 545 | Ref(P<Pat>, Mutability), |
e9174d1e | 546 | /// A literal |
7453a54e | 547 | Lit(P<Expr>), |
e9174d1e | 548 | /// A range pattern, e.g. `1...2` |
7453a54e | 549 | Range(P<Expr>, P<Expr>), |
92a42be0 | 550 | /// `[a, b, ..i, y, z]` is represented as: |
7453a54e SL |
551 | /// `PatKind::Vec(box [a, b], Some(i), box [y, z])` |
552 | Vec(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>), | |
e9174d1e SL |
553 | } |
554 | ||
555 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
556 | pub enum Mutability { | |
557 | MutMutable, | |
558 | MutImmutable, | |
559 | } | |
560 | ||
561 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
562 | pub enum BinOp_ { | |
563 | /// The `+` operator (addition) | |
564 | BiAdd, | |
565 | /// The `-` operator (subtraction) | |
566 | BiSub, | |
567 | /// The `*` operator (multiplication) | |
568 | BiMul, | |
569 | /// The `/` operator (division) | |
570 | BiDiv, | |
571 | /// The `%` operator (modulus) | |
572 | BiRem, | |
573 | /// The `&&` operator (logical and) | |
574 | BiAnd, | |
575 | /// The `||` operator (logical or) | |
576 | BiOr, | |
577 | /// The `^` operator (bitwise xor) | |
578 | BiBitXor, | |
579 | /// The `&` operator (bitwise and) | |
580 | BiBitAnd, | |
581 | /// The `|` operator (bitwise or) | |
582 | BiBitOr, | |
583 | /// The `<<` operator (shift left) | |
584 | BiShl, | |
585 | /// The `>>` operator (shift right) | |
586 | BiShr, | |
587 | /// The `==` operator (equality) | |
588 | BiEq, | |
589 | /// The `<` operator (less than) | |
590 | BiLt, | |
591 | /// The `<=` operator (less than or equal to) | |
592 | BiLe, | |
593 | /// The `!=` operator (not equal to) | |
594 | BiNe, | |
595 | /// The `>=` operator (greater than or equal to) | |
596 | BiGe, | |
597 | /// The `>` operator (greater than) | |
598 | BiGt, | |
599 | } | |
600 | ||
601 | pub type BinOp = Spanned<BinOp_>; | |
602 | ||
603 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
604 | pub enum UnOp { | |
e9174d1e SL |
605 | /// The `*` operator for dereferencing |
606 | UnDeref, | |
607 | /// The `!` operator for logical inversion | |
608 | UnNot, | |
609 | /// The `-` operator for negation | |
b039eaaf | 610 | UnNeg, |
e9174d1e SL |
611 | } |
612 | ||
613 | /// A statement | |
614 | pub type Stmt = Spanned<Stmt_>; | |
615 | ||
616 | impl fmt::Debug for Stmt_ { | |
617 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
618 | // Sadness. | |
619 | let spanned = codemap::dummy_spanned(self.clone()); | |
b039eaaf SL |
620 | write!(f, |
621 | "stmt({}: {})", | |
e9174d1e SL |
622 | util::stmt_id(&spanned), |
623 | pprust::stmt_to_string(&spanned)) | |
624 | } | |
625 | } | |
626 | ||
627 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
628 | pub enum Stmt_ { | |
629 | /// Could be an item or a local (let) binding: | |
630 | StmtDecl(P<Decl>, NodeId), | |
631 | ||
632 | /// Expr without trailing semi-colon (must have unit type): | |
633 | StmtExpr(P<Expr>, NodeId), | |
634 | ||
635 | /// Expr with trailing semi-colon (may have any type): | |
636 | StmtSemi(P<Expr>, NodeId), | |
637 | } | |
638 | ||
639 | // FIXME (pending discussion of #1697, #2178...): local should really be | |
640 | // a refinement on pat. | |
641 | /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;` | |
642 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
643 | pub struct Local { | |
644 | pub pat: P<Pat>, | |
645 | pub ty: Option<P<Ty>>, | |
646 | /// Initializer expression to set the value, if any | |
647 | pub init: Option<P<Expr>>, | |
648 | pub id: NodeId, | |
649 | pub span: Span, | |
92a42be0 | 650 | pub attrs: ThinAttributes, |
e9174d1e SL |
651 | } |
652 | ||
653 | pub type Decl = Spanned<Decl_>; | |
654 | ||
655 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
656 | pub enum Decl_ { | |
657 | /// A local (let) binding: | |
658 | DeclLocal(P<Local>), | |
659 | /// An item binding: | |
92a42be0 | 660 | DeclItem(ItemId), |
e9174d1e SL |
661 | } |
662 | ||
663 | /// represents one arm of a 'match' | |
664 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
665 | pub struct Arm { | |
9cc50fc6 SL |
666 | pub attrs: HirVec<Attribute>, |
667 | pub pats: HirVec<P<Pat>>, | |
e9174d1e SL |
668 | pub guard: Option<P<Expr>>, |
669 | pub body: P<Expr>, | |
670 | } | |
671 | ||
672 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
673 | pub struct Field { | |
b039eaaf | 674 | pub name: Spanned<Name>, |
e9174d1e SL |
675 | pub expr: P<Expr>, |
676 | pub span: Span, | |
677 | } | |
678 | ||
e9174d1e SL |
679 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
680 | pub enum BlockCheckMode { | |
681 | DefaultBlock, | |
682 | UnsafeBlock(UnsafeSource), | |
683 | PushUnsafeBlock(UnsafeSource), | |
684 | PopUnsafeBlock(UnsafeSource), | |
b039eaaf SL |
685 | // Within this block (but outside a PopUnstableBlock), we suspend checking of stability. |
686 | PushUnstableBlock, | |
687 | PopUnstableBlock, | |
e9174d1e SL |
688 | } |
689 | ||
690 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
691 | pub enum UnsafeSource { | |
692 | CompilerGenerated, | |
693 | UserProvided, | |
694 | } | |
695 | ||
696 | /// An expression | |
b039eaaf | 697 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] |
e9174d1e SL |
698 | pub struct Expr { |
699 | pub id: NodeId, | |
700 | pub node: Expr_, | |
701 | pub span: Span, | |
92a42be0 | 702 | pub attrs: ThinAttributes, |
e9174d1e SL |
703 | } |
704 | ||
705 | impl fmt::Debug for Expr { | |
706 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
707 | write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self)) | |
708 | } | |
709 | } | |
710 | ||
711 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
712 | pub enum Expr_ { | |
b039eaaf SL |
713 | /// A `box x` expression. |
714 | ExprBox(P<Expr>), | |
e9174d1e | 715 | /// An array (`[a, b, c, d]`) |
9cc50fc6 | 716 | ExprVec(HirVec<P<Expr>>), |
e9174d1e SL |
717 | /// A function call |
718 | /// | |
719 | /// The first field resolves to the function itself, | |
720 | /// and the second field is the list of arguments | |
9cc50fc6 | 721 | ExprCall(P<Expr>, HirVec<P<Expr>>), |
e9174d1e SL |
722 | /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`) |
723 | /// | |
b039eaaf | 724 | /// The `Spanned<Name>` is the identifier for the method name. |
e9174d1e SL |
725 | /// The vector of `Ty`s are the ascripted type parameters for the method |
726 | /// (within the angle brackets). | |
727 | /// | |
728 | /// The first element of the vector of `Expr`s is the expression that evaluates | |
729 | /// to the object on which the method is being called on (the receiver), | |
730 | /// and the remaining elements are the rest of the arguments. | |
731 | /// | |
732 | /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as | |
733 | /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. | |
9cc50fc6 | 734 | ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<P<Expr>>), |
e9174d1e | 735 | /// A tuple (`(a, b, c ,d)`) |
9cc50fc6 | 736 | ExprTup(HirVec<P<Expr>>), |
e9174d1e SL |
737 | /// A binary operation (For example: `a + b`, `a * b`) |
738 | ExprBinary(BinOp, P<Expr>, P<Expr>), | |
739 | /// A unary operation (For example: `!x`, `*x`) | |
740 | ExprUnary(UnOp, P<Expr>), | |
741 | /// A literal (For example: `1u8`, `"foo"`) | |
742 | ExprLit(P<Lit>), | |
743 | /// A cast (`foo as f64`) | |
744 | ExprCast(P<Expr>, P<Ty>), | |
9cc50fc6 | 745 | ExprType(P<Expr>, P<Ty>), |
e9174d1e SL |
746 | /// An `if` block, with an optional else block |
747 | /// | |
748 | /// `if expr { block } else { expr }` | |
749 | ExprIf(P<Expr>, P<Block>, Option<P<Expr>>), | |
e9174d1e SL |
750 | /// A while loop, with an optional label |
751 | /// | |
752 | /// `'label: while expr { block }` | |
753 | ExprWhile(P<Expr>, P<Block>, Option<Ident>), | |
754 | /// Conditionless loop (can be exited with break, continue, or return) | |
755 | /// | |
756 | /// `'label: loop { block }` | |
e9174d1e SL |
757 | ExprLoop(P<Block>, Option<Ident>), |
758 | /// A `match` block, with a source that indicates whether or not it is | |
759 | /// the result of a desugaring, and if so, which kind. | |
9cc50fc6 | 760 | ExprMatch(P<Expr>, HirVec<Arm>, MatchSource), |
e9174d1e SL |
761 | /// A closure (for example, `move |a, b, c| {a + b + c}`) |
762 | ExprClosure(CaptureClause, P<FnDecl>, P<Block>), | |
763 | /// A block (`{ ... }`) | |
764 | ExprBlock(P<Block>), | |
765 | ||
766 | /// An assignment (`a = foo()`) | |
767 | ExprAssign(P<Expr>, P<Expr>), | |
768 | /// An assignment with an operator | |
769 | /// | |
770 | /// For example, `a += 1`. | |
771 | ExprAssignOp(BinOp, P<Expr>, P<Expr>), | |
772 | /// Access of a named struct field (`obj.foo`) | |
b039eaaf | 773 | ExprField(P<Expr>, Spanned<Name>), |
e9174d1e SL |
774 | /// Access of an unnamed field of a struct or tuple-struct |
775 | /// | |
776 | /// For example, `foo.0`. | |
777 | ExprTupField(P<Expr>, Spanned<usize>), | |
778 | /// An indexing operation (`foo[2]`) | |
779 | ExprIndex(P<Expr>, P<Expr>), | |
780 | /// A range (`1..2`, `1..`, or `..2`) | |
781 | ExprRange(Option<P<Expr>>, Option<P<Expr>>), | |
782 | ||
783 | /// Variable reference, possibly containing `::` and/or type | |
784 | /// parameters, e.g. foo::bar::<baz>. | |
785 | /// | |
786 | /// Optionally "qualified", | |
9cc50fc6 | 787 | /// e.g. `<HirVec<T> as SomeTrait>::SomeType`. |
e9174d1e SL |
788 | ExprPath(Option<QSelf>, Path), |
789 | ||
790 | /// A referencing operation (`&a` or `&mut a`) | |
791 | ExprAddrOf(Mutability, P<Expr>), | |
792 | /// A `break`, with an optional label to break | |
b039eaaf | 793 | ExprBreak(Option<Spanned<Ident>>), |
e9174d1e | 794 | /// A `continue`, with an optional label |
b039eaaf | 795 | ExprAgain(Option<Spanned<Ident>>), |
e9174d1e SL |
796 | /// A `return`, with an optional value to be returned |
797 | ExprRet(Option<P<Expr>>), | |
798 | ||
799 | /// Output of the `asm!()` macro | |
800 | ExprInlineAsm(InlineAsm), | |
801 | ||
802 | /// A struct literal expression. | |
803 | /// | |
804 | /// For example, `Foo {x: 1, y: 2}`, or | |
805 | /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`. | |
9cc50fc6 | 806 | ExprStruct(Path, HirVec<Field>, Option<P<Expr>>), |
e9174d1e SL |
807 | |
808 | /// A vector literal constructed from one repeated element. | |
809 | /// | |
810 | /// For example, `[1u8; 5]`. The first expression is the element | |
811 | /// to be repeated; the second is the number of times to repeat it. | |
812 | ExprRepeat(P<Expr>, P<Expr>), | |
e9174d1e SL |
813 | } |
814 | ||
815 | /// The explicit Self type in a "qualified path". The actual | |
816 | /// path, including the trait and the associated item, is stored | |
817 | /// separately. `position` represents the index of the associated | |
818 | /// item qualified with this Self type. | |
819 | /// | |
9cc50fc6 | 820 | /// <HirVec<T> as a::b::Trait>::AssociatedItem |
e9174d1e SL |
821 | /// ^~~~~ ~~~~~~~~~~~~~~^ |
822 | /// ty position = 3 | |
823 | /// | |
9cc50fc6 | 824 | /// <HirVec<T>>::AssociatedItem |
e9174d1e SL |
825 | /// ^~~~~ ^ |
826 | /// ty position = 0 | |
827 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
828 | pub struct QSelf { | |
829 | pub ty: P<Ty>, | |
b039eaaf | 830 | pub position: usize, |
e9174d1e SL |
831 | } |
832 | ||
833 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
834 | pub enum MatchSource { | |
835 | Normal, | |
b039eaaf SL |
836 | IfLetDesugar { |
837 | contains_else_clause: bool, | |
838 | }, | |
e9174d1e SL |
839 | WhileLetDesugar, |
840 | ForLoopDesugar, | |
841 | } | |
842 | ||
843 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
844 | pub enum CaptureClause { | |
845 | CaptureByValue, | |
846 | CaptureByRef, | |
847 | } | |
848 | ||
e9174d1e SL |
849 | // NB: If you change this, you'll probably want to change the corresponding |
850 | // type structure in middle/ty.rs as well. | |
851 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
852 | pub struct MutTy { | |
853 | pub ty: P<Ty>, | |
854 | pub mutbl: Mutability, | |
855 | } | |
856 | ||
e9174d1e SL |
857 | /// Represents a method's signature in a trait declaration, |
858 | /// or in an implementation. | |
859 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
860 | pub struct MethodSig { | |
861 | pub unsafety: Unsafety, | |
862 | pub constness: Constness, | |
863 | pub abi: Abi, | |
864 | pub decl: P<FnDecl>, | |
865 | pub generics: Generics, | |
866 | pub explicit_self: ExplicitSelf, | |
867 | } | |
868 | ||
869 | /// Represents a method declaration in a trait declaration, possibly including | |
870 | /// a default implementation A trait method is either required (meaning it | |
871 | /// doesn't have an implementation, just a signature) or provided (meaning it | |
872 | /// has a default implementation). | |
873 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
874 | pub struct TraitItem { | |
875 | pub id: NodeId, | |
b039eaaf | 876 | pub name: Name, |
9cc50fc6 | 877 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
878 | pub node: TraitItem_, |
879 | pub span: Span, | |
880 | } | |
881 | ||
882 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
883 | pub enum TraitItem_ { | |
884 | ConstTraitItem(P<Ty>, Option<P<Expr>>), | |
885 | MethodTraitItem(MethodSig, Option<P<Block>>), | |
886 | TypeTraitItem(TyParamBounds, Option<P<Ty>>), | |
887 | } | |
888 | ||
889 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
890 | pub struct ImplItem { | |
891 | pub id: NodeId, | |
b039eaaf | 892 | pub name: Name, |
e9174d1e | 893 | pub vis: Visibility, |
9cc50fc6 | 894 | pub attrs: HirVec<Attribute>, |
92a42be0 | 895 | pub node: ImplItemKind, |
e9174d1e SL |
896 | pub span: Span, |
897 | } | |
898 | ||
899 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
92a42be0 SL |
900 | pub enum ImplItemKind { |
901 | Const(P<Ty>, P<Expr>), | |
902 | Method(MethodSig, P<Block>), | |
903 | Type(P<Ty>), | |
e9174d1e SL |
904 | } |
905 | ||
e9174d1e SL |
906 | // Bind a type to an associated type: `A=Foo`. |
907 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
908 | pub struct TypeBinding { | |
909 | pub id: NodeId, | |
b039eaaf | 910 | pub name: Name, |
e9174d1e SL |
911 | pub ty: P<Ty>, |
912 | pub span: Span, | |
913 | } | |
914 | ||
915 | ||
916 | // NB PartialEq method appears below. | |
917 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
918 | pub struct Ty { | |
919 | pub id: NodeId, | |
920 | pub node: Ty_, | |
921 | pub span: Span, | |
922 | } | |
923 | ||
924 | impl fmt::Debug for Ty { | |
925 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
926 | write!(f, "type({})", pprust::ty_to_string(self)) | |
927 | } | |
928 | } | |
929 | ||
930 | /// Not represented directly in the AST, referred to by name through a ty_path. | |
931 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
932 | pub enum PrimTy { | |
933 | TyInt(IntTy), | |
934 | TyUint(UintTy), | |
935 | TyFloat(FloatTy), | |
936 | TyStr, | |
937 | TyBool, | |
b039eaaf | 938 | TyChar, |
e9174d1e SL |
939 | } |
940 | ||
941 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
942 | pub struct BareFnTy { | |
943 | pub unsafety: Unsafety, | |
944 | pub abi: Abi, | |
9cc50fc6 | 945 | pub lifetimes: HirVec<LifetimeDef>, |
b039eaaf | 946 | pub decl: P<FnDecl>, |
e9174d1e SL |
947 | } |
948 | ||
949 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
950 | /// The different kinds of types recognized by the compiler | |
951 | pub enum Ty_ { | |
952 | TyVec(P<Ty>), | |
953 | /// A fixed length array (`[T; n]`) | |
954 | TyFixedLengthVec(P<Ty>, P<Expr>), | |
955 | /// A raw pointer (`*const T` or `*mut T`) | |
956 | TyPtr(MutTy), | |
957 | /// A reference (`&'a T` or `&'a mut T`) | |
958 | TyRptr(Option<Lifetime>, MutTy), | |
959 | /// A bare function (e.g. `fn(usize) -> bool`) | |
960 | TyBareFn(P<BareFnTy>), | |
961 | /// A tuple (`(A, B, C, D,...)`) | |
9cc50fc6 | 962 | TyTup(HirVec<P<Ty>>), |
e9174d1e | 963 | /// A path (`module::module::...::Type`), optionally |
9cc50fc6 | 964 | /// "qualified", e.g. `<HirVec<T> as SomeTrait>::SomeType`. |
e9174d1e SL |
965 | /// |
966 | /// Type parameters are stored in the Path itself | |
967 | TyPath(Option<QSelf>, Path), | |
968 | /// Something like `A+B`. Note that `B` must always be a path. | |
969 | TyObjectSum(P<Ty>, TyParamBounds), | |
970 | /// A type like `for<'a> Foo<&'a Bar>` | |
971 | TyPolyTraitRef(TyParamBounds), | |
e9174d1e SL |
972 | /// Unused for now |
973 | TyTypeof(P<Expr>), | |
974 | /// TyInfer means the type should be inferred instead of it having been | |
975 | /// specified. This can appear anywhere in a type. | |
976 | TyInfer, | |
977 | } | |
978 | ||
9cc50fc6 SL |
979 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
980 | pub struct InlineAsmOutput { | |
981 | pub constraint: InternedString, | |
982 | pub expr: P<Expr>, | |
983 | pub is_rw: bool, | |
984 | pub is_indirect: bool, | |
985 | } | |
986 | ||
e9174d1e SL |
987 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
988 | pub struct InlineAsm { | |
989 | pub asm: InternedString, | |
990 | pub asm_str_style: StrStyle, | |
9cc50fc6 SL |
991 | pub outputs: HirVec<InlineAsmOutput>, |
992 | pub inputs: HirVec<(InternedString, P<Expr>)>, | |
993 | pub clobbers: HirVec<InternedString>, | |
e9174d1e SL |
994 | pub volatile: bool, |
995 | pub alignstack: bool, | |
996 | pub dialect: AsmDialect, | |
997 | pub expn_id: ExpnId, | |
998 | } | |
999 | ||
1000 | /// represents an argument in a function header | |
1001 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1002 | pub struct Arg { | |
1003 | pub ty: P<Ty>, | |
1004 | pub pat: P<Pat>, | |
1005 | pub id: NodeId, | |
1006 | } | |
1007 | ||
1008 | impl Arg { | |
1009 | pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { | |
b039eaaf SL |
1010 | let path = Spanned { |
1011 | span: span, | |
1012 | node: self_ident, | |
1013 | }; | |
e9174d1e SL |
1014 | Arg { |
1015 | // HACK(eddyb) fake type for the self argument. | |
1016 | ty: P(Ty { | |
1017 | id: DUMMY_NODE_ID, | |
1018 | node: TyInfer, | |
1019 | span: DUMMY_SP, | |
1020 | }), | |
1021 | pat: P(Pat { | |
1022 | id: DUMMY_NODE_ID, | |
7453a54e | 1023 | node: PatKind::Ident(BindByValue(mutability), path, None), |
b039eaaf | 1024 | span: span, |
e9174d1e | 1025 | }), |
b039eaaf | 1026 | id: DUMMY_NODE_ID, |
e9174d1e SL |
1027 | } |
1028 | } | |
1029 | } | |
1030 | ||
1031 | /// Represents the header (not the body) of a function declaration | |
1032 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1033 | pub struct FnDecl { | |
9cc50fc6 | 1034 | pub inputs: HirVec<Arg>, |
e9174d1e | 1035 | pub output: FunctionRetTy, |
b039eaaf | 1036 | pub variadic: bool, |
e9174d1e SL |
1037 | } |
1038 | ||
1039 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1040 | pub enum Unsafety { | |
1041 | Unsafe, | |
1042 | Normal, | |
1043 | } | |
1044 | ||
1045 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1046 | pub enum Constness { | |
1047 | Const, | |
1048 | NotConst, | |
1049 | } | |
1050 | ||
1051 | impl fmt::Display for Unsafety { | |
1052 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
1053 | fmt::Display::fmt(match *self { | |
b039eaaf SL |
1054 | Unsafety::Normal => "normal", |
1055 | Unsafety::Unsafe => "unsafe", | |
1056 | }, | |
1057 | f) | |
e9174d1e SL |
1058 | } |
1059 | } | |
1060 | ||
1061 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
1062 | pub enum ImplPolarity { | |
1063 | /// `impl Trait for Type` | |
1064 | Positive, | |
1065 | /// `impl !Trait for Type` | |
1066 | Negative, | |
1067 | } | |
1068 | ||
1069 | impl fmt::Debug for ImplPolarity { | |
1070 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
1071 | match *self { | |
1072 | ImplPolarity::Positive => "positive".fmt(f), | |
1073 | ImplPolarity::Negative => "negative".fmt(f), | |
1074 | } | |
1075 | } | |
1076 | } | |
1077 | ||
1078 | ||
1079 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1080 | pub enum FunctionRetTy { | |
1081 | /// Functions with return type `!`that always | |
1082 | /// raise an error or exit (i.e. never return to the caller) | |
1083 | NoReturn(Span), | |
1084 | /// Return type is not specified. | |
1085 | /// | |
1086 | /// Functions default to `()` and | |
1087 | /// closures default to inference. Span points to where return | |
1088 | /// type would be inserted. | |
1089 | DefaultReturn(Span), | |
1090 | /// Everything else | |
1091 | Return(P<Ty>), | |
1092 | } | |
1093 | ||
1094 | impl FunctionRetTy { | |
1095 | pub fn span(&self) -> Span { | |
1096 | match *self { | |
1097 | NoReturn(span) => span, | |
1098 | DefaultReturn(span) => span, | |
b039eaaf | 1099 | Return(ref ty) => ty.span, |
e9174d1e SL |
1100 | } |
1101 | } | |
1102 | } | |
1103 | ||
1104 | /// Represents the kind of 'self' associated with a method | |
1105 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1106 | pub enum ExplicitSelf_ { | |
1107 | /// No self | |
1108 | SelfStatic, | |
1109 | /// `self` | |
b039eaaf | 1110 | SelfValue(Name), |
e9174d1e | 1111 | /// `&'lt self`, `&'lt mut self` |
b039eaaf | 1112 | SelfRegion(Option<Lifetime>, Mutability, Name), |
e9174d1e | 1113 | /// `self: TYPE` |
b039eaaf | 1114 | SelfExplicit(P<Ty>, Name), |
e9174d1e SL |
1115 | } |
1116 | ||
1117 | pub type ExplicitSelf = Spanned<ExplicitSelf_>; | |
1118 | ||
1119 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1120 | pub struct Mod { | |
1121 | /// A span from the first token past `{` to the last token until `}`. | |
1122 | /// For `mod foo;`, the inner span ranges from the first token | |
1123 | /// to the last token in the external file. | |
1124 | pub inner: Span, | |
9cc50fc6 | 1125 | pub item_ids: HirVec<ItemId>, |
e9174d1e SL |
1126 | } |
1127 | ||
1128 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1129 | pub struct ForeignMod { | |
1130 | pub abi: Abi, | |
9cc50fc6 | 1131 | pub items: HirVec<ForeignItem>, |
e9174d1e SL |
1132 | } |
1133 | ||
e9174d1e SL |
1134 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1135 | pub struct EnumDef { | |
9cc50fc6 | 1136 | pub variants: HirVec<Variant>, |
e9174d1e SL |
1137 | } |
1138 | ||
1139 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1140 | pub struct Variant_ { | |
b039eaaf | 1141 | pub name: Name, |
9cc50fc6 | 1142 | pub attrs: HirVec<Attribute>, |
b039eaaf | 1143 | pub data: VariantData, |
e9174d1e SL |
1144 | /// Explicit discriminant, eg `Foo = 1` |
1145 | pub disr_expr: Option<P<Expr>>, | |
e9174d1e SL |
1146 | } |
1147 | ||
1148 | pub type Variant = Spanned<Variant_>; | |
1149 | ||
1150 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
1151 | pub enum PathListItem_ { | |
1152 | PathListIdent { | |
b039eaaf | 1153 | name: Name, |
e9174d1e | 1154 | /// renamed in list, eg `use foo::{bar as baz};` |
b039eaaf SL |
1155 | rename: Option<Name>, |
1156 | id: NodeId, | |
e9174d1e SL |
1157 | }, |
1158 | PathListMod { | |
1159 | /// renamed in list, eg `use foo::{self as baz};` | |
b039eaaf SL |
1160 | rename: Option<Name>, |
1161 | id: NodeId, | |
1162 | }, | |
e9174d1e SL |
1163 | } |
1164 | ||
1165 | impl PathListItem_ { | |
1166 | pub fn id(&self) -> NodeId { | |
1167 | match *self { | |
b039eaaf SL |
1168 | PathListIdent { id, .. } | PathListMod { id, .. } => id, |
1169 | } | |
1170 | } | |
1171 | ||
1172 | pub fn name(&self) -> Option<Name> { | |
1173 | match *self { | |
1174 | PathListIdent { name, .. } => Some(name), | |
1175 | PathListMod { .. } => None, | |
e9174d1e SL |
1176 | } |
1177 | } | |
1178 | ||
b039eaaf | 1179 | pub fn rename(&self) -> Option<Name> { |
e9174d1e | 1180 | match *self { |
b039eaaf | 1181 | PathListIdent { rename, .. } | PathListMod { rename, .. } => rename, |
e9174d1e SL |
1182 | } |
1183 | } | |
1184 | } | |
1185 | ||
1186 | pub type PathListItem = Spanned<PathListItem_>; | |
1187 | ||
1188 | pub type ViewPath = Spanned<ViewPath_>; | |
1189 | ||
1190 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1191 | pub enum ViewPath_ { | |
e9174d1e SL |
1192 | /// `foo::bar::baz as quux` |
1193 | /// | |
1194 | /// or just | |
1195 | /// | |
1196 | /// `foo::bar::baz` (with `as baz` implicitly on the right) | |
b039eaaf | 1197 | ViewPathSimple(Name, Path), |
e9174d1e SL |
1198 | |
1199 | /// `foo::bar::*` | |
1200 | ViewPathGlob(Path), | |
1201 | ||
1202 | /// `foo::bar::{a,b,c}` | |
9cc50fc6 | 1203 | ViewPathList(Path, HirVec<PathListItem>), |
e9174d1e SL |
1204 | } |
1205 | ||
1206 | /// TraitRef's appear in impls. | |
1207 | /// | |
1208 | /// resolve maps each TraitRef's ref_id to its defining trait; that's all | |
1209 | /// that the ref_id is for. The impl_id maps to the "self type" of this impl. | |
1210 | /// If this impl is an ItemImpl, the impl_id is redundant (it could be the | |
1211 | /// same as the impl's node id). | |
1212 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1213 | pub struct TraitRef { | |
1214 | pub path: Path, | |
1215 | pub ref_id: NodeId, | |
1216 | } | |
1217 | ||
1218 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1219 | pub struct PolyTraitRef { | |
1220 | /// The `'a` in `<'a> Foo<&'a T>` | |
9cc50fc6 | 1221 | pub bound_lifetimes: HirVec<LifetimeDef>, |
e9174d1e SL |
1222 | |
1223 | /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` | |
1224 | pub trait_ref: TraitRef, | |
1225 | ||
1226 | pub span: Span, | |
1227 | } | |
1228 | ||
1229 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
1230 | pub enum Visibility { | |
1231 | Public, | |
1232 | Inherited, | |
1233 | } | |
1234 | ||
1235 | impl Visibility { | |
1236 | pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility { | |
1237 | match self { | |
1238 | &Inherited => parent_visibility, | |
b039eaaf | 1239 | &Public => *self, |
e9174d1e SL |
1240 | } |
1241 | } | |
1242 | } | |
1243 | ||
1244 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1245 | pub struct StructField_ { | |
1246 | pub kind: StructFieldKind, | |
1247 | pub id: NodeId, | |
1248 | pub ty: P<Ty>, | |
9cc50fc6 | 1249 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
1250 | } |
1251 | ||
1252 | impl StructField_ { | |
b039eaaf | 1253 | pub fn name(&self) -> Option<Name> { |
e9174d1e | 1254 | match self.kind { |
b039eaaf SL |
1255 | NamedField(name, _) => Some(name), |
1256 | UnnamedField(_) => None, | |
e9174d1e SL |
1257 | } |
1258 | } | |
1259 | } | |
1260 | ||
1261 | pub type StructField = Spanned<StructField_>; | |
1262 | ||
1263 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
1264 | pub enum StructFieldKind { | |
b039eaaf | 1265 | NamedField(Name, Visibility), |
e9174d1e SL |
1266 | /// Element of a tuple-like struct |
1267 | UnnamedField(Visibility), | |
1268 | } | |
1269 | ||
1270 | impl StructFieldKind { | |
1271 | pub fn is_unnamed(&self) -> bool { | |
1272 | match *self { | |
1273 | UnnamedField(..) => true, | |
1274 | NamedField(..) => false, | |
1275 | } | |
1276 | } | |
92a42be0 SL |
1277 | |
1278 | pub fn visibility(&self) -> Visibility { | |
1279 | match *self { | |
1280 | NamedField(_, vis) | UnnamedField(vis) => vis, | |
1281 | } | |
1282 | } | |
e9174d1e SL |
1283 | } |
1284 | ||
b039eaaf SL |
1285 | /// Fields and Ids of enum variants and structs |
1286 | /// | |
1287 | /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all | |
1288 | /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants). | |
1289 | /// One shared Id can be successfully used for these two purposes. | |
1290 | /// Id of the whole enum lives in `Item`. | |
1291 | /// | |
1292 | /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually | |
1293 | /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of | |
1294 | /// the variant itself" from enum variants. | |
1295 | /// Id of the whole struct lives in `Item`. | |
e9174d1e | 1296 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
b039eaaf | 1297 | pub enum VariantData { |
9cc50fc6 SL |
1298 | Struct(HirVec<StructField>, NodeId), |
1299 | Tuple(HirVec<StructField>, NodeId), | |
b039eaaf SL |
1300 | Unit(NodeId), |
1301 | } | |
1302 | ||
1303 | impl VariantData { | |
1304 | pub fn fields(&self) -> &[StructField] { | |
1305 | match *self { | |
1306 | VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields, | |
1307 | _ => &[], | |
1308 | } | |
1309 | } | |
1310 | pub fn id(&self) -> NodeId { | |
1311 | match *self { | |
92a42be0 | 1312 | VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id, |
b039eaaf SL |
1313 | } |
1314 | } | |
1315 | pub fn is_struct(&self) -> bool { | |
92a42be0 SL |
1316 | if let VariantData::Struct(..) = *self { |
1317 | true | |
1318 | } else { | |
1319 | false | |
1320 | } | |
b039eaaf SL |
1321 | } |
1322 | pub fn is_tuple(&self) -> bool { | |
92a42be0 SL |
1323 | if let VariantData::Tuple(..) = *self { |
1324 | true | |
1325 | } else { | |
1326 | false | |
1327 | } | |
b039eaaf SL |
1328 | } |
1329 | pub fn is_unit(&self) -> bool { | |
92a42be0 SL |
1330 | if let VariantData::Unit(..) = *self { |
1331 | true | |
1332 | } else { | |
1333 | false | |
1334 | } | |
b039eaaf | 1335 | } |
e9174d1e SL |
1336 | } |
1337 | ||
92a42be0 SL |
1338 | // The bodies for items are stored "out of line", in a separate |
1339 | // hashmap in the `Crate`. Here we just record the node-id of the item | |
1340 | // so it can fetched later. | |
1341 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1342 | pub struct ItemId { | |
1343 | pub id: NodeId, | |
1344 | } | |
1345 | ||
1346 | // FIXME (#3300): Should allow items to be anonymous. Right now | |
1347 | // we just use dummy names for anon items. | |
e9174d1e SL |
1348 | /// An item |
1349 | /// | |
1350 | /// The name might be a dummy name in case of anonymous items | |
1351 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1352 | pub struct Item { | |
b039eaaf | 1353 | pub name: Name, |
9cc50fc6 | 1354 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
1355 | pub id: NodeId, |
1356 | pub node: Item_, | |
1357 | pub vis: Visibility, | |
1358 | pub span: Span, | |
1359 | } | |
1360 | ||
1361 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1362 | pub enum Item_ { | |
1363 | /// An`extern crate` item, with optional original crate name, | |
1364 | /// | |
1365 | /// e.g. `extern crate foo` or `extern crate foo_bar as foo` | |
1366 | ItemExternCrate(Option<Name>), | |
1367 | /// A `use` or `pub use` item | |
1368 | ItemUse(P<ViewPath>), | |
1369 | ||
1370 | /// A `static` item | |
1371 | ItemStatic(P<Ty>, Mutability, P<Expr>), | |
1372 | /// A `const` item | |
1373 | ItemConst(P<Ty>, P<Expr>), | |
1374 | /// A function declaration | |
1375 | ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>), | |
1376 | /// A module | |
1377 | ItemMod(Mod), | |
1378 | /// An external module | |
1379 | ItemForeignMod(ForeignMod), | |
1380 | /// A type alias, e.g. `type Foo = Bar<u8>` | |
1381 | ItemTy(P<Ty>, Generics), | |
1382 | /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}` | |
1383 | ItemEnum(EnumDef, Generics), | |
1384 | /// A struct definition, e.g. `struct Foo<A> {x: A}` | |
b039eaaf | 1385 | ItemStruct(VariantData, Generics), |
e9174d1e | 1386 | /// Represents a Trait Declaration |
9cc50fc6 | 1387 | ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>), |
e9174d1e SL |
1388 | |
1389 | // Default trait implementations | |
1390 | /// | |
92a42be0 | 1391 | /// `impl Trait for .. {}` |
e9174d1e SL |
1392 | ItemDefaultImpl(Unsafety, TraitRef), |
1393 | /// An implementation, eg `impl<A> Trait for Foo { .. }` | |
1394 | ItemImpl(Unsafety, | |
1395 | ImplPolarity, | |
1396 | Generics, | |
1397 | Option<TraitRef>, // (optional) trait this impl implements | |
1398 | P<Ty>, // self | |
9cc50fc6 | 1399 | HirVec<ImplItem>), |
e9174d1e SL |
1400 | } |
1401 | ||
1402 | impl Item_ { | |
1403 | pub fn descriptive_variant(&self) -> &str { | |
1404 | match *self { | |
1405 | ItemExternCrate(..) => "extern crate", | |
1406 | ItemUse(..) => "use", | |
1407 | ItemStatic(..) => "static item", | |
1408 | ItemConst(..) => "constant item", | |
1409 | ItemFn(..) => "function", | |
1410 | ItemMod(..) => "module", | |
1411 | ItemForeignMod(..) => "foreign module", | |
1412 | ItemTy(..) => "type alias", | |
1413 | ItemEnum(..) => "enum", | |
1414 | ItemStruct(..) => "struct", | |
1415 | ItemTrait(..) => "trait", | |
1416 | ItemImpl(..) | | |
b039eaaf | 1417 | ItemDefaultImpl(..) => "item", |
e9174d1e SL |
1418 | } |
1419 | } | |
1420 | } | |
1421 | ||
1422 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1423 | pub struct ForeignItem { | |
b039eaaf | 1424 | pub name: Name, |
9cc50fc6 | 1425 | pub attrs: HirVec<Attribute>, |
e9174d1e SL |
1426 | pub node: ForeignItem_, |
1427 | pub id: NodeId, | |
1428 | pub span: Span, | |
1429 | pub vis: Visibility, | |
1430 | } | |
1431 | ||
1432 | /// An item within an `extern` block | |
1433 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1434 | pub enum ForeignItem_ { | |
1435 | /// A foreign function | |
1436 | ForeignItemFn(P<FnDecl>, Generics), | |
1437 | /// A foreign static item (`static ext: u8`), with optional mutability | |
1438 | /// (the boolean is true when mutable) | |
1439 | ForeignItemStatic(P<Ty>, bool), | |
1440 | } | |
1441 | ||
1442 | impl ForeignItem_ { | |
1443 | pub fn descriptive_variant(&self) -> &str { | |
1444 | match *self { | |
1445 | ForeignItemFn(..) => "foreign function", | |
b039eaaf | 1446 | ForeignItemStatic(..) => "foreign static item", |
e9174d1e SL |
1447 | } |
1448 | } | |
1449 | } |