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