rustc_ast/
ast.rs

1//! The Rust abstract syntax tree module.
2//!
3//! This module contains common structures forming the language AST.
4//! Two main entities in the module are [`Item`] (which represents an AST element with
5//! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
6//! information specific to the type of the item).
7//!
8//! Other module items worth mentioning:
9//! - [`Ty`] and [`TyKind`]: A parsed Rust type.
10//! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
11//! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
12//! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value.
13//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
14//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
15//! - [`EnumDef`] and [`Variant`]: Enum declaration.
16//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
17//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`]: Macro definition and invocation.
18//! - [`Attribute`]: Metadata associated with item.
19//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
20
21use std::borrow::Cow;
22use std::sync::Arc;
23use std::{cmp, fmt};
24
25pub use GenericArgs::*;
26pub use UnsafeSource::*;
27pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
28use rustc_data_structures::packed::Pu128;
29use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30use rustc_data_structures::stack::ensure_sufficient_stack;
31use rustc_data_structures::tagged_ptr::Tag;
32use rustc_macros::{Decodable, Encodable, HashStable_Generic};
33pub use rustc_span::AttrId;
34use rustc_span::source_map::{Spanned, respan};
35use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
36use thin_vec::{ThinVec, thin_vec};
37
38pub use crate::format::*;
39use crate::ptr::P;
40use crate::token::{self, CommentKind, Delimiter};
41use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42use crate::util::parser::{ExprPrecedence, Fixity};
43
44/// A "Label" is an identifier of some point in sources,
45/// e.g. in the following code:
46///
47/// ```rust
48/// 'outer: loop {
49///     break 'outer;
50/// }
51/// ```
52///
53/// `'outer` is a label.
54#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
55pub struct Label {
56    pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "label({:?})", self.ident)
62    }
63}
64
65/// A "Lifetime" is an annotation of the scope in which variable
66/// can be used, e.g. `'a` in `&'a i32`.
67#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
68pub struct Lifetime {
69    pub id: NodeId,
70    pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(f, "lifetime({}: {})", self.id, self)
76    }
77}
78
79impl fmt::Display for Lifetime {
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        write!(f, "{}", self.ident.name)
82    }
83}
84
85/// A "Path" is essentially Rust's notion of a name.
86///
87/// It's represented as a sequence of identifiers,
88/// along with a bunch of supporting information.
89///
90/// E.g., `std::cmp::PartialEq`.
91#[derive(Clone, Encodable, Decodable, Debug)]
92pub struct Path {
93    pub span: Span,
94    /// The segments in the path: the things separated by `::`.
95    /// Global paths begin with `kw::PathRoot`.
96    pub segments: ThinVec<PathSegment>,
97    pub tokens: Option<LazyAttrTokenStream>,
98}
99
100// Succeeds if the path has a single segment that is arg-free and matches the given symbol.
101impl PartialEq<Symbol> for Path {
102    #[inline]
103    fn eq(&self, name: &Symbol) -> bool {
104        if let [segment] = self.segments.as_ref()
105            && segment == name
106        {
107            true
108        } else {
109            false
110        }
111    }
112}
113
114// Succeeds if the path has segments that are arg-free and match the given symbols.
115impl PartialEq<&[Symbol]> for Path {
116    #[inline]
117    fn eq(&self, names: &&[Symbol]) -> bool {
118        self.segments.len() == names.len()
119            && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
120    }
121}
122
123impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
124    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
125        self.segments.len().hash_stable(hcx, hasher);
126        for segment in &self.segments {
127            segment.ident.hash_stable(hcx, hasher);
128        }
129    }
130}
131
132impl Path {
133    /// Convert a span and an identifier to the corresponding
134    /// one-segment path.
135    pub fn from_ident(ident: Ident) -> Path {
136        Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
137    }
138
139    pub fn is_global(&self) -> bool {
140        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
141    }
142
143    /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_
144    /// be represented without an anon const in the HIR.
145    ///
146    /// If `allow_mgca_arg` is true (as should be the case in most situations when
147    /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true
148    /// because all paths are valid.
149    ///
150    /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args
151    /// (i.e., it is _potentially_ a const parameter).
152    #[tracing::instrument(level = "debug", ret)]
153    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
154        allow_mgca_arg
155            || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
156    }
157}
158
159/// A segment of a path: an identifier, an optional lifetime, and a set of types.
160///
161/// E.g., `std`, `String` or `Box<T>`.
162#[derive(Clone, Encodable, Decodable, Debug)]
163pub struct PathSegment {
164    /// The identifier portion of this path segment.
165    pub ident: Ident,
166
167    pub id: NodeId,
168
169    /// Type/lifetime parameters attached to this path. They come in
170    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
171    /// `None` means that no parameter list is supplied (`Path`),
172    /// `Some` means that parameter list is supplied (`Path<X, Y>`)
173    /// but it can be empty (`Path<>`).
174    /// `P` is used as a size optimization for the common case with no parameters.
175    pub args: Option<P<GenericArgs>>,
176}
177
178// Succeeds if the path segment is arg-free and matches the given symbol.
179impl PartialEq<Symbol> for PathSegment {
180    #[inline]
181    fn eq(&self, name: &Symbol) -> bool {
182        self.args.is_none() && self.ident.name == *name
183    }
184}
185
186impl PathSegment {
187    pub fn from_ident(ident: Ident) -> Self {
188        PathSegment { ident, id: DUMMY_NODE_ID, args: None }
189    }
190
191    pub fn path_root(span: Span) -> Self {
192        PathSegment::from_ident(Ident::new(kw::PathRoot, span))
193    }
194
195    pub fn span(&self) -> Span {
196        match &self.args {
197            Some(args) => self.ident.span.to(args.span()),
198            None => self.ident.span,
199        }
200    }
201}
202
203/// The generic arguments and associated item constraints of a path segment.
204///
205/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
206#[derive(Clone, Encodable, Decodable, Debug)]
207pub enum GenericArgs {
208    /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
209    AngleBracketed(AngleBracketedArgs),
210    /// The `(A, B)` and `C` in `Foo(A, B) -> C`.
211    Parenthesized(ParenthesizedArgs),
212    /// `(..)` in return type notation.
213    ParenthesizedElided(Span),
214}
215
216impl GenericArgs {
217    pub fn is_angle_bracketed(&self) -> bool {
218        matches!(self, AngleBracketed(..))
219    }
220
221    pub fn span(&self) -> Span {
222        match self {
223            AngleBracketed(data) => data.span,
224            Parenthesized(data) => data.span,
225            ParenthesizedElided(span) => *span,
226        }
227    }
228}
229
230/// Concrete argument in the sequence of generic args.
231#[derive(Clone, Encodable, Decodable, Debug)]
232pub enum GenericArg {
233    /// `'a` in `Foo<'a>`.
234    Lifetime(Lifetime),
235    /// `Bar` in `Foo<Bar>`.
236    Type(P<Ty>),
237    /// `1` in `Foo<1>`.
238    Const(AnonConst),
239}
240
241impl GenericArg {
242    pub fn span(&self) -> Span {
243        match self {
244            GenericArg::Lifetime(lt) => lt.ident.span,
245            GenericArg::Type(ty) => ty.span,
246            GenericArg::Const(ct) => ct.value.span,
247        }
248    }
249}
250
251/// A path like `Foo<'a, T>`.
252#[derive(Clone, Encodable, Decodable, Debug, Default)]
253pub struct AngleBracketedArgs {
254    /// The overall span.
255    pub span: Span,
256    /// The comma separated parts in the `<...>`.
257    pub args: ThinVec<AngleBracketedArg>,
258}
259
260/// Either an argument for a generic parameter or a constraint on an associated item.
261#[derive(Clone, Encodable, Decodable, Debug)]
262pub enum AngleBracketedArg {
263    /// A generic argument for a generic parameter.
264    Arg(GenericArg),
265    /// A constraint on an associated item.
266    Constraint(AssocItemConstraint),
267}
268
269impl AngleBracketedArg {
270    pub fn span(&self) -> Span {
271        match self {
272            AngleBracketedArg::Arg(arg) => arg.span(),
273            AngleBracketedArg::Constraint(constraint) => constraint.span,
274        }
275    }
276}
277
278impl From<AngleBracketedArgs> for P<GenericArgs> {
279    fn from(val: AngleBracketedArgs) -> Self {
280        P(GenericArgs::AngleBracketed(val))
281    }
282}
283
284impl From<ParenthesizedArgs> for P<GenericArgs> {
285    fn from(val: ParenthesizedArgs) -> Self {
286        P(GenericArgs::Parenthesized(val))
287    }
288}
289
290/// A path like `Foo(A, B) -> C`.
291#[derive(Clone, Encodable, Decodable, Debug)]
292pub struct ParenthesizedArgs {
293    /// ```text
294    /// Foo(A, B) -> C
295    /// ^^^^^^^^^^^^^^
296    /// ```
297    pub span: Span,
298
299    /// `(A, B)`
300    pub inputs: ThinVec<P<Ty>>,
301
302    /// ```text
303    /// Foo(A, B) -> C
304    ///    ^^^^^^
305    /// ```
306    pub inputs_span: Span,
307
308    /// `C`
309    pub output: FnRetTy,
310}
311
312impl ParenthesizedArgs {
313    pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
314        let args = self
315            .inputs
316            .iter()
317            .cloned()
318            .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
319            .collect();
320        AngleBracketedArgs { span: self.inputs_span, args }
321    }
322}
323
324pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
325
326/// Modifiers on a trait bound like `~const`, `?` and `!`.
327#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
328pub struct TraitBoundModifiers {
329    pub constness: BoundConstness,
330    pub asyncness: BoundAsyncness,
331    pub polarity: BoundPolarity,
332}
333
334impl TraitBoundModifiers {
335    pub const NONE: Self = Self {
336        constness: BoundConstness::Never,
337        asyncness: BoundAsyncness::Normal,
338        polarity: BoundPolarity::Positive,
339    };
340}
341
342#[derive(Clone, Encodable, Decodable, Debug)]
343pub enum GenericBound {
344    Trait(PolyTraitRef),
345    Outlives(Lifetime),
346    /// Precise capturing syntax: `impl Sized + use<'a>`
347    Use(ThinVec<PreciseCapturingArg>, Span),
348}
349
350impl GenericBound {
351    pub fn span(&self) -> Span {
352        match self {
353            GenericBound::Trait(t, ..) => t.span,
354            GenericBound::Outlives(l) => l.ident.span,
355            GenericBound::Use(_, span) => *span,
356        }
357    }
358}
359
360pub type GenericBounds = Vec<GenericBound>;
361
362/// Specifies the enforced ordering for generic parameters. In the future,
363/// if we wanted to relax this order, we could override `PartialEq` and
364/// `PartialOrd`, to allow the kinds to be unordered.
365#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
366pub enum ParamKindOrd {
367    Lifetime,
368    TypeOrConst,
369}
370
371impl fmt::Display for ParamKindOrd {
372    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373        match self {
374            ParamKindOrd::Lifetime => "lifetime".fmt(f),
375            ParamKindOrd::TypeOrConst => "type and const".fmt(f),
376        }
377    }
378}
379
380#[derive(Clone, Encodable, Decodable, Debug)]
381pub enum GenericParamKind {
382    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
383    Lifetime,
384    Type {
385        default: Option<P<Ty>>,
386    },
387    Const {
388        ty: P<Ty>,
389        /// Span of the `const` keyword.
390        kw_span: Span,
391        /// Optional default value for the const generic param.
392        default: Option<AnonConst>,
393    },
394}
395
396#[derive(Clone, Encodable, Decodable, Debug)]
397pub struct GenericParam {
398    pub id: NodeId,
399    pub ident: Ident,
400    pub attrs: AttrVec,
401    pub bounds: GenericBounds,
402    pub is_placeholder: bool,
403    pub kind: GenericParamKind,
404    pub colon_span: Option<Span>,
405}
406
407impl GenericParam {
408    pub fn span(&self) -> Span {
409        match &self.kind {
410            GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
411                self.ident.span
412            }
413            GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
414            GenericParamKind::Const { kw_span, default: Some(default), .. } => {
415                kw_span.to(default.value.span)
416            }
417            GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
418        }
419    }
420}
421
422/// Represents lifetime, type and const parameters attached to a declaration of
423/// a function, enum, trait, etc.
424#[derive(Clone, Encodable, Decodable, Debug, Default)]
425pub struct Generics {
426    pub params: ThinVec<GenericParam>,
427    pub where_clause: WhereClause,
428    pub span: Span,
429}
430
431/// A where-clause in a definition.
432#[derive(Clone, Encodable, Decodable, Debug, Default)]
433pub struct WhereClause {
434    /// `true` if we ate a `where` token.
435    ///
436    /// This can happen if we parsed no predicates, e.g., `struct Foo where {}`.
437    /// This allows us to pretty-print accurately and provide correct suggestion diagnostics.
438    pub has_where_token: bool,
439    pub predicates: ThinVec<WherePredicate>,
440    pub span: Span,
441}
442
443impl WhereClause {
444    pub fn is_empty(&self) -> bool {
445        !self.has_where_token && self.predicates.is_empty()
446    }
447}
448
449/// A single predicate in a where-clause.
450#[derive(Clone, Encodable, Decodable, Debug)]
451pub struct WherePredicate {
452    pub attrs: AttrVec,
453    pub kind: WherePredicateKind,
454    pub id: NodeId,
455    pub span: Span,
456    pub is_placeholder: bool,
457}
458
459/// Predicate kind in where-clause.
460#[derive(Clone, Encodable, Decodable, Debug)]
461pub enum WherePredicateKind {
462    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
463    BoundPredicate(WhereBoundPredicate),
464    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
465    RegionPredicate(WhereRegionPredicate),
466    /// An equality predicate (unsupported).
467    EqPredicate(WhereEqPredicate),
468}
469
470/// A type bound.
471///
472/// E.g., `for<'c> Foo: Send + Clone + 'c`.
473#[derive(Clone, Encodable, Decodable, Debug)]
474pub struct WhereBoundPredicate {
475    /// Any generics from a `for` binding.
476    pub bound_generic_params: ThinVec<GenericParam>,
477    /// The type being bounded.
478    pub bounded_ty: P<Ty>,
479    /// Trait and lifetime bounds (`Clone + Send + 'static`).
480    pub bounds: GenericBounds,
481}
482
483/// A lifetime predicate.
484///
485/// E.g., `'a: 'b + 'c`.
486#[derive(Clone, Encodable, Decodable, Debug)]
487pub struct WhereRegionPredicate {
488    pub lifetime: Lifetime,
489    pub bounds: GenericBounds,
490}
491
492/// An equality predicate (unsupported).
493///
494/// E.g., `T = int`.
495#[derive(Clone, Encodable, Decodable, Debug)]
496pub struct WhereEqPredicate {
497    pub lhs_ty: P<Ty>,
498    pub rhs_ty: P<Ty>,
499}
500
501#[derive(Clone, Encodable, Decodable, Debug)]
502pub struct Crate {
503    pub attrs: AttrVec,
504    pub items: ThinVec<P<Item>>,
505    pub spans: ModSpans,
506    /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
507    /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
508    pub id: NodeId,
509    pub is_placeholder: bool,
510}
511
512/// A semantic representation of a meta item. A meta item is a slightly
513/// restricted form of an attribute -- it can only contain expressions in
514/// certain leaf positions, rather than arbitrary token streams -- that is used
515/// for most built-in attributes.
516///
517/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
518#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
519pub struct MetaItem {
520    pub unsafety: Safety,
521    pub path: Path,
522    pub kind: MetaItemKind,
523    pub span: Span,
524}
525
526/// The meta item kind, containing the data after the initial path.
527#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
528pub enum MetaItemKind {
529    /// Word meta item.
530    ///
531    /// E.g., `#[test]`, which lacks any arguments after `test`.
532    Word,
533
534    /// List meta item.
535    ///
536    /// E.g., `#[derive(..)]`, where the field represents the `..`.
537    List(ThinVec<MetaItemInner>),
538
539    /// Name value meta item.
540    ///
541    /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
542    NameValue(MetaItemLit),
543}
544
545/// Values inside meta item lists.
546///
547/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
548#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
549pub enum MetaItemInner {
550    /// A full MetaItem, for recursive meta items.
551    MetaItem(MetaItem),
552
553    /// A literal.
554    ///
555    /// E.g., `"foo"`, `64`, `true`.
556    Lit(MetaItemLit),
557}
558
559/// A block (`{ .. }`).
560///
561/// E.g., `{ .. }` as in `fn foo() { .. }`.
562#[derive(Clone, Encodable, Decodable, Debug)]
563pub struct Block {
564    /// The statements in the block.
565    pub stmts: ThinVec<Stmt>,
566    pub id: NodeId,
567    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
568    pub rules: BlockCheckMode,
569    pub span: Span,
570    pub tokens: Option<LazyAttrTokenStream>,
571}
572
573/// A match pattern.
574///
575/// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
576#[derive(Clone, Encodable, Decodable, Debug)]
577pub struct Pat {
578    pub id: NodeId,
579    pub kind: PatKind,
580    pub span: Span,
581    pub tokens: Option<LazyAttrTokenStream>,
582}
583
584impl Pat {
585    /// Attempt reparsing the pattern as a type.
586    /// This is intended for use by diagnostics.
587    pub fn to_ty(&self) -> Option<P<Ty>> {
588        let kind = match &self.kind {
589            PatKind::Missing => unreachable!(),
590            // In a type expression `_` is an inference variable.
591            PatKind::Wild => TyKind::Infer,
592            // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
593            PatKind::Ident(BindingMode::NONE, ident, None) => {
594                TyKind::Path(None, Path::from_ident(*ident))
595            }
596            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
597            PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
598            // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
599            PatKind::Ref(pat, mutbl) => {
600                pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
601            }
602            // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
603            // when `P` can be reparsed as a type `T`.
604            PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
605                pat.to_ty().map(TyKind::Slice)?
606            }
607            // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
608            // assuming `T0` to `Tn` are all syntactically valid as types.
609            PatKind::Tuple(pats) => {
610                let mut tys = ThinVec::with_capacity(pats.len());
611                // FIXME(#48994) - could just be collected into an Option<Vec>
612                for pat in pats {
613                    tys.push(pat.to_ty()?);
614                }
615                TyKind::Tup(tys)
616            }
617            _ => return None,
618        };
619
620        Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
621    }
622
623    /// Walk top-down and call `it` in each place where a pattern occurs
624    /// starting with the root pattern `walk` is called on. If `it` returns
625    /// false then we will descend no further but siblings will be processed.
626    pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
627        if !it(self) {
628            return;
629        }
630
631        match &self.kind {
632            // Walk into the pattern associated with `Ident` (if any).
633            PatKind::Ident(_, _, Some(p)) => p.walk(it),
634
635            // Walk into each field of struct.
636            PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
637
638            // Sequence of patterns.
639            PatKind::TupleStruct(_, _, s)
640            | PatKind::Tuple(s)
641            | PatKind::Slice(s)
642            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
643
644            // Trivial wrappers over inner patterns.
645            PatKind::Box(s)
646            | PatKind::Deref(s)
647            | PatKind::Ref(s, _)
648            | PatKind::Paren(s)
649            | PatKind::Guard(s, _) => s.walk(it),
650
651            // These patterns do not contain subpatterns, skip.
652            PatKind::Missing
653            | PatKind::Wild
654            | PatKind::Rest
655            | PatKind::Never
656            | PatKind::Expr(_)
657            | PatKind::Range(..)
658            | PatKind::Ident(..)
659            | PatKind::Path(..)
660            | PatKind::MacCall(_)
661            | PatKind::Err(_) => {}
662        }
663    }
664
665    /// Is this a `..` pattern?
666    pub fn is_rest(&self) -> bool {
667        matches!(self.kind, PatKind::Rest)
668    }
669
670    /// Whether this could be a never pattern, taking into account that a macro invocation can
671    /// return a never pattern. Used to inform errors during parsing.
672    pub fn could_be_never_pattern(&self) -> bool {
673        let mut could_be_never_pattern = false;
674        self.walk(&mut |pat| match &pat.kind {
675            PatKind::Never | PatKind::MacCall(_) => {
676                could_be_never_pattern = true;
677                false
678            }
679            PatKind::Or(s) => {
680                could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
681                false
682            }
683            _ => true,
684        });
685        could_be_never_pattern
686    }
687
688    /// Whether this contains a `!` pattern. This in particular means that a feature gate error will
689    /// be raised if the feature is off. Used to avoid gating the feature twice.
690    pub fn contains_never_pattern(&self) -> bool {
691        let mut contains_never_pattern = false;
692        self.walk(&mut |pat| {
693            if matches!(pat.kind, PatKind::Never) {
694                contains_never_pattern = true;
695            }
696            true
697        });
698        contains_never_pattern
699    }
700
701    /// Return a name suitable for diagnostics.
702    pub fn descr(&self) -> Option<String> {
703        match &self.kind {
704            PatKind::Missing => unreachable!(),
705            PatKind::Wild => Some("_".to_string()),
706            PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
707            PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
708            _ => None,
709        }
710    }
711}
712
713impl From<P<Pat>> for Pat {
714    fn from(value: P<Pat>) -> Self {
715        *value
716    }
717}
718
719/// A single field in a struct pattern.
720///
721/// Patterns like the fields of `Foo { x, ref y, ref mut z }`
722/// are treated the same as `x: x, y: ref y, z: ref mut z`,
723/// except when `is_shorthand` is true.
724#[derive(Clone, Encodable, Decodable, Debug)]
725pub struct PatField {
726    /// The identifier for the field.
727    pub ident: Ident,
728    /// The pattern the field is destructured to.
729    pub pat: P<Pat>,
730    pub is_shorthand: bool,
731    pub attrs: AttrVec,
732    pub id: NodeId,
733    pub span: Span,
734    pub is_placeholder: bool,
735}
736
737#[derive(Clone, Copy, Debug, Eq, PartialEq)]
738#[derive(Encodable, Decodable, HashStable_Generic)]
739pub enum ByRef {
740    Yes(Mutability),
741    No,
742}
743
744impl ByRef {
745    #[must_use]
746    pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
747        if let ByRef::Yes(old_mutbl) = &mut self {
748            *old_mutbl = cmp::min(*old_mutbl, mutbl);
749        }
750        self
751    }
752}
753
754/// The mode of a binding (`mut`, `ref mut`, etc).
755/// Used for both the explicit binding annotations given in the HIR for a binding
756/// and the final binding mode that we infer after type inference/match ergonomics.
757/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
758/// `.1` is the mutability of the binding.
759#[derive(Clone, Copy, Debug, Eq, PartialEq)]
760#[derive(Encodable, Decodable, HashStable_Generic)]
761pub struct BindingMode(pub ByRef, pub Mutability);
762
763impl BindingMode {
764    pub const NONE: Self = Self(ByRef::No, Mutability::Not);
765    pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
766    pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
767    pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
768    pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
769    pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
770
771    pub fn prefix_str(self) -> &'static str {
772        match self {
773            Self::NONE => "",
774            Self::REF => "ref ",
775            Self::MUT => "mut ",
776            Self::REF_MUT => "ref mut ",
777            Self::MUT_REF => "mut ref ",
778            Self::MUT_REF_MUT => "mut ref mut ",
779        }
780    }
781}
782
783#[derive(Clone, Encodable, Decodable, Debug)]
784pub enum RangeEnd {
785    /// `..=` or `...`
786    Included(RangeSyntax),
787    /// `..`
788    Excluded,
789}
790
791#[derive(Clone, Encodable, Decodable, Debug)]
792pub enum RangeSyntax {
793    /// `...`
794    DotDotDot,
795    /// `..=`
796    DotDotEq,
797}
798
799/// All the different flavors of pattern that Rust recognizes.
800//
801// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
802#[derive(Clone, Encodable, Decodable, Debug)]
803pub enum PatKind {
804    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
805    Missing,
806
807    /// Represents a wildcard pattern (`_`).
808    Wild,
809
810    /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
811    /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
812    /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
813    /// during name resolution.
814    Ident(BindingMode, Ident, Option<P<Pat>>),
815
816    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
817    Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
818
819    /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
820    TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
821
822    /// An or-pattern `A | B | C`.
823    /// Invariant: `pats.len() >= 2`.
824    Or(ThinVec<P<Pat>>),
825
826    /// A possibly qualified path pattern.
827    /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
828    /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
829    /// only legally refer to associated constants.
830    Path(Option<P<QSelf>>, Path),
831
832    /// A tuple pattern (`(a, b)`).
833    Tuple(ThinVec<P<Pat>>),
834
835    /// A `box` pattern.
836    Box(P<Pat>),
837
838    /// A `deref` pattern (currently `deref!()` macro-based syntax).
839    Deref(P<Pat>),
840
841    /// A reference pattern (e.g., `&mut (a, b)`).
842    Ref(P<Pat>, Mutability),
843
844    /// A literal, const block or path.
845    Expr(P<Expr>),
846
847    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
848    Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
849
850    /// A slice pattern `[a, b, c]`.
851    Slice(ThinVec<P<Pat>>),
852
853    /// A rest pattern `..`.
854    ///
855    /// Syntactically it is valid anywhere.
856    ///
857    /// Semantically however, it only has meaning immediately inside:
858    /// - a slice pattern: `[a, .., b]`,
859    /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
860    /// - a tuple pattern: `(a, .., b)`,
861    /// - a tuple struct/variant pattern: `$path(a, .., b)`.
862    ///
863    /// In all of these cases, an additional restriction applies,
864    /// only one rest pattern may occur in the pattern sequences.
865    Rest,
866
867    // A never pattern `!`.
868    Never,
869
870    /// A guard pattern (e.g., `x if guard(x)`).
871    Guard(P<Pat>, P<Expr>),
872
873    /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
874    Paren(P<Pat>),
875
876    /// A macro pattern; pre-expansion.
877    MacCall(P<MacCall>),
878
879    /// Placeholder for a pattern that wasn't syntactically well formed in some way.
880    Err(ErrorGuaranteed),
881}
882
883/// Whether the `..` is present in a struct fields pattern.
884#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
885pub enum PatFieldsRest {
886    /// `module::StructName { field, ..}`
887    Rest,
888    /// `module::StructName { field, syntax error }`
889    Recovered(ErrorGuaranteed),
890    /// `module::StructName { field }`
891    None,
892}
893
894/// The kind of borrow in an `AddrOf` expression,
895/// e.g., `&place` or `&raw const place`.
896#[derive(Clone, Copy, PartialEq, Eq, Debug)]
897#[derive(Encodable, Decodable, HashStable_Generic)]
898pub enum BorrowKind {
899    /// A normal borrow, `&$expr` or `&mut $expr`.
900    /// The resulting type is either `&'a T` or `&'a mut T`
901    /// where `T = typeof($expr)` and `'a` is some lifetime.
902    Ref,
903    /// A raw borrow, `&raw const $expr` or `&raw mut $expr`.
904    /// The resulting type is either `*const T` or `*mut T`
905    /// where `T = typeof($expr)`.
906    Raw,
907}
908
909#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
910pub enum BinOpKind {
911    /// The `+` operator (addition)
912    Add,
913    /// The `-` operator (subtraction)
914    Sub,
915    /// The `*` operator (multiplication)
916    Mul,
917    /// The `/` operator (division)
918    Div,
919    /// The `%` operator (modulus)
920    Rem,
921    /// The `&&` operator (logical and)
922    And,
923    /// The `||` operator (logical or)
924    Or,
925    /// The `^` operator (bitwise xor)
926    BitXor,
927    /// The `&` operator (bitwise and)
928    BitAnd,
929    /// The `|` operator (bitwise or)
930    BitOr,
931    /// The `<<` operator (shift left)
932    Shl,
933    /// The `>>` operator (shift right)
934    Shr,
935    /// The `==` operator (equality)
936    Eq,
937    /// The `<` operator (less than)
938    Lt,
939    /// The `<=` operator (less than or equal to)
940    Le,
941    /// The `!=` operator (not equal to)
942    Ne,
943    /// The `>=` operator (greater than or equal to)
944    Ge,
945    /// The `>` operator (greater than)
946    Gt,
947}
948
949impl BinOpKind {
950    pub fn as_str(&self) -> &'static str {
951        use BinOpKind::*;
952        match self {
953            Add => "+",
954            Sub => "-",
955            Mul => "*",
956            Div => "/",
957            Rem => "%",
958            And => "&&",
959            Or => "||",
960            BitXor => "^",
961            BitAnd => "&",
962            BitOr => "|",
963            Shl => "<<",
964            Shr => ">>",
965            Eq => "==",
966            Lt => "<",
967            Le => "<=",
968            Ne => "!=",
969            Ge => ">=",
970            Gt => ">",
971        }
972    }
973
974    pub fn is_lazy(&self) -> bool {
975        matches!(self, BinOpKind::And | BinOpKind::Or)
976    }
977
978    pub fn precedence(&self) -> ExprPrecedence {
979        use BinOpKind::*;
980        match *self {
981            Mul | Div | Rem => ExprPrecedence::Product,
982            Add | Sub => ExprPrecedence::Sum,
983            Shl | Shr => ExprPrecedence::Shift,
984            BitAnd => ExprPrecedence::BitAnd,
985            BitXor => ExprPrecedence::BitXor,
986            BitOr => ExprPrecedence::BitOr,
987            Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
988            And => ExprPrecedence::LAnd,
989            Or => ExprPrecedence::LOr,
990        }
991    }
992
993    pub fn fixity(&self) -> Fixity {
994        use BinOpKind::*;
995        match self {
996            Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
997            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
998                Fixity::Left
999            }
1000        }
1001    }
1002
1003    pub fn is_comparison(self) -> bool {
1004        use BinOpKind::*;
1005        match self {
1006            Eq | Ne | Lt | Le | Gt | Ge => true,
1007            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1008        }
1009    }
1010
1011    /// Returns `true` if the binary operator takes its arguments by value.
1012    pub fn is_by_value(self) -> bool {
1013        !self.is_comparison()
1014    }
1015}
1016
1017pub type BinOp = Spanned<BinOpKind>;
1018
1019// Sometimes `BinOpKind` and `AssignOpKind` need the same treatment. The
1020// operations covered by `AssignOpKind` are a subset of those covered by
1021// `BinOpKind`, so it makes sense to convert `AssignOpKind` to `BinOpKind`.
1022impl From<AssignOpKind> for BinOpKind {
1023    fn from(op: AssignOpKind) -> BinOpKind {
1024        match op {
1025            AssignOpKind::AddAssign => BinOpKind::Add,
1026            AssignOpKind::SubAssign => BinOpKind::Sub,
1027            AssignOpKind::MulAssign => BinOpKind::Mul,
1028            AssignOpKind::DivAssign => BinOpKind::Div,
1029            AssignOpKind::RemAssign => BinOpKind::Rem,
1030            AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1031            AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1032            AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1033            AssignOpKind::ShlAssign => BinOpKind::Shl,
1034            AssignOpKind::ShrAssign => BinOpKind::Shr,
1035        }
1036    }
1037}
1038
1039#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1040pub enum AssignOpKind {
1041    /// The `+=` operator (addition)
1042    AddAssign,
1043    /// The `-=` operator (subtraction)
1044    SubAssign,
1045    /// The `*=` operator (multiplication)
1046    MulAssign,
1047    /// The `/=` operator (division)
1048    DivAssign,
1049    /// The `%=` operator (modulus)
1050    RemAssign,
1051    /// The `^=` operator (bitwise xor)
1052    BitXorAssign,
1053    /// The `&=` operator (bitwise and)
1054    BitAndAssign,
1055    /// The `|=` operator (bitwise or)
1056    BitOrAssign,
1057    /// The `<<=` operator (shift left)
1058    ShlAssign,
1059    /// The `>>=` operator (shift right)
1060    ShrAssign,
1061}
1062
1063impl AssignOpKind {
1064    pub fn as_str(&self) -> &'static str {
1065        use AssignOpKind::*;
1066        match self {
1067            AddAssign => "+=",
1068            SubAssign => "-=",
1069            MulAssign => "*=",
1070            DivAssign => "/=",
1071            RemAssign => "%=",
1072            BitXorAssign => "^=",
1073            BitAndAssign => "&=",
1074            BitOrAssign => "|=",
1075            ShlAssign => "<<=",
1076            ShrAssign => ">>=",
1077        }
1078    }
1079
1080    /// AssignOps are always by value.
1081    pub fn is_by_value(self) -> bool {
1082        true
1083    }
1084}
1085
1086pub type AssignOp = Spanned<AssignOpKind>;
1087
1088/// Unary operator.
1089///
1090/// Note that `&data` is not an operator, it's an `AddrOf` expression.
1091#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1092pub enum UnOp {
1093    /// The `*` operator for dereferencing
1094    Deref,
1095    /// The `!` operator for logical inversion
1096    Not,
1097    /// The `-` operator for negation
1098    Neg,
1099}
1100
1101impl UnOp {
1102    pub fn as_str(&self) -> &'static str {
1103        match self {
1104            UnOp::Deref => "*",
1105            UnOp::Not => "!",
1106            UnOp::Neg => "-",
1107        }
1108    }
1109
1110    /// Returns `true` if the unary operator takes its argument by value.
1111    pub fn is_by_value(self) -> bool {
1112        matches!(self, Self::Neg | Self::Not)
1113    }
1114}
1115
1116/// A statement. No `attrs` or `tokens` fields because each `StmtKind` variant
1117/// contains an AST node with those fields. (Except for `StmtKind::Empty`,
1118/// which never has attrs or tokens)
1119#[derive(Clone, Encodable, Decodable, Debug)]
1120pub struct Stmt {
1121    pub id: NodeId,
1122    pub kind: StmtKind,
1123    pub span: Span,
1124}
1125
1126impl Stmt {
1127    pub fn has_trailing_semicolon(&self) -> bool {
1128        match &self.kind {
1129            StmtKind::Semi(_) => true,
1130            StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1131            _ => false,
1132        }
1133    }
1134
1135    /// Converts a parsed `Stmt` to a `Stmt` with
1136    /// a trailing semicolon.
1137    ///
1138    /// This only modifies the parsed AST struct, not the attached
1139    /// `LazyAttrTokenStream`. The parser is responsible for calling
1140    /// `ToAttrTokenStream::add_trailing_semi` when there is actually
1141    /// a semicolon in the tokenstream.
1142    pub fn add_trailing_semicolon(mut self) -> Self {
1143        self.kind = match self.kind {
1144            StmtKind::Expr(expr) => StmtKind::Semi(expr),
1145            StmtKind::MacCall(mut mac) => {
1146                mac.style = MacStmtStyle::Semicolon;
1147                StmtKind::MacCall(mac)
1148            }
1149            kind => kind,
1150        };
1151
1152        self
1153    }
1154
1155    pub fn is_item(&self) -> bool {
1156        matches!(self.kind, StmtKind::Item(_))
1157    }
1158
1159    pub fn is_expr(&self) -> bool {
1160        matches!(self.kind, StmtKind::Expr(_))
1161    }
1162}
1163
1164// Adding a new variant? Please update `test_stmt` in `tests/ui/macros/stringify.rs`.
1165#[derive(Clone, Encodable, Decodable, Debug)]
1166pub enum StmtKind {
1167    /// A local (let) binding.
1168    Let(P<Local>),
1169    /// An item definition.
1170    Item(P<Item>),
1171    /// Expr without trailing semi-colon.
1172    Expr(P<Expr>),
1173    /// Expr with a trailing semi-colon.
1174    Semi(P<Expr>),
1175    /// Just a trailing semi-colon.
1176    Empty,
1177    /// Macro.
1178    MacCall(P<MacCallStmt>),
1179}
1180
1181#[derive(Clone, Encodable, Decodable, Debug)]
1182pub struct MacCallStmt {
1183    pub mac: P<MacCall>,
1184    pub style: MacStmtStyle,
1185    pub attrs: AttrVec,
1186    pub tokens: Option<LazyAttrTokenStream>,
1187}
1188
1189#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1190pub enum MacStmtStyle {
1191    /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
1192    /// `foo!(...);`, `foo![...];`).
1193    Semicolon,
1194    /// The macro statement had braces (e.g., `foo! { ... }`).
1195    Braces,
1196    /// The macro statement had parentheses or brackets and no semicolon (e.g.,
1197    /// `foo!(...)`). All of these will end up being converted into macro
1198    /// expressions.
1199    NoBraces,
1200}
1201
1202/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
1203#[derive(Clone, Encodable, Decodable, Debug)]
1204pub struct Local {
1205    pub id: NodeId,
1206    pub super_: Option<Span>,
1207    pub pat: P<Pat>,
1208    pub ty: Option<P<Ty>>,
1209    pub kind: LocalKind,
1210    pub span: Span,
1211    pub colon_sp: Option<Span>,
1212    pub attrs: AttrVec,
1213    pub tokens: Option<LazyAttrTokenStream>,
1214}
1215
1216#[derive(Clone, Encodable, Decodable, Debug)]
1217pub enum LocalKind {
1218    /// Local declaration.
1219    /// Example: `let x;`
1220    Decl,
1221    /// Local declaration with an initializer.
1222    /// Example: `let x = y;`
1223    Init(P<Expr>),
1224    /// Local declaration with an initializer and an `else` clause.
1225    /// Example: `let Some(x) = y else { return };`
1226    InitElse(P<Expr>, P<Block>),
1227}
1228
1229impl LocalKind {
1230    pub fn init(&self) -> Option<&Expr> {
1231        match self {
1232            Self::Decl => None,
1233            Self::Init(i) | Self::InitElse(i, _) => Some(i),
1234        }
1235    }
1236
1237    pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1238        match self {
1239            Self::Decl => None,
1240            Self::Init(init) => Some((init, None)),
1241            Self::InitElse(init, els) => Some((init, Some(els))),
1242        }
1243    }
1244}
1245
1246/// An arm of a 'match'.
1247///
1248/// E.g., `0..=10 => { println!("match!") }` as in
1249///
1250/// ```
1251/// match 123 {
1252///     0..=10 => { println!("match!") },
1253///     _ => { println!("no match!") },
1254/// }
1255/// ```
1256#[derive(Clone, Encodable, Decodable, Debug)]
1257pub struct Arm {
1258    pub attrs: AttrVec,
1259    /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
1260    pub pat: P<Pat>,
1261    /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`.
1262    pub guard: Option<P<Expr>>,
1263    /// Match arm body. Omitted if the pattern is a never pattern.
1264    pub body: Option<P<Expr>>,
1265    pub span: Span,
1266    pub id: NodeId,
1267    pub is_placeholder: bool,
1268}
1269
1270/// A single field in a struct expression, e.g. `x: value` and `y` in `Foo { x: value, y }`.
1271#[derive(Clone, Encodable, Decodable, Debug)]
1272pub struct ExprField {
1273    pub attrs: AttrVec,
1274    pub id: NodeId,
1275    pub span: Span,
1276    pub ident: Ident,
1277    pub expr: P<Expr>,
1278    pub is_shorthand: bool,
1279    pub is_placeholder: bool,
1280}
1281
1282#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1283pub enum BlockCheckMode {
1284    Default,
1285    Unsafe(UnsafeSource),
1286}
1287
1288#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1289pub enum UnsafeSource {
1290    CompilerGenerated,
1291    UserProvided,
1292}
1293
1294/// A constant (expression) that's not an item or associated item,
1295/// but needs its own `DefId` for type-checking, const-eval, etc.
1296/// These are usually found nested inside types (e.g., array lengths)
1297/// or expressions (e.g., repeat counts), and also used to define
1298/// explicit discriminant values for enum variants.
1299#[derive(Clone, Encodable, Decodable, Debug)]
1300pub struct AnonConst {
1301    pub id: NodeId,
1302    pub value: P<Expr>,
1303}
1304
1305/// An expression.
1306#[derive(Clone, Encodable, Decodable, Debug)]
1307pub struct Expr {
1308    pub id: NodeId,
1309    pub kind: ExprKind,
1310    pub span: Span,
1311    pub attrs: AttrVec,
1312    pub tokens: Option<LazyAttrTokenStream>,
1313}
1314
1315impl Expr {
1316    /// Check if this expression is potentially a trivial const arg, i.e., one that can _potentially_
1317    /// be represented without an anon const in the HIR.
1318    ///
1319    /// This will unwrap at most one block level (curly braces). After that, if the expression
1320    /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`].
1321    /// See there for more info about `allow_mgca_arg`.
1322    ///
1323    /// The only additional thing to note is that when `allow_mgca_arg` is false, this function
1324    /// will only allow paths with no qself, before dispatching to the `Path` function of
1325    /// the same name.
1326    ///
1327    /// Does not ensure that the path resolves to a const param/item, the caller should check this.
1328    /// This also does not consider macros, so it's only correct after macro-expansion.
1329    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1330        let this = self.maybe_unwrap_block();
1331        if allow_mgca_arg {
1332            matches!(this.kind, ExprKind::Path(..))
1333        } else {
1334            if let ExprKind::Path(None, path) = &this.kind
1335                && path.is_potential_trivial_const_arg(allow_mgca_arg)
1336            {
1337                true
1338            } else {
1339                false
1340            }
1341        }
1342    }
1343
1344    /// Returns an expression with (when possible) *one* outter brace removed
1345    pub fn maybe_unwrap_block(&self) -> &Expr {
1346        if let ExprKind::Block(block, None) = &self.kind
1347            && let [stmt] = block.stmts.as_slice()
1348            && let StmtKind::Expr(expr) = &stmt.kind
1349        {
1350            expr
1351        } else {
1352            self
1353        }
1354    }
1355
1356    /// Determines whether this expression is a macro call optionally wrapped in braces . If
1357    /// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
1358    ///
1359    /// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
1360    /// either before, or part of, this function.
1361    pub fn optionally_braced_mac_call(
1362        &self,
1363        already_stripped_block: bool,
1364    ) -> Option<(bool, NodeId)> {
1365        match &self.kind {
1366            ExprKind::Block(block, None)
1367                if let [stmt] = &*block.stmts
1368                    && !already_stripped_block =>
1369            {
1370                match &stmt.kind {
1371                    StmtKind::MacCall(_) => Some((true, stmt.id)),
1372                    StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1373                        Some((true, expr.id))
1374                    }
1375                    _ => None,
1376                }
1377            }
1378            ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1379            _ => None,
1380        }
1381    }
1382
1383    pub fn to_bound(&self) -> Option<GenericBound> {
1384        match &self.kind {
1385            ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1386                ThinVec::new(),
1387                path.clone(),
1388                TraitBoundModifiers::NONE,
1389                self.span,
1390            ))),
1391            _ => None,
1392        }
1393    }
1394
1395    pub fn peel_parens(&self) -> &Expr {
1396        let mut expr = self;
1397        while let ExprKind::Paren(inner) = &expr.kind {
1398            expr = inner;
1399        }
1400        expr
1401    }
1402
1403    pub fn peel_parens_and_refs(&self) -> &Expr {
1404        let mut expr = self;
1405        while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1406        {
1407            expr = inner;
1408        }
1409        expr
1410    }
1411
1412    /// Attempts to reparse as `Ty` (for diagnostic purposes).
1413    pub fn to_ty(&self) -> Option<P<Ty>> {
1414        let kind = match &self.kind {
1415            // Trivial conversions.
1416            ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1417            ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1418
1419            ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1420
1421            ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1422                expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1423            }
1424
1425            ExprKind::Repeat(expr, expr_len) => {
1426                expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1427            }
1428
1429            ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1430                expr.to_ty().map(TyKind::Slice)?
1431            }
1432
1433            ExprKind::Tup(exprs) => {
1434                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1435                TyKind::Tup(tys)
1436            }
1437
1438            // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
1439            // then type of result is trait object.
1440            // Otherwise we don't assume the result type.
1441            ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1442                if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1443                    TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1444                } else {
1445                    return None;
1446                }
1447            }
1448
1449            ExprKind::Underscore => TyKind::Infer,
1450
1451            // This expression doesn't look like a type syntactically.
1452            _ => return None,
1453        };
1454
1455        Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1456    }
1457
1458    pub fn precedence(&self) -> ExprPrecedence {
1459        fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1460            for attr in attrs {
1461                if let AttrStyle::Outer = attr.style {
1462                    return ExprPrecedence::Prefix;
1463                }
1464            }
1465            ExprPrecedence::Unambiguous
1466        }
1467
1468        match &self.kind {
1469            ExprKind::Closure(closure) => {
1470                match closure.fn_decl.output {
1471                    FnRetTy::Default(_) => ExprPrecedence::Jump,
1472                    FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1473                }
1474            }
1475
1476            ExprKind::Break(_ /*label*/, value)
1477            | ExprKind::Ret(value)
1478            | ExprKind::Yield(YieldKind::Prefix(value))
1479            | ExprKind::Yeet(value) => match value {
1480                Some(_) => ExprPrecedence::Jump,
1481                None => prefix_attrs_precedence(&self.attrs),
1482            },
1483
1484            ExprKind::Become(_) => ExprPrecedence::Jump,
1485
1486            // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
1487            // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
1488            // ensures that `pprust` will add parentheses in the right places to get the desired
1489            // parse.
1490            ExprKind::Range(..) => ExprPrecedence::Range,
1491
1492            // Binop-like expr kinds, handled by `AssocOp`.
1493            ExprKind::Binary(op, ..) => op.node.precedence(),
1494            ExprKind::Cast(..) => ExprPrecedence::Cast,
1495
1496            ExprKind::Assign(..) |
1497            ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1498
1499            // Unary, prefix
1500            ExprKind::AddrOf(..)
1501            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
1502            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
1503            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
1504            // but we need to print `(let _ = a) < b` as-is with parens.
1505            | ExprKind::Let(..)
1506            | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1507
1508            // Need parens if and only if there are prefix attributes.
1509            ExprKind::Array(_)
1510            | ExprKind::Await(..)
1511            | ExprKind::Use(..)
1512            | ExprKind::Block(..)
1513            | ExprKind::Call(..)
1514            | ExprKind::ConstBlock(_)
1515            | ExprKind::Continue(..)
1516            | ExprKind::Field(..)
1517            | ExprKind::ForLoop { .. }
1518            | ExprKind::FormatArgs(..)
1519            | ExprKind::Gen(..)
1520            | ExprKind::If(..)
1521            | ExprKind::IncludedBytes(..)
1522            | ExprKind::Index(..)
1523            | ExprKind::InlineAsm(..)
1524            | ExprKind::Lit(_)
1525            | ExprKind::Loop(..)
1526            | ExprKind::MacCall(..)
1527            | ExprKind::Match(..)
1528            | ExprKind::MethodCall(..)
1529            | ExprKind::OffsetOf(..)
1530            | ExprKind::Paren(..)
1531            | ExprKind::Path(..)
1532            | ExprKind::Repeat(..)
1533            | ExprKind::Struct(..)
1534            | ExprKind::Try(..)
1535            | ExprKind::TryBlock(..)
1536            | ExprKind::Tup(_)
1537            | ExprKind::Type(..)
1538            | ExprKind::Underscore
1539            | ExprKind::UnsafeBinderCast(..)
1540            | ExprKind::While(..)
1541            | ExprKind::Yield(YieldKind::Postfix(..))
1542            | ExprKind::Err(_)
1543            | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1544        }
1545    }
1546
1547    /// To a first-order approximation, is this a pattern?
1548    pub fn is_approximately_pattern(&self) -> bool {
1549        matches!(
1550            &self.peel_parens().kind,
1551            ExprKind::Array(_)
1552                | ExprKind::Call(_, _)
1553                | ExprKind::Tup(_)
1554                | ExprKind::Lit(_)
1555                | ExprKind::Range(_, _, _)
1556                | ExprKind::Underscore
1557                | ExprKind::Path(_, _)
1558                | ExprKind::Struct(_)
1559        )
1560    }
1561
1562    /// Creates a dummy `Expr`.
1563    ///
1564    /// Should only be used when it will be replaced afterwards or as a return value when an error was encountered.
1565    pub fn dummy() -> Expr {
1566        Expr {
1567            id: DUMMY_NODE_ID,
1568            kind: ExprKind::Dummy,
1569            span: DUMMY_SP,
1570            attrs: ThinVec::new(),
1571            tokens: None,
1572        }
1573    }
1574}
1575
1576impl From<P<Expr>> for Expr {
1577    fn from(value: P<Expr>) -> Self {
1578        *value
1579    }
1580}
1581
1582#[derive(Clone, Encodable, Decodable, Debug)]
1583pub struct Closure {
1584    pub binder: ClosureBinder,
1585    pub capture_clause: CaptureBy,
1586    pub constness: Const,
1587    pub coroutine_kind: Option<CoroutineKind>,
1588    pub movability: Movability,
1589    pub fn_decl: P<FnDecl>,
1590    pub body: P<Expr>,
1591    /// The span of the declaration block: 'move |...| -> ...'
1592    pub fn_decl_span: Span,
1593    /// The span of the argument block `|...|`
1594    pub fn_arg_span: Span,
1595}
1596
1597/// Limit types of a range (inclusive or exclusive).
1598#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1599pub enum RangeLimits {
1600    /// Inclusive at the beginning, exclusive at the end.
1601    HalfOpen,
1602    /// Inclusive at the beginning and end.
1603    Closed,
1604}
1605
1606impl RangeLimits {
1607    pub fn as_str(&self) -> &'static str {
1608        match self {
1609            RangeLimits::HalfOpen => "..",
1610            RangeLimits::Closed => "..=",
1611        }
1612    }
1613}
1614
1615/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
1616#[derive(Clone, Encodable, Decodable, Debug)]
1617pub struct MethodCall {
1618    /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
1619    pub seg: PathSegment,
1620    /// The receiver, e.g. `x`.
1621    pub receiver: P<Expr>,
1622    /// The arguments, e.g. `a, b, c`.
1623    pub args: ThinVec<P<Expr>>,
1624    /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
1625    /// Baz>(a, b, c)`.
1626    pub span: Span,
1627}
1628
1629#[derive(Clone, Encodable, Decodable, Debug)]
1630pub enum StructRest {
1631    /// `..x`.
1632    Base(P<Expr>),
1633    /// `..`.
1634    Rest(Span),
1635    /// No trailing `..` or expression.
1636    None,
1637}
1638
1639#[derive(Clone, Encodable, Decodable, Debug)]
1640pub struct StructExpr {
1641    pub qself: Option<P<QSelf>>,
1642    pub path: Path,
1643    pub fields: ThinVec<ExprField>,
1644    pub rest: StructRest,
1645}
1646
1647// Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
1648#[derive(Clone, Encodable, Decodable, Debug)]
1649pub enum ExprKind {
1650    /// An array (e.g, `[a, b, c, d]`).
1651    Array(ThinVec<P<Expr>>),
1652    /// Allow anonymous constants from an inline `const` block.
1653    ConstBlock(AnonConst),
1654    /// A function call.
1655    ///
1656    /// The first field resolves to the function itself,
1657    /// and the second field is the list of arguments.
1658    /// This also represents calling the constructor of
1659    /// tuple-like ADTs such as tuple structs and enum variants.
1660    Call(P<Expr>, ThinVec<P<Expr>>),
1661    /// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
1662    MethodCall(Box<MethodCall>),
1663    /// A tuple (e.g., `(a, b, c, d)`).
1664    Tup(ThinVec<P<Expr>>),
1665    /// A binary operation (e.g., `a + b`, `a * b`).
1666    Binary(BinOp, P<Expr>, P<Expr>),
1667    /// A unary operation (e.g., `!x`, `*x`).
1668    Unary(UnOp, P<Expr>),
1669    /// A literal (e.g., `1`, `"foo"`).
1670    Lit(token::Lit),
1671    /// A cast (e.g., `foo as f64`).
1672    Cast(P<Expr>, P<Ty>),
1673    /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
1674    ///
1675    /// Usually not written directly in user code but
1676    /// indirectly via the macro `type_ascribe!(...)`.
1677    Type(P<Expr>, P<Ty>),
1678    /// A `let pat = expr` expression that is only semantically allowed in the condition
1679    /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
1680    ///
1681    /// `Span` represents the whole `let pat = expr` statement.
1682    Let(P<Pat>, P<Expr>, Span, Recovered),
1683    /// An `if` block, with an optional `else` block.
1684    ///
1685    /// `if expr { block } else { expr }`
1686    ///
1687    /// If present, the "else" expr is always `ExprKind::Block` (for `else`) or
1688    /// `ExprKind::If` (for `else if`).
1689    If(P<Expr>, P<Block>, Option<P<Expr>>),
1690    /// A while loop, with an optional label.
1691    ///
1692    /// `'label: while expr { block }`
1693    While(P<Expr>, P<Block>, Option<Label>),
1694    /// A `for` loop, with an optional label.
1695    ///
1696    /// `'label: for await? pat in iter { block }`
1697    ///
1698    /// This is desugared to a combination of `loop` and `match` expressions.
1699    ForLoop {
1700        pat: P<Pat>,
1701        iter: P<Expr>,
1702        body: P<Block>,
1703        label: Option<Label>,
1704        kind: ForLoopKind,
1705    },
1706    /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
1707    ///
1708    /// `'label: loop { block }`
1709    Loop(P<Block>, Option<Label>, Span),
1710    /// A `match` block.
1711    Match(P<Expr>, ThinVec<Arm>, MatchKind),
1712    /// A closure (e.g., `move |a, b, c| a + b + c`).
1713    Closure(Box<Closure>),
1714    /// A block (`'label: { ... }`).
1715    Block(P<Block>, Option<Label>),
1716    /// An `async` block (`async move { ... }`),
1717    /// or a `gen` block (`gen move { ... }`).
1718    ///
1719    /// The span is the "decl", which is the header before the body `{ }`
1720    /// including the `asyng`/`gen` keywords and possibly `move`.
1721    Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1722    /// An await expression (`my_future.await`). Span is of await keyword.
1723    Await(P<Expr>, Span),
1724    /// A use expression (`x.use`). Span is of use keyword.
1725    Use(P<Expr>, Span),
1726
1727    /// A try block (`try { ... }`).
1728    TryBlock(P<Block>),
1729
1730    /// An assignment (`a = foo()`).
1731    /// The `Span` argument is the span of the `=` token.
1732    Assign(P<Expr>, P<Expr>, Span),
1733    /// An assignment with an operator.
1734    ///
1735    /// E.g., `a += 1`.
1736    AssignOp(AssignOp, P<Expr>, P<Expr>),
1737    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
1738    Field(P<Expr>, Ident),
1739    /// An indexing operation (e.g., `foo[2]`).
1740    /// The span represents the span of the `[2]`, including brackets.
1741    Index(P<Expr>, P<Expr>, Span),
1742    /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
1743    Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1744    /// An underscore, used in destructuring assignment to ignore a value.
1745    Underscore,
1746
1747    /// Variable reference, possibly containing `::` and/or type
1748    /// parameters (e.g., `foo::bar::<baz>`).
1749    ///
1750    /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
1751    Path(Option<P<QSelf>>, Path),
1752
1753    /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
1754    AddrOf(BorrowKind, Mutability, P<Expr>),
1755    /// A `break`, with an optional label to break, and an optional expression.
1756    Break(Option<Label>, Option<P<Expr>>),
1757    /// A `continue`, with an optional label.
1758    Continue(Option<Label>),
1759    /// A `return`, with an optional value to be returned.
1760    Ret(Option<P<Expr>>),
1761
1762    /// Output of the `asm!()` macro.
1763    InlineAsm(P<InlineAsm>),
1764
1765    /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
1766    ///
1767    /// Usually not written directly in user code but
1768    /// indirectly via the macro `core::mem::offset_of!(...)`.
1769    OffsetOf(P<Ty>, Vec<Ident>),
1770
1771    /// A macro invocation; pre-expansion.
1772    MacCall(P<MacCall>),
1773
1774    /// A struct literal expression.
1775    ///
1776    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
1777    Struct(P<StructExpr>),
1778
1779    /// An array literal constructed from one repeated element.
1780    ///
1781    /// E.g., `[1; 5]`. The expression is the element to be
1782    /// repeated; the constant is the number of times to repeat it.
1783    Repeat(P<Expr>, AnonConst),
1784
1785    /// No-op: used solely so we can pretty-print faithfully.
1786    Paren(P<Expr>),
1787
1788    /// A try expression (`expr?`).
1789    Try(P<Expr>),
1790
1791    /// A `yield`, with an optional value to be yielded.
1792    Yield(YieldKind),
1793
1794    /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
1795    /// with an optional value to be returned.
1796    Yeet(Option<P<Expr>>),
1797
1798    /// A tail call return, with the value to be returned.
1799    ///
1800    /// While `.0` must be a function call, we check this later, after parsing.
1801    Become(P<Expr>),
1802
1803    /// Bytes included via `include_bytes!`
1804    /// Added for optimization purposes to avoid the need to escape
1805    /// large binary blobs - should always behave like [`ExprKind::Lit`]
1806    /// with a `ByteStr` literal.
1807    IncludedBytes(Arc<[u8]>),
1808
1809    /// A `format_args!()` expression.
1810    FormatArgs(P<FormatArgs>),
1811
1812    UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1813
1814    /// Placeholder for an expression that wasn't syntactically well formed in some way.
1815    Err(ErrorGuaranteed),
1816
1817    /// Acts as a null expression. Lowering it will always emit a bug.
1818    Dummy,
1819}
1820
1821/// Used to differentiate between `for` loops and `for await` loops.
1822#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1823pub enum ForLoopKind {
1824    For,
1825    ForAwait,
1826}
1827
1828/// Used to differentiate between `async {}` blocks and `gen {}` blocks.
1829#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1830pub enum GenBlockKind {
1831    Async,
1832    Gen,
1833    AsyncGen,
1834}
1835
1836impl fmt::Display for GenBlockKind {
1837    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1838        self.modifier().fmt(f)
1839    }
1840}
1841
1842impl GenBlockKind {
1843    pub fn modifier(&self) -> &'static str {
1844        match self {
1845            GenBlockKind::Async => "async",
1846            GenBlockKind::Gen => "gen",
1847            GenBlockKind::AsyncGen => "async gen",
1848        }
1849    }
1850}
1851
1852/// Whether we're unwrapping or wrapping an unsafe binder
1853#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1854#[derive(Encodable, Decodable, HashStable_Generic)]
1855pub enum UnsafeBinderCastKind {
1856    // e.g. `&i32` -> `unsafe<'a> &'a i32`
1857    Wrap,
1858    // e.g. `unsafe<'a> &'a i32` -> `&i32`
1859    Unwrap,
1860}
1861
1862/// The explicit `Self` type in a "qualified path". The actual
1863/// path, including the trait and the associated item, is stored
1864/// separately. `position` represents the index of the associated
1865/// item qualified with this `Self` type.
1866///
1867/// ```ignore (only-for-syntax-highlight)
1868/// <Vec<T> as a::b::Trait>::AssociatedItem
1869///  ^~~~~     ~~~~~~~~~~~~~~^
1870///  ty        position = 3
1871///
1872/// <Vec<T>>::AssociatedItem
1873///  ^~~~~    ^
1874///  ty       position = 0
1875/// ```
1876#[derive(Clone, Encodable, Decodable, Debug)]
1877pub struct QSelf {
1878    pub ty: P<Ty>,
1879
1880    /// The span of `a::b::Trait` in a path like `<Vec<T> as
1881    /// a::b::Trait>::AssociatedItem`; in the case where `position ==
1882    /// 0`, this is an empty span.
1883    pub path_span: Span,
1884    pub position: usize,
1885}
1886
1887/// A capture clause used in closures and `async` blocks.
1888#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1889pub enum CaptureBy {
1890    /// `move |x| y + x`.
1891    Value {
1892        /// The span of the `move` keyword.
1893        move_kw: Span,
1894    },
1895    /// `move` or `use` keywords were not specified.
1896    Ref,
1897    /// `use |x| y + x`.
1898    ///
1899    /// Note that if you have a regular closure like `|| x.use`, this will *not* result
1900    /// in a `Use` capture. Instead, the `ExprUseVisitor` will look at the type
1901    /// of `x` and treat `x.use` as either a copy/clone/move as appropriate.
1902    Use {
1903        /// The span of the `use` keyword.
1904        use_kw: Span,
1905    },
1906}
1907
1908/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
1909#[derive(Clone, Encodable, Decodable, Debug)]
1910pub enum ClosureBinder {
1911    /// The binder is not present, all closure lifetimes are inferred.
1912    NotPresent,
1913    /// The binder is present.
1914    For {
1915        /// Span of the whole `for<>` clause
1916        ///
1917        /// ```text
1918        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
1919        /// ^^^^^^^^^^^ -- this
1920        /// ```
1921        span: Span,
1922
1923        /// Lifetimes in the `for<>` closure
1924        ///
1925        /// ```text
1926        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
1927        ///     ^^^^^^ -- this
1928        /// ```
1929        generic_params: ThinVec<GenericParam>,
1930    },
1931}
1932
1933/// Represents a macro invocation. The `path` indicates which macro
1934/// is being invoked, and the `args` are arguments passed to it.
1935#[derive(Clone, Encodable, Decodable, Debug)]
1936pub struct MacCall {
1937    pub path: Path,
1938    pub args: P<DelimArgs>,
1939}
1940
1941impl MacCall {
1942    pub fn span(&self) -> Span {
1943        self.path.span.to(self.args.dspan.entire())
1944    }
1945}
1946
1947/// Arguments passed to an attribute macro.
1948#[derive(Clone, Encodable, Decodable, Debug)]
1949pub enum AttrArgs {
1950    /// No arguments: `#[attr]`.
1951    Empty,
1952    /// Delimited arguments: `#[attr()/[]/{}]`.
1953    Delimited(DelimArgs),
1954    /// Arguments of a key-value attribute: `#[attr = "value"]`.
1955    Eq {
1956        /// Span of the `=` token.
1957        eq_span: Span,
1958        expr: P<Expr>,
1959    },
1960}
1961
1962impl AttrArgs {
1963    pub fn span(&self) -> Option<Span> {
1964        match self {
1965            AttrArgs::Empty => None,
1966            AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1967            AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1968        }
1969    }
1970
1971    /// Tokens inside the delimiters or after `=`.
1972    /// Proc macros see these tokens, for example.
1973    pub fn inner_tokens(&self) -> TokenStream {
1974        match self {
1975            AttrArgs::Empty => TokenStream::default(),
1976            AttrArgs::Delimited(args) => args.tokens.clone(),
1977            AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1978        }
1979    }
1980}
1981
1982/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
1983#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1984pub struct DelimArgs {
1985    pub dspan: DelimSpan,
1986    pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
1987    pub tokens: TokenStream,
1988}
1989
1990impl DelimArgs {
1991    /// Whether a macro with these arguments needs a semicolon
1992    /// when used as a standalone item or statement.
1993    pub fn need_semicolon(&self) -> bool {
1994        !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1995    }
1996}
1997
1998/// Represents a macro definition.
1999#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2000pub struct MacroDef {
2001    pub body: P<DelimArgs>,
2002    /// `true` if macro was defined with `macro_rules`.
2003    pub macro_rules: bool,
2004}
2005
2006#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2007#[derive(HashStable_Generic)]
2008pub enum StrStyle {
2009    /// A regular string, like `"foo"`.
2010    Cooked,
2011    /// A raw string, like `r##"foo"##`.
2012    ///
2013    /// The value is the number of `#` symbols used.
2014    Raw(u8),
2015}
2016
2017/// The kind of match expression
2018#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
2019pub enum MatchKind {
2020    /// match expr { ... }
2021    Prefix,
2022    /// expr.match { ... }
2023    Postfix,
2024}
2025
2026/// The kind of yield expression
2027#[derive(Clone, Encodable, Decodable, Debug)]
2028pub enum YieldKind {
2029    /// yield expr { ... }
2030    Prefix(Option<P<Expr>>),
2031    /// expr.yield { ... }
2032    Postfix(P<Expr>),
2033}
2034
2035impl YieldKind {
2036    /// Returns the expression inside the yield expression, if any.
2037    ///
2038    /// For postfix yields, this is guaranteed to be `Some`.
2039    pub const fn expr(&self) -> Option<&P<Expr>> {
2040        match self {
2041            YieldKind::Prefix(expr) => expr.as_ref(),
2042            YieldKind::Postfix(expr) => Some(expr),
2043        }
2044    }
2045
2046    /// Returns a mutable reference to the expression being yielded, if any.
2047    pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2048        match self {
2049            YieldKind::Prefix(expr) => expr.as_mut(),
2050            YieldKind::Postfix(expr) => Some(expr),
2051        }
2052    }
2053
2054    /// Returns true if both yields are prefix or both are postfix.
2055    pub const fn same_kind(&self, other: &Self) -> bool {
2056        match (self, other) {
2057            (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2058            (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2059            _ => false,
2060        }
2061    }
2062}
2063
2064/// A literal in a meta item.
2065#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2066pub struct MetaItemLit {
2067    /// The original literal as written in the source code.
2068    pub symbol: Symbol,
2069    /// The original suffix as written in the source code.
2070    pub suffix: Option<Symbol>,
2071    /// The "semantic" representation of the literal lowered from the original tokens.
2072    /// Strings are unescaped, hexadecimal forms are eliminated, etc.
2073    pub kind: LitKind,
2074    pub span: Span,
2075}
2076
2077/// Similar to `MetaItemLit`, but restricted to string literals.
2078#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2079pub struct StrLit {
2080    /// The original literal as written in source code.
2081    pub symbol: Symbol,
2082    /// The original suffix as written in source code.
2083    pub suffix: Option<Symbol>,
2084    /// The semantic (unescaped) representation of the literal.
2085    pub symbol_unescaped: Symbol,
2086    pub style: StrStyle,
2087    pub span: Span,
2088}
2089
2090impl StrLit {
2091    pub fn as_token_lit(&self) -> token::Lit {
2092        let token_kind = match self.style {
2093            StrStyle::Cooked => token::Str,
2094            StrStyle::Raw(n) => token::StrRaw(n),
2095        };
2096        token::Lit::new(token_kind, self.symbol, self.suffix)
2097    }
2098}
2099
2100/// Type of the integer literal based on provided suffix.
2101#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2102#[derive(HashStable_Generic)]
2103pub enum LitIntType {
2104    /// e.g. `42_i32`.
2105    Signed(IntTy),
2106    /// e.g. `42_u32`.
2107    Unsigned(UintTy),
2108    /// e.g. `42`.
2109    Unsuffixed,
2110}
2111
2112/// Type of the float literal based on provided suffix.
2113#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2114#[derive(HashStable_Generic)]
2115pub enum LitFloatType {
2116    /// A float literal with a suffix (`1f32` or `1E10f32`).
2117    Suffixed(FloatTy),
2118    /// A float literal without a suffix (`1.0 or 1.0E10`).
2119    Unsuffixed,
2120}
2121
2122/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
2123///
2124/// Note that the entire literal (including the suffix) is considered when
2125/// deciding the `LitKind`. This means that float literals like `1f32` are
2126/// classified by this type as `Float`. This is different to `token::LitKind`
2127/// which does *not* consider the suffix.
2128#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2129pub enum LitKind {
2130    /// A string literal (`"foo"`). The symbol is unescaped, and so may differ
2131    /// from the original token's symbol.
2132    Str(Symbol, StrStyle),
2133    /// A byte string (`b"foo"`). Not stored as a symbol because it might be
2134    /// non-utf8, and symbols only allow utf8 strings.
2135    ByteStr(Arc<[u8]>, StrStyle),
2136    /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end.
2137    CStr(Arc<[u8]>, StrStyle),
2138    /// A byte char (`b'f'`).
2139    Byte(u8),
2140    /// A character literal (`'a'`).
2141    Char(char),
2142    /// An integer literal (`1`).
2143    Int(Pu128, LitIntType),
2144    /// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
2145    /// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
2146    /// and `Hash`.
2147    Float(Symbol, LitFloatType),
2148    /// A boolean literal (`true`, `false`).
2149    Bool(bool),
2150    /// Placeholder for a literal that wasn't well-formed in some way.
2151    Err(ErrorGuaranteed),
2152}
2153
2154impl LitKind {
2155    pub fn str(&self) -> Option<Symbol> {
2156        match *self {
2157            LitKind::Str(s, _) => Some(s),
2158            _ => None,
2159        }
2160    }
2161
2162    /// Returns `true` if this literal is a string.
2163    pub fn is_str(&self) -> bool {
2164        matches!(self, LitKind::Str(..))
2165    }
2166
2167    /// Returns `true` if this literal is byte literal string.
2168    pub fn is_bytestr(&self) -> bool {
2169        matches!(self, LitKind::ByteStr(..))
2170    }
2171
2172    /// Returns `true` if this is a numeric literal.
2173    pub fn is_numeric(&self) -> bool {
2174        matches!(self, LitKind::Int(..) | LitKind::Float(..))
2175    }
2176
2177    /// Returns `true` if this literal has no suffix.
2178    /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
2179    pub fn is_unsuffixed(&self) -> bool {
2180        !self.is_suffixed()
2181    }
2182
2183    /// Returns `true` if this literal has a suffix.
2184    pub fn is_suffixed(&self) -> bool {
2185        match *self {
2186            // suffixed variants
2187            LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2188            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2189            // unsuffixed variants
2190            LitKind::Str(..)
2191            | LitKind::ByteStr(..)
2192            | LitKind::CStr(..)
2193            | LitKind::Byte(..)
2194            | LitKind::Char(..)
2195            | LitKind::Int(_, LitIntType::Unsuffixed)
2196            | LitKind::Float(_, LitFloatType::Unsuffixed)
2197            | LitKind::Bool(..)
2198            | LitKind::Err(_) => false,
2199        }
2200    }
2201}
2202
2203// N.B., If you change this, you'll probably want to change the corresponding
2204// type structure in `middle/ty.rs` as well.
2205#[derive(Clone, Encodable, Decodable, Debug)]
2206pub struct MutTy {
2207    pub ty: P<Ty>,
2208    pub mutbl: Mutability,
2209}
2210
2211/// Represents a function's signature in a trait declaration,
2212/// trait implementation, or free function.
2213#[derive(Clone, Encodable, Decodable, Debug)]
2214pub struct FnSig {
2215    pub header: FnHeader,
2216    pub decl: P<FnDecl>,
2217    pub span: Span,
2218}
2219
2220#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2221#[derive(Encodable, Decodable, HashStable_Generic)]
2222pub enum FloatTy {
2223    F16,
2224    F32,
2225    F64,
2226    F128,
2227}
2228
2229impl FloatTy {
2230    pub fn name_str(self) -> &'static str {
2231        match self {
2232            FloatTy::F16 => "f16",
2233            FloatTy::F32 => "f32",
2234            FloatTy::F64 => "f64",
2235            FloatTy::F128 => "f128",
2236        }
2237    }
2238
2239    pub fn name(self) -> Symbol {
2240        match self {
2241            FloatTy::F16 => sym::f16,
2242            FloatTy::F32 => sym::f32,
2243            FloatTy::F64 => sym::f64,
2244            FloatTy::F128 => sym::f128,
2245        }
2246    }
2247}
2248
2249#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2250#[derive(Encodable, Decodable, HashStable_Generic)]
2251pub enum IntTy {
2252    Isize,
2253    I8,
2254    I16,
2255    I32,
2256    I64,
2257    I128,
2258}
2259
2260impl IntTy {
2261    pub fn name_str(&self) -> &'static str {
2262        match *self {
2263            IntTy::Isize => "isize",
2264            IntTy::I8 => "i8",
2265            IntTy::I16 => "i16",
2266            IntTy::I32 => "i32",
2267            IntTy::I64 => "i64",
2268            IntTy::I128 => "i128",
2269        }
2270    }
2271
2272    pub fn name(&self) -> Symbol {
2273        match *self {
2274            IntTy::Isize => sym::isize,
2275            IntTy::I8 => sym::i8,
2276            IntTy::I16 => sym::i16,
2277            IntTy::I32 => sym::i32,
2278            IntTy::I64 => sym::i64,
2279            IntTy::I128 => sym::i128,
2280        }
2281    }
2282}
2283
2284#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2285#[derive(Encodable, Decodable, HashStable_Generic)]
2286pub enum UintTy {
2287    Usize,
2288    U8,
2289    U16,
2290    U32,
2291    U64,
2292    U128,
2293}
2294
2295impl UintTy {
2296    pub fn name_str(&self) -> &'static str {
2297        match *self {
2298            UintTy::Usize => "usize",
2299            UintTy::U8 => "u8",
2300            UintTy::U16 => "u16",
2301            UintTy::U32 => "u32",
2302            UintTy::U64 => "u64",
2303            UintTy::U128 => "u128",
2304        }
2305    }
2306
2307    pub fn name(&self) -> Symbol {
2308        match *self {
2309            UintTy::Usize => sym::usize,
2310            UintTy::U8 => sym::u8,
2311            UintTy::U16 => sym::u16,
2312            UintTy::U32 => sym::u32,
2313            UintTy::U64 => sym::u64,
2314            UintTy::U128 => sym::u128,
2315        }
2316    }
2317}
2318
2319/// A constraint on an associated item.
2320///
2321/// ### Examples
2322///
2323/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
2324/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
2325/// * the `A: Bound` in `Trait<A: Bound>`
2326/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
2327/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
2328/// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
2329#[derive(Clone, Encodable, Decodable, Debug)]
2330pub struct AssocItemConstraint {
2331    pub id: NodeId,
2332    pub ident: Ident,
2333    pub gen_args: Option<GenericArgs>,
2334    pub kind: AssocItemConstraintKind,
2335    pub span: Span,
2336}
2337
2338#[derive(Clone, Encodable, Decodable, Debug)]
2339pub enum Term {
2340    Ty(P<Ty>),
2341    Const(AnonConst),
2342}
2343
2344impl From<P<Ty>> for Term {
2345    fn from(v: P<Ty>) -> Self {
2346        Term::Ty(v)
2347    }
2348}
2349
2350impl From<AnonConst> for Term {
2351    fn from(v: AnonConst) -> Self {
2352        Term::Const(v)
2353    }
2354}
2355
2356/// The kind of [associated item constraint][AssocItemConstraint].
2357#[derive(Clone, Encodable, Decodable, Debug)]
2358pub enum AssocItemConstraintKind {
2359    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
2360    ///
2361    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
2362    ///
2363    /// Furthermore, associated type equality constraints can also be referred to as *associated type
2364    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
2365    Equality { term: Term },
2366    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
2367    Bound { bounds: GenericBounds },
2368}
2369
2370#[derive(Encodable, Decodable, Debug)]
2371pub struct Ty {
2372    pub id: NodeId,
2373    pub kind: TyKind,
2374    pub span: Span,
2375    pub tokens: Option<LazyAttrTokenStream>,
2376}
2377
2378impl Clone for Ty {
2379    fn clone(&self) -> Self {
2380        ensure_sufficient_stack(|| Self {
2381            id: self.id,
2382            kind: self.kind.clone(),
2383            span: self.span,
2384            tokens: self.tokens.clone(),
2385        })
2386    }
2387}
2388
2389impl From<P<Ty>> for Ty {
2390    fn from(value: P<Ty>) -> Self {
2391        *value
2392    }
2393}
2394
2395impl Ty {
2396    pub fn peel_refs(&self) -> &Self {
2397        let mut final_ty = self;
2398        while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2399        {
2400            final_ty = ty;
2401        }
2402        final_ty
2403    }
2404
2405    pub fn is_maybe_parenthesised_infer(&self) -> bool {
2406        match &self.kind {
2407            TyKind::Infer => true,
2408            TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2409            _ => false,
2410        }
2411    }
2412}
2413
2414#[derive(Clone, Encodable, Decodable, Debug)]
2415pub struct BareFnTy {
2416    pub safety: Safety,
2417    pub ext: Extern,
2418    pub generic_params: ThinVec<GenericParam>,
2419    pub decl: P<FnDecl>,
2420    /// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything
2421    /// after the generic params (if there are any, e.g. `for<'a>`).
2422    pub decl_span: Span,
2423}
2424
2425#[derive(Clone, Encodable, Decodable, Debug)]
2426pub struct UnsafeBinderTy {
2427    pub generic_params: ThinVec<GenericParam>,
2428    pub inner_ty: P<Ty>,
2429}
2430
2431/// The various kinds of type recognized by the compiler.
2432//
2433// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
2434#[derive(Clone, Encodable, Decodable, Debug)]
2435pub enum TyKind {
2436    /// A variable-length slice (`[T]`).
2437    Slice(P<Ty>),
2438    /// A fixed length array (`[T; n]`).
2439    Array(P<Ty>, AnonConst),
2440    /// A raw pointer (`*const T` or `*mut T`).
2441    Ptr(MutTy),
2442    /// A reference (`&'a T` or `&'a mut T`).
2443    Ref(Option<Lifetime>, MutTy),
2444    /// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
2445    ///
2446    /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
2447    PinnedRef(Option<Lifetime>, MutTy),
2448    /// A bare function (e.g., `fn(usize) -> bool`).
2449    BareFn(P<BareFnTy>),
2450    /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
2451    UnsafeBinder(P<UnsafeBinderTy>),
2452    /// The never type (`!`).
2453    Never,
2454    /// A tuple (`(A, B, C, D,...)`).
2455    Tup(ThinVec<P<Ty>>),
2456    /// A path (`module::module::...::Type`), optionally
2457    /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
2458    ///
2459    /// Type parameters are stored in the `Path` itself.
2460    Path(Option<P<QSelf>>, Path),
2461    /// A trait object type `Bound1 + Bound2 + Bound3`
2462    /// where `Bound` is a trait or a lifetime.
2463    TraitObject(GenericBounds, TraitObjectSyntax),
2464    /// An `impl Bound1 + Bound2 + Bound3` type
2465    /// where `Bound` is a trait or a lifetime.
2466    ///
2467    /// The `NodeId` exists to prevent lowering from having to
2468    /// generate `NodeId`s on the fly, which would complicate
2469    /// the generation of opaque `type Foo = impl Trait` items significantly.
2470    ImplTrait(NodeId, GenericBounds),
2471    /// No-op; kept solely so that we can pretty-print faithfully.
2472    Paren(P<Ty>),
2473    /// Unused for now.
2474    Typeof(AnonConst),
2475    /// This means the type should be inferred instead of it having been
2476    /// specified. This can appear anywhere in a type.
2477    Infer,
2478    /// Inferred type of a `self` or `&self` argument in a method.
2479    ImplicitSelf,
2480    /// A macro in the type position.
2481    MacCall(P<MacCall>),
2482    /// Placeholder for a `va_list`.
2483    CVarArgs,
2484    /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
2485    /// just as part of the type system.
2486    Pat(P<Ty>, P<TyPat>),
2487    /// Sometimes we need a dummy value when no error has occurred.
2488    Dummy,
2489    /// Placeholder for a kind that has failed to be defined.
2490    Err(ErrorGuaranteed),
2491}
2492
2493impl TyKind {
2494    pub fn is_implicit_self(&self) -> bool {
2495        matches!(self, TyKind::ImplicitSelf)
2496    }
2497
2498    pub fn is_unit(&self) -> bool {
2499        matches!(self, TyKind::Tup(tys) if tys.is_empty())
2500    }
2501
2502    pub fn is_simple_path(&self) -> Option<Symbol> {
2503        if let TyKind::Path(None, Path { segments, .. }) = &self
2504            && let [segment] = &segments[..]
2505            && segment.args.is_none()
2506        {
2507            Some(segment.ident.name)
2508        } else {
2509            None
2510        }
2511    }
2512
2513    /// Returns `true` if this type is considered a scalar primitive (e.g.,
2514    /// `i32`, `u8`, `bool`, etc).
2515    ///
2516    /// This check is based on **symbol equality** and does **not** remove any
2517    /// path prefixes or references. If a type alias or shadowing is present
2518    /// (e.g., `type i32 = CustomType;`), this method will still return `true`
2519    /// for `i32`, even though it may not refer to the primitive type.
2520    pub fn maybe_scalar(&self) -> bool {
2521        let Some(ty_sym) = self.is_simple_path() else {
2522            // unit type
2523            return self.is_unit();
2524        };
2525        matches!(
2526            ty_sym,
2527            sym::i8
2528                | sym::i16
2529                | sym::i32
2530                | sym::i64
2531                | sym::i128
2532                | sym::u8
2533                | sym::u16
2534                | sym::u32
2535                | sym::u64
2536                | sym::u128
2537                | sym::f16
2538                | sym::f32
2539                | sym::f64
2540                | sym::f128
2541                | sym::char
2542                | sym::bool
2543        )
2544    }
2545}
2546
2547/// A pattern type pattern.
2548#[derive(Clone, Encodable, Decodable, Debug)]
2549pub struct TyPat {
2550    pub id: NodeId,
2551    pub kind: TyPatKind,
2552    pub span: Span,
2553    pub tokens: Option<LazyAttrTokenStream>,
2554}
2555
2556/// All the different flavors of pattern that Rust recognizes.
2557//
2558// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
2559#[derive(Clone, Encodable, Decodable, Debug)]
2560pub enum TyPatKind {
2561    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
2562    Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2563
2564    Or(ThinVec<P<TyPat>>),
2565
2566    /// Placeholder for a pattern that wasn't syntactically well formed in some way.
2567    Err(ErrorGuaranteed),
2568}
2569
2570/// Syntax used to declare a trait object.
2571#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2572#[repr(u8)]
2573pub enum TraitObjectSyntax {
2574    // SAFETY: When adding new variants make sure to update the `Tag` impl.
2575    Dyn = 0,
2576    DynStar = 1,
2577    None = 2,
2578}
2579
2580/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
2581/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
2582/// discriminants of the variants are no greater than `3`.
2583unsafe impl Tag for TraitObjectSyntax {
2584    const BITS: u32 = 2;
2585
2586    fn into_usize(self) -> usize {
2587        self as u8 as usize
2588    }
2589
2590    unsafe fn from_usize(tag: usize) -> Self {
2591        match tag {
2592            0 => TraitObjectSyntax::Dyn,
2593            1 => TraitObjectSyntax::DynStar,
2594            2 => TraitObjectSyntax::None,
2595            _ => unreachable!(),
2596        }
2597    }
2598}
2599
2600#[derive(Clone, Encodable, Decodable, Debug)]
2601pub enum PreciseCapturingArg {
2602    /// Lifetime parameter.
2603    Lifetime(Lifetime),
2604    /// Type or const parameter.
2605    Arg(Path, NodeId),
2606}
2607
2608/// Inline assembly operand explicit register or register class.
2609///
2610/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
2611#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2612pub enum InlineAsmRegOrRegClass {
2613    Reg(Symbol),
2614    RegClass(Symbol),
2615}
2616
2617#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2618pub struct InlineAsmOptions(u16);
2619bitflags::bitflags! {
2620    impl InlineAsmOptions: u16 {
2621        const PURE            = 1 << 0;
2622        const NOMEM           = 1 << 1;
2623        const READONLY        = 1 << 2;
2624        const PRESERVES_FLAGS = 1 << 3;
2625        const NORETURN        = 1 << 4;
2626        const NOSTACK         = 1 << 5;
2627        const ATT_SYNTAX      = 1 << 6;
2628        const RAW             = 1 << 7;
2629        const MAY_UNWIND      = 1 << 8;
2630    }
2631}
2632
2633impl InlineAsmOptions {
2634    pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2635
2636    pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2637    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2638
2639    pub fn human_readable_names(&self) -> Vec<&'static str> {
2640        let mut options = vec![];
2641
2642        if self.contains(InlineAsmOptions::PURE) {
2643            options.push("pure");
2644        }
2645        if self.contains(InlineAsmOptions::NOMEM) {
2646            options.push("nomem");
2647        }
2648        if self.contains(InlineAsmOptions::READONLY) {
2649            options.push("readonly");
2650        }
2651        if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2652            options.push("preserves_flags");
2653        }
2654        if self.contains(InlineAsmOptions::NORETURN) {
2655            options.push("noreturn");
2656        }
2657        if self.contains(InlineAsmOptions::NOSTACK) {
2658            options.push("nostack");
2659        }
2660        if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2661            options.push("att_syntax");
2662        }
2663        if self.contains(InlineAsmOptions::RAW) {
2664            options.push("raw");
2665        }
2666        if self.contains(InlineAsmOptions::MAY_UNWIND) {
2667            options.push("may_unwind");
2668        }
2669
2670        options
2671    }
2672}
2673
2674impl std::fmt::Debug for InlineAsmOptions {
2675    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2676        bitflags::parser::to_writer(self, f)
2677    }
2678}
2679
2680#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2681pub enum InlineAsmTemplatePiece {
2682    String(Cow<'static, str>),
2683    Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2684}
2685
2686impl fmt::Display for InlineAsmTemplatePiece {
2687    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2688        match self {
2689            Self::String(s) => {
2690                for c in s.chars() {
2691                    match c {
2692                        '{' => f.write_str("{{")?,
2693                        '}' => f.write_str("}}")?,
2694                        _ => c.fmt(f)?,
2695                    }
2696                }
2697                Ok(())
2698            }
2699            Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2700                write!(f, "{{{operand_idx}:{modifier}}}")
2701            }
2702            Self::Placeholder { operand_idx, modifier: None, .. } => {
2703                write!(f, "{{{operand_idx}}}")
2704            }
2705        }
2706    }
2707}
2708
2709impl InlineAsmTemplatePiece {
2710    /// Rebuilds the asm template string from its pieces.
2711    pub fn to_string(s: &[Self]) -> String {
2712        use fmt::Write;
2713        let mut out = String::new();
2714        for p in s.iter() {
2715            let _ = write!(out, "{p}");
2716        }
2717        out
2718    }
2719}
2720
2721/// Inline assembly symbol operands get their own AST node that is somewhat
2722/// similar to `AnonConst`.
2723///
2724/// The main difference is that we specifically don't assign it `DefId` in
2725/// `DefCollector`. Instead this is deferred until AST lowering where we
2726/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
2727/// depending on what the path resolves to.
2728#[derive(Clone, Encodable, Decodable, Debug)]
2729pub struct InlineAsmSym {
2730    pub id: NodeId,
2731    pub qself: Option<P<QSelf>>,
2732    pub path: Path,
2733}
2734
2735/// Inline assembly operand.
2736///
2737/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
2738#[derive(Clone, Encodable, Decodable, Debug)]
2739pub enum InlineAsmOperand {
2740    In {
2741        reg: InlineAsmRegOrRegClass,
2742        expr: P<Expr>,
2743    },
2744    Out {
2745        reg: InlineAsmRegOrRegClass,
2746        late: bool,
2747        expr: Option<P<Expr>>,
2748    },
2749    InOut {
2750        reg: InlineAsmRegOrRegClass,
2751        late: bool,
2752        expr: P<Expr>,
2753    },
2754    SplitInOut {
2755        reg: InlineAsmRegOrRegClass,
2756        late: bool,
2757        in_expr: P<Expr>,
2758        out_expr: Option<P<Expr>>,
2759    },
2760    Const {
2761        anon_const: AnonConst,
2762    },
2763    Sym {
2764        sym: InlineAsmSym,
2765    },
2766    Label {
2767        block: P<Block>,
2768    },
2769}
2770
2771impl InlineAsmOperand {
2772    pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2773        match self {
2774            Self::In { reg, .. }
2775            | Self::Out { reg, .. }
2776            | Self::InOut { reg, .. }
2777            | Self::SplitInOut { reg, .. } => Some(reg),
2778            Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2779        }
2780    }
2781}
2782
2783#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2784pub enum AsmMacro {
2785    /// The `asm!` macro
2786    Asm,
2787    /// The `global_asm!` macro
2788    GlobalAsm,
2789    /// The `naked_asm!` macro
2790    NakedAsm,
2791}
2792
2793impl AsmMacro {
2794    pub const fn macro_name(self) -> &'static str {
2795        match self {
2796            AsmMacro::Asm => "asm",
2797            AsmMacro::GlobalAsm => "global_asm",
2798            AsmMacro::NakedAsm => "naked_asm",
2799        }
2800    }
2801
2802    pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2803        match self {
2804            AsmMacro::Asm => true,
2805            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2806            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2807        }
2808    }
2809
2810    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2811        match self {
2812            AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2813            AsmMacro::GlobalAsm => true,
2814            AsmMacro::NakedAsm => true,
2815        }
2816    }
2817}
2818
2819/// Inline assembly.
2820///
2821/// E.g., `asm!("NOP");`.
2822#[derive(Clone, Encodable, Decodable, Debug)]
2823pub struct InlineAsm {
2824    pub asm_macro: AsmMacro,
2825    pub template: Vec<InlineAsmTemplatePiece>,
2826    pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2827    pub operands: Vec<(InlineAsmOperand, Span)>,
2828    pub clobber_abis: Vec<(Symbol, Span)>,
2829    pub options: InlineAsmOptions,
2830    pub line_spans: Vec<Span>,
2831}
2832
2833/// A parameter in a function header.
2834///
2835/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
2836#[derive(Clone, Encodable, Decodable, Debug)]
2837pub struct Param {
2838    pub attrs: AttrVec,
2839    pub ty: P<Ty>,
2840    pub pat: P<Pat>,
2841    pub id: NodeId,
2842    pub span: Span,
2843    pub is_placeholder: bool,
2844}
2845
2846/// Alternative representation for `Arg`s describing `self` parameter of methods.
2847///
2848/// E.g., `&mut self` as in `fn foo(&mut self)`.
2849#[derive(Clone, Encodable, Decodable, Debug)]
2850pub enum SelfKind {
2851    /// `self`, `mut self`
2852    Value(Mutability),
2853    /// `&'lt self`, `&'lt mut self`
2854    Region(Option<Lifetime>, Mutability),
2855    /// `&'lt pin const self`, `&'lt pin mut self`
2856    Pinned(Option<Lifetime>, Mutability),
2857    /// `self: TYPE`, `mut self: TYPE`
2858    Explicit(P<Ty>, Mutability),
2859}
2860
2861impl SelfKind {
2862    pub fn to_ref_suggestion(&self) -> String {
2863        match self {
2864            SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2865            SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2866            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2867            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2868            SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2869                unreachable!("if we had an explicit self, we wouldn't be here")
2870            }
2871        }
2872    }
2873}
2874
2875pub type ExplicitSelf = Spanned<SelfKind>;
2876
2877impl Param {
2878    /// Attempts to cast parameter to `ExplicitSelf`.
2879    pub fn to_self(&self) -> Option<ExplicitSelf> {
2880        if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2881            if ident.name == kw::SelfLower {
2882                return match self.ty.kind {
2883                    TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2884                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2885                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2886                    }
2887                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2888                        if ty.kind.is_implicit_self() =>
2889                    {
2890                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2891                    }
2892                    _ => Some(respan(
2893                        self.pat.span.to(self.ty.span),
2894                        SelfKind::Explicit(self.ty.clone(), mutbl),
2895                    )),
2896                };
2897            }
2898        }
2899        None
2900    }
2901
2902    /// Returns `true` if parameter is `self`.
2903    pub fn is_self(&self) -> bool {
2904        if let PatKind::Ident(_, ident, _) = self.pat.kind {
2905            ident.name == kw::SelfLower
2906        } else {
2907            false
2908        }
2909    }
2910
2911    /// Builds a `Param` object from `ExplicitSelf`.
2912    pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2913        let span = eself.span.to(eself_ident.span);
2914        let infer_ty = P(Ty {
2915            id: DUMMY_NODE_ID,
2916            kind: TyKind::ImplicitSelf,
2917            span: eself_ident.span,
2918            tokens: None,
2919        });
2920        let (mutbl, ty) = match eself.node {
2921            SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2922            SelfKind::Value(mutbl) => (mutbl, infer_ty),
2923            SelfKind::Region(lt, mutbl) => (
2924                Mutability::Not,
2925                P(Ty {
2926                    id: DUMMY_NODE_ID,
2927                    kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2928                    span,
2929                    tokens: None,
2930                }),
2931            ),
2932            SelfKind::Pinned(lt, mutbl) => (
2933                mutbl,
2934                P(Ty {
2935                    id: DUMMY_NODE_ID,
2936                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2937                    span,
2938                    tokens: None,
2939                }),
2940            ),
2941        };
2942        Param {
2943            attrs,
2944            pat: P(Pat {
2945                id: DUMMY_NODE_ID,
2946                kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2947                span,
2948                tokens: None,
2949            }),
2950            span,
2951            ty,
2952            id: DUMMY_NODE_ID,
2953            is_placeholder: false,
2954        }
2955    }
2956}
2957
2958/// A signature (not the body) of a function declaration.
2959///
2960/// E.g., `fn foo(bar: baz)`.
2961///
2962/// Please note that it's different from `FnHeader` structure
2963/// which contains metadata about function safety, asyncness, constness and ABI.
2964#[derive(Clone, Encodable, Decodable, Debug)]
2965pub struct FnDecl {
2966    pub inputs: ThinVec<Param>,
2967    pub output: FnRetTy,
2968}
2969
2970impl FnDecl {
2971    pub fn has_self(&self) -> bool {
2972        self.inputs.get(0).is_some_and(Param::is_self)
2973    }
2974    pub fn c_variadic(&self) -> bool {
2975        self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2976    }
2977}
2978
2979/// Is the trait definition an auto trait?
2980#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2981pub enum IsAuto {
2982    Yes,
2983    No,
2984}
2985
2986/// Safety of items.
2987#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2988#[derive(HashStable_Generic)]
2989pub enum Safety {
2990    /// `unsafe` an item is explicitly marked as `unsafe`.
2991    Unsafe(Span),
2992    /// `safe` an item is explicitly marked as `safe`.
2993    Safe(Span),
2994    /// Default means no value was provided, it will take a default value given the context in
2995    /// which is used.
2996    Default,
2997}
2998
2999/// Describes what kind of coroutine markers, if any, a function has.
3000///
3001/// Coroutine markers are things that cause the function to generate a coroutine, such as `async`,
3002/// which makes the function return `impl Future`, or `gen`, which makes the function return `impl
3003/// Iterator`.
3004#[derive(Copy, Clone, Encodable, Decodable, Debug)]
3005pub enum CoroutineKind {
3006    /// `async`, which returns an `impl Future`.
3007    Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3008    /// `gen`, which returns an `impl Iterator`.
3009    Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3010    /// `async gen`, which returns an `impl AsyncIterator`.
3011    AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3012}
3013
3014impl CoroutineKind {
3015    pub fn span(self) -> Span {
3016        match self {
3017            CoroutineKind::Async { span, .. } => span,
3018            CoroutineKind::Gen { span, .. } => span,
3019            CoroutineKind::AsyncGen { span, .. } => span,
3020        }
3021    }
3022
3023    pub fn as_str(self) -> &'static str {
3024        match self {
3025            CoroutineKind::Async { .. } => "async",
3026            CoroutineKind::Gen { .. } => "gen",
3027            CoroutineKind::AsyncGen { .. } => "async gen",
3028        }
3029    }
3030
3031    pub fn closure_id(self) -> NodeId {
3032        match self {
3033            CoroutineKind::Async { closure_id, .. }
3034            | CoroutineKind::Gen { closure_id, .. }
3035            | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3036        }
3037    }
3038
3039    /// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
3040    /// item.
3041    pub fn return_id(self) -> (NodeId, Span) {
3042        match self {
3043            CoroutineKind::Async { return_impl_trait_id, span, .. }
3044            | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3045            | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3046                (return_impl_trait_id, span)
3047            }
3048        }
3049    }
3050}
3051
3052#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3053#[derive(HashStable_Generic)]
3054pub enum Const {
3055    Yes(Span),
3056    No,
3057}
3058
3059/// Item defaultness.
3060/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
3061#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3062pub enum Defaultness {
3063    Default(Span),
3064    Final,
3065}
3066
3067#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3068pub enum ImplPolarity {
3069    /// `impl Trait for Type`
3070    Positive,
3071    /// `impl !Trait for Type`
3072    Negative(Span),
3073}
3074
3075impl fmt::Debug for ImplPolarity {
3076    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3077        match *self {
3078            ImplPolarity::Positive => "positive".fmt(f),
3079            ImplPolarity::Negative(_) => "negative".fmt(f),
3080        }
3081    }
3082}
3083
3084/// The polarity of a trait bound.
3085#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3086#[derive(HashStable_Generic)]
3087pub enum BoundPolarity {
3088    /// `Type: Trait`
3089    Positive,
3090    /// `Type: !Trait`
3091    Negative(Span),
3092    /// `Type: ?Trait`
3093    Maybe(Span),
3094}
3095
3096impl BoundPolarity {
3097    pub fn as_str(self) -> &'static str {
3098        match self {
3099            Self::Positive => "",
3100            Self::Negative(_) => "!",
3101            Self::Maybe(_) => "?",
3102        }
3103    }
3104}
3105
3106/// The constness of a trait bound.
3107#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3108#[derive(HashStable_Generic)]
3109pub enum BoundConstness {
3110    /// `Type: Trait`
3111    Never,
3112    /// `Type: const Trait`
3113    Always(Span),
3114    /// `Type: ~const Trait`
3115    Maybe(Span),
3116}
3117
3118impl BoundConstness {
3119    pub fn as_str(self) -> &'static str {
3120        match self {
3121            Self::Never => "",
3122            Self::Always(_) => "const",
3123            Self::Maybe(_) => "~const",
3124        }
3125    }
3126}
3127
3128/// The asyncness of a trait bound.
3129#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3130#[derive(HashStable_Generic)]
3131pub enum BoundAsyncness {
3132    /// `Type: Trait`
3133    Normal,
3134    /// `Type: async Trait`
3135    Async(Span),
3136}
3137
3138impl BoundAsyncness {
3139    pub fn as_str(self) -> &'static str {
3140        match self {
3141            Self::Normal => "",
3142            Self::Async(_) => "async",
3143        }
3144    }
3145}
3146
3147#[derive(Clone, Encodable, Decodable, Debug)]
3148pub enum FnRetTy {
3149    /// Returns type is not specified.
3150    ///
3151    /// Functions default to `()` and closures default to inference.
3152    /// Span points to where return type would be inserted.
3153    Default(Span),
3154    /// Everything else.
3155    Ty(P<Ty>),
3156}
3157
3158impl FnRetTy {
3159    pub fn span(&self) -> Span {
3160        match self {
3161            &FnRetTy::Default(span) => span,
3162            FnRetTy::Ty(ty) => ty.span,
3163        }
3164    }
3165}
3166
3167#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3168pub enum Inline {
3169    Yes,
3170    No,
3171}
3172
3173/// Module item kind.
3174#[derive(Clone, Encodable, Decodable, Debug)]
3175pub enum ModKind {
3176    /// Module with inlined definition `mod foo { ... }`,
3177    /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
3178    /// The inner span is from the first token past `{` to the last token until `}`,
3179    /// or from the first to the last token in the loaded file.
3180    Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3181    /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
3182    Unloaded,
3183}
3184
3185#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3186pub struct ModSpans {
3187    /// `inner_span` covers the body of the module; for a file module, its the whole file.
3188    /// For an inline module, its the span inside the `{ ... }`, not including the curly braces.
3189    pub inner_span: Span,
3190    pub inject_use_span: Span,
3191}
3192
3193/// Foreign module declaration.
3194///
3195/// E.g., `extern { .. }` or `extern "C" { .. }`.
3196#[derive(Clone, Encodable, Decodable, Debug)]
3197pub struct ForeignMod {
3198    /// Span of the `extern` keyword.
3199    pub extern_span: Span,
3200    /// `unsafe` keyword accepted syntactically for macro DSLs, but not
3201    /// semantically by Rust.
3202    pub safety: Safety,
3203    pub abi: Option<StrLit>,
3204    pub items: ThinVec<P<ForeignItem>>,
3205}
3206
3207#[derive(Clone, Encodable, Decodable, Debug)]
3208pub struct EnumDef {
3209    pub variants: ThinVec<Variant>,
3210}
3211/// Enum variant.
3212#[derive(Clone, Encodable, Decodable, Debug)]
3213pub struct Variant {
3214    /// Attributes of the variant.
3215    pub attrs: AttrVec,
3216    /// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
3217    pub id: NodeId,
3218    /// Span
3219    pub span: Span,
3220    /// The visibility of the variant. Syntactically accepted but not semantically.
3221    pub vis: Visibility,
3222    /// Name of the variant.
3223    pub ident: Ident,
3224
3225    /// Fields and constructor id of the variant.
3226    pub data: VariantData,
3227    /// Explicit discriminant, e.g., `Foo = 1`.
3228    pub disr_expr: Option<AnonConst>,
3229    /// Is a macro placeholder.
3230    pub is_placeholder: bool,
3231}
3232
3233/// Part of `use` item to the right of its prefix.
3234#[derive(Clone, Encodable, Decodable, Debug)]
3235pub enum UseTreeKind {
3236    /// `use prefix` or `use prefix as rename`
3237    Simple(Option<Ident>),
3238    /// `use prefix::{...}`
3239    ///
3240    /// The span represents the braces of the nested group and all elements within:
3241    ///
3242    /// ```text
3243    /// use foo::{bar, baz};
3244    ///          ^^^^^^^^^^
3245    /// ```
3246    Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3247    /// `use prefix::*`
3248    Glob,
3249}
3250
3251/// A tree of paths sharing common prefixes.
3252/// Used in `use` items both at top-level and inside of braces in import groups.
3253#[derive(Clone, Encodable, Decodable, Debug)]
3254pub struct UseTree {
3255    pub prefix: Path,
3256    pub kind: UseTreeKind,
3257    pub span: Span,
3258}
3259
3260impl UseTree {
3261    pub fn ident(&self) -> Ident {
3262        match self.kind {
3263            UseTreeKind::Simple(Some(rename)) => rename,
3264            UseTreeKind::Simple(None) => {
3265                self.prefix.segments.last().expect("empty prefix in a simple import").ident
3266            }
3267            _ => panic!("`UseTree::ident` can only be used on a simple import"),
3268        }
3269    }
3270}
3271
3272/// Distinguishes between `Attribute`s that decorate items and Attributes that
3273/// are contained as statements within items. These two cases need to be
3274/// distinguished for pretty-printing.
3275#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3276pub enum AttrStyle {
3277    Outer,
3278    Inner,
3279}
3280
3281/// A list of attributes.
3282pub type AttrVec = ThinVec<Attribute>;
3283
3284/// A syntax-level representation of an attribute.
3285#[derive(Clone, Encodable, Decodable, Debug)]
3286pub struct Attribute {
3287    pub kind: AttrKind,
3288    pub id: AttrId,
3289    /// Denotes if the attribute decorates the following construct (outer)
3290    /// or the construct this attribute is contained within (inner).
3291    pub style: AttrStyle,
3292    pub span: Span,
3293}
3294
3295#[derive(Clone, Encodable, Decodable, Debug)]
3296pub enum AttrKind {
3297    /// A normal attribute.
3298    Normal(P<NormalAttr>),
3299
3300    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
3301    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
3302    /// variant (which is much less compact and thus more expensive).
3303    DocComment(CommentKind, Symbol),
3304}
3305
3306#[derive(Clone, Encodable, Decodable, Debug)]
3307pub struct NormalAttr {
3308    pub item: AttrItem,
3309    // Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`.
3310    pub tokens: Option<LazyAttrTokenStream>,
3311}
3312
3313impl NormalAttr {
3314    pub fn from_ident(ident: Ident) -> Self {
3315        Self {
3316            item: AttrItem {
3317                unsafety: Safety::Default,
3318                path: Path::from_ident(ident),
3319                args: AttrArgs::Empty,
3320                tokens: None,
3321            },
3322            tokens: None,
3323        }
3324    }
3325}
3326
3327#[derive(Clone, Encodable, Decodable, Debug)]
3328pub struct AttrItem {
3329    pub unsafety: Safety,
3330    pub path: Path,
3331    pub args: AttrArgs,
3332    // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`.
3333    pub tokens: Option<LazyAttrTokenStream>,
3334}
3335
3336impl AttrItem {
3337    pub fn is_valid_for_outer_style(&self) -> bool {
3338        self.path == sym::cfg_attr
3339            || self.path == sym::cfg
3340            || self.path == sym::forbid
3341            || self.path == sym::warn
3342            || self.path == sym::allow
3343            || self.path == sym::deny
3344    }
3345}
3346
3347/// `TraitRef`s appear in impls.
3348///
3349/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
3350/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
3351/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
3352/// same as the impl's `NodeId`).
3353#[derive(Clone, Encodable, Decodable, Debug)]
3354pub struct TraitRef {
3355    pub path: Path,
3356    pub ref_id: NodeId,
3357}
3358
3359#[derive(Clone, Encodable, Decodable, Debug)]
3360pub struct PolyTraitRef {
3361    /// The `'a` in `for<'a> Foo<&'a T>`.
3362    pub bound_generic_params: ThinVec<GenericParam>,
3363
3364    // Optional constness, asyncness, or polarity.
3365    pub modifiers: TraitBoundModifiers,
3366
3367    /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
3368    pub trait_ref: TraitRef,
3369
3370    pub span: Span,
3371}
3372
3373impl PolyTraitRef {
3374    pub fn new(
3375        generic_params: ThinVec<GenericParam>,
3376        path: Path,
3377        modifiers: TraitBoundModifiers,
3378        span: Span,
3379    ) -> Self {
3380        PolyTraitRef {
3381            bound_generic_params: generic_params,
3382            modifiers,
3383            trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3384            span,
3385        }
3386    }
3387}
3388
3389#[derive(Clone, Encodable, Decodable, Debug)]
3390pub struct Visibility {
3391    pub kind: VisibilityKind,
3392    pub span: Span,
3393    pub tokens: Option<LazyAttrTokenStream>,
3394}
3395
3396#[derive(Clone, Encodable, Decodable, Debug)]
3397pub enum VisibilityKind {
3398    Public,
3399    Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3400    Inherited,
3401}
3402
3403impl VisibilityKind {
3404    pub fn is_pub(&self) -> bool {
3405        matches!(self, VisibilityKind::Public)
3406    }
3407}
3408
3409/// Field definition in a struct, variant or union.
3410///
3411/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
3412#[derive(Clone, Encodable, Decodable, Debug)]
3413pub struct FieldDef {
3414    pub attrs: AttrVec,
3415    pub id: NodeId,
3416    pub span: Span,
3417    pub vis: Visibility,
3418    pub safety: Safety,
3419    pub ident: Option<Ident>,
3420
3421    pub ty: P<Ty>,
3422    pub default: Option<AnonConst>,
3423    pub is_placeholder: bool,
3424}
3425
3426/// Was parsing recovery performed?
3427#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3428pub enum Recovered {
3429    No,
3430    Yes(ErrorGuaranteed),
3431}
3432
3433/// Fields and constructor ids of enum variants and structs.
3434#[derive(Clone, Encodable, Decodable, Debug)]
3435pub enum VariantData {
3436    /// Struct variant.
3437    ///
3438    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
3439    Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3440    /// Tuple variant.
3441    ///
3442    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
3443    Tuple(ThinVec<FieldDef>, NodeId),
3444    /// Unit variant.
3445    ///
3446    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
3447    Unit(NodeId),
3448}
3449
3450impl VariantData {
3451    /// Return the fields of this variant.
3452    pub fn fields(&self) -> &[FieldDef] {
3453        match self {
3454            VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3455            _ => &[],
3456        }
3457    }
3458
3459    /// Return the `NodeId` of this variant's constructor, if it has one.
3460    pub fn ctor_node_id(&self) -> Option<NodeId> {
3461        match *self {
3462            VariantData::Struct { .. } => None,
3463            VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3464        }
3465    }
3466}
3467
3468/// An item definition.
3469#[derive(Clone, Encodable, Decodable, Debug)]
3470pub struct Item<K = ItemKind> {
3471    pub attrs: AttrVec,
3472    pub id: NodeId,
3473    pub span: Span,
3474    pub vis: Visibility,
3475
3476    pub kind: K,
3477
3478    /// Original tokens this item was parsed from. This isn't necessarily
3479    /// available for all items, although over time more and more items should
3480    /// have this be `Some`. Right now this is primarily used for procedural
3481    /// macros, notably custom attributes.
3482    ///
3483    /// Note that the tokens here do not include the outer attributes, but will
3484    /// include inner attributes.
3485    pub tokens: Option<LazyAttrTokenStream>,
3486}
3487
3488impl Item {
3489    /// Return the span that encompasses the attributes.
3490    pub fn span_with_attributes(&self) -> Span {
3491        self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3492    }
3493
3494    pub fn opt_generics(&self) -> Option<&Generics> {
3495        match &self.kind {
3496            ItemKind::ExternCrate(..)
3497            | ItemKind::Use(_)
3498            | ItemKind::Mod(..)
3499            | ItemKind::ForeignMod(_)
3500            | ItemKind::GlobalAsm(_)
3501            | ItemKind::MacCall(_)
3502            | ItemKind::Delegation(_)
3503            | ItemKind::DelegationMac(_)
3504            | ItemKind::MacroDef(..) => None,
3505            ItemKind::Static(_) => None,
3506            ItemKind::Const(i) => Some(&i.generics),
3507            ItemKind::Fn(i) => Some(&i.generics),
3508            ItemKind::TyAlias(i) => Some(&i.generics),
3509            ItemKind::TraitAlias(_, generics, _)
3510            | ItemKind::Enum(_, generics, _)
3511            | ItemKind::Struct(_, generics, _)
3512            | ItemKind::Union(_, generics, _) => Some(&generics),
3513            ItemKind::Trait(i) => Some(&i.generics),
3514            ItemKind::Impl(i) => Some(&i.generics),
3515        }
3516    }
3517}
3518
3519/// `extern` qualifier on a function item or function type.
3520#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3521pub enum Extern {
3522    /// No explicit extern keyword was used.
3523    ///
3524    /// E.g. `fn foo() {}`.
3525    None,
3526    /// An explicit extern keyword was used, but with implicit ABI.
3527    ///
3528    /// E.g. `extern fn foo() {}`.
3529    ///
3530    /// This is just `extern "C"` (see `rustc_abi::ExternAbi::FALLBACK`).
3531    Implicit(Span),
3532    /// An explicit extern keyword was used with an explicit ABI.
3533    ///
3534    /// E.g. `extern "C" fn foo() {}`.
3535    Explicit(StrLit, Span),
3536}
3537
3538impl Extern {
3539    pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3540        match abi {
3541            Some(name) => Extern::Explicit(name, span),
3542            None => Extern::Implicit(span),
3543        }
3544    }
3545}
3546
3547/// A function header.
3548///
3549/// All the information between the visibility and the name of the function is
3550/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
3551#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3552pub struct FnHeader {
3553    /// Whether this is `unsafe`, or has a default safety.
3554    pub safety: Safety,
3555    /// Whether this is `async`, `gen`, or nothing.
3556    pub coroutine_kind: Option<CoroutineKind>,
3557    /// The `const` keyword, if any
3558    pub constness: Const,
3559    /// The `extern` keyword and corresponding ABI string, if any.
3560    pub ext: Extern,
3561}
3562
3563impl FnHeader {
3564    /// Does this function header have any qualifiers or is it empty?
3565    pub fn has_qualifiers(&self) -> bool {
3566        let Self { safety, coroutine_kind, constness, ext } = self;
3567        matches!(safety, Safety::Unsafe(_))
3568            || coroutine_kind.is_some()
3569            || matches!(constness, Const::Yes(_))
3570            || !matches!(ext, Extern::None)
3571    }
3572
3573    /// Return a span encompassing the header, or none if all options are default.
3574    pub fn span(&self) -> Option<Span> {
3575        fn append(a: &mut Option<Span>, b: Span) {
3576            *a = match a {
3577                None => Some(b),
3578                Some(x) => Some(x.to(b)),
3579            }
3580        }
3581
3582        let mut full_span = None;
3583
3584        match self.safety {
3585            Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3586            Safety::Default => {}
3587        };
3588
3589        if let Some(coroutine_kind) = self.coroutine_kind {
3590            append(&mut full_span, coroutine_kind.span());
3591        }
3592
3593        if let Const::Yes(span) = self.constness {
3594            append(&mut full_span, span);
3595        }
3596
3597        match self.ext {
3598            Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3599            Extern::None => {}
3600        }
3601
3602        full_span
3603    }
3604}
3605
3606impl Default for FnHeader {
3607    fn default() -> FnHeader {
3608        FnHeader {
3609            safety: Safety::Default,
3610            coroutine_kind: None,
3611            constness: Const::No,
3612            ext: Extern::None,
3613        }
3614    }
3615}
3616
3617#[derive(Clone, Encodable, Decodable, Debug)]
3618pub struct Trait {
3619    pub safety: Safety,
3620    pub is_auto: IsAuto,
3621    pub ident: Ident,
3622    pub generics: Generics,
3623    pub bounds: GenericBounds,
3624    pub items: ThinVec<P<AssocItem>>,
3625}
3626
3627/// The location of a where clause on a `TyAlias` (`Span`) and whether there was
3628/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there
3629/// are two locations for where clause on type aliases, but their predicates
3630/// are concatenated together.
3631///
3632/// Take this example:
3633/// ```ignore (only-for-syntax-highlight)
3634/// trait Foo {
3635///   type Assoc<'a, 'b> where Self: 'a, Self: 'b;
3636/// }
3637/// impl Foo for () {
3638///   type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
3639///   //                 ^^^^^^^^^^^^^^ first where clause
3640///   //                                     ^^^^^^^^^^^^^^ second where clause
3641/// }
3642/// ```
3643///
3644/// If there is no where clause, then this is `false` with `DUMMY_SP`.
3645#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3646pub struct TyAliasWhereClause {
3647    pub has_where_token: bool,
3648    pub span: Span,
3649}
3650
3651/// The span information for the two where clauses on a `TyAlias`.
3652#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3653pub struct TyAliasWhereClauses {
3654    /// Before the equals sign.
3655    pub before: TyAliasWhereClause,
3656    /// After the equals sign.
3657    pub after: TyAliasWhereClause,
3658    /// The index in `TyAlias.generics.where_clause.predicates` that would split
3659    /// into predicates from the where clause before the equals sign and the ones
3660    /// from the where clause after the equals sign.
3661    pub split: usize,
3662}
3663
3664#[derive(Clone, Encodable, Decodable, Debug)]
3665pub struct TyAlias {
3666    pub defaultness: Defaultness,
3667    pub ident: Ident,
3668    pub generics: Generics,
3669    pub where_clauses: TyAliasWhereClauses,
3670    pub bounds: GenericBounds,
3671    pub ty: Option<P<Ty>>,
3672}
3673
3674#[derive(Clone, Encodable, Decodable, Debug)]
3675pub struct Impl {
3676    pub defaultness: Defaultness,
3677    pub safety: Safety,
3678    pub generics: Generics,
3679    pub constness: Const,
3680    pub polarity: ImplPolarity,
3681    /// The trait being implemented, if any.
3682    pub of_trait: Option<TraitRef>,
3683    pub self_ty: P<Ty>,
3684    pub items: ThinVec<P<AssocItem>>,
3685}
3686
3687#[derive(Clone, Encodable, Decodable, Debug, Default)]
3688pub struct FnContract {
3689    pub requires: Option<P<Expr>>,
3690    pub ensures: Option<P<Expr>>,
3691}
3692
3693#[derive(Clone, Encodable, Decodable, Debug)]
3694pub struct Fn {
3695    pub defaultness: Defaultness,
3696    pub ident: Ident,
3697    pub generics: Generics,
3698    pub sig: FnSig,
3699    pub contract: Option<P<FnContract>>,
3700    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3701    pub body: Option<P<Block>>,
3702}
3703
3704#[derive(Clone, Encodable, Decodable, Debug)]
3705pub struct Delegation {
3706    /// Path resolution id.
3707    pub id: NodeId,
3708    pub qself: Option<P<QSelf>>,
3709    pub path: Path,
3710    pub ident: Ident,
3711    pub rename: Option<Ident>,
3712    pub body: Option<P<Block>>,
3713    /// The item was expanded from a glob delegation item.
3714    pub from_glob: bool,
3715}
3716
3717#[derive(Clone, Encodable, Decodable, Debug)]
3718pub struct DelegationMac {
3719    pub qself: Option<P<QSelf>>,
3720    pub prefix: Path,
3721    // Some for list delegation, and None for glob delegation.
3722    pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3723    pub body: Option<P<Block>>,
3724}
3725
3726#[derive(Clone, Encodable, Decodable, Debug)]
3727pub struct StaticItem {
3728    pub ident: Ident,
3729    pub ty: P<Ty>,
3730    pub safety: Safety,
3731    pub mutability: Mutability,
3732    pub expr: Option<P<Expr>>,
3733    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3734}
3735
3736#[derive(Clone, Encodable, Decodable, Debug)]
3737pub struct ConstItem {
3738    pub defaultness: Defaultness,
3739    pub ident: Ident,
3740    pub generics: Generics,
3741    pub ty: P<Ty>,
3742    pub expr: Option<P<Expr>>,
3743    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3744}
3745
3746// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
3747#[derive(Clone, Encodable, Decodable, Debug)]
3748pub enum ItemKind {
3749    /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
3750    ///
3751    /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
3752    ExternCrate(Option<Symbol>, Ident),
3753    /// A use declaration item (`use`).
3754    ///
3755    /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
3756    Use(UseTree),
3757    /// A static item (`static`).
3758    ///
3759    /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
3760    Static(Box<StaticItem>),
3761    /// A constant item (`const`).
3762    ///
3763    /// E.g., `const FOO: i32 = 42;`.
3764    Const(Box<ConstItem>),
3765    /// A function declaration (`fn`).
3766    ///
3767    /// E.g., `fn foo(bar: usize) -> usize { .. }`.
3768    Fn(Box<Fn>),
3769    /// A module declaration (`mod`).
3770    ///
3771    /// E.g., `mod foo;` or `mod foo { .. }`.
3772    /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
3773    /// semantically by Rust.
3774    Mod(Safety, Ident, ModKind),
3775    /// An external module (`extern`).
3776    ///
3777    /// E.g., `extern {}` or `extern "C" {}`.
3778    ForeignMod(ForeignMod),
3779    /// Module-level inline assembly (from `global_asm!()`).
3780    GlobalAsm(Box<InlineAsm>),
3781    /// A type alias (`type`).
3782    ///
3783    /// E.g., `type Foo = Bar<u8>;`.
3784    TyAlias(Box<TyAlias>),
3785    /// An enum definition (`enum`).
3786    ///
3787    /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
3788    Enum(Ident, Generics, EnumDef),
3789    /// A struct definition (`struct`).
3790    ///
3791    /// E.g., `struct Foo<A> { x: A }`.
3792    Struct(Ident, Generics, VariantData),
3793    /// A union definition (`union`).
3794    ///
3795    /// E.g., `union Foo<A, B> { x: A, y: B }`.
3796    Union(Ident, Generics, VariantData),
3797    /// A trait declaration (`trait`).
3798    ///
3799    /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
3800    Trait(Box<Trait>),
3801    /// Trait alias.
3802    ///
3803    /// E.g., `trait Foo = Bar + Quux;`.
3804    TraitAlias(Ident, Generics, GenericBounds),
3805    /// An implementation.
3806    ///
3807    /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
3808    Impl(Box<Impl>),
3809    /// A macro invocation.
3810    ///
3811    /// E.g., `foo!(..)`.
3812    MacCall(P<MacCall>),
3813    /// A macro definition.
3814    MacroDef(Ident, MacroDef),
3815    /// A single delegation item (`reuse`).
3816    ///
3817    /// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
3818    Delegation(Box<Delegation>),
3819    /// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
3820    /// Treated similarly to a macro call and expanded early.
3821    DelegationMac(Box<DelegationMac>),
3822}
3823
3824impl ItemKind {
3825    pub fn ident(&self) -> Option<Ident> {
3826        match *self {
3827            ItemKind::ExternCrate(_, ident)
3828            | ItemKind::Static(box StaticItem { ident, .. })
3829            | ItemKind::Const(box ConstItem { ident, .. })
3830            | ItemKind::Fn(box Fn { ident, .. })
3831            | ItemKind::Mod(_, ident, _)
3832            | ItemKind::TyAlias(box TyAlias { ident, .. })
3833            | ItemKind::Enum(ident, ..)
3834            | ItemKind::Struct(ident, ..)
3835            | ItemKind::Union(ident, ..)
3836            | ItemKind::Trait(box Trait { ident, .. })
3837            | ItemKind::TraitAlias(ident, ..)
3838            | ItemKind::MacroDef(ident, _)
3839            | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3840
3841            ItemKind::Use(_)
3842            | ItemKind::ForeignMod(_)
3843            | ItemKind::GlobalAsm(_)
3844            | ItemKind::Impl(_)
3845            | ItemKind::MacCall(_)
3846            | ItemKind::DelegationMac(_) => None,
3847        }
3848    }
3849
3850    /// "a" or "an"
3851    pub fn article(&self) -> &'static str {
3852        use ItemKind::*;
3853        match self {
3854            Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3855            | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3856            | Delegation(..) | DelegationMac(..) => "a",
3857            ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3858        }
3859    }
3860
3861    pub fn descr(&self) -> &'static str {
3862        match self {
3863            ItemKind::ExternCrate(..) => "extern crate",
3864            ItemKind::Use(..) => "`use` import",
3865            ItemKind::Static(..) => "static item",
3866            ItemKind::Const(..) => "constant item",
3867            ItemKind::Fn(..) => "function",
3868            ItemKind::Mod(..) => "module",
3869            ItemKind::ForeignMod(..) => "extern block",
3870            ItemKind::GlobalAsm(..) => "global asm item",
3871            ItemKind::TyAlias(..) => "type alias",
3872            ItemKind::Enum(..) => "enum",
3873            ItemKind::Struct(..) => "struct",
3874            ItemKind::Union(..) => "union",
3875            ItemKind::Trait(..) => "trait",
3876            ItemKind::TraitAlias(..) => "trait alias",
3877            ItemKind::MacCall(..) => "item macro invocation",
3878            ItemKind::MacroDef(..) => "macro definition",
3879            ItemKind::Impl { .. } => "implementation",
3880            ItemKind::Delegation(..) => "delegated function",
3881            ItemKind::DelegationMac(..) => "delegation",
3882        }
3883    }
3884
3885    pub fn generics(&self) -> Option<&Generics> {
3886        match self {
3887            Self::Fn(box Fn { generics, .. })
3888            | Self::TyAlias(box TyAlias { generics, .. })
3889            | Self::Const(box ConstItem { generics, .. })
3890            | Self::Enum(_, generics, _)
3891            | Self::Struct(_, generics, _)
3892            | Self::Union(_, generics, _)
3893            | Self::Trait(box Trait { generics, .. })
3894            | Self::TraitAlias(_, generics, _)
3895            | Self::Impl(box Impl { generics, .. }) => Some(generics),
3896            _ => None,
3897        }
3898    }
3899}
3900
3901/// Represents associated items.
3902/// These include items in `impl` and `trait` definitions.
3903pub type AssocItem = Item<AssocItemKind>;
3904
3905/// Represents associated item kinds.
3906///
3907/// The term "provided" in the variants below refers to the item having a default
3908/// definition / body. Meanwhile, a "required" item lacks a definition / body.
3909/// In an implementation, all items must be provided.
3910/// The `Option`s below denote the bodies, where `Some(_)`
3911/// means "provided" and conversely `None` means "required".
3912#[derive(Clone, Encodable, Decodable, Debug)]
3913pub enum AssocItemKind {
3914    /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
3915    /// If `def` is parsed, then the constant is provided, and otherwise required.
3916    Const(Box<ConstItem>),
3917    /// An associated function.
3918    Fn(Box<Fn>),
3919    /// An associated type.
3920    Type(Box<TyAlias>),
3921    /// A macro expanding to associated items.
3922    MacCall(P<MacCall>),
3923    /// An associated delegation item.
3924    Delegation(Box<Delegation>),
3925    /// An associated list or glob delegation item.
3926    DelegationMac(Box<DelegationMac>),
3927}
3928
3929impl AssocItemKind {
3930    pub fn ident(&self) -> Option<Ident> {
3931        match *self {
3932            AssocItemKind::Const(box ConstItem { ident, .. })
3933            | AssocItemKind::Fn(box Fn { ident, .. })
3934            | AssocItemKind::Type(box TyAlias { ident, .. })
3935            | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3936
3937            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3938        }
3939    }
3940
3941    pub fn defaultness(&self) -> Defaultness {
3942        match *self {
3943            Self::Const(box ConstItem { defaultness, .. })
3944            | Self::Fn(box Fn { defaultness, .. })
3945            | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3946            Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3947                Defaultness::Final
3948            }
3949        }
3950    }
3951}
3952
3953impl From<AssocItemKind> for ItemKind {
3954    fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3955        match assoc_item_kind {
3956            AssocItemKind::Const(item) => ItemKind::Const(item),
3957            AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3958            AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3959            AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3960            AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3961            AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3962        }
3963    }
3964}
3965
3966impl TryFrom<ItemKind> for AssocItemKind {
3967    type Error = ItemKind;
3968
3969    fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3970        Ok(match item_kind {
3971            ItemKind::Const(item) => AssocItemKind::Const(item),
3972            ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3973            ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3974            ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3975            ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3976            ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3977            _ => return Err(item_kind),
3978        })
3979    }
3980}
3981
3982/// An item in `extern` block.
3983#[derive(Clone, Encodable, Decodable, Debug)]
3984pub enum ForeignItemKind {
3985    /// A foreign static item (`static FOO: u8`).
3986    Static(Box<StaticItem>),
3987    /// A foreign function.
3988    Fn(Box<Fn>),
3989    /// A foreign type.
3990    TyAlias(Box<TyAlias>),
3991    /// A macro expanding to foreign items.
3992    MacCall(P<MacCall>),
3993}
3994
3995impl ForeignItemKind {
3996    pub fn ident(&self) -> Option<Ident> {
3997        match *self {
3998            ForeignItemKind::Static(box StaticItem { ident, .. })
3999            | ForeignItemKind::Fn(box Fn { ident, .. })
4000            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4001
4002            ForeignItemKind::MacCall(_) => None,
4003        }
4004    }
4005}
4006
4007impl From<ForeignItemKind> for ItemKind {
4008    fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4009        match foreign_item_kind {
4010            ForeignItemKind::Static(box static_foreign_item) => {
4011                ItemKind::Static(Box::new(static_foreign_item))
4012            }
4013            ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4014            ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4015            ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4016        }
4017    }
4018}
4019
4020impl TryFrom<ItemKind> for ForeignItemKind {
4021    type Error = ItemKind;
4022
4023    fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4024        Ok(match item_kind {
4025            ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4026            ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4027            ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4028            ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4029            _ => return Err(item_kind),
4030        })
4031    }
4032}
4033
4034pub type ForeignItem = Item<ForeignItemKind>;
4035
4036// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
4037#[cfg(target_pointer_width = "64")]
4038mod size_asserts {
4039    use rustc_data_structures::static_assert_size;
4040
4041    use super::*;
4042    // tidy-alphabetical-start
4043    static_assert_size!(AssocItem, 80);
4044    static_assert_size!(AssocItemKind, 16);
4045    static_assert_size!(Attribute, 32);
4046    static_assert_size!(Block, 32);
4047    static_assert_size!(Expr, 72);
4048    static_assert_size!(ExprKind, 40);
4049    static_assert_size!(Fn, 184);
4050    static_assert_size!(ForeignItem, 80);
4051    static_assert_size!(ForeignItemKind, 16);
4052    static_assert_size!(GenericArg, 24);
4053    static_assert_size!(GenericBound, 88);
4054    static_assert_size!(Generics, 40);
4055    static_assert_size!(Impl, 136);
4056    static_assert_size!(Item, 144);
4057    static_assert_size!(ItemKind, 80);
4058    static_assert_size!(LitKind, 24);
4059    static_assert_size!(Local, 96);
4060    static_assert_size!(MetaItemLit, 40);
4061    static_assert_size!(Param, 40);
4062    static_assert_size!(Pat, 72);
4063    static_assert_size!(Path, 24);
4064    static_assert_size!(PathSegment, 24);
4065    static_assert_size!(PatKind, 48);
4066    static_assert_size!(Stmt, 32);
4067    static_assert_size!(StmtKind, 16);
4068    static_assert_size!(Ty, 64);
4069    static_assert_size!(TyKind, 40);
4070    // tidy-alphabetical-end
4071}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy