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