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