]>
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 JJ |
13 | pub use self::AsmDialect::*; |
14 | pub use self::AttrStyle::*; | |
15 | pub use self::BindingMode::*; | |
85aaf69f | 16 | pub use self::BinOp_::*; |
1a4d82fc JJ |
17 | pub use self::BlockCheckMode::*; |
18 | pub use self::CaptureClause::*; | |
19 | pub use self::Decl_::*; | |
20 | pub use self::ExplicitSelf_::*; | |
21 | pub use self::Expr_::*; | |
22 | pub use self::FloatTy::*; | |
23 | pub use self::FunctionRetTy::*; | |
24 | pub use self::ForeignItem_::*; | |
c34b1796 | 25 | pub use self::ImplItem_::*; |
1a4d82fc JJ |
26 | pub use self::InlinedItem::*; |
27 | pub use self::IntTy::*; | |
28 | pub use self::Item_::*; | |
29 | pub use self::KleeneOp::*; | |
30 | pub use self::Lit_::*; | |
31 | pub use self::LitIntType::*; | |
32 | pub use self::LocalSource::*; | |
33 | pub use self::Mac_::*; | |
34 | pub use self::MacStmtStyle::*; | |
35 | pub use self::MetaItem_::*; | |
1a4d82fc | 36 | pub use self::Mutability::*; |
1a4d82fc JJ |
37 | pub use self::Pat_::*; |
38 | pub use self::PathListItem_::*; | |
39 | pub use self::PatWildKind::*; | |
40 | pub use self::PrimTy::*; | |
41 | pub use self::Sign::*; | |
42 | pub use self::Stmt_::*; | |
43 | pub use self::StrStyle::*; | |
44 | pub use self::StructFieldKind::*; | |
45 | pub use self::TokenTree::*; | |
c34b1796 | 46 | pub use self::TraitItem_::*; |
1a4d82fc JJ |
47 | pub use self::Ty_::*; |
48 | pub use self::TyParamBound::*; | |
49 | pub use self::UintTy::*; | |
1a4d82fc JJ |
50 | pub use self::UnOp::*; |
51 | pub use self::UnsafeSource::*; | |
52 | pub use self::VariantKind::*; | |
1a4d82fc JJ |
53 | pub use self::ViewPath_::*; |
54 | pub use self::Visibility::*; | |
55 | pub use self::PathParameters::*; | |
56 | ||
57 | use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; | |
58 | use abi::Abi; | |
59 | use ast_util; | |
c34b1796 AL |
60 | use ext::base; |
61 | use ext::tt::macro_parser; | |
1a4d82fc JJ |
62 | use owned_slice::OwnedSlice; |
63 | use parse::token::{InternedString, str_to_ident}; | |
64 | use parse::token; | |
c34b1796 | 65 | use parse::lexer; |
1a4d82fc JJ |
66 | use ptr::P; |
67 | ||
68 | use std::fmt; | |
1a4d82fc JJ |
69 | use std::rc::Rc; |
70 | use serialize::{Encodable, Decodable, Encoder, Decoder}; | |
71 | ||
72 | // FIXME #6993: in librustc, uses of "ident" should be replaced | |
73 | // by just "Name". | |
74 | ||
75 | /// An identifier contains a Name (index into the interner | |
76 | /// table) and a SyntaxContext to track renaming and | |
77 | /// macro expansion per Flatt et al., "Macros | |
78 | /// That Work Together" | |
79 | #[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)] | |
80 | pub struct Ident { | |
81 | pub name: Name, | |
82 | pub ctxt: SyntaxContext | |
83 | } | |
84 | ||
85 | impl Ident { | |
86 | /// Construct an identifier with the given name and an empty context: | |
87 | pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}} | |
88 | ||
89 | pub fn as_str<'a>(&'a self) -> &'a str { | |
90 | self.name.as_str() | |
91 | } | |
223e47cc | 92 | |
1a4d82fc JJ |
93 | pub fn encode_with_hygiene(&self) -> String { |
94 | format!("\x00name_{},ctxt_{}\x00", | |
85aaf69f | 95 | self.name.usize(), |
1a4d82fc JJ |
96 | self.ctxt) |
97 | } | |
98 | } | |
223e47cc | 99 | |
85aaf69f | 100 | impl fmt::Debug for Ident { |
1a4d82fc JJ |
101 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
102 | write!(f, "{}#{}", self.name, self.ctxt) | |
103 | } | |
104 | } | |
970d7e83 | 105 | |
85aaf69f | 106 | impl fmt::Display for Ident { |
1a4d82fc | 107 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 108 | fmt::Display::fmt(&self.name, f) |
1a4d82fc JJ |
109 | } |
110 | } | |
223e47cc | 111 | |
85aaf69f | 112 | impl fmt::Debug for Name { |
1a4d82fc JJ |
113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
114 | let Name(nm) = *self; | |
85aaf69f | 115 | write!(f, "{:?}({})", token::get_name(*self), nm) |
1a4d82fc JJ |
116 | } |
117 | } | |
118 | ||
85aaf69f | 119 | impl fmt::Display for Name { |
1a4d82fc | 120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 121 | fmt::Display::fmt(&token::get_name(*self), f) |
1a4d82fc JJ |
122 | } |
123 | } | |
124 | ||
125 | impl PartialEq for Ident { | |
126 | fn eq(&self, other: &Ident) -> bool { | |
127 | if self.ctxt == other.ctxt { | |
128 | self.name == other.name | |
129 | } else { | |
130 | // IF YOU SEE ONE OF THESE FAILS: it means that you're comparing | |
131 | // idents that have different contexts. You can't fix this without | |
132 | // knowing whether the comparison should be hygienic or non-hygienic. | |
133 | // if it should be non-hygienic (most things are), just compare the | |
134 | // 'name' fields of the idents. Or, even better, replace the idents | |
135 | // with Name's. | |
136 | // | |
137 | // On the other hand, if the comparison does need to be hygienic, | |
138 | // one example and its non-hygienic counterpart would be: | |
139 | // syntax::parse::token::Token::mtwt_eq | |
140 | // syntax::ext::tt::macro_parser::token_name_eq | |
141 | panic!("not allowed to compare these idents: {}, {}. \ | |
142 | Probably related to issue \\#6993", self, other); | |
143 | } | |
144 | } | |
145 | fn ne(&self, other: &Ident) -> bool { | |
146 | ! self.eq(other) | |
147 | } | |
148 | } | |
149 | ||
150 | /// A SyntaxContext represents a chain of macro-expandings | |
151 | /// and renamings. Each macro expansion corresponds to | |
c34b1796 | 152 | /// a fresh u32 |
223e47cc | 153 | |
970d7e83 LB |
154 | // I'm representing this syntax context as an index into |
155 | // a table, in order to work around a compiler bug | |
156 | // that's causing unreleased memory to cause core dumps | |
157 | // and also perhaps to save some work in destructor checks. | |
158 | // the special uint '0' will be used to indicate an empty | |
159 | // syntax context. | |
160 | ||
161 | // this uint is a reference to a table stored in thread-local | |
162 | // storage. | |
1a4d82fc JJ |
163 | pub type SyntaxContext = u32; |
164 | pub const EMPTY_CTXT : SyntaxContext = 0; | |
165 | pub const ILLEGAL_CTXT : SyntaxContext = 1; | |
166 | ||
167 | /// A name is a part of an identifier, representing a string or gensym. It's | |
168 | /// the result of interning. | |
169 | #[derive(Eq, Ord, PartialEq, PartialOrd, Hash, | |
170 | RustcEncodable, RustcDecodable, Clone, Copy)] | |
171 | pub struct Name(pub u32); | |
172 | ||
173 | impl Name { | |
174 | pub fn as_str<'a>(&'a self) -> &'a str { | |
175 | unsafe { | |
176 | // FIXME #12938: can't use copy_lifetime since &str isn't a &T | |
85aaf69f | 177 | ::std::mem::transmute::<&str,&str>(&token::get_name(*self)) |
1a4d82fc JJ |
178 | } |
179 | } | |
180 | ||
85aaf69f | 181 | pub fn usize(&self) -> usize { |
1a4d82fc | 182 | let Name(nm) = *self; |
85aaf69f | 183 | nm as usize |
1a4d82fc JJ |
184 | } |
185 | ||
186 | pub fn ident(&self) -> Ident { | |
187 | Ident { name: *self, ctxt: 0 } | |
223e47cc LB |
188 | } |
189 | } | |
190 | ||
1a4d82fc JJ |
191 | /// A mark represents a unique id associated with a macro expansion |
192 | pub type Mrk = u32; | |
193 | ||
194 | impl Encodable for Ident { | |
195 | fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
85aaf69f | 196 | s.emit_str(&token::get_ident(*self)) |
223e47cc LB |
197 | } |
198 | } | |
199 | ||
1a4d82fc JJ |
200 | impl Decodable for Ident { |
201 | fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> { | |
85aaf69f | 202 | Ok(str_to_ident(&try!(d.read_str())[..])) |
1a4d82fc JJ |
203 | } |
204 | } | |
223e47cc | 205 | |
1a4d82fc JJ |
206 | /// Function name (not all functions have names) |
207 | pub type FnIdent = Option<Ident>; | |
208 | ||
209 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, | |
85aaf69f | 210 | Debug, Copy)] |
223e47cc | 211 | pub struct Lifetime { |
1a4d82fc JJ |
212 | pub id: NodeId, |
213 | pub span: Span, | |
214 | pub name: Name | |
215 | } | |
216 | ||
c34b1796 | 217 | /// A lifetime definition, eg `'a: 'b+'c+'d` |
85aaf69f | 218 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
219 | pub struct LifetimeDef { |
220 | pub lifetime: Lifetime, | |
221 | pub bounds: Vec<Lifetime> | |
223e47cc LB |
222 | } |
223 | ||
1a4d82fc JJ |
224 | /// A "Path" is essentially Rust's notion of a name; for instance: |
225 | /// std::cmp::PartialEq . It's represented as a sequence of identifiers, | |
226 | /// along with a bunch of supporting information. | |
85aaf69f | 227 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
970d7e83 | 228 | pub struct Path { |
1a4d82fc JJ |
229 | pub span: Span, |
230 | /// A `::foo` path, is relative to the crate root rather than current | |
231 | /// module (like paths in an import). | |
232 | pub global: bool, | |
233 | /// The segments in the path: the things separated by `::`. | |
234 | pub segments: Vec<PathSegment>, | |
235 | } | |
236 | ||
237 | /// A segment of a path: an identifier, an optional lifetime, and a set of | |
238 | /// types. | |
85aaf69f | 239 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
240 | pub struct PathSegment { |
241 | /// The identifier portion of this path segment. | |
242 | pub identifier: Ident, | |
243 | ||
244 | /// Type/lifetime parameters attached to this path. They come in | |
245 | /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that | |
246 | /// this is more than just simple syntactic sugar; the use of | |
247 | /// parens affects the region binding rules, so we preserve the | |
248 | /// distinction. | |
249 | pub parameters: PathParameters, | |
250 | } | |
251 | ||
85aaf69f | 252 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 253 | pub enum PathParameters { |
c34b1796 | 254 | /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` |
1a4d82fc | 255 | AngleBracketedParameters(AngleBracketedParameterData), |
c34b1796 | 256 | /// The `(A,B)` and `C` in `Foo(A,B) -> C` |
1a4d82fc JJ |
257 | ParenthesizedParameters(ParenthesizedParameterData), |
258 | } | |
259 | ||
260 | impl PathParameters { | |
261 | pub fn none() -> PathParameters { | |
262 | AngleBracketedParameters(AngleBracketedParameterData { | |
263 | lifetimes: Vec::new(), | |
264 | types: OwnedSlice::empty(), | |
265 | bindings: OwnedSlice::empty(), | |
266 | }) | |
267 | } | |
268 | ||
269 | pub fn is_empty(&self) -> bool { | |
270 | match *self { | |
271 | AngleBracketedParameters(ref data) => data.is_empty(), | |
272 | ||
273 | // Even if the user supplied no types, something like | |
274 | // `X()` is equivalent to `X<(),()>`. | |
275 | ParenthesizedParameters(..) => false, | |
276 | } | |
277 | } | |
278 | ||
279 | pub fn has_lifetimes(&self) -> bool { | |
280 | match *self { | |
281 | AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), | |
282 | ParenthesizedParameters(_) => false, | |
283 | } | |
284 | } | |
285 | ||
286 | pub fn has_types(&self) -> bool { | |
287 | match *self { | |
288 | AngleBracketedParameters(ref data) => !data.types.is_empty(), | |
289 | ParenthesizedParameters(..) => true, | |
290 | } | |
291 | } | |
292 | ||
293 | /// Returns the types that the user wrote. Note that these do not necessarily map to the type | |
294 | /// parameters in the parenthesized case. | |
295 | pub fn types(&self) -> Vec<&P<Ty>> { | |
296 | match *self { | |
297 | AngleBracketedParameters(ref data) => { | |
298 | data.types.iter().collect() | |
299 | } | |
300 | ParenthesizedParameters(ref data) => { | |
301 | data.inputs.iter() | |
302 | .chain(data.output.iter()) | |
303 | .collect() | |
304 | } | |
305 | } | |
306 | } | |
307 | ||
308 | pub fn lifetimes(&self) -> Vec<&Lifetime> { | |
309 | match *self { | |
310 | AngleBracketedParameters(ref data) => { | |
311 | data.lifetimes.iter().collect() | |
312 | } | |
313 | ParenthesizedParameters(_) => { | |
314 | Vec::new() | |
315 | } | |
316 | } | |
317 | } | |
318 | ||
319 | pub fn bindings(&self) -> Vec<&P<TypeBinding>> { | |
320 | match *self { | |
321 | AngleBracketedParameters(ref data) => { | |
322 | data.bindings.iter().collect() | |
323 | } | |
324 | ParenthesizedParameters(_) => { | |
325 | Vec::new() | |
326 | } | |
327 | } | |
328 | } | |
329 | } | |
330 | ||
331 | /// A path like `Foo<'a, T>` | |
85aaf69f | 332 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
333 | pub struct AngleBracketedParameterData { |
334 | /// The lifetime parameters for this path segment. | |
335 | pub lifetimes: Vec<Lifetime>, | |
336 | /// The type parameters for this path segment, if present. | |
337 | pub types: OwnedSlice<P<Ty>>, | |
338 | /// Bindings (equality constraints) on associated types, if present. | |
339 | /// E.g., `Foo<A=Bar>`. | |
340 | pub bindings: OwnedSlice<P<TypeBinding>>, | |
223e47cc LB |
341 | } |
342 | ||
1a4d82fc JJ |
343 | impl AngleBracketedParameterData { |
344 | fn is_empty(&self) -> bool { | |
345 | self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty() | |
346 | } | |
347 | } | |
348 | ||
349 | /// A path like `Foo(A,B) -> C` | |
85aaf69f | 350 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 351 | pub struct ParenthesizedParameterData { |
85aaf69f SL |
352 | /// Overall span |
353 | pub span: Span, | |
354 | ||
1a4d82fc JJ |
355 | /// `(A,B)` |
356 | pub inputs: Vec<P<Ty>>, | |
357 | ||
358 | /// `C` | |
359 | pub output: Option<P<Ty>>, | |
360 | } | |
361 | ||
362 | pub type CrateNum = u32; | |
223e47cc | 363 | |
1a4d82fc | 364 | pub type NodeId = u32; |
223e47cc | 365 | |
1a4d82fc | 366 | #[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, |
85aaf69f | 367 | RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
368 | pub struct DefId { |
369 | pub krate: CrateNum, | |
370 | pub node: NodeId, | |
223e47cc LB |
371 | } |
372 | ||
85aaf69f SL |
373 | impl DefId { |
374 | /// Read the node id, asserting that this def-id is krate-local. | |
375 | pub fn local_id(&self) -> NodeId { | |
376 | assert_eq!(self.krate, LOCAL_CRATE); | |
377 | self.node | |
378 | } | |
379 | } | |
380 | ||
1a4d82fc JJ |
381 | /// Item definitions in the currently-compiled crate would have the CrateNum |
382 | /// LOCAL_CRATE in their DefId. | |
383 | pub const LOCAL_CRATE: CrateNum = 0; | |
384 | pub const CRATE_NODE_ID: NodeId = 0; | |
223e47cc | 385 | |
1a4d82fc JJ |
386 | /// When parsing and doing expansions, we initially give all AST nodes this AST |
387 | /// node value. Then later, in the renumber pass, we renumber them to have | |
388 | /// small, positive ids. | |
c34b1796 | 389 | pub const DUMMY_NODE_ID: NodeId = !0; |
1a4d82fc JJ |
390 | |
391 | /// The AST represents all type param bounds as types. | |
392 | /// typeck::collect::compute_bounds matches these against | |
393 | /// the "special" built-in traits (see middle::lang_items) and | |
394 | /// detects Copy, Send and Sync. | |
85aaf69f | 395 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
223e47cc | 396 | pub enum TyParamBound { |
1a4d82fc JJ |
397 | TraitTyParamBound(PolyTraitRef, TraitBoundModifier), |
398 | RegionTyParamBound(Lifetime) | |
223e47cc LB |
399 | } |
400 | ||
1a4d82fc JJ |
401 | /// A modifier on a bound, currently this is only used for `?Sized`, where the |
402 | /// modifier is `Maybe`. Negative bounds should also be handled here. | |
85aaf69f | 403 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
404 | pub enum TraitBoundModifier { |
405 | None, | |
406 | Maybe, | |
407 | } | |
408 | ||
409 | pub type TyParamBounds = OwnedSlice<TyParamBound>; | |
410 | ||
85aaf69f | 411 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
223e47cc | 412 | pub struct TyParam { |
1a4d82fc JJ |
413 | pub ident: Ident, |
414 | pub id: NodeId, | |
415 | pub bounds: TyParamBounds, | |
416 | pub default: Option<P<Ty>>, | |
417 | pub span: Span | |
223e47cc LB |
418 | } |
419 | ||
1a4d82fc JJ |
420 | /// Represents lifetimes and type parameters attached to a declaration |
421 | /// of a function, enum, trait, etc. | |
85aaf69f | 422 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
223e47cc | 423 | pub struct Generics { |
1a4d82fc JJ |
424 | pub lifetimes: Vec<LifetimeDef>, |
425 | pub ty_params: OwnedSlice<TyParam>, | |
426 | pub where_clause: WhereClause, | |
223e47cc LB |
427 | } |
428 | ||
970d7e83 | 429 | impl Generics { |
970d7e83 | 430 | pub fn is_lt_parameterized(&self) -> bool { |
9346a6ac | 431 | !self.lifetimes.is_empty() |
223e47cc | 432 | } |
970d7e83 | 433 | pub fn is_type_parameterized(&self) -> bool { |
9346a6ac AL |
434 | !self.ty_params.is_empty() |
435 | } | |
436 | pub fn is_parameterized(&self) -> bool { | |
437 | self.is_lt_parameterized() || self.is_type_parameterized() | |
223e47cc LB |
438 | } |
439 | } | |
440 | ||
c34b1796 | 441 | /// A `where` clause in a definition |
85aaf69f | 442 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
443 | pub struct WhereClause { |
444 | pub id: NodeId, | |
445 | pub predicates: Vec<WherePredicate>, | |
223e47cc LB |
446 | } |
447 | ||
c34b1796 | 448 | /// A single predicate in a `where` clause |
85aaf69f | 449 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 450 | pub enum WherePredicate { |
c34b1796 | 451 | /// A type binding, eg `for<'c> Foo: Send+Clone+'c` |
1a4d82fc | 452 | BoundPredicate(WhereBoundPredicate), |
c34b1796 | 453 | /// A lifetime predicate, e.g. `'a: 'b+'c` |
1a4d82fc | 454 | RegionPredicate(WhereRegionPredicate), |
c34b1796 | 455 | /// An equality predicate (unsupported) |
1a4d82fc | 456 | EqPredicate(WhereEqPredicate) |
223e47cc LB |
457 | } |
458 | ||
c34b1796 | 459 | /// A type bound, eg `for<'c> Foo: Send+Clone+'c` |
85aaf69f | 460 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
461 | pub struct WhereBoundPredicate { |
462 | pub span: Span, | |
c34b1796 | 463 | /// Any lifetimes from a `for` binding |
85aaf69f | 464 | pub bound_lifetimes: Vec<LifetimeDef>, |
c34b1796 | 465 | /// The type being bounded |
1a4d82fc | 466 | pub bounded_ty: P<Ty>, |
c34b1796 | 467 | /// Trait and lifetime bounds (`Clone+Send+'static`) |
1a4d82fc | 468 | pub bounds: OwnedSlice<TyParamBound>, |
223e47cc LB |
469 | } |
470 | ||
c34b1796 | 471 | /// A lifetime predicate, e.g. `'a: 'b+'c` |
85aaf69f | 472 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
473 | pub struct WhereRegionPredicate { |
474 | pub span: Span, | |
475 | pub lifetime: Lifetime, | |
476 | pub bounds: Vec<Lifetime>, | |
477 | } | |
223e47cc | 478 | |
c34b1796 | 479 | /// An equality predicate (unsupported), e.g. `T=int` |
85aaf69f | 480 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
481 | pub struct WhereEqPredicate { |
482 | pub id: NodeId, | |
483 | pub span: Span, | |
484 | pub path: Path, | |
485 | pub ty: P<Ty>, | |
486 | } | |
487 | ||
488 | /// The set of MetaItems that define the compilation environment of the crate, | |
489 | /// used to drive conditional compilation | |
490 | pub type CrateConfig = Vec<P<MetaItem>> ; | |
223e47cc | 491 | |
85aaf69f | 492 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
493 | pub struct Crate { |
494 | pub module: Mod, | |
495 | pub attrs: Vec<Attribute>, | |
496 | pub config: CrateConfig, | |
497 | pub span: Span, | |
498 | pub exported_macros: Vec<MacroDef>, | |
970d7e83 | 499 | } |
223e47cc | 500 | |
1a4d82fc JJ |
501 | pub type MetaItem = Spanned<MetaItem_>; |
502 | ||
85aaf69f | 503 | #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
504 | pub enum MetaItem_ { |
505 | MetaWord(InternedString), | |
506 | MetaList(InternedString, Vec<P<MetaItem>>), | |
507 | MetaNameValue(InternedString, Lit), | |
508 | } | |
509 | ||
510 | // can't be derived because the MetaList requires an unordered comparison | |
511 | impl PartialEq for MetaItem_ { | |
512 | fn eq(&self, other: &MetaItem_) -> bool { | |
513 | match *self { | |
514 | MetaWord(ref ns) => match *other { | |
515 | MetaWord(ref no) => (*ns) == (*no), | |
516 | _ => false | |
517 | }, | |
518 | MetaNameValue(ref ns, ref vs) => match *other { | |
519 | MetaNameValue(ref no, ref vo) => { | |
520 | (*ns) == (*no) && vs.node == vo.node | |
521 | } | |
522 | _ => false | |
523 | }, | |
524 | MetaList(ref ns, ref miss) => match *other { | |
525 | MetaList(ref no, ref miso) => { | |
526 | ns == no && | |
527 | miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node)) | |
528 | } | |
529 | _ => false | |
530 | } | |
531 | } | |
532 | } | |
223e47cc LB |
533 | } |
534 | ||
85aaf69f | 535 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 536 | pub struct Block { |
c34b1796 | 537 | /// Statements in a block |
1a4d82fc | 538 | pub stmts: Vec<P<Stmt>>, |
c34b1796 AL |
539 | /// An expression at the end of the block |
540 | /// without a semicolon, if any | |
1a4d82fc JJ |
541 | pub expr: Option<P<Expr>>, |
542 | pub id: NodeId, | |
c34b1796 | 543 | /// Distinguishes between `unsafe { ... }` and `{ ... }` |
1a4d82fc JJ |
544 | pub rules: BlockCheckMode, |
545 | pub span: Span, | |
546 | } | |
547 | ||
85aaf69f | 548 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
549 | pub struct Pat { |
550 | pub id: NodeId, | |
551 | pub node: Pat_, | |
552 | pub span: Span, | |
553 | } | |
554 | ||
c34b1796 AL |
555 | /// A single field in a struct pattern |
556 | /// | |
557 | /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` | |
558 | /// are treated the same as` x: x, y: ref y, z: ref mut z`, | |
559 | /// except is_shorthand is true | |
85aaf69f | 560 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 561 | pub struct FieldPat { |
c34b1796 | 562 | /// The identifier for the field |
1a4d82fc | 563 | pub ident: Ident, |
c34b1796 | 564 | /// The pattern the field is destructured to |
1a4d82fc JJ |
565 | pub pat: P<Pat>, |
566 | pub is_shorthand: bool, | |
567 | } | |
568 | ||
85aaf69f | 569 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
570 | pub enum BindingMode { |
571 | BindByRef(Mutability), | |
572 | BindByValue(Mutability), | |
573 | } | |
574 | ||
85aaf69f | 575 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
576 | pub enum PatWildKind { |
577 | /// Represents the wildcard pattern `_` | |
578 | PatWildSingle, | |
579 | ||
580 | /// Represents the wildcard pattern `..` | |
581 | PatWildMulti, | |
582 | } | |
583 | ||
85aaf69f | 584 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
585 | pub enum Pat_ { |
586 | /// Represents a wildcard pattern (either `_` or `..`) | |
587 | PatWild(PatWildKind), | |
588 | ||
589 | /// A PatIdent may either be a new bound variable, | |
590 | /// or a nullary enum (in which case the third field | |
591 | /// is None). | |
c34b1796 | 592 | /// |
1a4d82fc JJ |
593 | /// In the nullary enum case, the parser can't determine |
594 | /// which it is. The resolver determines this, and | |
595 | /// records this pattern's NodeId in an auxiliary | |
596 | /// set (of "PatIdents that refer to nullary enums") | |
597 | PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>), | |
598 | ||
599 | /// "None" means a * pattern where we don't bind the fields to names. | |
600 | PatEnum(Path, Option<Vec<P<Pat>>>), | |
601 | ||
c34b1796 AL |
602 | /// Destructuring of a struct, e.g. `Foo {x, y, ..}` |
603 | /// The `bool` is `true` in the presence of a `..` | |
1a4d82fc | 604 | PatStruct(Path, Vec<Spanned<FieldPat>>, bool), |
c34b1796 | 605 | /// A tuple pattern `(a, b)` |
1a4d82fc | 606 | PatTup(Vec<P<Pat>>), |
c34b1796 | 607 | /// A `box` pattern |
1a4d82fc | 608 | PatBox(P<Pat>), |
c34b1796 AL |
609 | /// A reference pattern, e.g. `&mut (a, b)` |
610 | PatRegion(P<Pat>, Mutability), | |
611 | /// A literal | |
1a4d82fc | 612 | PatLit(P<Expr>), |
c34b1796 | 613 | /// A range pattern, e.g. `1...2` |
1a4d82fc JJ |
614 | PatRange(P<Expr>, P<Expr>), |
615 | /// [a, b, ..i, y, z] is represented as: | |
616 | /// PatVec(box [a, b], Some(i), box [y, z]) | |
617 | PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>), | |
c34b1796 | 618 | /// A macro pattern; pre-expansion |
1a4d82fc JJ |
619 | PatMac(Mac), |
620 | } | |
621 | ||
85aaf69f | 622 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
623 | pub enum Mutability { |
624 | MutMutable, | |
625 | MutImmutable, | |
626 | } | |
627 | ||
85aaf69f SL |
628 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
629 | pub enum BinOp_ { | |
c34b1796 | 630 | /// The `+` operator (addition) |
1a4d82fc | 631 | BiAdd, |
c34b1796 | 632 | /// The `-` operator (subtraction) |
1a4d82fc | 633 | BiSub, |
c34b1796 | 634 | /// The `*` operator (multiplication) |
1a4d82fc | 635 | BiMul, |
c34b1796 | 636 | /// The `/` operator (division) |
1a4d82fc | 637 | BiDiv, |
c34b1796 | 638 | /// The `%` operator (modulus) |
1a4d82fc | 639 | BiRem, |
c34b1796 | 640 | /// The `&&` operator (logical and) |
1a4d82fc | 641 | BiAnd, |
c34b1796 | 642 | /// The `||` operator (logical or) |
1a4d82fc | 643 | BiOr, |
c34b1796 | 644 | /// The `^` operator (bitwise xor) |
1a4d82fc | 645 | BiBitXor, |
c34b1796 | 646 | /// The `&` operator (bitwise and) |
1a4d82fc | 647 | BiBitAnd, |
c34b1796 | 648 | /// The `|` operator (bitwise or) |
1a4d82fc | 649 | BiBitOr, |
c34b1796 | 650 | /// The `<<` operator (shift left) |
1a4d82fc | 651 | BiShl, |
c34b1796 | 652 | /// The `>>` operator (shift right) |
1a4d82fc | 653 | BiShr, |
c34b1796 | 654 | /// The `==` operator (equality) |
1a4d82fc | 655 | BiEq, |
c34b1796 | 656 | /// The `<` operator (less than) |
1a4d82fc | 657 | BiLt, |
c34b1796 | 658 | /// The `<=` operator (less than or equal to) |
1a4d82fc | 659 | BiLe, |
c34b1796 | 660 | /// The `!=` operator (not equal to) |
1a4d82fc | 661 | BiNe, |
c34b1796 | 662 | /// The `>=` operator (greater than or equal to) |
1a4d82fc | 663 | BiGe, |
c34b1796 | 664 | /// The `>` operator (greater than) |
1a4d82fc JJ |
665 | BiGt, |
666 | } | |
667 | ||
85aaf69f SL |
668 | pub type BinOp = Spanned<BinOp_>; |
669 | ||
670 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] | |
1a4d82fc | 671 | pub enum UnOp { |
c34b1796 | 672 | /// The `box` operator |
1a4d82fc | 673 | UnUniq, |
c34b1796 | 674 | /// The `*` operator for dereferencing |
1a4d82fc | 675 | UnDeref, |
c34b1796 | 676 | /// The `!` operator for logical inversion |
1a4d82fc | 677 | UnNot, |
c34b1796 | 678 | /// The `-` operator for negation |
1a4d82fc JJ |
679 | UnNeg |
680 | } | |
681 | ||
c34b1796 | 682 | /// A statement |
1a4d82fc JJ |
683 | pub type Stmt = Spanned<Stmt_>; |
684 | ||
85aaf69f | 685 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
686 | pub enum Stmt_ { |
687 | /// Could be an item or a local (let) binding: | |
688 | StmtDecl(P<Decl>, NodeId), | |
689 | ||
690 | /// Expr without trailing semi-colon (must have unit type): | |
691 | StmtExpr(P<Expr>, NodeId), | |
692 | ||
693 | /// Expr with trailing semi-colon (may have any type): | |
694 | StmtSemi(P<Expr>, NodeId), | |
695 | ||
696 | StmtMac(P<Mac>, MacStmtStyle), | |
697 | } | |
698 | ||
85aaf69f | 699 | #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
700 | pub enum MacStmtStyle { |
701 | /// The macro statement had a trailing semicolon, e.g. `foo! { ... };` | |
702 | /// `foo!(...);`, `foo![...];` | |
703 | MacStmtWithSemicolon, | |
704 | /// The macro statement had braces; e.g. foo! { ... } | |
705 | MacStmtWithBraces, | |
706 | /// The macro statement had parentheses or brackets and no semicolon; e.g. | |
707 | /// `foo!(...)`. All of these will end up being converted into macro | |
708 | /// expressions. | |
709 | MacStmtWithoutBraces, | |
710 | } | |
711 | ||
712 | /// Where a local declaration came from: either a true `let ... = | |
713 | /// ...;`, or one desugared from the pattern of a for loop. | |
85aaf69f | 714 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
715 | pub enum LocalSource { |
716 | LocalLet, | |
717 | LocalFor, | |
223e47cc LB |
718 | } |
719 | ||
1a4d82fc JJ |
720 | // FIXME (pending discussion of #1697, #2178...): local should really be |
721 | // a refinement on pat. | |
722 | /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;` | |
85aaf69f | 723 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
724 | pub struct Local { |
725 | pub pat: P<Pat>, | |
726 | pub ty: Option<P<Ty>>, | |
c34b1796 | 727 | /// Initializer expression to set the value, if any |
1a4d82fc JJ |
728 | pub init: Option<P<Expr>>, |
729 | pub id: NodeId, | |
730 | pub span: Span, | |
731 | pub source: LocalSource, | |
732 | } | |
733 | ||
734 | pub type Decl = Spanned<Decl_>; | |
735 | ||
85aaf69f | 736 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
737 | pub enum Decl_ { |
738 | /// A local (let) binding: | |
739 | DeclLocal(P<Local>), | |
740 | /// An item binding: | |
741 | DeclItem(P<Item>), | |
742 | } | |
743 | ||
744 | /// represents one arm of a 'match' | |
85aaf69f | 745 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
746 | pub struct Arm { |
747 | pub attrs: Vec<Attribute>, | |
748 | pub pats: Vec<P<Pat>>, | |
749 | pub guard: Option<P<Expr>>, | |
750 | pub body: P<Expr>, | |
751 | } | |
752 | ||
85aaf69f | 753 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
754 | pub struct Field { |
755 | pub ident: SpannedIdent, | |
756 | pub expr: P<Expr>, | |
757 | pub span: Span, | |
758 | } | |
759 | ||
760 | pub type SpannedIdent = Spanned<Ident>; | |
761 | ||
85aaf69f | 762 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
763 | pub enum BlockCheckMode { |
764 | DefaultBlock, | |
765 | UnsafeBlock(UnsafeSource), | |
766 | } | |
767 | ||
85aaf69f | 768 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
769 | pub enum UnsafeSource { |
770 | CompilerGenerated, | |
771 | UserProvided, | |
772 | } | |
773 | ||
c34b1796 | 774 | /// An expression |
85aaf69f | 775 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
776 | pub struct Expr { |
777 | pub id: NodeId, | |
778 | pub node: Expr_, | |
779 | pub span: Span, | |
780 | } | |
781 | ||
85aaf69f | 782 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
783 | pub enum Expr_ { |
784 | /// First expr is the place; second expr is the value. | |
785 | ExprBox(Option<P<Expr>>, P<Expr>), | |
c34b1796 | 786 | /// An array (`[a, b, c, d]`) |
1a4d82fc | 787 | ExprVec(Vec<P<Expr>>), |
c34b1796 AL |
788 | /// A function call |
789 | /// | |
790 | /// The first field resolves to the function itself, | |
791 | /// and the second field is the list of arguments | |
1a4d82fc | 792 | ExprCall(P<Expr>, Vec<P<Expr>>), |
c34b1796 AL |
793 | /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`) |
794 | /// | |
795 | /// The `SpannedIdent` is the identifier for the method name. | |
796 | /// The vector of `Ty`s are the ascripted type parameters for the method | |
797 | /// (within the angle brackets). | |
798 | /// | |
799 | /// The first element of the vector of `Expr`s is the expression that evaluates | |
800 | /// to the object on which the method is being called on (the receiver), | |
801 | /// and the remaining elements are the rest of the arguments. | |
802 | /// | |
803 | /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as | |
804 | /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. | |
1a4d82fc | 805 | ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>), |
c34b1796 | 806 | /// A tuple (`(a, b, c ,d)`) |
1a4d82fc | 807 | ExprTup(Vec<P<Expr>>), |
c34b1796 | 808 | /// A binary operation (For example: `a + b`, `a * b`) |
1a4d82fc | 809 | ExprBinary(BinOp, P<Expr>, P<Expr>), |
c34b1796 | 810 | /// A unary operation (For example: `!x`, `*x`) |
1a4d82fc | 811 | ExprUnary(UnOp, P<Expr>), |
c34b1796 | 812 | /// A literal (For example: `1u8`, `"foo"`) |
1a4d82fc | 813 | ExprLit(P<Lit>), |
c34b1796 | 814 | /// A cast (`foo as f64`) |
1a4d82fc | 815 | ExprCast(P<Expr>, P<Ty>), |
c34b1796 AL |
816 | /// An `if` block, with an optional else block |
817 | /// | |
818 | /// `if expr { block } else { expr }` | |
1a4d82fc | 819 | ExprIf(P<Expr>, P<Block>, Option<P<Expr>>), |
c34b1796 AL |
820 | /// An `if let` expression with an optional else block |
821 | /// | |
822 | /// `if let pat = expr { block } else { expr }` | |
823 | /// | |
824 | /// This is desugared to a `match` expression. | |
1a4d82fc JJ |
825 | ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>), |
826 | // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. | |
c34b1796 AL |
827 | /// A while loop, with an optional label |
828 | /// | |
829 | /// `'label: while expr { block }` | |
1a4d82fc JJ |
830 | ExprWhile(P<Expr>, P<Block>, Option<Ident>), |
831 | // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. | |
c34b1796 AL |
832 | /// A while-let loop, with an optional label |
833 | /// | |
834 | /// `'label: while let pat = expr { block }` | |
835 | /// | |
836 | /// This is desugared to a combination of `loop` and `match` expressions. | |
1a4d82fc JJ |
837 | ExprWhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>), |
838 | // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. | |
c34b1796 AL |
839 | /// A for loop, with an optional label |
840 | /// | |
841 | /// `'label: for pat in expr { block }` | |
842 | /// | |
843 | /// This is desugared to a combination of `loop` and `match` expressions. | |
1a4d82fc | 844 | ExprForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>), |
c34b1796 AL |
845 | /// Conditionless loop (can be exited with break, continue, or return) |
846 | /// | |
847 | /// `'label: loop { block }` | |
1a4d82fc JJ |
848 | // FIXME #6993: change to Option<Name> ... or not, if these are hygienic. |
849 | ExprLoop(P<Block>, Option<Ident>), | |
c34b1796 AL |
850 | /// A `match` block, with a source that indicates whether or not it is |
851 | /// the result of a desugaring, and if so, which kind. | |
1a4d82fc | 852 | ExprMatch(P<Expr>, Vec<Arm>, MatchSource), |
c34b1796 | 853 | /// A closure (for example, `move |a, b, c| {a + b + c}`) |
85aaf69f | 854 | ExprClosure(CaptureClause, P<FnDecl>, P<Block>), |
c34b1796 | 855 | /// A block (`{ ... }`) |
1a4d82fc JJ |
856 | ExprBlock(P<Block>), |
857 | ||
c34b1796 | 858 | /// An assignment (`a = foo()`) |
1a4d82fc | 859 | ExprAssign(P<Expr>, P<Expr>), |
c34b1796 AL |
860 | /// An assignment with an operator |
861 | /// | |
862 | /// For example, `a += 1`. | |
1a4d82fc | 863 | ExprAssignOp(BinOp, P<Expr>, P<Expr>), |
c34b1796 | 864 | /// Access of a named struct field (`obj.foo`) |
1a4d82fc | 865 | ExprField(P<Expr>, SpannedIdent), |
c34b1796 AL |
866 | /// Access of an unnamed field of a struct or tuple-struct |
867 | /// | |
868 | /// For example, `foo.0`. | |
85aaf69f | 869 | ExprTupField(P<Expr>, Spanned<usize>), |
c34b1796 | 870 | /// An indexing operation (`foo[2]`) |
1a4d82fc | 871 | ExprIndex(P<Expr>, P<Expr>), |
c34b1796 | 872 | /// A range (`1..2`, `1..`, or `..2`) |
1a4d82fc JJ |
873 | ExprRange(Option<P<Expr>>, Option<P<Expr>>), |
874 | ||
c34b1796 AL |
875 | /// Variable reference, possibly containing `::` and/or type |
876 | /// parameters, e.g. foo::bar::<baz>. | |
877 | /// | |
878 | /// Optionally "qualified", | |
879 | /// e.g. `<Vec<T> as SomeTrait>::SomeType`. | |
880 | ExprPath(Option<QSelf>, Path), | |
1a4d82fc | 881 | |
c34b1796 | 882 | /// A referencing operation (`&a` or `&mut a`) |
1a4d82fc | 883 | ExprAddrOf(Mutability, P<Expr>), |
c34b1796 | 884 | /// A `break`, with an optional label to break |
1a4d82fc | 885 | ExprBreak(Option<Ident>), |
c34b1796 | 886 | /// A `continue`, with an optional label |
1a4d82fc | 887 | ExprAgain(Option<Ident>), |
c34b1796 | 888 | /// A `return`, with an optional value to be returned |
1a4d82fc JJ |
889 | ExprRet(Option<P<Expr>>), |
890 | ||
c34b1796 | 891 | /// Output of the `asm!()` macro |
1a4d82fc JJ |
892 | ExprInlineAsm(InlineAsm), |
893 | ||
c34b1796 | 894 | /// A macro invocation; pre-expansion |
1a4d82fc JJ |
895 | ExprMac(Mac), |
896 | ||
897 | /// A struct literal expression. | |
c34b1796 AL |
898 | /// |
899 | /// For example, `Foo {x: 1, y: 2}`, or | |
900 | /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`. | |
901 | ExprStruct(Path, Vec<Field>, Option<P<Expr>>), | |
1a4d82fc JJ |
902 | |
903 | /// A vector literal constructed from one repeated element. | |
c34b1796 AL |
904 | /// |
905 | /// For example, `[1u8; 5]`. The first expression is the element | |
906 | /// to be repeated; the second is the number of times to repeat it. | |
907 | ExprRepeat(P<Expr>, P<Expr>), | |
1a4d82fc JJ |
908 | |
909 | /// No-op: used solely so we can pretty-print faithfully | |
910 | ExprParen(P<Expr>) | |
911 | } | |
912 | ||
c34b1796 AL |
913 | /// The explicit Self type in a "qualified path". The actual |
914 | /// path, including the trait and the associated item, is stored | |
915 | /// separately. `position` represents the index of the associated | |
916 | /// item qualified with this Self type. | |
917 | /// | |
918 | /// <Vec<T> as a::b::Trait>::AssociatedItem | |
919 | /// ^~~~~ ~~~~~~~~~~~~~~^ | |
920 | /// ty position = 3 | |
1a4d82fc | 921 | /// |
c34b1796 AL |
922 | /// <Vec<T>>::AssociatedItem |
923 | /// ^~~~~ ^ | |
924 | /// ty position = 0 | |
85aaf69f | 925 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
c34b1796 AL |
926 | pub struct QSelf { |
927 | pub ty: P<Ty>, | |
928 | pub position: usize | |
1a4d82fc JJ |
929 | } |
930 | ||
85aaf69f | 931 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
932 | pub enum MatchSource { |
933 | Normal, | |
934 | IfLetDesugar { contains_else_clause: bool }, | |
935 | WhileLetDesugar, | |
85aaf69f | 936 | ForLoopDesugar, |
1a4d82fc JJ |
937 | } |
938 | ||
85aaf69f | 939 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
940 | pub enum CaptureClause { |
941 | CaptureByValue, | |
942 | CaptureByRef, | |
943 | } | |
944 | ||
945 | /// A delimited sequence of token trees | |
85aaf69f | 946 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
947 | pub struct Delimited { |
948 | /// The type of delimiter | |
949 | pub delim: token::DelimToken, | |
950 | /// The span covering the opening delimiter | |
951 | pub open_span: Span, | |
952 | /// The delimited sequence of token trees | |
953 | pub tts: Vec<TokenTree>, | |
954 | /// The span covering the closing delimiter | |
955 | pub close_span: Span, | |
956 | } | |
957 | ||
958 | impl Delimited { | |
959 | /// Returns the opening delimiter as a token. | |
960 | pub fn open_token(&self) -> token::Token { | |
961 | token::OpenDelim(self.delim) | |
962 | } | |
223e47cc | 963 | |
1a4d82fc JJ |
964 | /// Returns the closing delimiter as a token. |
965 | pub fn close_token(&self) -> token::Token { | |
966 | token::CloseDelim(self.delim) | |
967 | } | |
223e47cc | 968 | |
1a4d82fc JJ |
969 | /// Returns the opening delimiter as a token tree. |
970 | pub fn open_tt(&self) -> TokenTree { | |
971 | TtToken(self.open_span, self.open_token()) | |
972 | } | |
973 | ||
974 | /// Returns the closing delimiter as a token tree. | |
975 | pub fn close_tt(&self) -> TokenTree { | |
976 | TtToken(self.close_span, self.close_token()) | |
977 | } | |
978 | } | |
979 | ||
980 | /// A sequence of token treesee | |
85aaf69f | 981 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
982 | pub struct SequenceRepetition { |
983 | /// The sequence of token trees | |
984 | pub tts: Vec<TokenTree>, | |
985 | /// The optional separator | |
986 | pub separator: Option<token::Token>, | |
987 | /// Whether the sequence can be repeated zero (*), or one or more times (+) | |
988 | pub op: KleeneOp, | |
989 | /// The number of `MatchNt`s that appear in the sequence (and subsequences) | |
85aaf69f | 990 | pub num_captures: usize, |
1a4d82fc JJ |
991 | } |
992 | ||
993 | /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star) | |
994 | /// for token sequences. | |
85aaf69f | 995 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
996 | pub enum KleeneOp { |
997 | ZeroOrMore, | |
998 | OneOrMore, | |
999 | } | |
1000 | ||
1001 | /// When the main rust parser encounters a syntax-extension invocation, it | |
1002 | /// parses the arguments to the invocation as a token-tree. This is a very | |
1003 | /// loose structure, such that all sorts of different AST-fragments can | |
1004 | /// be passed to syntax extensions using a uniform type. | |
1005 | /// | |
1006 | /// If the syntax extension is an MBE macro, it will attempt to match its | |
1007 | /// LHS token tree against the provided token tree, and if it finds a | |
1008 | /// match, will transcribe the RHS token tree, splicing in any captured | |
1009 | /// macro_parser::matched_nonterminals into the `SubstNt`s it finds. | |
1010 | /// | |
1011 | /// The RHS of an MBE macro is the only place `SubstNt`s are substituted. | |
1012 | /// Nothing special happens to misnamed or misplaced `SubstNt`s. | |
85aaf69f | 1013 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1014 | pub enum TokenTree { |
1015 | /// A single token | |
1016 | TtToken(Span, token::Token), | |
1017 | /// A delimited sequence of token trees | |
1018 | TtDelimited(Span, Rc<Delimited>), | |
1019 | ||
1020 | // This only makes sense in MBE macros. | |
1021 | ||
1022 | /// A kleene-style repetition sequence with a span | |
1023 | // FIXME(eddyb) #12938 Use DST. | |
1024 | TtSequence(Span, Rc<SequenceRepetition>), | |
223e47cc LB |
1025 | } |
1026 | ||
1a4d82fc | 1027 | impl TokenTree { |
85aaf69f | 1028 | pub fn len(&self) -> usize { |
1a4d82fc JJ |
1029 | match *self { |
1030 | TtToken(_, token::DocComment(_)) => 2, | |
1031 | TtToken(_, token::SpecialVarNt(..)) => 2, | |
1032 | TtToken(_, token::MatchNt(..)) => 3, | |
1033 | TtDelimited(_, ref delimed) => { | |
1034 | delimed.tts.len() + 2 | |
1035 | } | |
1036 | TtSequence(_, ref seq) => { | |
1037 | seq.tts.len() | |
1038 | } | |
1039 | TtToken(..) => 0 | |
1040 | } | |
1041 | } | |
1042 | ||
85aaf69f | 1043 | pub fn get_tt(&self, index: usize) -> TokenTree { |
1a4d82fc JJ |
1044 | match (self, index) { |
1045 | (&TtToken(sp, token::DocComment(_)), 0) => { | |
1046 | TtToken(sp, token::Pound) | |
1047 | } | |
1048 | (&TtToken(sp, token::DocComment(name)), 1) => { | |
1049 | TtDelimited(sp, Rc::new(Delimited { | |
1050 | delim: token::Bracket, | |
1051 | open_span: sp, | |
1052 | tts: vec![TtToken(sp, token::Ident(token::str_to_ident("doc"), | |
1053 | token::Plain)), | |
1054 | TtToken(sp, token::Eq), | |
1055 | TtToken(sp, token::Literal(token::Str_(name), None))], | |
1056 | close_span: sp, | |
1057 | })) | |
1058 | } | |
1059 | (&TtDelimited(_, ref delimed), _) => { | |
1060 | if index == 0 { | |
1061 | return delimed.open_tt(); | |
1062 | } | |
1063 | if index == delimed.tts.len() + 1 { | |
1064 | return delimed.close_tt(); | |
1065 | } | |
1066 | delimed.tts[index - 1].clone() | |
1067 | } | |
1068 | (&TtToken(sp, token::SpecialVarNt(var)), _) => { | |
1069 | let v = [TtToken(sp, token::Dollar), | |
1070 | TtToken(sp, token::Ident(token::str_to_ident(var.as_str()), | |
1071 | token::Plain))]; | |
85aaf69f | 1072 | v[index].clone() |
1a4d82fc JJ |
1073 | } |
1074 | (&TtToken(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => { | |
1075 | let v = [TtToken(sp, token::SubstNt(name, name_st)), | |
1076 | TtToken(sp, token::Colon), | |
1077 | TtToken(sp, token::Ident(kind, kind_st))]; | |
85aaf69f | 1078 | v[index].clone() |
1a4d82fc JJ |
1079 | } |
1080 | (&TtSequence(_, ref seq), _) => { | |
1081 | seq.tts[index].clone() | |
1082 | } | |
1083 | _ => panic!("Cannot expand a token tree") | |
1084 | } | |
1085 | } | |
1086 | ||
1087 | /// Returns the `Span` corresponding to this token tree. | |
1088 | pub fn get_span(&self) -> Span { | |
1089 | match *self { | |
1090 | TtToken(span, _) => span, | |
1091 | TtDelimited(span, _) => span, | |
1092 | TtSequence(span, _) => span, | |
970d7e83 LB |
1093 | } |
1094 | } | |
c34b1796 AL |
1095 | |
1096 | /// Use this token tree as a matcher to parse given tts. | |
1097 | pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree]) | |
1098 | -> macro_parser::NamedParseResult { | |
1099 | // `None` is because we're not interpolating | |
1100 | let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic, | |
1101 | None, | |
1102 | None, | |
1103 | tts.iter().cloned().collect(), | |
1104 | true); | |
1105 | macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch) | |
1106 | } | |
970d7e83 LB |
1107 | } |
1108 | ||
1a4d82fc | 1109 | pub type Mac = Spanned<Mac_>; |
223e47cc | 1110 | |
1a4d82fc JJ |
1111 | /// Represents a macro invocation. The Path indicates which macro |
1112 | /// is being invoked, and the vector of token-trees contains the source | |
1113 | /// of the macro invocation. | |
c34b1796 | 1114 | /// |
1a4d82fc | 1115 | /// There's only one flavor, now, so this could presumably be simplified. |
85aaf69f | 1116 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1117 | pub enum Mac_ { |
1118 | // NB: the additional ident for a macro_rules-style macro is actually | |
1119 | // stored in the enclosing item. Oog. | |
85aaf69f | 1120 | MacInvocTT(Path, Vec<TokenTree>, SyntaxContext), // new macro-invocation |
1a4d82fc | 1121 | } |
223e47cc | 1122 | |
85aaf69f | 1123 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc | 1124 | pub enum StrStyle { |
c34b1796 | 1125 | /// A regular string, like `"foo"` |
1a4d82fc | 1126 | CookedStr, |
c34b1796 AL |
1127 | /// A raw string, like `r##"foo"##` |
1128 | /// | |
1129 | /// The uint is the number of `#` symbols used | |
85aaf69f | 1130 | RawStr(usize) |
223e47cc LB |
1131 | } |
1132 | ||
c34b1796 | 1133 | /// A literal |
1a4d82fc | 1134 | pub type Lit = Spanned<Lit_>; |
223e47cc | 1135 | |
85aaf69f | 1136 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1137 | pub enum Sign { |
1138 | Minus, | |
1139 | Plus | |
223e47cc LB |
1140 | } |
1141 | ||
1a4d82fc | 1142 | impl Sign { |
9346a6ac AL |
1143 | pub fn new<T: IntSign>(n: T) -> Sign { |
1144 | n.sign() | |
1a4d82fc JJ |
1145 | } |
1146 | } | |
223e47cc | 1147 | |
9346a6ac AL |
1148 | pub trait IntSign { |
1149 | fn sign(&self) -> Sign; | |
1150 | } | |
1151 | macro_rules! doit { | |
1152 | ($($t:ident)*) => ($(impl IntSign for $t { | |
1153 | #[allow(unused_comparisons)] | |
1154 | fn sign(&self) -> Sign { | |
1155 | if *self < 0 {Minus} else {Plus} | |
1156 | } | |
1157 | })*) | |
1158 | } | |
1159 | doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } | |
1160 | ||
85aaf69f | 1161 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1162 | pub enum LitIntType { |
1163 | SignedIntLit(IntTy, Sign), | |
1164 | UnsignedIntLit(UintTy), | |
1165 | UnsuffixedIntLit(Sign) | |
223e47cc LB |
1166 | } |
1167 | ||
1a4d82fc | 1168 | impl LitIntType { |
85aaf69f | 1169 | pub fn suffix_len(&self) -> usize { |
1a4d82fc JJ |
1170 | match *self { |
1171 | UnsuffixedIntLit(_) => 0, | |
1172 | SignedIntLit(s, _) => s.suffix_len(), | |
1173 | UnsignedIntLit(u) => u.suffix_len() | |
1174 | } | |
1175 | } | |
1176 | } | |
223e47cc | 1177 | |
85aaf69f | 1178 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1179 | pub enum Lit_ { |
c34b1796 | 1180 | /// A string literal (`"foo"`) |
1a4d82fc | 1181 | LitStr(InternedString, StrStyle), |
c34b1796 | 1182 | /// A byte string (`b"foo"`) |
1a4d82fc | 1183 | LitBinary(Rc<Vec<u8>>), |
c34b1796 | 1184 | /// A byte char (`b'f'`) |
1a4d82fc | 1185 | LitByte(u8), |
c34b1796 | 1186 | /// A character literal (`'a'`) |
1a4d82fc | 1187 | LitChar(char), |
c34b1796 | 1188 | /// An integer literal (`1u8`) |
1a4d82fc | 1189 | LitInt(u64, LitIntType), |
c34b1796 | 1190 | /// A float literal (`1f64` or `1E10f64`) |
1a4d82fc | 1191 | LitFloat(InternedString, FloatTy), |
c34b1796 | 1192 | /// A float literal without a suffix (`1.0 or 1.0E10`) |
1a4d82fc | 1193 | LitFloatUnsuffixed(InternedString), |
c34b1796 | 1194 | /// A boolean literal |
1a4d82fc | 1195 | LitBool(bool), |
223e47cc LB |
1196 | } |
1197 | ||
1198 | // NB: If you change this, you'll probably want to change the corresponding | |
1199 | // type structure in middle/ty.rs as well. | |
85aaf69f | 1200 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1201 | pub struct MutTy { |
1202 | pub ty: P<Ty>, | |
1203 | pub mutbl: Mutability, | |
1204 | } | |
1205 | ||
85aaf69f | 1206 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1207 | pub struct TypeField { |
1208 | pub ident: Ident, | |
1209 | pub mt: MutTy, | |
1210 | pub span: Span, | |
1211 | } | |
1212 | ||
c34b1796 AL |
1213 | /// Represents a method's signature in a trait declaration, |
1214 | /// or in an implementation. | |
85aaf69f | 1215 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
c34b1796 | 1216 | pub struct MethodSig { |
1a4d82fc JJ |
1217 | pub unsafety: Unsafety, |
1218 | pub abi: Abi, | |
1219 | pub decl: P<FnDecl>, | |
1220 | pub generics: Generics, | |
1221 | pub explicit_self: ExplicitSelf, | |
1a4d82fc JJ |
1222 | } |
1223 | ||
1224 | /// Represents a method declaration in a trait declaration, possibly including | |
1225 | /// a default implementation A trait method is either required (meaning it | |
1226 | /// doesn't have an implementation, just a signature) or provided (meaning it | |
1227 | /// has a default implementation). | |
85aaf69f | 1228 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
c34b1796 AL |
1229 | pub struct TraitItem { |
1230 | pub id: NodeId, | |
1231 | pub ident: Ident, | |
1232 | pub attrs: Vec<Attribute>, | |
1233 | pub node: TraitItem_, | |
1234 | pub span: Span, | |
1a4d82fc JJ |
1235 | } |
1236 | ||
85aaf69f | 1237 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
c34b1796 AL |
1238 | pub enum TraitItem_ { |
1239 | MethodTraitItem(MethodSig, Option<P<Block>>), | |
1240 | TypeTraitItem(TyParamBounds, Option<P<Ty>>), | |
1a4d82fc JJ |
1241 | } |
1242 | ||
85aaf69f | 1243 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
c34b1796 | 1244 | pub struct ImplItem { |
1a4d82fc | 1245 | pub id: NodeId, |
1a4d82fc JJ |
1246 | pub ident: Ident, |
1247 | pub vis: Visibility, | |
1248 | pub attrs: Vec<Attribute>, | |
c34b1796 AL |
1249 | pub node: ImplItem_, |
1250 | pub span: Span, | |
1251 | } | |
1252 | ||
1253 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
1254 | pub enum ImplItem_ { | |
1255 | MethodImplItem(MethodSig, P<Block>), | |
1256 | TypeImplItem(P<Ty>), | |
1257 | MacImplItem(Mac), | |
1a4d82fc JJ |
1258 | } |
1259 | ||
c34b1796 | 1260 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] |
1a4d82fc | 1261 | pub enum IntTy { |
c34b1796 | 1262 | TyIs, |
1a4d82fc JJ |
1263 | TyI8, |
1264 | TyI16, | |
1265 | TyI32, | |
1266 | TyI64, | |
1267 | } | |
1268 | ||
85aaf69f | 1269 | impl fmt::Debug for IntTy { |
1a4d82fc | 1270 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 1271 | fmt::Display::fmt(self, f) |
1a4d82fc | 1272 | } |
223e47cc LB |
1273 | } |
1274 | ||
85aaf69f | 1275 | impl fmt::Display for IntTy { |
1a4d82fc JJ |
1276 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1277 | write!(f, "{}", ast_util::int_ty_to_string(*self, None)) | |
1278 | } | |
1279 | } | |
223e47cc | 1280 | |
1a4d82fc | 1281 | impl IntTy { |
85aaf69f | 1282 | pub fn suffix_len(&self) -> usize { |
1a4d82fc | 1283 | match *self { |
c34b1796 | 1284 | TyIs | TyI8 => 2, |
1a4d82fc JJ |
1285 | TyI16 | TyI32 | TyI64 => 3, |
1286 | } | |
1287 | } | |
223e47cc LB |
1288 | } |
1289 | ||
c34b1796 | 1290 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] |
1a4d82fc | 1291 | pub enum UintTy { |
c34b1796 | 1292 | TyUs, |
1a4d82fc JJ |
1293 | TyU8, |
1294 | TyU16, | |
1295 | TyU32, | |
1296 | TyU64, | |
1297 | } | |
1298 | ||
1a4d82fc | 1299 | impl UintTy { |
85aaf69f | 1300 | pub fn suffix_len(&self) -> usize { |
1a4d82fc | 1301 | match *self { |
c34b1796 | 1302 | TyUs | TyU8 => 2, |
1a4d82fc JJ |
1303 | TyU16 | TyU32 | TyU64 => 3, |
1304 | } | |
1305 | } | |
1306 | } | |
223e47cc | 1307 | |
85aaf69f | 1308 | impl fmt::Debug for UintTy { |
1a4d82fc | 1309 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 1310 | fmt::Display::fmt(self, f) |
223e47cc LB |
1311 | } |
1312 | } | |
1313 | ||
85aaf69f | 1314 | impl fmt::Display for UintTy { |
1a4d82fc JJ |
1315 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1316 | write!(f, "{}", ast_util::uint_ty_to_string(*self, None)) | |
1317 | } | |
1318 | } | |
1319 | ||
1320 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] | |
1321 | pub enum FloatTy { | |
1322 | TyF32, | |
1323 | TyF64, | |
1324 | } | |
223e47cc | 1325 | |
85aaf69f | 1326 | impl fmt::Debug for FloatTy { |
1a4d82fc | 1327 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 1328 | fmt::Display::fmt(self, f) |
223e47cc LB |
1329 | } |
1330 | } | |
1331 | ||
85aaf69f | 1332 | impl fmt::Display for FloatTy { |
1a4d82fc JJ |
1333 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1334 | write!(f, "{}", ast_util::float_ty_to_string(*self)) | |
1335 | } | |
1336 | } | |
223e47cc | 1337 | |
1a4d82fc | 1338 | impl FloatTy { |
85aaf69f | 1339 | pub fn suffix_len(&self) -> usize { |
1a4d82fc JJ |
1340 | match *self { |
1341 | TyF32 | TyF64 => 3, // add F128 handling here | |
1342 | } | |
223e47cc LB |
1343 | } |
1344 | } | |
1345 | ||
1a4d82fc | 1346 | // Bind a type to an associated type: `A=Foo`. |
85aaf69f | 1347 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1348 | pub struct TypeBinding { |
1349 | pub id: NodeId, | |
1350 | pub ident: Ident, | |
1351 | pub ty: P<Ty>, | |
1352 | pub span: Span, | |
1353 | } | |
1354 | ||
1355 | ||
1356 | // NB PartialEq method appears below. | |
85aaf69f | 1357 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
223e47cc | 1358 | pub struct Ty { |
1a4d82fc JJ |
1359 | pub id: NodeId, |
1360 | pub node: Ty_, | |
1361 | pub span: Span, | |
223e47cc LB |
1362 | } |
1363 | ||
1a4d82fc | 1364 | /// Not represented directly in the AST, referred to by name through a ty_path. |
85aaf69f | 1365 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1366 | pub enum PrimTy { |
1367 | TyInt(IntTy), | |
1368 | TyUint(UintTy), | |
1369 | TyFloat(FloatTy), | |
1370 | TyStr, | |
1371 | TyBool, | |
1372 | TyChar | |
223e47cc LB |
1373 | } |
1374 | ||
85aaf69f | 1375 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1376 | pub struct BareFnTy { |
1377 | pub unsafety: Unsafety, | |
1378 | pub abi: Abi, | |
1379 | pub lifetimes: Vec<LifetimeDef>, | |
1380 | pub decl: P<FnDecl> | |
1381 | } | |
1382 | ||
85aaf69f | 1383 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1384 | /// The different kinds of types recognized by the compiler |
1385 | pub enum Ty_ { | |
1386 | TyVec(P<Ty>), | |
c34b1796 | 1387 | /// A fixed length array (`[T; n]`) |
1a4d82fc JJ |
1388 | TyFixedLengthVec(P<Ty>, P<Expr>), |
1389 | /// A raw pointer (`*const T` or `*mut T`) | |
1390 | TyPtr(MutTy), | |
1391 | /// A reference (`&'a T` or `&'a mut T`) | |
1392 | TyRptr(Option<Lifetime>, MutTy), | |
85aaf69f | 1393 | /// A bare function (e.g. `fn(usize) -> bool`) |
1a4d82fc JJ |
1394 | TyBareFn(P<BareFnTy>), |
1395 | /// A tuple (`(A, B, C, D,...)`) | |
1396 | TyTup(Vec<P<Ty>> ), | |
c34b1796 AL |
1397 | /// A path (`module::module::...::Type`), optionally |
1398 | /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`. | |
1a4d82fc JJ |
1399 | /// |
1400 | /// Type parameters are stored in the Path itself | |
c34b1796 | 1401 | TyPath(Option<QSelf>, Path), |
1a4d82fc JJ |
1402 | /// Something like `A+B`. Note that `B` must always be a path. |
1403 | TyObjectSum(P<Ty>, TyParamBounds), | |
1404 | /// A type like `for<'a> Foo<&'a Bar>` | |
1405 | TyPolyTraitRef(TyParamBounds), | |
1a4d82fc JJ |
1406 | /// No-op; kept solely so that we can pretty-print faithfully |
1407 | TyParen(P<Ty>), | |
1408 | /// Unused for now | |
1409 | TyTypeof(P<Expr>), | |
1410 | /// TyInfer means the type should be inferred instead of it having been | |
1411 | /// specified. This can appear anywhere in a type. | |
1412 | TyInfer, | |
1413 | } | |
1414 | ||
85aaf69f | 1415 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1416 | pub enum AsmDialect { |
1417 | AsmAtt, | |
1418 | AsmIntel | |
1419 | } | |
1420 | ||
85aaf69f | 1421 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1422 | pub struct InlineAsm { |
1423 | pub asm: InternedString, | |
1424 | pub asm_str_style: StrStyle, | |
1425 | pub outputs: Vec<(InternedString, P<Expr>, bool)>, | |
1426 | pub inputs: Vec<(InternedString, P<Expr>)>, | |
1427 | pub clobbers: Vec<InternedString>, | |
1428 | pub volatile: bool, | |
1429 | pub alignstack: bool, | |
1430 | pub dialect: AsmDialect, | |
1431 | pub expn_id: ExpnId, | |
1432 | } | |
1433 | ||
1434 | /// represents an argument in a function header | |
85aaf69f | 1435 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1436 | pub struct Arg { |
1437 | pub ty: P<Ty>, | |
1438 | pub pat: P<Pat>, | |
1439 | pub id: NodeId, | |
1440 | } | |
1441 | ||
1442 | impl Arg { | |
1443 | pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { | |
1444 | let path = Spanned{span:span,node:self_ident}; | |
1445 | Arg { | |
1446 | // HACK(eddyb) fake type for the self argument. | |
1447 | ty: P(Ty { | |
1448 | id: DUMMY_NODE_ID, | |
1449 | node: TyInfer, | |
1450 | span: DUMMY_SP, | |
1451 | }), | |
1452 | pat: P(Pat { | |
1453 | id: DUMMY_NODE_ID, | |
1454 | node: PatIdent(BindByValue(mutability), path, None), | |
1455 | span: span | |
1456 | }), | |
1457 | id: DUMMY_NODE_ID | |
223e47cc LB |
1458 | } |
1459 | } | |
1460 | } | |
1461 | ||
c34b1796 | 1462 | /// Represents the header (not the body) of a function declaration |
85aaf69f | 1463 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1464 | pub struct FnDecl { |
1465 | pub inputs: Vec<Arg>, | |
1466 | pub output: FunctionRetTy, | |
1467 | pub variadic: bool | |
1468 | } | |
1469 | ||
85aaf69f | 1470 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1471 | pub enum Unsafety { |
1472 | Unsafe, | |
1473 | Normal, | |
1474 | } | |
1475 | ||
85aaf69f | 1476 | impl fmt::Display for Unsafety { |
1a4d82fc | 1477 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 1478 | fmt::Display::fmt(match *self { |
1a4d82fc JJ |
1479 | Unsafety::Normal => "normal", |
1480 | Unsafety::Unsafe => "unsafe", | |
1481 | }, f) | |
1482 | } | |
1483 | } | |
1484 | ||
1485 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] | |
1486 | pub enum ImplPolarity { | |
c34b1796 | 1487 | /// `impl Trait for Type` |
1a4d82fc | 1488 | Positive, |
c34b1796 | 1489 | /// `impl !Trait for Type` |
1a4d82fc JJ |
1490 | Negative, |
1491 | } | |
1492 | ||
85aaf69f | 1493 | impl fmt::Debug for ImplPolarity { |
1a4d82fc | 1494 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
223e47cc | 1495 | match *self { |
1a4d82fc JJ |
1496 | ImplPolarity::Positive => "positive".fmt(f), |
1497 | ImplPolarity::Negative => "negative".fmt(f), | |
223e47cc LB |
1498 | } |
1499 | } | |
1500 | } | |
1501 | ||
1a4d82fc | 1502 | |
85aaf69f | 1503 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1504 | pub enum FunctionRetTy { |
c34b1796 | 1505 | /// Functions with return type `!`that always |
1a4d82fc JJ |
1506 | /// raise an error or exit (i.e. never return to the caller) |
1507 | NoReturn(Span), | |
c34b1796 AL |
1508 | /// Return type is not specified. |
1509 | /// | |
1510 | /// Functions default to `()` and | |
85aaf69f SL |
1511 | /// closures default to inference. Span points to where return |
1512 | /// type would be inserted. | |
1513 | DefaultReturn(Span), | |
1a4d82fc JJ |
1514 | /// Everything else |
1515 | Return(P<Ty>), | |
1516 | } | |
1517 | ||
1518 | impl FunctionRetTy { | |
1519 | pub fn span(&self) -> Span { | |
1520 | match *self { | |
1521 | NoReturn(span) => span, | |
85aaf69f | 1522 | DefaultReturn(span) => span, |
1a4d82fc JJ |
1523 | Return(ref ty) => ty.span |
1524 | } | |
1525 | } | |
223e47cc LB |
1526 | } |
1527 | ||
1a4d82fc | 1528 | /// Represents the kind of 'self' associated with a method |
85aaf69f | 1529 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1530 | pub enum ExplicitSelf_ { |
1531 | /// No self | |
1532 | SelfStatic, | |
1533 | /// `self` | |
1534 | SelfValue(Ident), | |
1535 | /// `&'lt self`, `&'lt mut self` | |
1536 | SelfRegion(Option<Lifetime>, Mutability, Ident), | |
1537 | /// `self: TYPE` | |
1538 | SelfExplicit(P<Ty>, Ident), | |
223e47cc LB |
1539 | } |
1540 | ||
1a4d82fc | 1541 | pub type ExplicitSelf = Spanned<ExplicitSelf_>; |
223e47cc | 1542 | |
85aaf69f | 1543 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1544 | pub struct Mod { |
1545 | /// A span from the first token past `{` to the last token until `}`. | |
1546 | /// For `mod foo;`, the inner span ranges from the first token | |
1547 | /// to the last token in the external file. | |
1548 | pub inner: Span, | |
1a4d82fc JJ |
1549 | pub items: Vec<P<Item>>, |
1550 | } | |
223e47cc | 1551 | |
85aaf69f | 1552 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1553 | pub struct ForeignMod { |
1554 | pub abi: Abi, | |
1a4d82fc | 1555 | pub items: Vec<P<ForeignItem>>, |
223e47cc LB |
1556 | } |
1557 | ||
85aaf69f | 1558 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1559 | pub struct VariantArg { |
1560 | pub ty: P<Ty>, | |
1561 | pub id: NodeId, | |
223e47cc LB |
1562 | } |
1563 | ||
85aaf69f | 1564 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1565 | pub enum VariantKind { |
c34b1796 | 1566 | /// Tuple variant, e.g. `Foo(A, B)` |
1a4d82fc | 1567 | TupleVariantKind(Vec<VariantArg>), |
c34b1796 | 1568 | /// Struct variant, e.g. `Foo {x: A, y: B}` |
1a4d82fc | 1569 | StructVariantKind(P<StructDef>), |
223e47cc LB |
1570 | } |
1571 | ||
85aaf69f | 1572 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1573 | pub struct EnumDef { |
1574 | pub variants: Vec<P<Variant>>, | |
223e47cc LB |
1575 | } |
1576 | ||
85aaf69f | 1577 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1578 | pub struct Variant_ { |
1579 | pub name: Ident, | |
1580 | pub attrs: Vec<Attribute>, | |
1581 | pub kind: VariantKind, | |
1582 | pub id: NodeId, | |
c34b1796 | 1583 | /// Explicit discriminant, eg `Foo = 1` |
1a4d82fc JJ |
1584 | pub disr_expr: Option<P<Expr>>, |
1585 | pub vis: Visibility, | |
223e47cc LB |
1586 | } |
1587 | ||
1a4d82fc | 1588 | pub type Variant = Spanned<Variant_>; |
223e47cc | 1589 | |
85aaf69f | 1590 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1591 | pub enum PathListItem_ { |
1592 | PathListIdent { name: Ident, id: NodeId }, | |
1593 | PathListMod { id: NodeId } | |
223e47cc LB |
1594 | } |
1595 | ||
1a4d82fc JJ |
1596 | impl PathListItem_ { |
1597 | pub fn id(&self) -> NodeId { | |
1598 | match *self { | |
1599 | PathListIdent { id, .. } | PathListMod { id } => id | |
1600 | } | |
1601 | } | |
1602 | } | |
223e47cc | 1603 | |
1a4d82fc | 1604 | pub type PathListItem = Spanned<PathListItem_>; |
223e47cc | 1605 | |
1a4d82fc | 1606 | pub type ViewPath = Spanned<ViewPath_>; |
223e47cc | 1607 | |
85aaf69f | 1608 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1609 | pub enum ViewPath_ { |
223e47cc | 1610 | |
1a4d82fc JJ |
1611 | /// `foo::bar::baz as quux` |
1612 | /// | |
1613 | /// or just | |
1614 | /// | |
1615 | /// `foo::bar::baz` (with `as baz` implicitly on the right) | |
85aaf69f | 1616 | ViewPathSimple(Ident, Path), |
223e47cc | 1617 | |
1a4d82fc | 1618 | /// `foo::bar::*` |
85aaf69f | 1619 | ViewPathGlob(Path), |
1a4d82fc JJ |
1620 | |
1621 | /// `foo::bar::{a,b,c}` | |
85aaf69f | 1622 | ViewPathList(Path, Vec<PathListItem>) |
223e47cc LB |
1623 | } |
1624 | ||
1a4d82fc JJ |
1625 | /// Meta-data associated with an item |
1626 | pub type Attribute = Spanned<Attribute_>; | |
223e47cc | 1627 | |
1a4d82fc JJ |
1628 | /// Distinguishes between Attributes that decorate items and Attributes that |
1629 | /// are contained as statements within items. These two cases need to be | |
1630 | /// distinguished for pretty-printing. | |
85aaf69f | 1631 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1632 | pub enum AttrStyle { |
1633 | AttrOuter, | |
1634 | AttrInner, | |
1635 | } | |
223e47cc | 1636 | |
85aaf69f SL |
1637 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1638 | pub struct AttrId(pub usize); | |
1a4d82fc JJ |
1639 | |
1640 | /// Doc-comments are promoted to attributes that have is_sugared_doc = true | |
85aaf69f | 1641 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1642 | pub struct Attribute_ { |
1643 | pub id: AttrId, | |
1644 | pub style: AttrStyle, | |
1645 | pub value: P<MetaItem>, | |
1646 | pub is_sugared_doc: bool, | |
223e47cc LB |
1647 | } |
1648 | ||
1a4d82fc | 1649 | /// TraitRef's appear in impls. |
c34b1796 | 1650 | /// |
1a4d82fc JJ |
1651 | /// resolve maps each TraitRef's ref_id to its defining trait; that's all |
1652 | /// that the ref_id is for. The impl_id maps to the "self type" of this impl. | |
1653 | /// If this impl is an ItemImpl, the impl_id is redundant (it could be the | |
1654 | /// same as the impl's node id). | |
85aaf69f | 1655 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1656 | pub struct TraitRef { |
1657 | pub path: Path, | |
1658 | pub ref_id: NodeId, | |
223e47cc LB |
1659 | } |
1660 | ||
85aaf69f | 1661 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1662 | pub struct PolyTraitRef { |
1663 | /// The `'a` in `<'a> Foo<&'a T>` | |
1664 | pub bound_lifetimes: Vec<LifetimeDef>, | |
223e47cc | 1665 | |
1a4d82fc JJ |
1666 | /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` |
1667 | pub trait_ref: TraitRef, | |
85aaf69f SL |
1668 | |
1669 | pub span: Span, | |
1a4d82fc JJ |
1670 | } |
1671 | ||
85aaf69f | 1672 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1673 | pub enum Visibility { |
1674 | Public, | |
1675 | Inherited, | |
1676 | } | |
1677 | ||
1678 | impl Visibility { | |
1679 | pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility { | |
970d7e83 | 1680 | match self { |
1a4d82fc JJ |
1681 | &Inherited => parent_visibility, |
1682 | &Public => *self | |
970d7e83 LB |
1683 | } |
1684 | } | |
1685 | } | |
1686 | ||
85aaf69f | 1687 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1688 | pub struct StructField_ { |
1689 | pub kind: StructFieldKind, | |
1690 | pub id: NodeId, | |
1691 | pub ty: P<Ty>, | |
1692 | pub attrs: Vec<Attribute>, | |
1693 | } | |
1694 | ||
1695 | impl StructField_ { | |
1696 | pub fn ident(&self) -> Option<Ident> { | |
1697 | match self.kind { | |
1698 | NamedField(ref ident, _) => Some(ident.clone()), | |
1699 | UnnamedField(_) => None | |
1700 | } | |
1701 | } | |
223e47cc LB |
1702 | } |
1703 | ||
1a4d82fc | 1704 | pub type StructField = Spanned<StructField_>; |
223e47cc | 1705 | |
85aaf69f | 1706 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] |
1a4d82fc JJ |
1707 | pub enum StructFieldKind { |
1708 | NamedField(Ident, Visibility), | |
1709 | /// Element of a tuple-like struct | |
1710 | UnnamedField(Visibility), | |
223e47cc LB |
1711 | } |
1712 | ||
1a4d82fc JJ |
1713 | impl StructFieldKind { |
1714 | pub fn is_unnamed(&self) -> bool { | |
1715 | match *self { | |
1716 | UnnamedField(..) => true, | |
1717 | NamedField(..) => false, | |
1718 | } | |
1719 | } | |
1720 | } | |
1721 | ||
85aaf69f | 1722 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1723 | pub struct StructDef { |
1724 | /// Fields, not including ctor | |
1725 | pub fields: Vec<StructField>, | |
1726 | /// ID of the constructor. This is only used for tuple- or enum-like | |
1727 | /// structs. | |
1728 | pub ctor_id: Option<NodeId>, | |
223e47cc LB |
1729 | } |
1730 | ||
1731 | /* | |
1732 | FIXME (#3300): Should allow items to be anonymous. Right now | |
1733 | we just use dummy names for anon items. | |
1734 | */ | |
c34b1796 AL |
1735 | /// An item |
1736 | /// | |
1737 | /// The name might be a dummy name in case of anonymous items | |
85aaf69f | 1738 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1739 | pub struct Item { |
1740 | pub ident: Ident, | |
1741 | pub attrs: Vec<Attribute>, | |
1742 | pub id: NodeId, | |
1743 | pub node: Item_, | |
1744 | pub vis: Visibility, | |
1745 | pub span: Span, | |
1746 | } | |
1747 | ||
85aaf69f | 1748 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1749 | pub enum Item_ { |
c34b1796 AL |
1750 | /// An`extern crate` item, with optional original crate name, |
1751 | /// | |
1752 | /// e.g. `extern crate foo` or `extern crate foo_bar as foo` | |
1753 | ItemExternCrate(Option<Name>), | |
1754 | /// A `use` or `pub use` item | |
85aaf69f SL |
1755 | ItemUse(P<ViewPath>), |
1756 | ||
c34b1796 | 1757 | /// A `static` item |
1a4d82fc | 1758 | ItemStatic(P<Ty>, Mutability, P<Expr>), |
c34b1796 | 1759 | /// A `const` item |
1a4d82fc | 1760 | ItemConst(P<Ty>, P<Expr>), |
c34b1796 | 1761 | /// A function declaration |
1a4d82fc | 1762 | ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>), |
c34b1796 | 1763 | /// A module |
1a4d82fc | 1764 | ItemMod(Mod), |
c34b1796 | 1765 | /// An external module |
1a4d82fc | 1766 | ItemForeignMod(ForeignMod), |
c34b1796 | 1767 | /// A type alias, e.g. `type Foo = Bar<u8>` |
1a4d82fc | 1768 | ItemTy(P<Ty>, Generics), |
c34b1796 | 1769 | /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}` |
1a4d82fc | 1770 | ItemEnum(EnumDef, Generics), |
c34b1796 | 1771 | /// A struct definition, e.g. `struct Foo<A> {x: A}` |
1a4d82fc JJ |
1772 | ItemStruct(P<StructDef>, Generics), |
1773 | /// Represents a Trait Declaration | |
1774 | ItemTrait(Unsafety, | |
1775 | Generics, | |
1776 | TyParamBounds, | |
c34b1796 AL |
1777 | Vec<P<TraitItem>>), |
1778 | ||
1779 | // Default trait implementations | |
1780 | /// | |
1781 | // `impl Trait for .. {}` | |
1782 | ItemDefaultImpl(Unsafety, TraitRef), | |
1783 | /// An implementation, eg `impl<A> Trait for Foo { .. }` | |
1a4d82fc JJ |
1784 | ItemImpl(Unsafety, |
1785 | ImplPolarity, | |
1786 | Generics, | |
1787 | Option<TraitRef>, // (optional) trait this impl implements | |
1788 | P<Ty>, // self | |
c34b1796 | 1789 | Vec<P<ImplItem>>), |
1a4d82fc JJ |
1790 | /// A macro invocation (which includes macro definition) |
1791 | ItemMac(Mac), | |
1792 | } | |
1793 | ||
1794 | impl Item_ { | |
1795 | pub fn descriptive_variant(&self) -> &str { | |
1796 | match *self { | |
85aaf69f SL |
1797 | ItemExternCrate(..) => "extern crate", |
1798 | ItemUse(..) => "use", | |
1a4d82fc JJ |
1799 | ItemStatic(..) => "static item", |
1800 | ItemConst(..) => "constant item", | |
1801 | ItemFn(..) => "function", | |
1802 | ItemMod(..) => "module", | |
1803 | ItemForeignMod(..) => "foreign module", | |
1804 | ItemTy(..) => "type alias", | |
1805 | ItemEnum(..) => "enum", | |
1806 | ItemStruct(..) => "struct", | |
1807 | ItemTrait(..) => "trait", | |
1808 | ItemMac(..) | | |
c34b1796 AL |
1809 | ItemImpl(..) | |
1810 | ItemDefaultImpl(..) => "item" | |
1a4d82fc | 1811 | } |
970d7e83 | 1812 | } |
1a4d82fc | 1813 | } |
970d7e83 | 1814 | |
85aaf69f | 1815 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1816 | pub struct ForeignItem { |
1817 | pub ident: Ident, | |
1818 | pub attrs: Vec<Attribute>, | |
1819 | pub node: ForeignItem_, | |
1820 | pub id: NodeId, | |
1821 | pub span: Span, | |
1822 | pub vis: Visibility, | |
1823 | } | |
970d7e83 | 1824 | |
c34b1796 | 1825 | /// An item within an `extern` block |
85aaf69f | 1826 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc | 1827 | pub enum ForeignItem_ { |
c34b1796 | 1828 | /// A foreign function |
1a4d82fc | 1829 | ForeignItemFn(P<FnDecl>, Generics), |
c34b1796 AL |
1830 | /// A foreign static item (`static ext: u8`), with optional mutability |
1831 | /// (the boolean is true when mutable) | |
1832 | ForeignItemStatic(P<Ty>, bool), | |
1a4d82fc | 1833 | } |
970d7e83 | 1834 | |
1a4d82fc JJ |
1835 | impl ForeignItem_ { |
1836 | pub fn descriptive_variant(&self) -> &str { | |
1837 | match *self { | |
1838 | ForeignItemFn(..) => "foreign function", | |
1839 | ForeignItemStatic(..) => "foreign static item" | |
1840 | } | |
223e47cc | 1841 | } |
1a4d82fc | 1842 | } |
970d7e83 | 1843 | |
1a4d82fc JJ |
1844 | /// The data we save and restore about an inlined item or method. This is not |
1845 | /// part of the AST that we parse from a file, but it becomes part of the tree | |
1846 | /// that we trans. | |
85aaf69f | 1847 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1848 | pub enum InlinedItem { |
1849 | IIItem(P<Item>), | |
c34b1796 AL |
1850 | IITraitItem(DefId /* impl id */, P<TraitItem>), |
1851 | IIImplItem(DefId /* impl id */, P<ImplItem>), | |
1a4d82fc | 1852 | IIForeign(P<ForeignItem>), |
223e47cc | 1853 | } |
970d7e83 | 1854 | |
1a4d82fc JJ |
1855 | /// A macro definition, in this crate or imported from another. |
1856 | /// | |
1857 | /// Not parsed directly, but created on macro import or `macro_rules!` expansion. | |
85aaf69f | 1858 | #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] |
1a4d82fc JJ |
1859 | pub struct MacroDef { |
1860 | pub ident: Ident, | |
1861 | pub attrs: Vec<Attribute>, | |
1862 | pub id: NodeId, | |
1863 | pub span: Span, | |
1864 | pub imported_from: Option<Ident>, | |
1865 | pub export: bool, | |
1866 | pub use_locally: bool, | |
c34b1796 | 1867 | pub allow_internal_unstable: bool, |
1a4d82fc JJ |
1868 | pub body: Vec<TokenTree>, |
1869 | } | |
1870 | ||
1871 | #[cfg(test)] | |
1872 | mod test { | |
1873 | use serialize; | |
1874 | use super::*; | |
1875 | ||
1876 | // are ASTs encodable? | |
1877 | #[test] | |
1878 | fn check_asts_encodable() { | |
1879 | fn assert_encodable<T: serialize::Encodable>() {} | |
1880 | assert_encodable::<Crate>(); | |
1881 | } | |
1882 | } |