]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | //! The Rust abstract syntax tree module. |
2 | //! | |
3 | //! This module contains common structures forming the language AST. | |
4 | //! Two main entities in the module are [`Item`] (which represents an AST element with | |
5 | //! additional metadata), and [`ItemKind`] (which represents a concrete type and contains | |
6 | //! information specific to the type of the item). | |
7 | //! | |
8 | //! Other module items that worth mentioning: | |
9 | //! - [`Ty`] and [`TyKind`]: A parsed Rust type. | |
10 | //! - [`Expr`] and [`ExprKind`]: A parsed Rust expression. | |
11 | //! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions. | |
12 | //! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value. | |
13 | //! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration. | |
14 | //! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters. | |
15 | //! - [`EnumDef`] and [`Variant`]: Enum declaration. | |
16 | //! - [`Lit`] and [`LitKind`]: Literal expressions. | |
17 | //! - [`MacroDef`], [`MacStmtStyle`], [`Mac`], [`MacDelimeter`]: Macro definition and invocation. | |
18 | //! - [`Attribute`]: Metadata associated with item. | |
19 | //! - [`UnOp`], [`UnOpKind`], [`BinOp`], [`BinOpKind`]: Unary and binary operators. | |
223e47cc | 20 | |
dfeec247 | 21 | pub use crate::util::parser::ExprPrecedence; |
9fa01778 XL |
22 | pub use GenericArgs::*; |
23 | pub use UnsafeSource::*; | |
9fa01778 | 24 | |
dfeec247 | 25 | pub use rustc_span::symbol::{Ident, Symbol as Name}; |
e74abb32 | 26 | |
9fa01778 | 27 | use crate::ptr::P; |
60c5eb7d | 28 | use crate::token::{self, DelimToken}; |
dfeec247 | 29 | use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; |
1a4d82fc | 30 | |
60c5eb7d | 31 | use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; |
0531ce1d | 32 | use rustc_data_structures::sync::Lrc; |
e74abb32 XL |
33 | use rustc_data_structures::thin_vec::ThinVec; |
34 | use rustc_index::vec::Idx; | |
60c5eb7d | 35 | use rustc_macros::HashStable_Generic; |
dfeec247 | 36 | use rustc_serialize::{self, Decoder, Encoder}; |
74b04a01 | 37 | use rustc_span::source_map::{respan, Spanned}; |
dfeec247 XL |
38 | use rustc_span::symbol::{kw, sym, Symbol}; |
39 | use rustc_span::{Span, DUMMY_SP}; | |
e74abb32 | 40 | |
74b04a01 | 41 | use std::convert::TryFrom; |
e74abb32 | 42 | use std::fmt; |
dfeec247 | 43 | use std::iter; |
94b46f34 | 44 | |
416331ca XL |
45 | #[cfg(test)] |
46 | mod tests; | |
47 | ||
e74abb32 XL |
48 | /// A "Label" is an identifier of some point in sources, |
49 | /// e.g. in the following code: | |
50 | /// | |
51 | /// ```rust | |
52 | /// 'outer: loop { | |
53 | /// break 'outer; | |
54 | /// } | |
55 | /// ``` | |
56 | /// | |
57 | /// `'outer` is a label. | |
60c5eb7d | 58 | #[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable_Generic)] |
2c00a5a8 XL |
59 | pub struct Label { |
60 | pub ident: Ident, | |
2c00a5a8 XL |
61 | } |
62 | ||
63 | impl fmt::Debug for Label { | |
9fa01778 | 64 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2c00a5a8 XL |
65 | write!(f, "label({:?})", self.ident) |
66 | } | |
67 | } | |
68 | ||
e74abb32 XL |
69 | /// A "Lifetime" is an annotation of the scope in which variable |
70 | /// can be used, e.g. `'a` in `&'a i32`. | |
8faf50e0 | 71 | #[derive(Clone, RustcEncodable, RustcDecodable, Copy)] |
223e47cc | 72 | pub struct Lifetime { |
1a4d82fc | 73 | pub id: NodeId, |
7cac9316 | 74 | pub ident: Ident, |
1a4d82fc JJ |
75 | } |
76 | ||
62682a34 | 77 | impl fmt::Debug for Lifetime { |
9fa01778 | 78 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
dfeec247 | 79 | write!(f, "lifetime({}: {})", self.id, self) |
62682a34 SL |
80 | } |
81 | } | |
82 | ||
416331ca XL |
83 | impl fmt::Display for Lifetime { |
84 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
60c5eb7d | 85 | write!(f, "{}", self.ident.name) |
416331ca XL |
86 | } |
87 | } | |
88 | ||
3157f602 XL |
89 | /// A "Path" is essentially Rust's notion of a name. |
90 | /// | |
91 | /// It's represented as a sequence of identifiers, | |
1a4d82fc | 92 | /// along with a bunch of supporting information. |
3157f602 | 93 | /// |
0731742a | 94 | /// E.g., `std::cmp::PartialEq`. |
e74abb32 | 95 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
970d7e83 | 96 | pub struct Path { |
1a4d82fc | 97 | pub span: Span, |
1a4d82fc | 98 | /// The segments in the path: the things separated by `::`. |
dc9dc135 | 99 | /// Global paths begin with `kw::PathRoot`. |
1a4d82fc JJ |
100 | pub segments: Vec<PathSegment>, |
101 | } | |
102 | ||
48663c56 XL |
103 | impl PartialEq<Symbol> for Path { |
104 | fn eq(&self, symbol: &Symbol) -> bool { | |
dfeec247 | 105 | self.segments.len() == 1 && { self.segments[0].ident.name == *symbol } |
cc61c64b XL |
106 | } |
107 | } | |
108 | ||
60c5eb7d XL |
109 | impl<CTX> HashStable<CTX> for Path { |
110 | fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { | |
111 | self.segments.len().hash_stable(hcx, hasher); | |
112 | for segment in &self.segments { | |
113 | segment.ident.name.hash_stable(hcx, hasher); | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
54a0048b | 118 | impl Path { |
0731742a XL |
119 | // Convert a span and an identifier to the corresponding |
120 | // one-segment path. | |
83c7162d | 121 | pub fn from_ident(ident: Ident) -> Path { |
dfeec247 | 122 | Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span } |
54a0048b | 123 | } |
32a655c1 | 124 | |
32a655c1 | 125 | pub fn is_global(&self) -> bool { |
dc9dc135 | 126 | !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot |
32a655c1 | 127 | } |
54a0048b SL |
128 | } |
129 | ||
3157f602 XL |
130 | /// A segment of a path: an identifier, an optional lifetime, and a set of types. |
131 | /// | |
0731742a | 132 | /// E.g., `std`, `String` or `Box<T>`. |
8faf50e0 | 133 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
134 | pub struct PathSegment { |
135 | /// The identifier portion of this path segment. | |
83c7162d | 136 | pub ident: Ident, |
1a4d82fc | 137 | |
13cf67c4 XL |
138 | pub id: NodeId, |
139 | ||
1a4d82fc | 140 | /// Type/lifetime parameters attached to this path. They come in |
3b2f2976 XL |
141 | /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. |
142 | /// `None` means that no parameter list is supplied (`Path`), | |
143 | /// `Some` means that parameter list is supplied (`Path<X, Y>`) | |
144 | /// but it can be empty (`Path<>`). | |
145 | /// `P` is used as a size optimization for the common case with no parameters. | |
8faf50e0 | 146 | pub args: Option<P<GenericArgs>>, |
32a655c1 SL |
147 | } |
148 | ||
32a655c1 | 149 | impl PathSegment { |
83c7162d | 150 | pub fn from_ident(ident: Ident) -> Self { |
13cf67c4 | 151 | PathSegment { ident, id: DUMMY_NODE_ID, args: None } |
8bb4bdeb | 152 | } |
0731742a | 153 | pub fn path_root(span: Span) -> Self { |
dc9dc135 | 154 | PathSegment::from_ident(Ident::new(kw::PathRoot, span)) |
32a655c1 | 155 | } |
1a4d82fc JJ |
156 | } |
157 | ||
9fa01778 | 158 | /// The arguments of a path segment. |
3157f602 | 159 | /// |
0731742a | 160 | /// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`. |
8faf50e0 XL |
161 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
162 | pub enum GenericArgs { | |
9fa01778 | 163 | /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`. |
8faf50e0 | 164 | AngleBracketed(AngleBracketedArgs), |
9fa01778 XL |
165 | /// The `(A, B)` and `C` in `Foo(A, B) -> C`. |
166 | Parenthesized(ParenthesizedArgs), | |
1a4d82fc JJ |
167 | } |
168 | ||
8faf50e0 | 169 | impl GenericArgs { |
9fa01778 XL |
170 | pub fn is_parenthesized(&self) -> bool { |
171 | match *self { | |
172 | Parenthesized(..) => true, | |
173 | _ => false, | |
174 | } | |
175 | } | |
176 | ||
177 | pub fn is_angle_bracketed(&self) -> bool { | |
178 | match *self { | |
179 | AngleBracketed(..) => true, | |
180 | _ => false, | |
181 | } | |
182 | } | |
183 | ||
3b2f2976 XL |
184 | pub fn span(&self) -> Span { |
185 | match *self { | |
186 | AngleBracketed(ref data) => data.span, | |
187 | Parenthesized(ref data) => data.span, | |
188 | } | |
189 | } | |
190 | } | |
191 | ||
e74abb32 | 192 | /// Concrete argument in the sequence of generic args. |
8faf50e0 XL |
193 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
194 | pub enum GenericArg { | |
e74abb32 | 195 | /// `'a` in `Foo<'a>` |
8faf50e0 | 196 | Lifetime(Lifetime), |
e74abb32 | 197 | /// `Bar` in `Foo<Bar>` |
8faf50e0 | 198 | Type(P<Ty>), |
e74abb32 | 199 | /// `1` in `Foo<1>` |
9fa01778 | 200 | Const(AnonConst), |
8faf50e0 XL |
201 | } |
202 | ||
9fa01778 XL |
203 | impl GenericArg { |
204 | pub fn span(&self) -> Span { | |
205 | match self { | |
206 | GenericArg::Lifetime(lt) => lt.ident.span, | |
207 | GenericArg::Type(ty) => ty.span, | |
208 | GenericArg::Const(ct) => ct.value.span, | |
209 | } | |
210 | } | |
211 | } | |
212 | ||
213 | /// A path like `Foo<'a, T>`. | |
8faf50e0 XL |
214 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] |
215 | pub struct AngleBracketedArgs { | |
9fa01778 | 216 | /// The overall span. |
3b2f2976 | 217 | pub span: Span, |
8faf50e0 XL |
218 | /// The arguments for this path segment. |
219 | pub args: Vec<GenericArg>, | |
dc9dc135 XL |
220 | /// Constraints on associated types, if any. |
221 | /// E.g., `Foo<A = Bar, B: Baz>`. | |
222 | pub constraints: Vec<AssocTyConstraint>, | |
223e47cc LB |
223 | } |
224 | ||
8faf50e0 XL |
225 | impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs { |
226 | fn into(self) -> Option<P<GenericArgs>> { | |
227 | Some(P(GenericArgs::AngleBracketed(self))) | |
3b2f2976 XL |
228 | } |
229 | } | |
230 | ||
9fa01778 | 231 | impl Into<Option<P<GenericArgs>>> for ParenthesizedArgs { |
8faf50e0 XL |
232 | fn into(self) -> Option<P<GenericArgs>> { |
233 | Some(P(GenericArgs::Parenthesized(self))) | |
1a4d82fc JJ |
234 | } |
235 | } | |
236 | ||
9fa01778 | 237 | /// A path like `Foo(A, B) -> C`. |
8faf50e0 | 238 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
9fa01778 | 239 | pub struct ParenthesizedArgs { |
85aaf69f SL |
240 | /// Overall span |
241 | pub span: Span, | |
242 | ||
dc9dc135 | 243 | /// `(A, B)` |
1a4d82fc JJ |
244 | pub inputs: Vec<P<Ty>>, |
245 | ||
246 | /// `C` | |
74b04a01 | 247 | pub output: FnRetTy, |
1a4d82fc JJ |
248 | } |
249 | ||
9fa01778 XL |
250 | impl ParenthesizedArgs { |
251 | pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { | |
252 | AngleBracketedArgs { | |
253 | span: self.span, | |
254 | args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(), | |
dc9dc135 | 255 | constraints: vec![], |
9fa01778 XL |
256 | } |
257 | } | |
258 | } | |
259 | ||
74b04a01 | 260 | pub use crate::node_id::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; |
1a4d82fc | 261 | |
dfeec247 XL |
262 | /// A modifier on a bound, e.g., `?Sized` or `?const Trait`. |
263 | /// | |
264 | /// Negative bounds should also be handled here. | |
8faf50e0 XL |
265 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] |
266 | pub enum TraitBoundModifier { | |
dfeec247 | 267 | /// No modifiers |
8faf50e0 | 268 | None, |
dfeec247 XL |
269 | |
270 | /// `?Trait` | |
8faf50e0 | 271 | Maybe, |
dfeec247 XL |
272 | |
273 | /// `?const Trait` | |
274 | MaybeConst, | |
275 | ||
276 | /// `?const ?Trait` | |
277 | // | |
278 | // This parses but will be rejected during AST validation. | |
279 | MaybeConstMaybe, | |
8faf50e0 XL |
280 | } |
281 | ||
1a4d82fc | 282 | /// The AST represents all type param bounds as types. |
a1dfa0c6 XL |
283 | /// `typeck::collect::compute_bounds` matches these against |
284 | /// the "special" built-in traits (see `middle::lang_items`) and | |
285 | /// detects `Copy`, `Send` and `Sync`. | |
8faf50e0 XL |
286 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
287 | pub enum GenericBound { | |
288 | Trait(PolyTraitRef, TraitBoundModifier), | |
0bf4aa26 | 289 | Outlives(Lifetime), |
223e47cc LB |
290 | } |
291 | ||
8faf50e0 | 292 | impl GenericBound { |
0531ce1d XL |
293 | pub fn span(&self) -> Span { |
294 | match self { | |
8faf50e0 XL |
295 | &GenericBound::Trait(ref t, ..) => t.span, |
296 | &GenericBound::Outlives(ref l) => l.ident.span, | |
0531ce1d XL |
297 | } |
298 | } | |
299 | } | |
300 | ||
8faf50e0 | 301 | pub type GenericBounds = Vec<GenericBound>; |
1a4d82fc | 302 | |
9fa01778 XL |
303 | /// Specifies the enforced ordering for generic parameters. In the future, |
304 | /// if we wanted to relax this order, we could override `PartialEq` and | |
305 | /// `PartialOrd`, to allow the kinds to be unordered. | |
306 | #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] | |
307 | pub enum ParamKindOrd { | |
308 | Lifetime, | |
309 | Type, | |
310 | Const, | |
311 | } | |
312 | ||
313 | impl fmt::Display for ParamKindOrd { | |
314 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
315 | match self { | |
316 | ParamKindOrd::Lifetime => "lifetime".fmt(f), | |
317 | ParamKindOrd::Type => "type".fmt(f), | |
318 | ParamKindOrd::Const => "const".fmt(f), | |
319 | } | |
320 | } | |
321 | } | |
322 | ||
8faf50e0 XL |
323 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
324 | pub enum GenericParamKind { | |
0731742a | 325 | /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). |
8faf50e0 | 326 | Lifetime, |
dfeec247 XL |
327 | Type { |
328 | default: Option<P<Ty>>, | |
329 | }, | |
330 | Const { | |
331 | ty: P<Ty>, | |
332 | }, | |
ff7c6d11 XL |
333 | } |
334 | ||
8faf50e0 XL |
335 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
336 | pub struct GenericParam { | |
337 | pub id: NodeId, | |
338 | pub ident: Ident, | |
dfeec247 | 339 | pub attrs: AttrVec, |
8faf50e0 | 340 | pub bounds: GenericBounds, |
e1599b0c | 341 | pub is_placeholder: bool, |
8faf50e0 | 342 | pub kind: GenericParamKind, |
ff7c6d11 XL |
343 | } |
344 | ||
345 | /// Represents lifetime, type and const parameters attached to a declaration of | |
346 | /// a function, enum, trait, etc. | |
8faf50e0 | 347 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
223e47cc | 348 | pub struct Generics { |
ff7c6d11 | 349 | pub params: Vec<GenericParam>, |
1a4d82fc | 350 | pub where_clause: WhereClause, |
9e0c209e | 351 | pub span: Span, |
223e47cc LB |
352 | } |
353 | ||
9cc50fc6 | 354 | impl Default for Generics { |
9e0c209e | 355 | /// Creates an instance of `Generics`. |
0bf4aa26 | 356 | fn default() -> Generics { |
9cc50fc6 | 357 | Generics { |
ff7c6d11 | 358 | params: Vec::new(), |
dfeec247 | 359 | where_clause: WhereClause { predicates: Vec::new(), span: DUMMY_SP }, |
9e0c209e | 360 | span: DUMMY_SP, |
9cc50fc6 SL |
361 | } |
362 | } | |
363 | } | |
364 | ||
9fa01778 | 365 | /// A where-clause in a definition. |
8faf50e0 | 366 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 367 | pub struct WhereClause { |
1a4d82fc | 368 | pub predicates: Vec<WherePredicate>, |
3b2f2976 | 369 | pub span: Span, |
223e47cc LB |
370 | } |
371 | ||
9fa01778 | 372 | /// A single predicate in a where-clause. |
8faf50e0 | 373 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 374 | pub enum WherePredicate { |
0731742a | 375 | /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). |
1a4d82fc | 376 | BoundPredicate(WhereBoundPredicate), |
0731742a | 377 | /// A lifetime predicate (e.g., `'a: 'b + 'c`). |
1a4d82fc | 378 | RegionPredicate(WhereRegionPredicate), |
0731742a | 379 | /// An equality predicate (unsupported). |
e9174d1e | 380 | EqPredicate(WhereEqPredicate), |
223e47cc LB |
381 | } |
382 | ||
0531ce1d XL |
383 | impl WherePredicate { |
384 | pub fn span(&self) -> Span { | |
385 | match self { | |
386 | &WherePredicate::BoundPredicate(ref p) => p.span, | |
387 | &WherePredicate::RegionPredicate(ref p) => p.span, | |
388 | &WherePredicate::EqPredicate(ref p) => p.span, | |
389 | } | |
390 | } | |
391 | } | |
392 | ||
3157f602 XL |
393 | /// A type bound. |
394 | /// | |
0731742a | 395 | /// E.g., `for<'c> Foo: Send + Clone + 'c`. |
8faf50e0 | 396 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
397 | pub struct WhereBoundPredicate { |
398 | pub span: Span, | |
e1599b0c | 399 | /// Any generics from a `for` binding. |
ff7c6d11 | 400 | pub bound_generic_params: Vec<GenericParam>, |
e1599b0c | 401 | /// The type being bounded. |
1a4d82fc | 402 | pub bounded_ty: P<Ty>, |
e1599b0c | 403 | /// Trait and lifetime bounds (`Clone + Send + 'static`). |
8faf50e0 | 404 | pub bounds: GenericBounds, |
223e47cc LB |
405 | } |
406 | ||
3157f602 XL |
407 | /// A lifetime predicate. |
408 | /// | |
0731742a | 409 | /// E.g., `'a: 'b + 'c`. |
8faf50e0 | 410 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
411 | pub struct WhereRegionPredicate { |
412 | pub span: Span, | |
413 | pub lifetime: Lifetime, | |
8faf50e0 | 414 | pub bounds: GenericBounds, |
1a4d82fc | 415 | } |
223e47cc | 416 | |
3157f602 XL |
417 | /// An equality predicate (unsupported). |
418 | /// | |
0731742a | 419 | /// E.g., `T = int`. |
8faf50e0 | 420 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
421 | pub struct WhereEqPredicate { |
422 | pub id: NodeId, | |
423 | pub span: Span, | |
32a655c1 SL |
424 | pub lhs_ty: P<Ty>, |
425 | pub rhs_ty: P<Ty>, | |
1a4d82fc JJ |
426 | } |
427 | ||
8faf50e0 | 428 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
429 | pub struct Crate { |
430 | pub module: Mod, | |
431 | pub attrs: Vec<Attribute>, | |
1a4d82fc | 432 | pub span: Span, |
74b04a01 XL |
433 | /// The order of items in the HIR is unrelated to the order of |
434 | /// items in the AST. However, we generate proc macro harnesses | |
435 | /// based on the AST order, and later refer to these harnesses | |
436 | /// from the HIR. This field keeps track of the order in which | |
437 | /// we generated proc macros harnesses, so that we can map | |
438 | /// HIR proc macros items back to their harness items. | |
439 | pub proc_macros: Vec<NodeId>, | |
970d7e83 | 440 | } |
223e47cc | 441 | |
9e0c209e SL |
442 | /// Possible values inside of compile-time attribute lists. |
443 | /// | |
0731742a | 444 | /// E.g., the '..' in `#[name(..)]`. |
60c5eb7d | 445 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
532ac7d7 | 446 | pub enum NestedMetaItem { |
9e0c209e | 447 | /// A full MetaItem, for recursive meta items. |
476ff2be | 448 | MetaItem(MetaItem), |
9e0c209e SL |
449 | /// A literal. |
450 | /// | |
0731742a | 451 | /// E.g., `"foo"`, `64`, `true`. |
9e0c209e SL |
452 | Literal(Lit), |
453 | } | |
454 | ||
3157f602 XL |
455 | /// A spanned compile-time attribute item. |
456 | /// | |
0731742a | 457 | /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. |
60c5eb7d | 458 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
476ff2be | 459 | pub struct MetaItem { |
532ac7d7 | 460 | pub path: Path, |
e74abb32 | 461 | pub kind: MetaItemKind, |
476ff2be SL |
462 | pub span: Span, |
463 | } | |
1a4d82fc | 464 | |
3157f602 XL |
465 | /// A compile-time attribute item. |
466 | /// | |
0731742a | 467 | /// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`. |
60c5eb7d | 468 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
7453a54e | 469 | pub enum MetaItemKind { |
3157f602 XL |
470 | /// Word meta item. |
471 | /// | |
0731742a | 472 | /// E.g., `test` as in `#[test]`. |
476ff2be | 473 | Word, |
3157f602 XL |
474 | /// List meta item. |
475 | /// | |
0731742a | 476 | /// E.g., `derive(..)` as in `#[derive(..)]`. |
476ff2be | 477 | List(Vec<NestedMetaItem>), |
3157f602 XL |
478 | /// Name value meta item. |
479 | /// | |
0731742a | 480 | /// E.g., `feature = "foo"` as in `#[feature = "foo"]`. |
0bf4aa26 | 481 | NameValue(Lit), |
223e47cc LB |
482 | } |
483 | ||
e1599b0c | 484 | /// A block (`{ .. }`). |
3157f602 | 485 | /// |
0731742a | 486 | /// E.g., `{ .. }` as in `fn foo() { .. }`. |
8faf50e0 | 487 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 488 | pub struct Block { |
e1599b0c | 489 | /// The statements in the block. |
7453a54e | 490 | pub stmts: Vec<Stmt>, |
1a4d82fc | 491 | pub id: NodeId, |
e1599b0c | 492 | /// Distinguishes between `unsafe { ... }` and `{ ... }`. |
1a4d82fc JJ |
493 | pub rules: BlockCheckMode, |
494 | pub span: Span, | |
495 | } | |
496 | ||
e74abb32 | 497 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
498 | pub struct Pat { |
499 | pub id: NodeId, | |
e74abb32 | 500 | pub kind: PatKind, |
1a4d82fc JJ |
501 | pub span: Span, |
502 | } | |
503 | ||
a7813a04 | 504 | impl Pat { |
416331ca XL |
505 | /// Attempt reparsing the pattern as a type. |
506 | /// This is intended for use by diagnostics. | |
60c5eb7d | 507 | pub fn to_ty(&self) -> Option<P<Ty>> { |
e74abb32 | 508 | let kind = match &self.kind { |
416331ca | 509 | // In a type expression `_` is an inference variable. |
ff7c6d11 | 510 | PatKind::Wild => TyKind::Infer, |
416331ca | 511 | // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. |
dfeec247 | 512 | PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => { |
0bf4aa26 XL |
513 | TyKind::Path(None, Path::from_ident(*ident)) |
514 | } | |
ff7c6d11 XL |
515 | PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), |
516 | PatKind::Mac(mac) => TyKind::Mac(mac.clone()), | |
416331ca | 517 | // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. |
dfeec247 XL |
518 | PatKind::Ref(pat, mutbl) => { |
519 | pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))? | |
520 | } | |
416331ca XL |
521 | // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, |
522 | // when `P` can be reparsed as a type `T`. | |
523 | PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?, | |
524 | // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)` | |
525 | // assuming `T0` to `Tn` are all syntactically valid as types. | |
526 | PatKind::Tuple(pats) => { | |
b7449926 XL |
527 | let mut tys = Vec::with_capacity(pats.len()); |
528 | // FIXME(#48994) - could just be collected into an Option<Vec> | |
529 | for pat in pats { | |
530 | tys.push(pat.to_ty()?); | |
531 | } | |
ff7c6d11 XL |
532 | TyKind::Tup(tys) |
533 | } | |
534 | _ => return None, | |
535 | }; | |
536 | ||
dfeec247 | 537 | Some(P(Ty { kind, id: self.id, span: self.span })) |
ff7c6d11 XL |
538 | } |
539 | ||
e1599b0c XL |
540 | /// Walk top-down and call `it` in each place where a pattern occurs |
541 | /// starting with the root pattern `walk` is called on. If `it` returns | |
542 | /// false then we will descend no further but siblings will be processed. | |
543 | pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) { | |
a7813a04 | 544 | if !it(self) { |
e1599b0c | 545 | return; |
a7813a04 XL |
546 | } |
547 | ||
e74abb32 XL |
548 | match &self.kind { |
549 | // Walk into the pattern associated with `Ident` (if any). | |
416331ca | 550 | PatKind::Ident(_, _, Some(p)) => p.walk(it), |
e74abb32 XL |
551 | |
552 | // Walk into each field of struct. | |
e1599b0c | 553 | PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)), |
e74abb32 XL |
554 | |
555 | // Sequence of patterns. | |
dfeec247 XL |
556 | PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => { |
557 | s.iter().for_each(|p| p.walk(it)) | |
558 | } | |
e74abb32 XL |
559 | |
560 | // Trivial wrappers over inner patterns. | |
dfeec247 | 561 | PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it), |
e74abb32 XL |
562 | |
563 | // These patterns do not contain subpatterns, skip. | |
0bf4aa26 | 564 | PatKind::Wild |
416331ca | 565 | | PatKind::Rest |
0bf4aa26 XL |
566 | | PatKind::Lit(_) |
567 | | PatKind::Range(..) | |
568 | | PatKind::Ident(..) | |
569 | | PatKind::Path(..) | |
dfeec247 | 570 | | PatKind::Mac(_) => {} |
a7813a04 XL |
571 | } |
572 | } | |
416331ca XL |
573 | |
574 | /// Is this a `..` pattern? | |
575 | pub fn is_rest(&self) -> bool { | |
e74abb32 | 576 | match self.kind { |
416331ca XL |
577 | PatKind::Rest => true, |
578 | _ => false, | |
579 | } | |
580 | } | |
a7813a04 XL |
581 | } |
582 | ||
c34b1796 AL |
583 | /// A single field in a struct pattern |
584 | /// | |
585 | /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` | |
586 | /// are treated the same as` x: x, y: ref y, z: ref mut z`, | |
587 | /// except is_shorthand is true | |
8faf50e0 | 588 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 589 | pub struct FieldPat { |
c34b1796 | 590 | /// The identifier for the field |
1a4d82fc | 591 | pub ident: Ident, |
c34b1796 | 592 | /// The pattern the field is destructured to |
1a4d82fc JJ |
593 | pub pat: P<Pat>, |
594 | pub is_shorthand: bool, | |
dfeec247 | 595 | pub attrs: AttrVec, |
e1599b0c XL |
596 | pub id: NodeId, |
597 | pub span: Span, | |
598 | pub is_placeholder: bool, | |
1a4d82fc JJ |
599 | } |
600 | ||
8faf50e0 | 601 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] |
1a4d82fc | 602 | pub enum BindingMode { |
9cc50fc6 SL |
603 | ByRef(Mutability), |
604 | ByValue(Mutability), | |
1a4d82fc JJ |
605 | } |
606 | ||
8faf50e0 | 607 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
32a655c1 | 608 | pub enum RangeEnd { |
ea8adc8c | 609 | Included(RangeSyntax), |
32a655c1 SL |
610 | Excluded, |
611 | } | |
612 | ||
8faf50e0 | 613 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
ea8adc8c | 614 | pub enum RangeSyntax { |
e74abb32 | 615 | /// `...` |
ea8adc8c | 616 | DotDotDot, |
e74abb32 | 617 | /// `..=` |
ea8adc8c XL |
618 | DotDotEq, |
619 | } | |
620 | ||
8faf50e0 | 621 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7453a54e | 622 | pub enum PatKind { |
0731742a | 623 | /// Represents a wildcard pattern (`_`). |
7453a54e | 624 | Wild, |
1a4d82fc | 625 | |
3157f602 XL |
626 | /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`), |
627 | /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third | |
628 | /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens | |
629 | /// during name resolution. | |
83c7162d | 630 | Ident(BindingMode, Ident, Option<P<Pat>>), |
1a4d82fc | 631 | |
0731742a | 632 | /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). |
7453a54e | 633 | /// The `bool` is `true` in the presence of a `..`. |
e1599b0c | 634 | Struct(Path, Vec<FieldPat>, /* recovered */ bool), |
7453a54e | 635 | |
0731742a | 636 | /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). |
416331ca | 637 | TupleStruct(Path, Vec<P<Pat>>), |
1a4d82fc | 638 | |
e1599b0c XL |
639 | /// An or-pattern `A | B | C`. |
640 | /// Invariant: `pats.len() >= 2`. | |
641 | Or(Vec<P<Pat>>), | |
642 | ||
3157f602 | 643 | /// A possibly qualified path pattern. |
3b2f2976 XL |
644 | /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants |
645 | /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can | |
3157f602 XL |
646 | /// only legally refer to associated constants. |
647 | Path(Option<QSelf>, Path), | |
d9579d0f | 648 | |
0731742a | 649 | /// A tuple pattern (`(a, b)`). |
416331ca | 650 | Tuple(Vec<P<Pat>>), |
9fa01778 | 651 | |
0731742a | 652 | /// A `box` pattern. |
7453a54e | 653 | Box(P<Pat>), |
9fa01778 | 654 | |
0731742a | 655 | /// A reference pattern (e.g., `&mut (a, b)`). |
7453a54e | 656 | Ref(P<Pat>, Mutability), |
9fa01778 | 657 | |
0731742a | 658 | /// A literal. |
7453a54e | 659 | Lit(P<Expr>), |
9fa01778 | 660 | |
0731742a | 661 | /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`). |
dfeec247 | 662 | Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>), |
9fa01778 | 663 | |
416331ca XL |
664 | /// A slice pattern `[a, b, c]`. |
665 | Slice(Vec<P<Pat>>), | |
666 | ||
667 | /// A rest pattern `..`. | |
668 | /// | |
669 | /// Syntactically it is valid anywhere. | |
670 | /// | |
671 | /// Semantically however, it only has meaning immediately inside: | |
672 | /// - a slice pattern: `[a, .., b]`, | |
673 | /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`, | |
674 | /// - a tuple pattern: `(a, .., b)`, | |
675 | /// - a tuple struct/variant pattern: `$path(a, .., b)`. | |
676 | /// | |
677 | /// In all of these cases, an additional restriction applies, | |
678 | /// only one rest pattern may occur in the pattern sequences. | |
679 | Rest, | |
9fa01778 | 680 | |
0731742a | 681 | /// Parentheses in patterns used for grouping (i.e., `(PAT)`). |
0531ce1d | 682 | Paren(P<Pat>), |
9fa01778 | 683 | |
0731742a | 684 | /// A macro pattern; pre-expansion. |
7453a54e | 685 | Mac(Mac), |
1a4d82fc JJ |
686 | } |
687 | ||
dfeec247 XL |
688 | #[derive( |
689 | Clone, | |
690 | PartialEq, | |
691 | Eq, | |
692 | PartialOrd, | |
693 | Ord, | |
694 | Hash, | |
695 | RustcEncodable, | |
696 | RustcDecodable, | |
697 | Debug, | |
698 | Copy, | |
699 | HashStable_Generic | |
700 | )] | |
1a4d82fc | 701 | pub enum Mutability { |
dfeec247 XL |
702 | Mut, |
703 | Not, | |
1a4d82fc JJ |
704 | } |
705 | ||
60c5eb7d XL |
706 | impl Mutability { |
707 | /// Returns `MutMutable` only if both `self` and `other` are mutable. | |
708 | pub fn and(self, other: Self) -> Self { | |
709 | match self { | |
dfeec247 XL |
710 | Mutability::Mut => other, |
711 | Mutability::Not => Mutability::Not, | |
60c5eb7d XL |
712 | } |
713 | } | |
714 | ||
715 | pub fn invert(self) -> Self { | |
716 | match self { | |
dfeec247 XL |
717 | Mutability::Mut => Mutability::Not, |
718 | Mutability::Not => Mutability::Mut, | |
60c5eb7d XL |
719 | } |
720 | } | |
721 | ||
722 | pub fn prefix_str(&self) -> &'static str { | |
723 | match self { | |
dfeec247 XL |
724 | Mutability::Mut => "mut ", |
725 | Mutability::Not => "", | |
60c5eb7d XL |
726 | } |
727 | } | |
728 | } | |
729 | ||
730 | /// The kind of borrow in an `AddrOf` expression, | |
731 | /// e.g., `&place` or `&raw const place`. | |
732 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | |
733 | #[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] | |
734 | pub enum BorrowKind { | |
60c5eb7d XL |
735 | /// A normal borrow, `&$expr` or `&mut $expr`. |
736 | /// The resulting type is either `&'a T` or `&'a mut T` | |
737 | /// where `T = typeof($expr)` and `'a` is some lifetime. | |
dfeec247 XL |
738 | Ref, |
739 | /// A raw borrow, `&raw const $expr` or `&raw mut $expr`. | |
740 | /// The resulting type is either `*const T` or `*mut T` | |
741 | /// where `T = typeof($expr)`. | |
60c5eb7d XL |
742 | Raw, |
743 | } | |
744 | ||
8faf50e0 | 745 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] |
7453a54e | 746 | pub enum BinOpKind { |
c34b1796 | 747 | /// The `+` operator (addition) |
7453a54e | 748 | Add, |
c34b1796 | 749 | /// The `-` operator (subtraction) |
7453a54e | 750 | Sub, |
c34b1796 | 751 | /// The `*` operator (multiplication) |
7453a54e | 752 | Mul, |
c34b1796 | 753 | /// The `/` operator (division) |
7453a54e | 754 | Div, |
c34b1796 | 755 | /// The `%` operator (modulus) |
7453a54e | 756 | Rem, |
c34b1796 | 757 | /// The `&&` operator (logical and) |
7453a54e | 758 | And, |
c34b1796 | 759 | /// The `||` operator (logical or) |
7453a54e | 760 | Or, |
c34b1796 | 761 | /// The `^` operator (bitwise xor) |
7453a54e | 762 | BitXor, |
c34b1796 | 763 | /// The `&` operator (bitwise and) |
7453a54e | 764 | BitAnd, |
c34b1796 | 765 | /// The `|` operator (bitwise or) |
7453a54e | 766 | BitOr, |
c34b1796 | 767 | /// The `<<` operator (shift left) |
7453a54e | 768 | Shl, |
c34b1796 | 769 | /// The `>>` operator (shift right) |
7453a54e | 770 | Shr, |
c34b1796 | 771 | /// The `==` operator (equality) |
7453a54e | 772 | Eq, |
c34b1796 | 773 | /// The `<` operator (less than) |
7453a54e | 774 | Lt, |
c34b1796 | 775 | /// The `<=` operator (less than or equal to) |
7453a54e | 776 | Le, |
c34b1796 | 777 | /// The `!=` operator (not equal to) |
7453a54e | 778 | Ne, |
c34b1796 | 779 | /// The `>=` operator (greater than or equal to) |
7453a54e | 780 | Ge, |
c34b1796 | 781 | /// The `>` operator (greater than) |
7453a54e | 782 | Gt, |
1a4d82fc JJ |
783 | } |
784 | ||
7453a54e | 785 | impl BinOpKind { |
9cc50fc6 | 786 | pub fn to_string(&self) -> &'static str { |
9fa01778 | 787 | use BinOpKind::*; |
9cc50fc6 | 788 | match *self { |
7453a54e SL |
789 | Add => "+", |
790 | Sub => "-", | |
791 | Mul => "*", | |
792 | Div => "/", | |
793 | Rem => "%", | |
794 | And => "&&", | |
795 | Or => "||", | |
796 | BitXor => "^", | |
797 | BitAnd => "&", | |
798 | BitOr => "|", | |
799 | Shl => "<<", | |
800 | Shr => ">>", | |
801 | Eq => "==", | |
802 | Lt => "<", | |
803 | Le => "<=", | |
804 | Ne => "!=", | |
805 | Ge => ">=", | |
806 | Gt => ">", | |
9cc50fc6 SL |
807 | } |
808 | } | |
809 | pub fn lazy(&self) -> bool { | |
810 | match *self { | |
7453a54e | 811 | BinOpKind::And | BinOpKind::Or => true, |
0bf4aa26 | 812 | _ => false, |
9cc50fc6 SL |
813 | } |
814 | } | |
815 | ||
816 | pub fn is_shift(&self) -> bool { | |
817 | match *self { | |
7453a54e | 818 | BinOpKind::Shl | BinOpKind::Shr => true, |
0bf4aa26 | 819 | _ => false, |
9cc50fc6 SL |
820 | } |
821 | } | |
2c00a5a8 | 822 | |
9cc50fc6 | 823 | pub fn is_comparison(&self) -> bool { |
9fa01778 | 824 | use BinOpKind::*; |
e74abb32 XL |
825 | // Note for developers: please keep this as is; |
826 | // we want compilation to fail if another variant is added. | |
9cc50fc6 | 827 | match *self { |
0bf4aa26 XL |
828 | Eq | Lt | Le | Ne | Gt | Ge => true, |
829 | And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false, | |
9cc50fc6 SL |
830 | } |
831 | } | |
2c00a5a8 | 832 | |
9cc50fc6 SL |
833 | /// Returns `true` if the binary operator takes its arguments by value |
834 | pub fn is_by_value(&self) -> bool { | |
7453a54e | 835 | !self.is_comparison() |
9cc50fc6 SL |
836 | } |
837 | } | |
838 | ||
7453a54e | 839 | pub type BinOp = Spanned<BinOpKind>; |
85aaf69f | 840 | |
e74abb32 XL |
841 | /// Unary operator. |
842 | /// | |
843 | /// Note that `&data` is not an operator, it's an `AddrOf` expression. | |
8faf50e0 | 844 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)] |
1a4d82fc | 845 | pub enum UnOp { |
c34b1796 | 846 | /// The `*` operator for dereferencing |
7453a54e | 847 | Deref, |
c34b1796 | 848 | /// The `!` operator for logical inversion |
7453a54e | 849 | Not, |
c34b1796 | 850 | /// The `-` operator for negation |
7453a54e | 851 | Neg, |
1a4d82fc JJ |
852 | } |
853 | ||
9cc50fc6 SL |
854 | impl UnOp { |
855 | /// Returns `true` if the unary operator takes its argument by value | |
856 | pub fn is_by_value(u: UnOp) -> bool { | |
857 | match u { | |
7453a54e | 858 | UnOp::Neg | UnOp::Not => true, |
9cc50fc6 SL |
859 | _ => false, |
860 | } | |
861 | } | |
862 | ||
863 | pub fn to_string(op: UnOp) -> &'static str { | |
864 | match op { | |
7453a54e SL |
865 | UnOp::Deref => "*", |
866 | UnOp::Not => "!", | |
867 | UnOp::Neg => "-", | |
9cc50fc6 SL |
868 | } |
869 | } | |
870 | } | |
871 | ||
c34b1796 | 872 | /// A statement |
e74abb32 | 873 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
3157f602 XL |
874 | pub struct Stmt { |
875 | pub id: NodeId, | |
e74abb32 | 876 | pub kind: StmtKind, |
3157f602 XL |
877 | pub span: Span, |
878 | } | |
1a4d82fc | 879 | |
5bcae85e SL |
880 | impl Stmt { |
881 | pub fn add_trailing_semicolon(mut self) -> Self { | |
e74abb32 | 882 | self.kind = match self.kind { |
5bcae85e | 883 | StmtKind::Expr(expr) => StmtKind::Semi(expr), |
0bf4aa26 XL |
884 | StmtKind::Mac(mac) => { |
885 | StmtKind::Mac(mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs))) | |
886 | } | |
e74abb32 | 887 | kind => kind, |
5bcae85e SL |
888 | }; |
889 | self | |
890 | } | |
3b2f2976 XL |
891 | |
892 | pub fn is_item(&self) -> bool { | |
e74abb32 | 893 | match self.kind { |
0531ce1d XL |
894 | StmtKind::Item(_) => true, |
895 | _ => false, | |
896 | } | |
897 | } | |
898 | ||
899 | pub fn is_expr(&self) -> bool { | |
e74abb32 | 900 | match self.kind { |
0531ce1d | 901 | StmtKind::Expr(_) => true, |
3b2f2976 XL |
902 | _ => false, |
903 | } | |
904 | } | |
5bcae85e SL |
905 | } |
906 | ||
e74abb32 | 907 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7453a54e | 908 | pub enum StmtKind { |
3157f602 XL |
909 | /// A local (let) binding. |
910 | Local(P<Local>), | |
3157f602 XL |
911 | /// An item definition. |
912 | Item(P<Item>), | |
3157f602 XL |
913 | /// Expr without trailing semi-colon. |
914 | Expr(P<Expr>), | |
ea8adc8c | 915 | /// Expr with a trailing semi-colon. |
3157f602 | 916 | Semi(P<Expr>), |
74b04a01 XL |
917 | /// Just a trailing semi-colon. |
918 | Empty, | |
ea8adc8c | 919 | /// Macro. |
dfeec247 | 920 | Mac(P<(Mac, MacStmtStyle, AttrVec)>), |
92a42be0 SL |
921 | } |
922 | ||
8faf50e0 | 923 | #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 924 | pub enum MacStmtStyle { |
0731742a XL |
925 | /// The macro statement had a trailing semicolon (e.g., `foo! { ... };` |
926 | /// `foo!(...);`, `foo![...];`). | |
7453a54e | 927 | Semicolon, |
0731742a | 928 | /// The macro statement had braces (e.g., `foo! { ... }`). |
7453a54e | 929 | Braces, |
0731742a XL |
930 | /// The macro statement had parentheses or brackets and no semicolon (e.g., |
931 | /// `foo!(...)`). All of these will end up being converted into macro | |
1a4d82fc | 932 | /// expressions. |
7453a54e | 933 | NoBraces, |
1a4d82fc JJ |
934 | } |
935 | ||
0731742a | 936 | /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`. |
8faf50e0 | 937 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 938 | pub struct Local { |
e1599b0c | 939 | pub id: NodeId, |
1a4d82fc JJ |
940 | pub pat: P<Pat>, |
941 | pub ty: Option<P<Ty>>, | |
0731742a | 942 | /// Initializer expression to set the value, if any. |
1a4d82fc | 943 | pub init: Option<P<Expr>>, |
1a4d82fc | 944 | pub span: Span, |
dfeec247 | 945 | pub attrs: AttrVec, |
1a4d82fc JJ |
946 | } |
947 | ||
3157f602 XL |
948 | /// An arm of a 'match'. |
949 | /// | |
0731742a | 950 | /// E.g., `0..=10 => { println!("match!") }` as in |
3157f602 | 951 | /// |
041b39d2 XL |
952 | /// ``` |
953 | /// match 123 { | |
8faf50e0 | 954 | /// 0..=10 => { println!("match!") }, |
041b39d2 | 955 | /// _ => { println!("no match!") }, |
3157f602 XL |
956 | /// } |
957 | /// ``` | |
8faf50e0 | 958 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
959 | pub struct Arm { |
960 | pub attrs: Vec<Attribute>, | |
e74abb32 | 961 | /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }` |
e1599b0c | 962 | pub pat: P<Pat>, |
e74abb32 | 963 | /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }` |
dc9dc135 | 964 | pub guard: Option<P<Expr>>, |
e74abb32 | 965 | /// Match arm body. |
1a4d82fc | 966 | pub body: P<Expr>, |
dc9dc135 | 967 | pub span: Span, |
e1599b0c XL |
968 | pub id: NodeId, |
969 | pub is_placeholder: bool, | |
b7449926 XL |
970 | } |
971 | ||
e74abb32 | 972 | /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field. |
8faf50e0 | 973 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 974 | pub struct Field { |
dfeec247 | 975 | pub attrs: AttrVec, |
60c5eb7d XL |
976 | pub id: NodeId, |
977 | pub span: Span, | |
83c7162d | 978 | pub ident: Ident, |
1a4d82fc | 979 | pub expr: P<Expr>, |
c30ab7b3 | 980 | pub is_shorthand: bool, |
e1599b0c | 981 | pub is_placeholder: bool, |
1a4d82fc JJ |
982 | } |
983 | ||
0731742a | 984 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] |
1a4d82fc | 985 | pub enum BlockCheckMode { |
7453a54e SL |
986 | Default, |
987 | Unsafe(UnsafeSource), | |
1a4d82fc JJ |
988 | } |
989 | ||
0731742a | 990 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)] |
1a4d82fc JJ |
991 | pub enum UnsafeSource { |
992 | CompilerGenerated, | |
993 | UserProvided, | |
994 | } | |
995 | ||
94b46f34 XL |
996 | /// A constant (expression) that's not an item or associated item, |
997 | /// but needs its own `DefId` for type-checking, const-eval, etc. | |
0731742a XL |
998 | /// These are usually found nested inside types (e.g., array lengths) |
999 | /// or expressions (e.g., repeat counts), and also used to define | |
94b46f34 | 1000 | /// explicit discriminant values for enum variants. |
8faf50e0 | 1001 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
94b46f34 XL |
1002 | pub struct AnonConst { |
1003 | pub id: NodeId, | |
1004 | pub value: P<Expr>, | |
1005 | } | |
1006 | ||
e1599b0c | 1007 | /// An expression. |
e74abb32 | 1008 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
1009 | pub struct Expr { |
1010 | pub id: NodeId, | |
e74abb32 | 1011 | pub kind: ExprKind, |
1a4d82fc | 1012 | pub span: Span, |
dfeec247 | 1013 | pub attrs: AttrVec, |
1a4d82fc JJ |
1014 | } |
1015 | ||
a1dfa0c6 XL |
1016 | // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. |
1017 | #[cfg(target_arch = "x86_64")] | |
60c5eb7d | 1018 | rustc_data_structures::static_assert_size!(Expr, 96); |
a1dfa0c6 | 1019 | |
3b2f2976 | 1020 | impl Expr { |
e1599b0c XL |
1021 | /// Returns `true` if this expression would be valid somewhere that expects a value; |
1022 | /// for example, an `if` condition. | |
3b2f2976 | 1023 | pub fn returns(&self) -> bool { |
e74abb32 XL |
1024 | if let ExprKind::Block(ref block, _) = self.kind { |
1025 | match block.stmts.last().map(|last_stmt| &last_stmt.kind) { | |
e1599b0c | 1026 | // Implicit return |
3b2f2976 XL |
1027 | Some(&StmtKind::Expr(_)) => true, |
1028 | Some(&StmtKind::Semi(ref expr)) => { | |
e74abb32 | 1029 | if let ExprKind::Ret(_) = expr.kind { |
e1599b0c | 1030 | // Last statement is explicit return. |
3b2f2976 XL |
1031 | true |
1032 | } else { | |
1033 | false | |
1034 | } | |
1035 | } | |
e1599b0c | 1036 | // This is a block that doesn't end in either an implicit or explicit return. |
3b2f2976 XL |
1037 | _ => false, |
1038 | } | |
1039 | } else { | |
e1599b0c | 1040 | // This is not a block, it is a value. |
3b2f2976 XL |
1041 | true |
1042 | } | |
1043 | } | |
ff7c6d11 | 1044 | |
60c5eb7d | 1045 | pub fn to_bound(&self) -> Option<GenericBound> { |
e74abb32 | 1046 | match &self.kind { |
0bf4aa26 XL |
1047 | ExprKind::Path(None, path) => Some(GenericBound::Trait( |
1048 | PolyTraitRef::new(Vec::new(), path.clone(), self.span), | |
1049 | TraitBoundModifier::None, | |
1050 | )), | |
ff7c6d11 XL |
1051 | _ => None, |
1052 | } | |
1053 | } | |
1054 | ||
e74abb32 | 1055 | /// Attempts to reparse as `Ty` (for diagnostic purposes). |
60c5eb7d | 1056 | pub fn to_ty(&self) -> Option<P<Ty>> { |
e74abb32 XL |
1057 | let kind = match &self.kind { |
1058 | // Trivial conversions. | |
ff7c6d11 XL |
1059 | ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), |
1060 | ExprKind::Mac(mac) => TyKind::Mac(mac.clone()), | |
e74abb32 | 1061 | |
ff7c6d11 | 1062 | ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?, |
e74abb32 | 1063 | |
dfeec247 XL |
1064 | ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => { |
1065 | expr.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))? | |
1066 | } | |
e74abb32 | 1067 | |
0bf4aa26 XL |
1068 | ExprKind::Repeat(expr, expr_len) => { |
1069 | expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))? | |
1070 | } | |
e74abb32 | 1071 | |
0bf4aa26 | 1072 | ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?, |
e74abb32 | 1073 | |
ff7c6d11 | 1074 | ExprKind::Tup(exprs) => { |
dfeec247 | 1075 | let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?; |
ff7c6d11 XL |
1076 | TyKind::Tup(tys) |
1077 | } | |
e74abb32 XL |
1078 | |
1079 | // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds, | |
1080 | // then type of result is trait object. | |
74b04a01 | 1081 | // Otherwise we don't assume the result type. |
0bf4aa26 | 1082 | ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => { |
ff7c6d11 XL |
1083 | if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) { |
1084 | TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) | |
1085 | } else { | |
1086 | return None; | |
1087 | } | |
0bf4aa26 | 1088 | } |
e74abb32 XL |
1089 | |
1090 | // This expression doesn't look like a type syntactically. | |
ff7c6d11 XL |
1091 | _ => return None, |
1092 | }; | |
1093 | ||
dfeec247 | 1094 | Some(P(Ty { kind, id: self.id, span: self.span })) |
ff7c6d11 | 1095 | } |
2c00a5a8 XL |
1096 | |
1097 | pub fn precedence(&self) -> ExprPrecedence { | |
e74abb32 | 1098 | match self.kind { |
2c00a5a8 | 1099 | ExprKind::Box(_) => ExprPrecedence::Box, |
2c00a5a8 XL |
1100 | ExprKind::Array(_) => ExprPrecedence::Array, |
1101 | ExprKind::Call(..) => ExprPrecedence::Call, | |
1102 | ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, | |
1103 | ExprKind::Tup(_) => ExprPrecedence::Tup, | |
1104 | ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), | |
1105 | ExprKind::Unary(..) => ExprPrecedence::Unary, | |
1106 | ExprKind::Lit(_) => ExprPrecedence::Lit, | |
1107 | ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, | |
dc9dc135 | 1108 | ExprKind::Let(..) => ExprPrecedence::Let, |
2c00a5a8 | 1109 | ExprKind::If(..) => ExprPrecedence::If, |
2c00a5a8 | 1110 | ExprKind::While(..) => ExprPrecedence::While, |
2c00a5a8 XL |
1111 | ExprKind::ForLoop(..) => ExprPrecedence::ForLoop, |
1112 | ExprKind::Loop(..) => ExprPrecedence::Loop, | |
1113 | ExprKind::Match(..) => ExprPrecedence::Match, | |
1114 | ExprKind::Closure(..) => ExprPrecedence::Closure, | |
1115 | ExprKind::Block(..) => ExprPrecedence::Block, | |
b7449926 | 1116 | ExprKind::TryBlock(..) => ExprPrecedence::TryBlock, |
8faf50e0 | 1117 | ExprKind::Async(..) => ExprPrecedence::Async, |
48663c56 | 1118 | ExprKind::Await(..) => ExprPrecedence::Await, |
2c00a5a8 XL |
1119 | ExprKind::Assign(..) => ExprPrecedence::Assign, |
1120 | ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, | |
1121 | ExprKind::Field(..) => ExprPrecedence::Field, | |
2c00a5a8 XL |
1122 | ExprKind::Index(..) => ExprPrecedence::Index, |
1123 | ExprKind::Range(..) => ExprPrecedence::Range, | |
1124 | ExprKind::Path(..) => ExprPrecedence::Path, | |
1125 | ExprKind::AddrOf(..) => ExprPrecedence::AddrOf, | |
1126 | ExprKind::Break(..) => ExprPrecedence::Break, | |
1127 | ExprKind::Continue(..) => ExprPrecedence::Continue, | |
1128 | ExprKind::Ret(..) => ExprPrecedence::Ret, | |
1129 | ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, | |
1130 | ExprKind::Mac(..) => ExprPrecedence::Mac, | |
1131 | ExprKind::Struct(..) => ExprPrecedence::Struct, | |
1132 | ExprKind::Repeat(..) => ExprPrecedence::Repeat, | |
1133 | ExprKind::Paren(..) => ExprPrecedence::Paren, | |
1134 | ExprKind::Try(..) => ExprPrecedence::Try, | |
1135 | ExprKind::Yield(..) => ExprPrecedence::Yield, | |
0731742a | 1136 | ExprKind::Err => ExprPrecedence::Err, |
2c00a5a8 XL |
1137 | } |
1138 | } | |
3b2f2976 XL |
1139 | } |
1140 | ||
54a0048b | 1141 | /// Limit types of a range (inclusive or exclusive) |
8faf50e0 | 1142 | #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] |
54a0048b SL |
1143 | pub enum RangeLimits { |
1144 | /// Inclusive at the beginning, exclusive at the end | |
1145 | HalfOpen, | |
1146 | /// Inclusive at the beginning and end | |
1147 | Closed, | |
1148 | } | |
1149 | ||
8faf50e0 | 1150 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7453a54e | 1151 | pub enum ExprKind { |
b039eaaf | 1152 | /// A `box x` expression. |
7453a54e | 1153 | Box(P<Expr>), |
c34b1796 | 1154 | /// An array (`[a, b, c, d]`) |
32a655c1 | 1155 | Array(Vec<P<Expr>>), |
c34b1796 AL |
1156 | /// A function call |
1157 | /// | |
1158 | /// The first field resolves to the function itself, | |
abe05a73 XL |
1159 | /// and the second field is the list of arguments. |
1160 | /// This also represents calling the constructor of | |
1161 | /// tuple-like ADTs such as tuple structs and enum variants. | |
7453a54e | 1162 | Call(P<Expr>, Vec<P<Expr>>), |
041b39d2 | 1163 | /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) |
c34b1796 | 1164 | /// |
041b39d2 | 1165 | /// The `PathSegment` represents the method name and its generic arguments |
c34b1796 | 1166 | /// (within the angle brackets). |
0731742a | 1167 | /// The first element of the vector of an `Expr` is the expression that evaluates |
c34b1796 AL |
1168 | /// to the object on which the method is being called on (the receiver), |
1169 | /// and the remaining elements are the rest of the arguments. | |
c34b1796 | 1170 | /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as |
041b39d2 XL |
1171 | /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. |
1172 | MethodCall(PathSegment, Vec<P<Expr>>), | |
0731742a | 1173 | /// A tuple (e.g., `(a, b, c, d)`). |
7453a54e | 1174 | Tup(Vec<P<Expr>>), |
0731742a | 1175 | /// A binary operation (e.g., `a + b`, `a * b`). |
7453a54e | 1176 | Binary(BinOp, P<Expr>, P<Expr>), |
0731742a | 1177 | /// A unary operation (e.g., `!x`, `*x`). |
7453a54e | 1178 | Unary(UnOp, P<Expr>), |
0731742a | 1179 | /// A literal (e.g., `1`, `"foo"`). |
a1dfa0c6 | 1180 | Lit(Lit), |
0731742a | 1181 | /// A cast (e.g., `foo as f64`). |
7453a54e | 1182 | Cast(P<Expr>, P<Ty>), |
48663c56 | 1183 | /// A type ascription (e.g., `42: usize`). |
7453a54e | 1184 | Type(P<Expr>, P<Ty>), |
e1599b0c | 1185 | /// A `let pat = expr` expression that is only semantically allowed in the condition |
dc9dc135 | 1186 | /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`). |
e1599b0c | 1187 | Let(P<Pat>, P<Expr>), |
0731742a | 1188 | /// An `if` block, with an optional `else` block. |
c34b1796 AL |
1189 | /// |
1190 | /// `if expr { block } else { expr }` | |
7453a54e | 1191 | If(P<Expr>, P<Block>, Option<P<Expr>>), |
dc9dc135 | 1192 | /// A while loop, with an optional label. |
c34b1796 AL |
1193 | /// |
1194 | /// `'label: while expr { block }` | |
2c00a5a8 | 1195 | While(P<Expr>, P<Block>, Option<Label>), |
0731742a | 1196 | /// A `for` loop, with an optional label. |
c34b1796 AL |
1197 | /// |
1198 | /// `'label: for pat in expr { block }` | |
1199 | /// | |
1200 | /// This is desugared to a combination of `loop` and `match` expressions. | |
2c00a5a8 | 1201 | ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>), |
0731742a | 1202 | /// Conditionless loop (can be exited with `break`, `continue`, or `return`). |
c34b1796 AL |
1203 | /// |
1204 | /// `'label: loop { block }` | |
2c00a5a8 | 1205 | Loop(P<Block>, Option<Label>), |
b039eaaf | 1206 | /// A `match` block. |
7453a54e | 1207 | Match(P<Expr>, Vec<Arm>), |
0731742a | 1208 | /// A closure (e.g., `move |a, b, c| a + b + c`). |
a7813a04 | 1209 | /// |
0731742a | 1210 | /// The final span is the span of the argument block `|...|`. |
74b04a01 | 1211 | Closure(CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span), |
0731742a | 1212 | /// A block (`'label: { ... }`). |
94b46f34 | 1213 | Block(P<Block>, Option<Label>), |
0731742a | 1214 | /// An async block (`async move { ... }`). |
8faf50e0 XL |
1215 | /// |
1216 | /// The `NodeId` is the `NodeId` for the closure that results from | |
1217 | /// desugaring an async block, just like the NodeId field in the | |
74b04a01 | 1218 | /// `Async::Yes` variant. This is necessary in order to create a def for the |
8faf50e0 XL |
1219 | /// closure which can be used as a parent of any child defs. Defs |
1220 | /// created during lowering cannot be made the parent of any other | |
1221 | /// preexisting defs. | |
1222 | Async(CaptureBy, NodeId, P<Block>), | |
48663c56 | 1223 | /// An await expression (`my_future.await`). |
416331ca | 1224 | Await(P<Expr>), |
48663c56 | 1225 | |
0731742a | 1226 | /// A try block (`try { ... }`). |
b7449926 | 1227 | TryBlock(P<Block>), |
1a4d82fc | 1228 | |
0731742a | 1229 | /// An assignment (`a = foo()`). |
dfeec247 XL |
1230 | /// The `Span` argument is the span of the `=` token. |
1231 | Assign(P<Expr>, P<Expr>, Span), | |
0731742a | 1232 | /// An assignment with an operator. |
c34b1796 | 1233 | /// |
0731742a | 1234 | /// E.g., `a += 1`. |
7453a54e | 1235 | AssignOp(BinOp, P<Expr>, P<Expr>), |
0731742a | 1236 | /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field. |
83c7162d | 1237 | Field(P<Expr>, Ident), |
0731742a | 1238 | /// An indexing operation (e.g., `foo[2]`). |
7453a54e | 1239 | Index(P<Expr>, P<Expr>), |
dc9dc135 | 1240 | /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`). |
54a0048b | 1241 | Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits), |
1a4d82fc | 1242 | |
c34b1796 | 1243 | /// Variable reference, possibly containing `::` and/or type |
0731742a | 1244 | /// parameters (e.g., `foo::bar::<baz>`). |
c34b1796 | 1245 | /// |
0731742a | 1246 | /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`). |
7453a54e | 1247 | Path(Option<QSelf>, Path), |
1a4d82fc | 1248 | |
60c5eb7d XL |
1249 | /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`). |
1250 | AddrOf(BorrowKind, Mutability, P<Expr>), | |
0731742a | 1251 | /// A `break`, with an optional label to break, and an optional expression. |
2c00a5a8 | 1252 | Break(Option<Label>, Option<P<Expr>>), |
0731742a | 1253 | /// A `continue`, with an optional label. |
2c00a5a8 | 1254 | Continue(Option<Label>), |
0731742a | 1255 | /// A `return`, with an optional value to be returned. |
7453a54e | 1256 | Ret(Option<P<Expr>>), |
1a4d82fc | 1257 | |
0731742a | 1258 | /// Output of the `asm!()` macro. |
c30ab7b3 | 1259 | InlineAsm(P<InlineAsm>), |
1a4d82fc | 1260 | |
0731742a | 1261 | /// A macro invocation; pre-expansion. |
7453a54e | 1262 | Mac(Mac), |
1a4d82fc JJ |
1263 | |
1264 | /// A struct literal expression. | |
c34b1796 | 1265 | /// |
0731742a XL |
1266 | /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`, |
1267 | /// where `base` is the `Option<Expr>`. | |
7453a54e | 1268 | Struct(Path, Vec<Field>, Option<P<Expr>>), |
1a4d82fc | 1269 | |
e9174d1e | 1270 | /// An array literal constructed from one repeated element. |
c34b1796 | 1271 | /// |
0731742a | 1272 | /// E.g., `[1; 5]`. The expression is the element to be |
94b46f34 XL |
1273 | /// repeated; the constant is the number of times to repeat it. |
1274 | Repeat(P<Expr>, AnonConst), | |
1a4d82fc | 1275 | |
0731742a | 1276 | /// No-op: used solely so we can pretty-print faithfully. |
7453a54e | 1277 | Paren(P<Expr>), |
54a0048b | 1278 | |
0731742a | 1279 | /// A try expression (`expr?`). |
54a0048b | 1280 | Try(P<Expr>), |
ea8adc8c | 1281 | |
0731742a | 1282 | /// A `yield`, with an optional value to be yielded. |
ea8adc8c | 1283 | Yield(Option<P<Expr>>), |
0731742a XL |
1284 | |
1285 | /// Placeholder for an expression that wasn't syntactically well formed in some way. | |
1286 | Err, | |
1a4d82fc JJ |
1287 | } |
1288 | ||
0731742a | 1289 | /// The explicit `Self` type in a "qualified path". The actual |
c34b1796 AL |
1290 | /// path, including the trait and the associated item, is stored |
1291 | /// separately. `position` represents the index of the associated | |
0731742a | 1292 | /// item qualified with this `Self` type. |
c34b1796 | 1293 | /// |
041b39d2 | 1294 | /// ```ignore (only-for-syntax-highlight) |
92a42be0 SL |
1295 | /// <Vec<T> as a::b::Trait>::AssociatedItem |
1296 | /// ^~~~~ ~~~~~~~~~~~~~~^ | |
1297 | /// ty position = 3 | |
1a4d82fc | 1298 | /// |
92a42be0 SL |
1299 | /// <Vec<T>>::AssociatedItem |
1300 | /// ^~~~~ ^ | |
1301 | /// ty position = 0 | |
1302 | /// ``` | |
8faf50e0 | 1303 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
c34b1796 AL |
1304 | pub struct QSelf { |
1305 | pub ty: P<Ty>, | |
94b46f34 XL |
1306 | |
1307 | /// The span of `a::b::Trait` in a path like `<Vec<T> as | |
1308 | /// a::b::Trait>::AssociatedItem`; in the case where `position == | |
1309 | /// 0`, this is an empty span. | |
1310 | pub path_span: Span, | |
0bf4aa26 | 1311 | pub position: usize, |
1a4d82fc JJ |
1312 | } |
1313 | ||
e74abb32 | 1314 | /// A capture clause used in closures and `async` blocks. |
60c5eb7d | 1315 | #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
7453a54e | 1316 | pub enum CaptureBy { |
e74abb32 | 1317 | /// `move |x| y + x`. |
7453a54e | 1318 | Value, |
e74abb32 | 1319 | /// `move` keyword was not specified. |
7453a54e | 1320 | Ref, |
1a4d82fc JJ |
1321 | } |
1322 | ||
60c5eb7d XL |
1323 | /// The movability of a generator / closure literal: |
1324 | /// whether a generator contains self-references, causing it to be `!Unpin`. | |
dfeec247 XL |
1325 | #[derive( |
1326 | Clone, | |
1327 | PartialEq, | |
1328 | Eq, | |
1329 | PartialOrd, | |
1330 | Ord, | |
1331 | Hash, | |
1332 | RustcEncodable, | |
1333 | RustcDecodable, | |
1334 | Debug, | |
1335 | Copy, | |
1336 | HashStable_Generic | |
1337 | )] | |
2c00a5a8 | 1338 | pub enum Movability { |
60c5eb7d | 1339 | /// May contain self-references, `!Unpin`. |
2c00a5a8 | 1340 | Static, |
60c5eb7d | 1341 | /// Must not contain self-references, `Unpin`. |
2c00a5a8 XL |
1342 | Movable, |
1343 | } | |
1344 | ||
60c5eb7d XL |
1345 | /// Represents a macro invocation. The `path` indicates which macro |
1346 | /// is being invoked, and the `args` are arguments passed to it. | |
8faf50e0 | 1347 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
e1599b0c | 1348 | pub struct Mac { |
b039eaaf | 1349 | pub path: Path, |
60c5eb7d | 1350 | pub args: P<MacArgs>, |
416331ca | 1351 | pub prior_type_ascription: Option<(Span, bool)>, |
8bb4bdeb XL |
1352 | } |
1353 | ||
60c5eb7d XL |
1354 | impl Mac { |
1355 | pub fn span(&self) -> Span { | |
1356 | self.path.span.to(self.args.span().unwrap_or(self.path.span)) | |
1357 | } | |
1358 | } | |
1359 | ||
1360 | /// Arguments passed to an attribute or a function-like macro. | |
1361 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] | |
1362 | pub enum MacArgs { | |
1363 | /// No arguments - `#[attr]`. | |
1364 | Empty, | |
1365 | /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. | |
1366 | Delimited(DelimSpan, MacDelimiter, TokenStream), | |
1367 | /// Arguments of a key-value attribute - `#[attr = "value"]`. | |
1368 | Eq( | |
1369 | /// Span of the `=` token. | |
1370 | Span, | |
1371 | /// Token stream of the "value". | |
1372 | TokenStream, | |
1373 | ), | |
1374 | } | |
1375 | ||
1376 | impl MacArgs { | |
1377 | pub fn delim(&self) -> DelimToken { | |
1378 | match self { | |
1379 | MacArgs::Delimited(_, delim, _) => delim.to_token(), | |
1380 | MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim, | |
1381 | } | |
1382 | } | |
1383 | ||
1384 | pub fn span(&self) -> Option<Span> { | |
1385 | match *self { | |
1386 | MacArgs::Empty => None, | |
1387 | MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), | |
1388 | MacArgs::Eq(eq_span, ref tokens) => Some(eq_span.to(tokens.span().unwrap_or(eq_span))), | |
1389 | } | |
1390 | } | |
1391 | ||
1392 | /// Tokens inside the delimiters or after `=`. | |
1393 | /// Proc macros see these tokens, for example. | |
1394 | pub fn inner_tokens(&self) -> TokenStream { | |
1395 | match self { | |
1396 | MacArgs::Empty => TokenStream::default(), | |
dfeec247 | 1397 | MacArgs::Delimited(.., tokens) | MacArgs::Eq(.., tokens) => tokens.clone(), |
60c5eb7d XL |
1398 | } |
1399 | } | |
1400 | ||
1401 | /// Tokens together with the delimiters or `=`. | |
1402 | /// Use of this method generally means that something suboptimal or hacky is happening. | |
1403 | pub fn outer_tokens(&self) -> TokenStream { | |
1404 | match *self { | |
1405 | MacArgs::Empty => TokenStream::default(), | |
dfeec247 XL |
1406 | MacArgs::Delimited(dspan, delim, ref tokens) => { |
1407 | TokenTree::Delimited(dspan, delim.to_token(), tokens.clone()).into() | |
1408 | } | |
1409 | MacArgs::Eq(eq_span, ref tokens) => { | |
1410 | iter::once(TokenTree::token(token::Eq, eq_span)).chain(tokens.trees()).collect() | |
1411 | } | |
60c5eb7d XL |
1412 | } |
1413 | } | |
1414 | ||
1415 | /// Whether a macro with these arguments needs a semicolon | |
1416 | /// when used as a standalone item or statement. | |
1417 | pub fn need_semicolon(&self) -> bool { | |
dfeec247 | 1418 | !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _)) |
60c5eb7d XL |
1419 | } |
1420 | } | |
1421 | ||
1422 | #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] | |
94b46f34 XL |
1423 | pub enum MacDelimiter { |
1424 | Parenthesis, | |
1425 | Bracket, | |
1426 | Brace, | |
1427 | } | |
1428 | ||
416331ca | 1429 | impl MacDelimiter { |
74b04a01 | 1430 | pub fn to_token(self) -> DelimToken { |
416331ca XL |
1431 | match self { |
1432 | MacDelimiter::Parenthesis => DelimToken::Paren, | |
1433 | MacDelimiter::Bracket => DelimToken::Bracket, | |
1434 | MacDelimiter::Brace => DelimToken::Brace, | |
1435 | } | |
1436 | } | |
60c5eb7d XL |
1437 | |
1438 | pub fn from_token(delim: DelimToken) -> Option<MacDelimiter> { | |
1439 | match delim { | |
1440 | token::Paren => Some(MacDelimiter::Parenthesis), | |
1441 | token::Bracket => Some(MacDelimiter::Bracket), | |
1442 | token::Brace => Some(MacDelimiter::Brace), | |
1443 | token::NoDelim => None, | |
1444 | } | |
1445 | } | |
416331ca XL |
1446 | } |
1447 | ||
e74abb32 | 1448 | /// Represents a macro definition. |
8faf50e0 | 1449 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7cac9316 | 1450 | pub struct MacroDef { |
60c5eb7d | 1451 | pub body: P<MacArgs>, |
e74abb32 | 1452 | /// `true` if macro was defined with `macro_rules`. |
7cac9316 XL |
1453 | pub legacy: bool, |
1454 | } | |
1455 | ||
dfeec247 XL |
1456 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)] |
1457 | #[derive(HashStable_Generic)] | |
1a4d82fc | 1458 | pub enum StrStyle { |
0731742a | 1459 | /// A regular string, like `"foo"`. |
7453a54e | 1460 | Cooked, |
0731742a | 1461 | /// A raw string, like `r##"foo"##`. |
c34b1796 | 1462 | /// |
83c7162d | 1463 | /// The value is the number of `#` symbols used. |
0bf4aa26 | 1464 | Raw(u16), |
223e47cc LB |
1465 | } |
1466 | ||
48663c56 | 1467 | /// An AST literal. |
60c5eb7d | 1468 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
48663c56 XL |
1469 | pub struct Lit { |
1470 | /// The original literal token as written in source code. | |
1471 | pub token: token::Lit, | |
48663c56 XL |
1472 | /// The "semantic" representation of the literal lowered from the original tokens. |
1473 | /// Strings are unescaped, hexadecimal forms are eliminated, etc. | |
1474 | /// FIXME: Remove this and only create the semantic representation during lowering to HIR. | |
e74abb32 | 1475 | pub kind: LitKind, |
48663c56 XL |
1476 | pub span: Span, |
1477 | } | |
9346a6ac | 1478 | |
60c5eb7d XL |
1479 | /// Same as `Lit`, but restricted to string literals. |
1480 | #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] | |
1481 | pub struct StrLit { | |
1482 | /// The original literal token as written in source code. | |
1483 | pub style: StrStyle, | |
1484 | pub symbol: Symbol, | |
1485 | pub suffix: Option<Symbol>, | |
1486 | pub span: Span, | |
1487 | /// The unescaped "semantic" representation of the literal lowered from the original token. | |
1488 | /// FIXME: Remove this and only create the semantic representation during lowering to HIR. | |
1489 | pub symbol_unescaped: Symbol, | |
1490 | } | |
1491 | ||
1492 | impl StrLit { | |
74b04a01 | 1493 | pub fn as_lit(&self) -> Lit { |
60c5eb7d XL |
1494 | let token_kind = match self.style { |
1495 | StrStyle::Cooked => token::Str, | |
1496 | StrStyle::Raw(n) => token::StrRaw(n), | |
1497 | }; | |
1498 | Lit { | |
1499 | token: token::Lit::new(token_kind, self.symbol, self.suffix), | |
1500 | span: self.span, | |
1501 | kind: LitKind::Str(self.symbol_unescaped, self.style), | |
1502 | } | |
1503 | } | |
1504 | } | |
1505 | ||
e74abb32 | 1506 | /// Type of the integer literal based on provided suffix. |
dfeec247 XL |
1507 | #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)] |
1508 | #[derive(HashStable_Generic)] | |
1a4d82fc | 1509 | pub enum LitIntType { |
e74abb32 | 1510 | /// e.g. `42_i32`. |
7453a54e | 1511 | Signed(IntTy), |
e74abb32 | 1512 | /// e.g. `42_u32`. |
7453a54e | 1513 | Unsigned(UintTy), |
e74abb32 | 1514 | /// e.g. `42`. |
7453a54e | 1515 | Unsuffixed, |
223e47cc LB |
1516 | } |
1517 | ||
60c5eb7d | 1518 | /// Type of the float literal based on provided suffix. |
dfeec247 XL |
1519 | #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)] |
1520 | #[derive(HashStable_Generic)] | |
60c5eb7d XL |
1521 | pub enum LitFloatType { |
1522 | /// A float literal with a suffix (`1f32` or `1E10f32`). | |
1523 | Suffixed(FloatTy), | |
1524 | /// A float literal without a suffix (`1.0 or 1.0E10`). | |
1525 | Unsuffixed, | |
1526 | } | |
1527 | ||
3157f602 XL |
1528 | /// Literal kind. |
1529 | /// | |
0731742a | 1530 | /// E.g., `"foo"`, `42`, `12.34`, or `bool`. |
dfeec247 | 1531 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)] |
7453a54e | 1532 | pub enum LitKind { |
0731742a | 1533 | /// A string literal (`"foo"`). |
476ff2be | 1534 | Str(Symbol, StrStyle), |
0731742a | 1535 | /// A byte string (`b"foo"`). |
0531ce1d | 1536 | ByteStr(Lrc<Vec<u8>>), |
0731742a | 1537 | /// A byte char (`b'f'`). |
7453a54e | 1538 | Byte(u8), |
0731742a | 1539 | /// A character literal (`'a'`). |
7453a54e | 1540 | Char(char), |
0731742a | 1541 | /// An integer literal (`1`). |
32a655c1 | 1542 | Int(u128, LitIntType), |
0731742a | 1543 | /// A float literal (`1f64` or `1E10f64`). |
60c5eb7d | 1544 | Float(Symbol, LitFloatType), |
0731742a | 1545 | /// A boolean literal. |
7453a54e | 1546 | Bool(bool), |
dc9dc135 | 1547 | /// Placeholder for a literal that wasn't well-formed in some way. |
9fa01778 | 1548 | Err(Symbol), |
223e47cc LB |
1549 | } |
1550 | ||
7453a54e | 1551 | impl LitKind { |
0731742a | 1552 | /// Returns `true` if this literal is a string. |
9cc50fc6 SL |
1553 | pub fn is_str(&self) -> bool { |
1554 | match *self { | |
7453a54e | 1555 | LitKind::Str(..) => true, |
9cc50fc6 SL |
1556 | _ => false, |
1557 | } | |
1558 | } | |
9e0c209e | 1559 | |
0731742a | 1560 | /// Returns `true` if this literal is byte literal string. |
a1dfa0c6 XL |
1561 | pub fn is_bytestr(&self) -> bool { |
1562 | match self { | |
1563 | LitKind::ByteStr(_) => true, | |
1564 | _ => false, | |
1565 | } | |
1566 | } | |
1567 | ||
0731742a | 1568 | /// Returns `true` if this is a numeric literal. |
8faf50e0 XL |
1569 | pub fn is_numeric(&self) -> bool { |
1570 | match *self { | |
60c5eb7d | 1571 | LitKind::Int(..) | LitKind::Float(..) => true, |
8faf50e0 XL |
1572 | _ => false, |
1573 | } | |
1574 | } | |
1575 | ||
0731742a XL |
1576 | /// Returns `true` if this literal has no suffix. |
1577 | /// Note: this will return true for literals with prefixes such as raw strings and byte strings. | |
9e0c209e | 1578 | pub fn is_unsuffixed(&self) -> bool { |
e74abb32 XL |
1579 | !self.is_suffixed() |
1580 | } | |
1581 | ||
1582 | /// Returns `true` if this literal has a suffix. | |
1583 | pub fn is_suffixed(&self) -> bool { | |
9e0c209e | 1584 | match *self { |
e74abb32 XL |
1585 | // suffixed variants |
1586 | LitKind::Int(_, LitIntType::Signed(..)) | |
1587 | | LitKind::Int(_, LitIntType::Unsigned(..)) | |
60c5eb7d | 1588 | | LitKind::Float(_, LitFloatType::Suffixed(..)) => true, |
9e0c209e | 1589 | // unsuffixed variants |
0bf4aa26 XL |
1590 | LitKind::Str(..) |
1591 | | LitKind::ByteStr(..) | |
1592 | | LitKind::Byte(..) | |
1593 | | LitKind::Char(..) | |
1594 | | LitKind::Int(_, LitIntType::Unsuffixed) | |
60c5eb7d | 1595 | | LitKind::Float(_, LitFloatType::Unsuffixed) |
dc9dc135 | 1596 | | LitKind::Bool(..) |
e74abb32 | 1597 | | LitKind::Err(..) => false, |
9e0c209e SL |
1598 | } |
1599 | } | |
9cc50fc6 SL |
1600 | } |
1601 | ||
0731742a XL |
1602 | // N.B., If you change this, you'll probably want to change the corresponding |
1603 | // type structure in `middle/ty.rs` as well. | |
8faf50e0 | 1604 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
1605 | pub struct MutTy { |
1606 | pub ty: P<Ty>, | |
1607 | pub mutbl: Mutability, | |
1608 | } | |
1609 | ||
60c5eb7d XL |
1610 | /// Represents a function's signature in a trait declaration, |
1611 | /// trait implementation, or free function. | |
8faf50e0 | 1612 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
60c5eb7d | 1613 | pub struct FnSig { |
8faf50e0 | 1614 | pub header: FnHeader, |
1a4d82fc | 1615 | pub decl: P<FnDecl>, |
1a4d82fc JJ |
1616 | } |
1617 | ||
dfeec247 XL |
1618 | #[derive( |
1619 | Clone, | |
1620 | Copy, | |
1621 | PartialEq, | |
1622 | Eq, | |
1623 | PartialOrd, | |
1624 | Ord, | |
1625 | Hash, | |
1626 | HashStable_Generic, | |
1627 | RustcEncodable, | |
1628 | RustcDecodable, | |
1629 | Debug | |
1630 | )] | |
60c5eb7d XL |
1631 | pub enum FloatTy { |
1632 | F32, | |
1633 | F64, | |
1634 | } | |
1635 | ||
1636 | impl FloatTy { | |
1637 | pub fn name_str(self) -> &'static str { | |
1638 | match self { | |
1639 | FloatTy::F32 => "f32", | |
1640 | FloatTy::F64 => "f64", | |
1641 | } | |
1642 | } | |
1643 | ||
1644 | pub fn name(self) -> Symbol { | |
1645 | match self { | |
1646 | FloatTy::F32 => sym::f32, | |
1647 | FloatTy::F64 => sym::f64, | |
1648 | } | |
1649 | } | |
1650 | ||
1651 | pub fn bit_width(self) -> usize { | |
1652 | match self { | |
1653 | FloatTy::F32 => 32, | |
1654 | FloatTy::F64 => 64, | |
1655 | } | |
1656 | } | |
1657 | } | |
1658 | ||
dfeec247 XL |
1659 | #[derive( |
1660 | Clone, | |
1661 | Copy, | |
1662 | PartialEq, | |
1663 | Eq, | |
1664 | PartialOrd, | |
1665 | Ord, | |
1666 | Hash, | |
1667 | HashStable_Generic, | |
1668 | RustcEncodable, | |
1669 | RustcDecodable, | |
1670 | Debug | |
1671 | )] | |
1a4d82fc | 1672 | pub enum IntTy { |
2c00a5a8 | 1673 | Isize, |
7453a54e SL |
1674 | I8, |
1675 | I16, | |
1676 | I32, | |
1677 | I64, | |
32a655c1 | 1678 | I128, |
1a4d82fc JJ |
1679 | } |
1680 | ||
1a4d82fc | 1681 | impl IntTy { |
60c5eb7d | 1682 | pub fn name_str(&self) -> &'static str { |
9cc50fc6 | 1683 | match *self { |
2c00a5a8 | 1684 | IntTy::Isize => "isize", |
7453a54e SL |
1685 | IntTy::I8 => "i8", |
1686 | IntTy::I16 => "i16", | |
1687 | IntTy::I32 => "i32", | |
32a655c1 SL |
1688 | IntTy::I64 => "i64", |
1689 | IntTy::I128 => "i128", | |
9cc50fc6 SL |
1690 | } |
1691 | } | |
1692 | ||
60c5eb7d | 1693 | pub fn name(&self) -> Symbol { |
dc9dc135 XL |
1694 | match *self { |
1695 | IntTy::Isize => sym::isize, | |
1696 | IntTy::I8 => sym::i8, | |
1697 | IntTy::I16 => sym::i16, | |
1698 | IntTy::I32 => sym::i32, | |
1699 | IntTy::I64 => sym::i64, | |
1700 | IntTy::I128 => sym::i128, | |
1701 | } | |
1702 | } | |
1703 | ||
32a655c1 | 1704 | pub fn val_to_string(&self, val: i128) -> String { |
0731742a XL |
1705 | // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types |
1706 | // are parsed as `u128`, so we wouldn't want to print an extra negative | |
9cc50fc6 | 1707 | // sign. |
60c5eb7d | 1708 | format!("{}{}", val as u128, self.name_str()) |
9cc50fc6 SL |
1709 | } |
1710 | ||
e9174d1e SL |
1711 | pub fn bit_width(&self) -> Option<usize> { |
1712 | Some(match *self { | |
2c00a5a8 | 1713 | IntTy::Isize => return None, |
7453a54e SL |
1714 | IntTy::I8 => 8, |
1715 | IntTy::I16 => 16, | |
1716 | IntTy::I32 => 32, | |
1717 | IntTy::I64 => 64, | |
32a655c1 | 1718 | IntTy::I128 => 128, |
e9174d1e | 1719 | }) |
1a4d82fc | 1720 | } |
60c5eb7d XL |
1721 | |
1722 | pub fn normalize(&self, target_width: u32) -> Self { | |
1723 | match self { | |
1724 | IntTy::Isize => match target_width { | |
1725 | 16 => IntTy::I16, | |
1726 | 32 => IntTy::I32, | |
1727 | 64 => IntTy::I64, | |
1728 | _ => unreachable!(), | |
1729 | }, | |
1730 | _ => *self, | |
1731 | } | |
1732 | } | |
223e47cc LB |
1733 | } |
1734 | ||
dfeec247 XL |
1735 | #[derive( |
1736 | Clone, | |
1737 | PartialEq, | |
1738 | Eq, | |
1739 | PartialOrd, | |
1740 | Ord, | |
1741 | Hash, | |
1742 | HashStable_Generic, | |
1743 | RustcEncodable, | |
1744 | RustcDecodable, | |
1745 | Copy, | |
1746 | Debug | |
1747 | )] | |
1a4d82fc | 1748 | pub enum UintTy { |
2c00a5a8 | 1749 | Usize, |
7453a54e SL |
1750 | U8, |
1751 | U16, | |
1752 | U32, | |
1753 | U64, | |
32a655c1 | 1754 | U128, |
1a4d82fc JJ |
1755 | } |
1756 | ||
1a4d82fc | 1757 | impl UintTy { |
60c5eb7d | 1758 | pub fn name_str(&self) -> &'static str { |
9cc50fc6 | 1759 | match *self { |
2c00a5a8 | 1760 | UintTy::Usize => "usize", |
7453a54e SL |
1761 | UintTy::U8 => "u8", |
1762 | UintTy::U16 => "u16", | |
1763 | UintTy::U32 => "u32", | |
32a655c1 SL |
1764 | UintTy::U64 => "u64", |
1765 | UintTy::U128 => "u128", | |
9cc50fc6 SL |
1766 | } |
1767 | } | |
1768 | ||
60c5eb7d | 1769 | pub fn name(&self) -> Symbol { |
dc9dc135 XL |
1770 | match *self { |
1771 | UintTy::Usize => sym::usize, | |
1772 | UintTy::U8 => sym::u8, | |
1773 | UintTy::U16 => sym::u16, | |
1774 | UintTy::U32 => sym::u32, | |
1775 | UintTy::U64 => sym::u64, | |
1776 | UintTy::U128 => sym::u128, | |
1777 | } | |
1778 | } | |
1779 | ||
32a655c1 | 1780 | pub fn val_to_string(&self, val: u128) -> String { |
60c5eb7d | 1781 | format!("{}{}", val, self.name_str()) |
9cc50fc6 SL |
1782 | } |
1783 | ||
e9174d1e SL |
1784 | pub fn bit_width(&self) -> Option<usize> { |
1785 | Some(match *self { | |
2c00a5a8 | 1786 | UintTy::Usize => return None, |
7453a54e SL |
1787 | UintTy::U8 => 8, |
1788 | UintTy::U16 => 16, | |
1789 | UintTy::U32 => 32, | |
1790 | UintTy::U64 => 64, | |
32a655c1 | 1791 | UintTy::U128 => 128, |
e9174d1e | 1792 | }) |
1a4d82fc | 1793 | } |
223e47cc | 1794 | |
60c5eb7d XL |
1795 | pub fn normalize(&self, target_width: u32) -> Self { |
1796 | match self { | |
1797 | UintTy::Usize => match target_width { | |
1798 | 16 => UintTy::U16, | |
1799 | 32 => UintTy::U32, | |
1800 | 64 => UintTy::U64, | |
1801 | _ => unreachable!(), | |
1802 | }, | |
1803 | _ => *self, | |
1804 | } | |
1a4d82fc JJ |
1805 | } |
1806 | } | |
1807 | ||
dc9dc135 XL |
1808 | /// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or |
1809 | /// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`). | |
8faf50e0 | 1810 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
dc9dc135 | 1811 | pub struct AssocTyConstraint { |
1a4d82fc JJ |
1812 | pub id: NodeId, |
1813 | pub ident: Ident, | |
dc9dc135 | 1814 | pub kind: AssocTyConstraintKind, |
1a4d82fc JJ |
1815 | pub span: Span, |
1816 | } | |
1817 | ||
dc9dc135 XL |
1818 | /// The kinds of an `AssocTyConstraint`. |
1819 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] | |
1820 | pub enum AssocTyConstraintKind { | |
1821 | /// E.g., `A = Bar` in `Foo<A = Bar>`. | |
dfeec247 | 1822 | Equality { ty: P<Ty> }, |
dc9dc135 | 1823 | /// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`. |
dfeec247 | 1824 | Bound { bounds: GenericBounds }, |
dc9dc135 XL |
1825 | } |
1826 | ||
e74abb32 | 1827 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
223e47cc | 1828 | pub struct Ty { |
1a4d82fc | 1829 | pub id: NodeId, |
e74abb32 | 1830 | pub kind: TyKind, |
1a4d82fc | 1831 | pub span: Span, |
223e47cc LB |
1832 | } |
1833 | ||
8faf50e0 | 1834 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 1835 | pub struct BareFnTy { |
74b04a01 | 1836 | pub unsafety: Unsafe, |
60c5eb7d | 1837 | pub ext: Extern, |
ff7c6d11 | 1838 | pub generic_params: Vec<GenericParam>, |
0bf4aa26 | 1839 | pub decl: P<FnDecl>, |
1a4d82fc JJ |
1840 | } |
1841 | ||
9fa01778 | 1842 | /// The various kinds of type recognized by the compiler. |
8faf50e0 | 1843 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7453a54e | 1844 | pub enum TyKind { |
0731742a | 1845 | /// A variable-length slice (`[T]`). |
c30ab7b3 | 1846 | Slice(P<Ty>), |
0731742a | 1847 | /// A fixed length array (`[T; n]`). |
94b46f34 | 1848 | Array(P<Ty>, AnonConst), |
0731742a | 1849 | /// A raw pointer (`*const T` or `*mut T`). |
7453a54e | 1850 | Ptr(MutTy), |
0731742a | 1851 | /// A reference (`&'a T` or `&'a mut T`). |
7453a54e | 1852 | Rptr(Option<Lifetime>, MutTy), |
0731742a | 1853 | /// A bare function (e.g., `fn(usize) -> bool`). |
7453a54e | 1854 | BareFn(P<BareFnTy>), |
0731742a | 1855 | /// The never type (`!`). |
5bcae85e | 1856 | Never, |
0731742a | 1857 | /// A tuple (`(A, B, C, D,...)`). |
0bf4aa26 | 1858 | Tup(Vec<P<Ty>>), |
c34b1796 | 1859 | /// A path (`module::module::...::Type`), optionally |
0731742a | 1860 | /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. |
1a4d82fc | 1861 | /// |
0731742a | 1862 | /// Type parameters are stored in the `Path` itself. |
7453a54e | 1863 | Path(Option<QSelf>, Path), |
32a655c1 SL |
1864 | /// A trait object type `Bound1 + Bound2 + Bound3` |
1865 | /// where `Bound` is a trait or a lifetime. | |
8faf50e0 | 1866 | TraitObject(GenericBounds, TraitObjectSyntax), |
32a655c1 SL |
1867 | /// An `impl Bound1 + Bound2 + Bound3` type |
1868 | /// where `Bound` is a trait or a lifetime. | |
8faf50e0 XL |
1869 | /// |
1870 | /// The `NodeId` exists to prevent lowering from having to | |
1871 | /// generate `NodeId`s on the fly, which would complicate | |
416331ca | 1872 | /// the generation of opaque `type Foo = impl Trait` items significantly. |
8faf50e0 | 1873 | ImplTrait(NodeId, GenericBounds), |
0731742a | 1874 | /// No-op; kept solely so that we can pretty-print faithfully. |
7453a54e | 1875 | Paren(P<Ty>), |
0731742a | 1876 | /// Unused for now. |
94b46f34 | 1877 | Typeof(AnonConst), |
0731742a | 1878 | /// This means the type should be inferred instead of it having been |
1a4d82fc | 1879 | /// specified. This can appear anywhere in a type. |
7453a54e | 1880 | Infer, |
3157f602 XL |
1881 | /// Inferred type of a `self` or `&self` argument in a method. |
1882 | ImplicitSelf, | |
0731742a | 1883 | /// A macro in the type position. |
7453a54e | 1884 | Mac(Mac), |
cc61c64b XL |
1885 | /// Placeholder for a kind that has failed to be defined. |
1886 | Err, | |
532ac7d7 XL |
1887 | /// Placeholder for a `va_list`. |
1888 | CVarArgs, | |
1a4d82fc JJ |
1889 | } |
1890 | ||
8faf50e0 XL |
1891 | impl TyKind { |
1892 | pub fn is_implicit_self(&self) -> bool { | |
dfeec247 | 1893 | if let TyKind::ImplicitSelf = *self { true } else { false } |
8faf50e0 XL |
1894 | } |
1895 | ||
b7449926 | 1896 | pub fn is_unit(&self) -> bool { |
dfeec247 | 1897 | if let TyKind::Tup(ref tys) = *self { tys.is_empty() } else { false } |
8faf50e0 | 1898 | } |
60c5eb7d XL |
1899 | |
1900 | /// HACK(type_alias_impl_trait, Centril): A temporary crutch used | |
1901 | /// in lowering to avoid making larger changes there and beyond. | |
1902 | pub fn opaque_top_hack(&self) -> Option<&GenericBounds> { | |
1903 | match self { | |
1904 | Self::ImplTrait(_, bounds) => Some(bounds), | |
1905 | _ => None, | |
1906 | } | |
1907 | } | |
8faf50e0 XL |
1908 | } |
1909 | ||
abe05a73 | 1910 | /// Syntax used to declare a trait object. |
8faf50e0 | 1911 | #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)] |
abe05a73 XL |
1912 | pub enum TraitObjectSyntax { |
1913 | Dyn, | |
1914 | None, | |
1915 | } | |
1916 | ||
3157f602 XL |
1917 | /// Inline assembly dialect. |
1918 | /// | |
0731742a | 1919 | /// E.g., `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`. |
60c5eb7d | 1920 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] |
1a4d82fc | 1921 | pub enum AsmDialect { |
b039eaaf SL |
1922 | Att, |
1923 | Intel, | |
1a4d82fc JJ |
1924 | } |
1925 | ||
3157f602 XL |
1926 | /// Inline assembly. |
1927 | /// | |
0731742a | 1928 | /// E.g., `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`. |
8faf50e0 | 1929 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
9cc50fc6 | 1930 | pub struct InlineAsmOutput { |
476ff2be | 1931 | pub constraint: Symbol, |
9cc50fc6 SL |
1932 | pub expr: P<Expr>, |
1933 | pub is_rw: bool, | |
1934 | pub is_indirect: bool, | |
1935 | } | |
1936 | ||
3157f602 XL |
1937 | /// Inline assembly. |
1938 | /// | |
0731742a | 1939 | /// E.g., `asm!("NOP");`. |
8faf50e0 | 1940 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 1941 | pub struct InlineAsm { |
476ff2be | 1942 | pub asm: Symbol, |
1a4d82fc | 1943 | pub asm_str_style: StrStyle, |
9cc50fc6 | 1944 | pub outputs: Vec<InlineAsmOutput>, |
476ff2be SL |
1945 | pub inputs: Vec<(Symbol, P<Expr>)>, |
1946 | pub clobbers: Vec<Symbol>, | |
1a4d82fc JJ |
1947 | pub volatile: bool, |
1948 | pub alignstack: bool, | |
1949 | pub dialect: AsmDialect, | |
1a4d82fc JJ |
1950 | } |
1951 | ||
e1599b0c | 1952 | /// A parameter in a function header. |
3157f602 | 1953 | /// |
0731742a | 1954 | /// E.g., `bar: usize` as in `fn foo(bar: usize)`. |
8faf50e0 | 1955 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
e1599b0c | 1956 | pub struct Param { |
dfeec247 | 1957 | pub attrs: AttrVec, |
1a4d82fc JJ |
1958 | pub ty: P<Ty>, |
1959 | pub pat: P<Pat>, | |
1960 | pub id: NodeId, | |
416331ca | 1961 | pub span: Span, |
e1599b0c | 1962 | pub is_placeholder: bool, |
1a4d82fc JJ |
1963 | } |
1964 | ||
3157f602 XL |
1965 | /// Alternative representation for `Arg`s describing `self` parameter of methods. |
1966 | /// | |
0731742a | 1967 | /// E.g., `&mut self` as in `fn foo(&mut self)`. |
8faf50e0 | 1968 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
a7813a04 | 1969 | pub enum SelfKind { |
a7813a04 | 1970 | /// `self`, `mut self` |
3157f602 | 1971 | Value(Mutability), |
a7813a04 | 1972 | /// `&'lt self`, `&'lt mut self` |
3157f602 | 1973 | Region(Option<Lifetime>, Mutability), |
a7813a04 | 1974 | /// `self: TYPE`, `mut self: TYPE` |
3157f602 | 1975 | Explicit(P<Ty>, Mutability), |
a7813a04 XL |
1976 | } |
1977 | ||
1978 | pub type ExplicitSelf = Spanned<SelfKind>; | |
1979 | ||
e1599b0c | 1980 | impl Param { |
e74abb32 | 1981 | /// Attempts to cast parameter to `ExplicitSelf`. |
a7813a04 | 1982 | pub fn to_self(&self) -> Option<ExplicitSelf> { |
e74abb32 | 1983 | if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind { |
dc9dc135 | 1984 | if ident.name == kw::SelfLower { |
e74abb32 | 1985 | return match self.ty.kind { |
3157f602 | 1986 | TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), |
e74abb32 | 1987 | TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { |
3157f602 | 1988 | Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) |
a7813a04 | 1989 | } |
0bf4aa26 XL |
1990 | _ => Some(respan( |
1991 | self.pat.span.to(self.ty.span), | |
1992 | SelfKind::Explicit(self.ty.clone(), mutbl), | |
1993 | )), | |
1994 | }; | |
a7813a04 XL |
1995 | } |
1996 | } | |
1997 | None | |
1998 | } | |
1999 | ||
e74abb32 | 2000 | /// Returns `true` if parameter is `self`. |
3157f602 | 2001 | pub fn is_self(&self) -> bool { |
e74abb32 | 2002 | if let PatKind::Ident(_, ident, _) = self.pat.kind { |
dc9dc135 | 2003 | ident.name == kw::SelfLower |
3157f602 XL |
2004 | } else { |
2005 | false | |
2006 | } | |
2007 | } | |
2008 | ||
e74abb32 | 2009 | /// Builds a `Param` object from `ExplicitSelf`. |
dfeec247 | 2010 | pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param { |
cc61c64b | 2011 | let span = eself.span.to(eself_ident.span); |
dfeec247 | 2012 | let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span }); |
e1599b0c | 2013 | let param = |mutbl, ty| Param { |
dc9dc135 | 2014 | attrs, |
3157f602 XL |
2015 | pat: P(Pat { |
2016 | id: DUMMY_NODE_ID, | |
e74abb32 | 2017 | kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), |
3b2f2976 | 2018 | span, |
3157f602 | 2019 | }), |
416331ca | 2020 | span, |
3b2f2976 | 2021 | ty, |
a7813a04 | 2022 | id: DUMMY_NODE_ID, |
dfeec247 | 2023 | is_placeholder: false, |
a7813a04 XL |
2024 | }; |
2025 | match eself.node { | |
e1599b0c XL |
2026 | SelfKind::Explicit(ty, mutbl) => param(mutbl, ty), |
2027 | SelfKind::Value(mutbl) => param(mutbl, infer_ty), | |
2028 | SelfKind::Region(lt, mutbl) => param( | |
dfeec247 | 2029 | Mutability::Not, |
0bf4aa26 XL |
2030 | P(Ty { |
2031 | id: DUMMY_NODE_ID, | |
dfeec247 | 2032 | kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }), |
0bf4aa26 XL |
2033 | span, |
2034 | }), | |
2035 | ), | |
a7813a04 XL |
2036 | } |
2037 | } | |
223e47cc LB |
2038 | } |
2039 | ||
e74abb32 | 2040 | /// A signature (not the body) of a function declaration. |
3157f602 | 2041 | /// |
0731742a | 2042 | /// E.g., `fn foo(bar: baz)`. |
e74abb32 XL |
2043 | /// |
2044 | /// Please note that it's different from `FnHeader` structure | |
2045 | /// which contains metadata about function safety, asyncness, constness and ABI. | |
8faf50e0 | 2046 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 2047 | pub struct FnDecl { |
e1599b0c | 2048 | pub inputs: Vec<Param>, |
74b04a01 | 2049 | pub output: FnRetTy, |
1a4d82fc JJ |
2050 | } |
2051 | ||
3157f602 XL |
2052 | impl FnDecl { |
2053 | pub fn get_self(&self) -> Option<ExplicitSelf> { | |
e1599b0c | 2054 | self.inputs.get(0).and_then(Param::to_self) |
3157f602 XL |
2055 | } |
2056 | pub fn has_self(&self) -> bool { | |
e74abb32 XL |
2057 | self.inputs.get(0).map_or(false, Param::is_self) |
2058 | } | |
2059 | pub fn c_variadic(&self) -> bool { | |
2060 | self.inputs.last().map_or(false, |arg| match arg.ty.kind { | |
2061 | TyKind::CVarArgs => true, | |
2062 | _ => false, | |
2063 | }) | |
3157f602 XL |
2064 | } |
2065 | } | |
2066 | ||
abe05a73 | 2067 | /// Is the trait definition an auto trait? |
60c5eb7d | 2068 | #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
abe05a73 XL |
2069 | pub enum IsAuto { |
2070 | Yes, | |
0bf4aa26 | 2071 | No, |
abe05a73 XL |
2072 | } |
2073 | ||
74b04a01 XL |
2074 | #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] |
2075 | #[derive(HashStable_Generic)] | |
2076 | pub enum Unsafe { | |
2077 | Yes(Span), | |
2078 | No, | |
60c5eb7d XL |
2079 | } |
2080 | ||
dc9dc135 | 2081 | #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] |
74b04a01 XL |
2082 | pub enum Async { |
2083 | Yes { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId }, | |
2084 | No, | |
8faf50e0 XL |
2085 | } |
2086 | ||
74b04a01 | 2087 | impl Async { |
dc9dc135 | 2088 | pub fn is_async(self) -> bool { |
74b04a01 | 2089 | if let Async::Yes { .. } = self { true } else { false } |
8faf50e0 | 2090 | } |
0731742a | 2091 | |
74b04a01 | 2092 | /// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item. |
dc9dc135 | 2093 | pub fn opt_return_id(self) -> Option<NodeId> { |
8faf50e0 | 2094 | match self { |
74b04a01 XL |
2095 | Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id), |
2096 | Async::No => None, | |
8faf50e0 XL |
2097 | } |
2098 | } | |
2099 | } | |
2100 | ||
dfeec247 XL |
2101 | #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] |
2102 | #[derive(HashStable_Generic)] | |
74b04a01 XL |
2103 | pub enum Const { |
2104 | Yes(Span), | |
2105 | No, | |
62682a34 SL |
2106 | } |
2107 | ||
e74abb32 XL |
2108 | /// Item defaultness. |
2109 | /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532). | |
60c5eb7d | 2110 | #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
54a0048b | 2111 | pub enum Defaultness { |
74b04a01 | 2112 | Default(Span), |
54a0048b SL |
2113 | Final, |
2114 | } | |
2115 | ||
60c5eb7d | 2116 | #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)] |
1a4d82fc | 2117 | pub enum ImplPolarity { |
c34b1796 | 2118 | /// `impl Trait for Type` |
1a4d82fc | 2119 | Positive, |
c34b1796 | 2120 | /// `impl !Trait for Type` |
1a4d82fc JJ |
2121 | Negative, |
2122 | } | |
2123 | ||
85aaf69f | 2124 | impl fmt::Debug for ImplPolarity { |
9fa01778 | 2125 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
223e47cc | 2126 | match *self { |
1a4d82fc JJ |
2127 | ImplPolarity::Positive => "positive".fmt(f), |
2128 | ImplPolarity::Negative => "negative".fmt(f), | |
223e47cc LB |
2129 | } |
2130 | } | |
2131 | } | |
2132 | ||
8faf50e0 | 2133 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
74b04a01 | 2134 | pub enum FnRetTy { |
9fa01778 | 2135 | /// Returns type is not specified. |
c34b1796 | 2136 | /// |
0731742a XL |
2137 | /// Functions default to `()` and closures default to inference. |
2138 | /// Span points to where return type would be inserted. | |
7453a54e | 2139 | Default(Span), |
0731742a | 2140 | /// Everything else. |
7453a54e | 2141 | Ty(P<Ty>), |
1a4d82fc JJ |
2142 | } |
2143 | ||
74b04a01 | 2144 | impl FnRetTy { |
1a4d82fc JJ |
2145 | pub fn span(&self) -> Span { |
2146 | match *self { | |
74b04a01 XL |
2147 | FnRetTy::Default(span) => span, |
2148 | FnRetTy::Ty(ref ty) => ty.span, | |
1a4d82fc JJ |
2149 | } |
2150 | } | |
223e47cc LB |
2151 | } |
2152 | ||
3157f602 XL |
2153 | /// Module declaration. |
2154 | /// | |
0731742a | 2155 | /// E.g., `mod foo;` or `mod foo { .. }`. |
8faf50e0 | 2156 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
2157 | pub struct Mod { |
2158 | /// A span from the first token past `{` to the last token until `}`. | |
2159 | /// For `mod foo;`, the inner span ranges from the first token | |
2160 | /// to the last token in the external file. | |
2161 | pub inner: Span, | |
1a4d82fc | 2162 | pub items: Vec<P<Item>>, |
0731742a | 2163 | /// `true` for `mod foo { .. }`; `false` for `mod foo;`. |
0bf4aa26 | 2164 | pub inline: bool, |
1a4d82fc | 2165 | } |
223e47cc | 2166 | |
3157f602 XL |
2167 | /// Foreign module declaration. |
2168 | /// | |
0731742a | 2169 | /// E.g., `extern { .. }` or `extern C { .. }`. |
8faf50e0 | 2170 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 2171 | pub struct ForeignMod { |
60c5eb7d | 2172 | pub abi: Option<StrLit>, |
74b04a01 | 2173 | pub items: Vec<P<ForeignItem>>, |
223e47cc LB |
2174 | } |
2175 | ||
0731742a | 2176 | /// Global inline assembly. |
cc61c64b | 2177 | /// |
0731742a | 2178 | /// Also known as "module-level assembly" or "file-scoped assembly". |
8faf50e0 | 2179 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)] |
cc61c64b XL |
2180 | pub struct GlobalAsm { |
2181 | pub asm: Symbol, | |
cc61c64b XL |
2182 | } |
2183 | ||
8faf50e0 | 2184 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 2185 | pub struct EnumDef { |
7453a54e | 2186 | pub variants: Vec<Variant>, |
223e47cc | 2187 | } |
e74abb32 | 2188 | /// Enum variant. |
8faf50e0 | 2189 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
e1599b0c | 2190 | pub struct Variant { |
532ac7d7 | 2191 | /// Attributes of the variant. |
1a4d82fc | 2192 | pub attrs: Vec<Attribute>, |
532ac7d7 XL |
2193 | /// Id of the variant (not the constructor, see `VariantData::ctor_id()`). |
2194 | pub id: NodeId, | |
60c5eb7d XL |
2195 | /// Span |
2196 | pub span: Span, | |
2197 | /// The visibility of the variant. Syntactically accepted but not semantically. | |
2198 | pub vis: Visibility, | |
2199 | /// Name of the variant. | |
2200 | pub ident: Ident, | |
2201 | ||
532ac7d7 | 2202 | /// Fields and constructor id of the variant. |
b039eaaf | 2203 | pub data: VariantData, |
0731742a | 2204 | /// Explicit discriminant, e.g., `Foo = 1`. |
94b46f34 | 2205 | pub disr_expr: Option<AnonConst>, |
e1599b0c XL |
2206 | /// Is a macro placeholder |
2207 | pub is_placeholder: bool, | |
223e47cc LB |
2208 | } |
2209 | ||
0531ce1d | 2210 | /// Part of `use` item to the right of its prefix. |
8faf50e0 | 2211 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
ff7c6d11 | 2212 | pub enum UseTreeKind { |
0531ce1d | 2213 | /// `use prefix` or `use prefix as rename` |
94b46f34 XL |
2214 | /// |
2215 | /// The extra `NodeId`s are for HIR lowering, when additional statements are created for each | |
2216 | /// namespace. | |
2217 | Simple(Option<Ident>, NodeId, NodeId), | |
0531ce1d | 2218 | /// `use prefix::{...}` |
ff7c6d11 | 2219 | Nested(Vec<(UseTree, NodeId)>), |
0531ce1d XL |
2220 | /// `use prefix::*` |
2221 | Glob, | |
223e47cc LB |
2222 | } |
2223 | ||
0531ce1d XL |
2224 | /// A tree of paths sharing common prefixes. |
2225 | /// Used in `use` items both at top-level and inside of braces in import groups. | |
8faf50e0 | 2226 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
ff7c6d11 | 2227 | pub struct UseTree { |
ff7c6d11 | 2228 | pub prefix: Path, |
0531ce1d | 2229 | pub kind: UseTreeKind, |
ff7c6d11 | 2230 | pub span: Span, |
3157f602 XL |
2231 | } |
2232 | ||
0531ce1d XL |
2233 | impl UseTree { |
2234 | pub fn ident(&self) -> Ident { | |
2235 | match self.kind { | |
94b46f34 | 2236 | UseTreeKind::Simple(Some(rename), ..) => rename, |
0bf4aa26 | 2237 | UseTreeKind::Simple(None, ..) => { |
dfeec247 | 2238 | self.prefix.segments.last().expect("empty prefix in a simple import").ident |
0bf4aa26 | 2239 | } |
0531ce1d XL |
2240 | _ => panic!("`UseTree::ident` can only be used on a simple import"), |
2241 | } | |
2242 | } | |
2243 | } | |
2244 | ||
0731742a | 2245 | /// Distinguishes between `Attribute`s that decorate items and Attributes that |
1a4d82fc JJ |
2246 | /// are contained as statements within items. These two cases need to be |
2247 | /// distinguished for pretty-printing. | |
60c5eb7d | 2248 | #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)] |
1a4d82fc | 2249 | pub enum AttrStyle { |
b039eaaf SL |
2250 | Outer, |
2251 | Inner, | |
1a4d82fc | 2252 | } |
223e47cc | 2253 | |
416331ca | 2254 | #[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)] |
85aaf69f | 2255 | pub struct AttrId(pub usize); |
1a4d82fc | 2256 | |
b7449926 XL |
2257 | impl Idx for AttrId { |
2258 | fn new(idx: usize) -> Self { | |
2259 | AttrId(idx) | |
2260 | } | |
2261 | fn index(self) -> usize { | |
2262 | self.0 | |
2263 | } | |
2264 | } | |
2265 | ||
416331ca XL |
2266 | impl rustc_serialize::Encodable for AttrId { |
2267 | fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
2268 | s.emit_unit() | |
2269 | } | |
2270 | } | |
2271 | ||
2272 | impl rustc_serialize::Decodable for AttrId { | |
2273 | fn decode<D: Decoder>(d: &mut D) -> Result<AttrId, D::Error> { | |
2274 | d.read_nil().map(|_| crate::attr::mk_attr_id()) | |
2275 | } | |
2276 | } | |
2277 | ||
60c5eb7d | 2278 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
e74abb32 XL |
2279 | pub struct AttrItem { |
2280 | pub path: Path, | |
60c5eb7d | 2281 | pub args: MacArgs, |
e74abb32 XL |
2282 | } |
2283 | ||
dfeec247 XL |
2284 | /// A list of attributes. |
2285 | pub type AttrVec = ThinVec<Attribute>; | |
2286 | ||
0731742a | 2287 | /// Metadata associated with an item. |
8faf50e0 | 2288 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
476ff2be | 2289 | pub struct Attribute { |
60c5eb7d | 2290 | pub kind: AttrKind, |
1a4d82fc | 2291 | pub id: AttrId, |
e74abb32 XL |
2292 | /// Denotes if the attribute decorates the following construct (outer) |
2293 | /// or the construct this attribute is contained within (inner). | |
1a4d82fc | 2294 | pub style: AttrStyle, |
476ff2be | 2295 | pub span: Span, |
223e47cc LB |
2296 | } |
2297 | ||
60c5eb7d XL |
2298 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
2299 | pub enum AttrKind { | |
2300 | /// A normal attribute. | |
2301 | Normal(AttrItem), | |
2302 | ||
2303 | /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`). | |
2304 | /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal` | |
2305 | /// variant (which is much less compact and thus more expensive). | |
60c5eb7d | 2306 | DocComment(Symbol), |
e74abb32 XL |
2307 | } |
2308 | ||
0731742a | 2309 | /// `TraitRef`s appear in impls. |
c34b1796 | 2310 | /// |
9fa01778 | 2311 | /// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all |
0731742a XL |
2312 | /// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl. |
2313 | /// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the | |
9fa01778 | 2314 | /// same as the impl's `NodeId`). |
8faf50e0 | 2315 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc JJ |
2316 | pub struct TraitRef { |
2317 | pub path: Path, | |
2318 | pub ref_id: NodeId, | |
223e47cc LB |
2319 | } |
2320 | ||
8faf50e0 | 2321 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
1a4d82fc | 2322 | pub struct PolyTraitRef { |
dc9dc135 | 2323 | /// The `'a` in `<'a> Foo<&'a T>`. |
ff7c6d11 | 2324 | pub bound_generic_params: Vec<GenericParam>, |
223e47cc | 2325 | |
dc9dc135 | 2326 | /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. |
1a4d82fc | 2327 | pub trait_ref: TraitRef, |
85aaf69f SL |
2328 | |
2329 | pub span: Span, | |
1a4d82fc JJ |
2330 | } |
2331 | ||
cc61c64b | 2332 | impl PolyTraitRef { |
ff7c6d11 | 2333 | pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self { |
cc61c64b | 2334 | PolyTraitRef { |
ff7c6d11 | 2335 | bound_generic_params: generic_params, |
dfeec247 | 2336 | trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, |
3b2f2976 | 2337 | span, |
cc61c64b XL |
2338 | } |
2339 | } | |
2340 | } | |
2341 | ||
60c5eb7d | 2342 | #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] |
abe05a73 | 2343 | pub enum CrateSugar { |
0731742a | 2344 | /// Source is `pub(crate)`. |
abe05a73 XL |
2345 | PubCrate, |
2346 | ||
0731742a | 2347 | /// Source is (just) `crate`. |
abe05a73 XL |
2348 | JustCrate, |
2349 | } | |
2350 | ||
0531ce1d XL |
2351 | pub type Visibility = Spanned<VisibilityKind>; |
2352 | ||
8faf50e0 | 2353 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
0531ce1d | 2354 | pub enum VisibilityKind { |
1a4d82fc | 2355 | Public, |
0531ce1d | 2356 | Crate(CrateSugar), |
54a0048b | 2357 | Restricted { path: P<Path>, id: NodeId }, |
1a4d82fc JJ |
2358 | Inherited, |
2359 | } | |
2360 | ||
8faf50e0 XL |
2361 | impl VisibilityKind { |
2362 | pub fn is_pub(&self) -> bool { | |
dfeec247 | 2363 | if let VisibilityKind::Public = *self { true } else { false } |
8faf50e0 XL |
2364 | } |
2365 | } | |
2366 | ||
3157f602 XL |
2367 | /// Field of a struct. |
2368 | /// | |
0731742a | 2369 | /// E.g., `bar: usize` as in `struct Foo { bar: usize }`. |
8faf50e0 | 2370 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
54a0048b | 2371 | pub struct StructField { |
60c5eb7d XL |
2372 | pub attrs: Vec<Attribute>, |
2373 | pub id: NodeId, | |
54a0048b | 2374 | pub span: Span, |
54a0048b | 2375 | pub vis: Visibility, |
60c5eb7d XL |
2376 | pub ident: Option<Ident>, |
2377 | ||
1a4d82fc | 2378 | pub ty: P<Ty>, |
e1599b0c | 2379 | pub is_placeholder: bool, |
1a4d82fc JJ |
2380 | } |
2381 | ||
532ac7d7 | 2382 | /// Fields and constructor ids of enum variants and structs. |
8faf50e0 | 2383 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
b039eaaf | 2384 | pub enum VariantData { |
3157f602 XL |
2385 | /// Struct variant. |
2386 | /// | |
0731742a | 2387 | /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. |
532ac7d7 | 2388 | Struct(Vec<StructField>, bool), |
3157f602 XL |
2389 | /// Tuple variant. |
2390 | /// | |
0731742a | 2391 | /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. |
b039eaaf | 2392 | Tuple(Vec<StructField>, NodeId), |
3157f602 XL |
2393 | /// Unit variant. |
2394 | /// | |
0731742a | 2395 | /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`. |
b039eaaf SL |
2396 | Unit(NodeId), |
2397 | } | |
2398 | ||
2399 | impl VariantData { | |
532ac7d7 | 2400 | /// Return the fields of this variant. |
b039eaaf SL |
2401 | pub fn fields(&self) -> &[StructField] { |
2402 | match *self { | |
532ac7d7 | 2403 | VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields, |
b039eaaf SL |
2404 | _ => &[], |
2405 | } | |
2406 | } | |
532ac7d7 XL |
2407 | |
2408 | /// Return the `NodeId` of this variant's constructor, if it has one. | |
2409 | pub fn ctor_id(&self) -> Option<NodeId> { | |
b039eaaf | 2410 | match *self { |
532ac7d7 XL |
2411 | VariantData::Struct(..) => None, |
2412 | VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), | |
0bf4aa26 | 2413 | } |
b039eaaf | 2414 | } |
223e47cc LB |
2415 | } |
2416 | ||
74b04a01 | 2417 | /// An item definition. |
8faf50e0 | 2418 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
60c5eb7d | 2419 | pub struct Item<K = ItemKind> { |
1a4d82fc JJ |
2420 | pub attrs: Vec<Attribute>, |
2421 | pub id: NodeId, | |
1a4d82fc | 2422 | pub span: Span, |
60c5eb7d | 2423 | pub vis: Visibility, |
74b04a01 XL |
2424 | /// The name of the item. |
2425 | /// It might be a dummy name in case of anonymous items. | |
60c5eb7d XL |
2426 | pub ident: Ident, |
2427 | ||
2428 | pub kind: K, | |
3b2f2976 XL |
2429 | |
2430 | /// Original tokens this item was parsed from. This isn't necessarily | |
2431 | /// available for all items, although over time more and more items should | |
2432 | /// have this be `Some`. Right now this is primarily used for procedural | |
2433 | /// macros, notably custom attributes. | |
2434 | /// | |
2435 | /// Note that the tokens here do not include the outer attributes, but will | |
2436 | /// include inner attributes. | |
2437 | pub tokens: Option<TokenStream>, | |
1a4d82fc JJ |
2438 | } |
2439 | ||
9fa01778 XL |
2440 | impl Item { |
2441 | /// Return the span that encompasses the attributes. | |
2442 | pub fn span_with_attributes(&self) -> Span { | |
532ac7d7 | 2443 | self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span)) |
9fa01778 XL |
2444 | } |
2445 | } | |
2446 | ||
74b04a01 XL |
2447 | impl<K: Into<ItemKind>> Item<K> { |
2448 | pub fn into_item(self) -> Item { | |
2449 | let Item { attrs, id, span, vis, ident, kind, tokens } = self; | |
2450 | Item { attrs, id, span, vis, ident, kind: kind.into(), tokens } | |
2451 | } | |
2452 | } | |
2453 | ||
60c5eb7d XL |
2454 | /// `extern` qualifier on a function item or function type. |
2455 | #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] | |
2456 | pub enum Extern { | |
2457 | None, | |
2458 | Implicit, | |
2459 | Explicit(StrLit), | |
2460 | } | |
2461 | ||
2462 | impl Extern { | |
2463 | pub fn from_abi(abi: Option<StrLit>) -> Extern { | |
2464 | abi.map_or(Extern::Implicit, Extern::Explicit) | |
2465 | } | |
2466 | } | |
2467 | ||
0731742a | 2468 | /// A function header. |
8faf50e0 | 2469 | /// |
0731742a XL |
2470 | /// All the information between the visibility and the name of the function is |
2471 | /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`). | |
dc9dc135 | 2472 | #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] |
8faf50e0 | 2473 | pub struct FnHeader { |
74b04a01 XL |
2474 | pub unsafety: Unsafe, |
2475 | pub asyncness: Async, | |
2476 | pub constness: Const, | |
60c5eb7d | 2477 | pub ext: Extern, |
8faf50e0 XL |
2478 | } |
2479 | ||
74b04a01 XL |
2480 | impl FnHeader { |
2481 | /// Does this function header have any qualifiers or is it empty? | |
2482 | pub fn has_qualifiers(&self) -> bool { | |
2483 | let Self { unsafety, asyncness, constness, ext } = self; | |
2484 | matches!(unsafety, Unsafe::Yes(_)) | |
2485 | || asyncness.is_async() | |
2486 | || matches!(constness, Const::Yes(_)) | |
2487 | || !matches!(ext, Extern::None) | |
2488 | } | |
2489 | } | |
2490 | ||
8faf50e0 XL |
2491 | impl Default for FnHeader { |
2492 | fn default() -> FnHeader { | |
2493 | FnHeader { | |
74b04a01 XL |
2494 | unsafety: Unsafe::No, |
2495 | asyncness: Async::No, | |
2496 | constness: Const::No, | |
60c5eb7d | 2497 | ext: Extern::None, |
8faf50e0 XL |
2498 | } |
2499 | } | |
2500 | } | |
2501 | ||
2502 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] | |
7453a54e | 2503 | pub enum ItemKind { |
e1599b0c | 2504 | /// An `extern crate` item, with the optional *original* crate name if the crate was renamed. |
c34b1796 | 2505 | /// |
0731742a | 2506 | /// E.g., `extern crate foo` or `extern crate foo_bar as foo`. |
7453a54e | 2507 | ExternCrate(Option<Name>), |
e1599b0c | 2508 | /// A use declaration item (`use`). |
3157f602 | 2509 | /// |
0731742a | 2510 | /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`. |
ff7c6d11 | 2511 | Use(P<UseTree>), |
e1599b0c | 2512 | /// A static item (`static`). |
3157f602 | 2513 | /// |
0731742a | 2514 | /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`. |
74b04a01 | 2515 | Static(P<Ty>, Mutability, Option<P<Expr>>), |
e1599b0c | 2516 | /// A constant item (`const`). |
3157f602 | 2517 | /// |
0731742a | 2518 | /// E.g., `const FOO: i32 = 42;`. |
74b04a01 | 2519 | Const(Defaultness, P<Ty>, Option<P<Expr>>), |
e1599b0c | 2520 | /// A function declaration (`fn`). |
3157f602 | 2521 | /// |
0731742a | 2522 | /// E.g., `fn foo(bar: usize) -> usize { .. }`. |
74b04a01 | 2523 | Fn(Defaultness, FnSig, Generics, Option<P<Block>>), |
e1599b0c | 2524 | /// A module declaration (`mod`). |
3157f602 | 2525 | /// |
0731742a | 2526 | /// E.g., `mod foo;` or `mod foo { .. }`. |
7453a54e | 2527 | Mod(Mod), |
e1599b0c | 2528 | /// An external module (`extern`). |
3157f602 | 2529 | /// |
0731742a | 2530 | /// E.g., `extern {}` or `extern "C" {}`. |
7453a54e | 2531 | ForeignMod(ForeignMod), |
0731742a | 2532 | /// Module-level inline assembly (from `global_asm!()`). |
cc61c64b | 2533 | GlobalAsm(P<GlobalAsm>), |
e1599b0c | 2534 | /// A type alias (`type`). |
3157f602 | 2535 | /// |
0731742a | 2536 | /// E.g., `type Foo = Bar<u8>;`. |
74b04a01 | 2537 | TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>), |
e1599b0c | 2538 | /// An enum definition (`enum`). |
3157f602 | 2539 | /// |
0731742a | 2540 | /// E.g., `enum Foo<A, B> { C<A>, D<B> }`. |
7453a54e | 2541 | Enum(EnumDef, Generics), |
e1599b0c | 2542 | /// A struct definition (`struct`). |
3157f602 | 2543 | /// |
0731742a | 2544 | /// E.g., `struct Foo<A> { x: A }`. |
7453a54e | 2545 | Struct(VariantData, Generics), |
e1599b0c | 2546 | /// A union definition (`union`). |
9e0c209e | 2547 | /// |
0731742a | 2548 | /// E.g., `union Foo<A, B> { x: A, y: B }`. |
9e0c209e | 2549 | Union(VariantData, Generics), |
e1599b0c | 2550 | /// A trait declaration (`trait`). |
3157f602 | 2551 | /// |
0731742a | 2552 | /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`. |
74b04a01 | 2553 | Trait(IsAuto, Unsafe, Generics, GenericBounds, Vec<P<AssocItem>>), |
ff7c6d11 XL |
2554 | /// Trait alias |
2555 | /// | |
0731742a | 2556 | /// E.g., `trait Foo = Bar + Quux;`. |
8faf50e0 | 2557 | TraitAlias(Generics, GenericBounds), |
3157f602 XL |
2558 | /// An implementation. |
2559 | /// | |
0731742a | 2560 | /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`. |
dfeec247 | 2561 | Impl { |
74b04a01 | 2562 | unsafety: Unsafe, |
dfeec247 XL |
2563 | polarity: ImplPolarity, |
2564 | defaultness: Defaultness, | |
74b04a01 | 2565 | constness: Const, |
dfeec247 XL |
2566 | generics: Generics, |
2567 | ||
2568 | /// The trait being implemented, if any. | |
2569 | of_trait: Option<TraitRef>, | |
2570 | ||
2571 | self_ty: P<Ty>, | |
74b04a01 | 2572 | items: Vec<P<AssocItem>>, |
dfeec247 | 2573 | }, |
8bb4bdeb | 2574 | /// A macro invocation. |
3157f602 | 2575 | /// |
e1599b0c | 2576 | /// E.g., `foo!(..)`. |
7453a54e | 2577 | Mac(Mac), |
8bb4bdeb XL |
2578 | |
2579 | /// A macro definition. | |
7cac9316 | 2580 | MacroDef(MacroDef), |
1a4d82fc JJ |
2581 | } |
2582 | ||
7453a54e | 2583 | impl ItemKind { |
74b04a01 XL |
2584 | pub fn article(&self) -> &str { |
2585 | use ItemKind::*; | |
2586 | match self { | |
2587 | Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..) | |
2588 | | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a", | |
2589 | ExternCrate(..) | ForeignMod(..) | Mac(..) | Enum(..) | Impl { .. } => "an", | |
2590 | } | |
2591 | } | |
2592 | ||
2593 | pub fn descr(&self) -> &str { | |
2594 | match self { | |
7453a54e | 2595 | ItemKind::ExternCrate(..) => "extern crate", |
74b04a01 | 2596 | ItemKind::Use(..) => "`use` import", |
7453a54e SL |
2597 | ItemKind::Static(..) => "static item", |
2598 | ItemKind::Const(..) => "constant item", | |
2599 | ItemKind::Fn(..) => "function", | |
2600 | ItemKind::Mod(..) => "module", | |
74b04a01 XL |
2601 | ItemKind::ForeignMod(..) => "extern block", |
2602 | ItemKind::GlobalAsm(..) => "global asm item", | |
416331ca | 2603 | ItemKind::TyAlias(..) => "type alias", |
7453a54e SL |
2604 | ItemKind::Enum(..) => "enum", |
2605 | ItemKind::Struct(..) => "struct", | |
9e0c209e | 2606 | ItemKind::Union(..) => "union", |
7453a54e | 2607 | ItemKind::Trait(..) => "trait", |
ff7c6d11 | 2608 | ItemKind::TraitAlias(..) => "trait alias", |
74b04a01 XL |
2609 | ItemKind::Mac(..) => "item macro invocation", |
2610 | ItemKind::MacroDef(..) => "macro definition", | |
2611 | ItemKind::Impl { .. } => "implementation", | |
dfeec247 XL |
2612 | } |
2613 | } | |
2614 | ||
2615 | pub fn generics(&self) -> Option<&Generics> { | |
2616 | match self { | |
74b04a01 XL |
2617 | Self::Fn(_, _, generics, _) |
2618 | | Self::TyAlias(_, generics, ..) | |
dfeec247 XL |
2619 | | Self::Enum(_, generics) |
2620 | | Self::Struct(_, generics) | |
2621 | | Self::Union(_, generics) | |
2622 | | Self::Trait(_, _, generics, ..) | |
2623 | | Self::TraitAlias(generics, _) | |
2624 | | Self::Impl { generics, .. } => Some(generics), | |
2625 | _ => None, | |
1a4d82fc | 2626 | } |
970d7e83 | 2627 | } |
1a4d82fc | 2628 | } |
970d7e83 | 2629 | |
74b04a01 XL |
2630 | /// Represents associated items. |
2631 | /// These include items in `impl` and `trait` definitions. | |
2632 | pub type AssocItem = Item<AssocItemKind>; | |
2633 | ||
2634 | /// Represents associated item kinds. | |
2635 | /// | |
2636 | /// The term "provided" in the variants below refers to the item having a default | |
2637 | /// definition / body. Meanwhile, a "required" item lacks a definition / body. | |
2638 | /// In an implementation, all items must be provided. | |
2639 | /// The `Option`s below denote the bodies, where `Some(_)` | |
2640 | /// means "provided" and conversely `None` means "required". | |
2641 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] | |
2642 | pub enum AssocItemKind { | |
2643 | /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. | |
2644 | /// If `def` is parsed, then the constant is provided, and otherwise required. | |
2645 | Const(Defaultness, P<Ty>, Option<P<Expr>>), | |
2646 | /// An associated function. | |
2647 | Fn(Defaultness, FnSig, Generics, Option<P<Block>>), | |
2648 | /// An associated type. | |
2649 | TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>), | |
2650 | /// A macro expanding to associated items. | |
2651 | Macro(Mac), | |
2652 | } | |
2653 | ||
2654 | impl AssocItemKind { | |
2655 | pub fn defaultness(&self) -> Defaultness { | |
2656 | match *self { | |
2657 | Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def, | |
2658 | Self::Macro(..) => Defaultness::Final, | |
2659 | } | |
2660 | } | |
2661 | } | |
2662 | ||
2663 | impl From<AssocItemKind> for ItemKind { | |
2664 | fn from(assoc_item_kind: AssocItemKind) -> ItemKind { | |
2665 | match assoc_item_kind { | |
2666 | AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c), | |
2667 | AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d), | |
2668 | AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d), | |
2669 | AssocItemKind::Macro(a) => ItemKind::Mac(a), | |
2670 | } | |
2671 | } | |
2672 | } | |
970d7e83 | 2673 | |
74b04a01 XL |
2674 | impl TryFrom<ItemKind> for AssocItemKind { |
2675 | type Error = ItemKind; | |
2676 | ||
2677 | fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> { | |
2678 | Ok(match item_kind { | |
2679 | ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c), | |
2680 | ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d), | |
2681 | ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d), | |
2682 | ItemKind::Mac(a) => AssocItemKind::Macro(a), | |
2683 | _ => return Err(item_kind), | |
2684 | }) | |
2685 | } | |
2686 | } | |
2687 | ||
2688 | /// An item in `extern` block. | |
8faf50e0 | 2689 | #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] |
7453a54e | 2690 | pub enum ForeignItemKind { |
74b04a01 XL |
2691 | /// A foreign static item (`static FOO: u8`). |
2692 | Static(P<Ty>, Mutability, Option<P<Expr>>), | |
0731742a | 2693 | /// A foreign function. |
74b04a01 | 2694 | Fn(Defaultness, FnSig, Generics, Option<P<Block>>), |
0731742a | 2695 | /// A foreign type. |
74b04a01 XL |
2696 | TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>), |
2697 | /// A macro expanding to foreign items. | |
83c7162d | 2698 | Macro(Mac), |
1a4d82fc | 2699 | } |
970d7e83 | 2700 | |
74b04a01 XL |
2701 | impl From<ForeignItemKind> for ItemKind { |
2702 | fn from(foreign_item_kind: ForeignItemKind) -> ItemKind { | |
2703 | match foreign_item_kind { | |
2704 | ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c), | |
2705 | ForeignItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d), | |
2706 | ForeignItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d), | |
2707 | ForeignItemKind::Macro(a) => ItemKind::Mac(a), | |
1a4d82fc | 2708 | } |
223e47cc | 2709 | } |
1a4d82fc | 2710 | } |
74b04a01 XL |
2711 | |
2712 | impl TryFrom<ItemKind> for ForeignItemKind { | |
2713 | type Error = ItemKind; | |
2714 | ||
2715 | fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> { | |
2716 | Ok(match item_kind { | |
2717 | ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c), | |
2718 | ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d), | |
2719 | ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d), | |
2720 | ItemKind::Mac(a) => ForeignItemKind::Macro(a), | |
2721 | _ => return Err(item_kind), | |
2722 | }) | |
2723 | } | |
2724 | } | |
2725 | ||
2726 | pub type ForeignItem = Item<ForeignItemKind>; |