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