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