rustc_hir/
hir.rs

1use std::fmt;
2
3use rustc_abi::ExternAbi;
4// ignore-tidy-filelength
5use rustc_ast::attr::AttributeExt;
6use rustc_ast::token::CommentKind;
7use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
8use rustc_ast::{
9    self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece,
10    IntTy, Label, LitIntType, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
11};
12pub use rustc_ast::{
13    BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy,
14    ImplPolarity, IsAuto, Movability, Mutability, UnOp, UnsafeBinderCastKind,
15};
16use rustc_data_structures::fingerprint::Fingerprint;
17use rustc_data_structures::sorted_map::SortedMap;
18use rustc_data_structures::tagged_ptr::TaggedRef;
19use rustc_index::IndexVec;
20use rustc_macros::{Decodable, Encodable, HashStable_Generic};
21use rustc_span::def_id::LocalDefId;
22use rustc_span::hygiene::MacroKind;
23use rustc_span::source_map::Spanned;
24use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
25use rustc_target::asm::InlineAsmRegOrRegClass;
26use smallvec::SmallVec;
27use thin_vec::ThinVec;
28use tracing::debug;
29
30use crate::LangItem;
31use crate::def::{CtorKind, DefKind, Res};
32use crate::def_id::{DefId, LocalDefIdMap};
33pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
34use crate::intravisit::{FnKind, VisitorExt};
35
36#[derive(Debug, Copy, Clone, HashStable_Generic)]
37pub struct Lifetime {
38    #[stable_hasher(ignore)]
39    pub hir_id: HirId,
40
41    /// Either "`'a`", referring to a named lifetime definition,
42    /// `'_` referring to an anonymous lifetime (either explicitly `'_` or `&type`),
43    /// or "``" (i.e., `kw::Empty`) when appearing in path.
44    ///
45    /// See `Lifetime::suggestion_position` for practical use.
46    pub ident: Ident,
47
48    /// Semantics of this lifetime.
49    pub res: LifetimeName,
50}
51
52#[derive(Debug, Copy, Clone, HashStable_Generic)]
53pub enum ParamName {
54    /// Some user-given name like `T` or `'x`.
55    Plain(Ident),
56
57    /// Indicates an illegal name was given and an error has been
58    /// reported (so we should squelch other derived errors).
59    ///
60    /// Occurs when, e.g., `'_` is used in the wrong place, or a
61    /// lifetime name is duplicated.
62    Error(Ident),
63
64    /// Synthetic name generated when user elided a lifetime in an impl header.
65    ///
66    /// E.g., the lifetimes in cases like these:
67    /// ```ignore (fragment)
68    /// impl Foo for &u32
69    /// impl Foo<'_> for u32
70    /// ```
71    /// in that case, we rewrite to
72    /// ```ignore (fragment)
73    /// impl<'f> Foo for &'f u32
74    /// impl<'f> Foo<'f> for u32
75    /// ```
76    /// where `'f` is something like `Fresh(0)`. The indices are
77    /// unique per impl, but not necessarily continuous.
78    Fresh,
79}
80
81impl ParamName {
82    pub fn ident(&self) -> Ident {
83        match *self {
84            ParamName::Plain(ident) | ParamName::Error(ident) => ident,
85            ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
86        }
87    }
88}
89
90#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
91pub enum LifetimeName {
92    /// User-given names or fresh (synthetic) names.
93    Param(LocalDefId),
94
95    /// Implicit lifetime in a context like `dyn Foo`. This is
96    /// distinguished from implicit lifetimes elsewhere because the
97    /// lifetime that they default to must appear elsewhere within the
98    /// enclosing type. This means that, in an `impl Trait` context, we
99    /// don't have to create a parameter for them. That is, `impl
100    /// Trait<Item = &u32>` expands to an opaque type like `type
101    /// Foo<'a> = impl Trait<Item = &'a u32>`, but `impl Trait<item =
102    /// dyn Bar>` expands to `type Foo = impl Trait<Item = dyn Bar +
103    /// 'static>`. The latter uses `ImplicitObjectLifetimeDefault` so
104    /// that surrounding code knows not to create a lifetime
105    /// parameter.
106    ImplicitObjectLifetimeDefault,
107
108    /// Indicates an error during lowering (usually `'_` in wrong place)
109    /// that was already reported.
110    Error,
111
112    /// User wrote an anonymous lifetime, either `'_` or nothing.
113    /// The semantics of this lifetime should be inferred by typechecking code.
114    Infer,
115
116    /// User wrote `'static`.
117    Static,
118}
119
120impl LifetimeName {
121    fn is_elided(&self) -> bool {
122        match self {
123            LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
124
125            // It might seem surprising that `Fresh` counts as not *elided*
126            // -- but this is because, as far as the code in the compiler is
127            // concerned -- `Fresh` variants act equivalently to "some fresh name".
128            // They correspond to early-bound regions on an impl, in other words.
129            LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
130        }
131    }
132}
133
134impl fmt::Display for Lifetime {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        if self.ident.name != kw::Empty { self.ident.name.fmt(f) } else { "'_".fmt(f) }
137    }
138}
139
140pub enum LifetimeSuggestionPosition {
141    /// The user wrote `'a` or `'_`.
142    Normal,
143    /// The user wrote `&type` or `&mut type`.
144    Ampersand,
145    /// The user wrote `Path` and omitted the `<'_>`.
146    ElidedPath,
147    /// The user wrote `Path<T>`, and omitted the `'_,`.
148    ElidedPathArgument,
149    /// The user wrote `dyn Trait` and omitted the `+ '_`.
150    ObjectDefault,
151}
152
153impl Lifetime {
154    pub fn is_elided(&self) -> bool {
155        self.res.is_elided()
156    }
157
158    pub fn is_anonymous(&self) -> bool {
159        self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime
160    }
161
162    pub fn suggestion_position(&self) -> (LifetimeSuggestionPosition, Span) {
163        if self.ident.name == kw::Empty {
164            if self.ident.span.is_empty() {
165                (LifetimeSuggestionPosition::ElidedPathArgument, self.ident.span)
166            } else {
167                (LifetimeSuggestionPosition::ElidedPath, self.ident.span.shrink_to_hi())
168            }
169        } else if self.res == LifetimeName::ImplicitObjectLifetimeDefault {
170            (LifetimeSuggestionPosition::ObjectDefault, self.ident.span)
171        } else if self.ident.span.is_empty() {
172            (LifetimeSuggestionPosition::Ampersand, self.ident.span)
173        } else {
174            (LifetimeSuggestionPosition::Normal, self.ident.span)
175        }
176    }
177
178    pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
179        debug_assert!(new_lifetime.starts_with('\''));
180        let (pos, span) = self.suggestion_position();
181        let code = match pos {
182            LifetimeSuggestionPosition::Normal => format!("{new_lifetime}"),
183            LifetimeSuggestionPosition::Ampersand => format!("{new_lifetime} "),
184            LifetimeSuggestionPosition::ElidedPath => format!("<{new_lifetime}>"),
185            LifetimeSuggestionPosition::ElidedPathArgument => format!("{new_lifetime}, "),
186            LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lifetime}"),
187        };
188        (span, code)
189    }
190}
191
192/// A `Path` is essentially Rust's notion of a name; for instance,
193/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
194/// along with a bunch of supporting information.
195#[derive(Debug, Clone, Copy, HashStable_Generic)]
196pub struct Path<'hir, R = Res> {
197    pub span: Span,
198    /// The resolution for the path.
199    pub res: R,
200    /// The segments in the path: the things separated by `::`.
201    pub segments: &'hir [PathSegment<'hir>],
202}
203
204/// Up to three resolutions for type, value and macro namespaces.
205pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
206
207impl Path<'_> {
208    pub fn is_global(&self) -> bool {
209        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
210    }
211}
212
213/// A segment of a path: an identifier, an optional lifetime, and a set of
214/// types.
215#[derive(Debug, Clone, Copy, HashStable_Generic)]
216pub struct PathSegment<'hir> {
217    /// The identifier portion of this path segment.
218    pub ident: Ident,
219    #[stable_hasher(ignore)]
220    pub hir_id: HirId,
221    pub res: Res,
222
223    /// Type/lifetime parameters attached to this path. They come in
224    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
225    /// this is more than just simple syntactic sugar; the use of
226    /// parens affects the region binding rules, so we preserve the
227    /// distinction.
228    pub args: Option<&'hir GenericArgs<'hir>>,
229
230    /// Whether to infer remaining type parameters, if any.
231    /// This only applies to expression and pattern paths, and
232    /// out of those only the segments with no type parameters
233    /// to begin with, e.g., `Vec::new` is `<Vec<..>>::new::<..>`.
234    pub infer_args: bool,
235}
236
237impl<'hir> PathSegment<'hir> {
238    /// Converts an identifier to the corresponding segment.
239    pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
240        PathSegment { ident, hir_id, res, infer_args: true, args: None }
241    }
242
243    pub fn invalid() -> Self {
244        Self::new(Ident::empty(), HirId::INVALID, Res::Err)
245    }
246
247    pub fn args(&self) -> &GenericArgs<'hir> {
248        if let Some(ref args) = self.args {
249            args
250        } else {
251            const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
252            DUMMY
253        }
254    }
255}
256
257/// A constant that enters the type system, used for arguments to const generics (e.g. array lengths).
258///
259/// These are distinct from [`AnonConst`] as anon consts in the type system are not allowed
260/// to use any generic parameters, therefore we must represent `N` differently. Additionally
261/// future designs for supporting generic parameters in const arguments will likely not use
262/// an anon const based design.
263///
264/// So, `ConstArg` (specifically, [`ConstArgKind`]) distinguishes between const args
265/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
266/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
267///
268/// The `Unambig` generic parameter represents whether the position this const is from is
269/// unambiguously a const or ambiguous as to whether it is a type or a const. When in an
270/// ambiguous context the parameter is instantiated with an uninhabited type making the
271/// [`ConstArgKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
272#[derive(Clone, Copy, Debug, HashStable_Generic)]
273#[repr(C)]
274pub struct ConstArg<'hir, Unambig = ()> {
275    #[stable_hasher(ignore)]
276    pub hir_id: HirId,
277    pub kind: ConstArgKind<'hir, Unambig>,
278}
279
280impl<'hir> ConstArg<'hir, AmbigArg> {
281    /// Converts a `ConstArg` in an ambiguous position to one in an unambiguous position.
282    ///
283    /// Functions accepting an unambiguous consts may expect the [`ConstArgKind::Infer`] variant
284    /// to be used. Care should be taken to separately handle infer consts when calling this
285    /// function as it cannot be handled by downstream code making use of the returned const.
286    ///
287    /// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
288    /// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
289    ///
290    /// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
291    pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
292        // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
293        // layout is the same across different ZST type arguments.
294        let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
295        unsafe { &*ptr }
296    }
297}
298
299impl<'hir> ConstArg<'hir> {
300    /// Converts a `ConstArg` in an unambigous position to one in an ambiguous position. This is
301    /// fallible as the [`ConstArgKind::Infer`] variant is not present in ambiguous positions.
302    ///
303    /// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
304    /// infer consts are relevant to you then care should be taken to handle them separately.
305    pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
306        if let ConstArgKind::Infer(_, ()) = self.kind {
307            return None;
308        }
309
310        // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
311        // the same across different ZST type arguments. We also asserted that the `self` is
312        // not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
313        let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
314        Some(unsafe { &*ptr })
315    }
316}
317
318impl<'hir, Unambig> ConstArg<'hir, Unambig> {
319    pub fn anon_const_hir_id(&self) -> Option<HirId> {
320        match self.kind {
321            ConstArgKind::Anon(ac) => Some(ac.hir_id),
322            _ => None,
323        }
324    }
325
326    pub fn span(&self) -> Span {
327        match self.kind {
328            ConstArgKind::Path(path) => path.span(),
329            ConstArgKind::Anon(anon) => anon.span,
330            ConstArgKind::Infer(span, _) => span,
331        }
332    }
333}
334
335/// See [`ConstArg`].
336#[derive(Clone, Copy, Debug, HashStable_Generic)]
337#[repr(u8, C)]
338pub enum ConstArgKind<'hir, Unambig = ()> {
339    /// **Note:** Currently this is only used for bare const params
340    /// (`N` where `fn foo<const N: usize>(...)`),
341    /// not paths to any const (`N` where `const N: usize = ...`).
342    ///
343    /// However, in the future, we'll be using it for all of those.
344    Path(QPath<'hir>),
345    Anon(&'hir AnonConst),
346    /// This variant is not always used to represent inference consts, sometimes
347    /// [`GenericArg::Infer`] is used instead.
348    Infer(Span, Unambig),
349}
350
351#[derive(Clone, Copy, Debug, HashStable_Generic)]
352pub struct InferArg {
353    #[stable_hasher(ignore)]
354    pub hir_id: HirId,
355    pub span: Span,
356}
357
358impl InferArg {
359    pub fn to_ty(&self) -> Ty<'static> {
360        Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
361    }
362}
363
364#[derive(Debug, Clone, Copy, HashStable_Generic)]
365pub enum GenericArg<'hir> {
366    Lifetime(&'hir Lifetime),
367    Type(&'hir Ty<'hir, AmbigArg>),
368    Const(&'hir ConstArg<'hir, AmbigArg>),
369    /// Inference variables in [`GenericArg`] are always represnted by
370    /// `GenericArg::Infer` instead of the `Infer` variants on [`TyKind`] and
371    /// [`ConstArgKind`] as it is not clear until hir ty lowering whether a
372    /// `_` argument is a type or const argument.
373    ///
374    /// However, some builtin types' generic arguments are represented by [`TyKind`]
375    /// without a [`GenericArg`], instead directly storing a [`Ty`] or [`ConstArg`]. In
376    /// such cases they *are* represented by the `Infer` variants on [`TyKind`] and
377    /// [`ConstArgKind`] as it is not ambiguous whether the argument is a type or const.
378    Infer(InferArg),
379}
380
381impl GenericArg<'_> {
382    pub fn span(&self) -> Span {
383        match self {
384            GenericArg::Lifetime(l) => l.ident.span,
385            GenericArg::Type(t) => t.span,
386            GenericArg::Const(c) => c.span(),
387            GenericArg::Infer(i) => i.span,
388        }
389    }
390
391    pub fn hir_id(&self) -> HirId {
392        match self {
393            GenericArg::Lifetime(l) => l.hir_id,
394            GenericArg::Type(t) => t.hir_id,
395            GenericArg::Const(c) => c.hir_id,
396            GenericArg::Infer(i) => i.hir_id,
397        }
398    }
399
400    pub fn descr(&self) -> &'static str {
401        match self {
402            GenericArg::Lifetime(_) => "lifetime",
403            GenericArg::Type(_) => "type",
404            GenericArg::Const(_) => "constant",
405            GenericArg::Infer(_) => "placeholder",
406        }
407    }
408
409    pub fn to_ord(&self) -> ast::ParamKindOrd {
410        match self {
411            GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
412            GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
413                ast::ParamKindOrd::TypeOrConst
414            }
415        }
416    }
417
418    pub fn is_ty_or_const(&self) -> bool {
419        match self {
420            GenericArg::Lifetime(_) => false,
421            GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
422        }
423    }
424}
425
426/// The generic arguments and associated item constraints of a path segment.
427#[derive(Debug, Clone, Copy, HashStable_Generic)]
428pub struct GenericArgs<'hir> {
429    /// The generic arguments for this path segment.
430    pub args: &'hir [GenericArg<'hir>],
431    /// The associated item constraints for this path segment.
432    pub constraints: &'hir [AssocItemConstraint<'hir>],
433    /// Whether the arguments were written in parenthesized form (e.g., `Fn(T) -> U`).
434    ///
435    /// This is required mostly for pretty-printing and diagnostics,
436    /// but also for changing lifetime elision rules to be "function-like".
437    pub parenthesized: GenericArgsParentheses,
438    /// The span encompassing the arguments, constraints and the surrounding brackets (`<>` or `()`).
439    ///
440    /// For example:
441    ///
442    /// ```ignore (illustrative)
443    ///       Foo<A, B, AssocTy = D>           Fn(T, U, V) -> W
444    ///          ^^^^^^^^^^^^^^^^^^^             ^^^^^^^^^
445    /// ```
446    ///
447    /// Note that this may be:
448    /// - empty, if there are no generic brackets (but there may be hidden lifetimes)
449    /// - dummy, if this was generated during desugaring
450    pub span_ext: Span,
451}
452
453impl<'hir> GenericArgs<'hir> {
454    pub const fn none() -> Self {
455        Self {
456            args: &[],
457            constraints: &[],
458            parenthesized: GenericArgsParentheses::No,
459            span_ext: DUMMY_SP,
460        }
461    }
462
463    /// Obtain the list of input types and the output type if the generic arguments are parenthesized.
464    ///
465    /// Returns the `Ty0, Ty1, ...` and the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
466    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
467    pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
468        if self.parenthesized != GenericArgsParentheses::ParenSugar {
469            return None;
470        }
471
472        let inputs = self
473            .args
474            .iter()
475            .find_map(|arg| {
476                let GenericArg::Type(ty) = arg else { return None };
477                let TyKind::Tup(tys) = &ty.kind else { return None };
478                Some(tys)
479            })
480            .unwrap();
481
482        Some((inputs, self.paren_sugar_output_inner()))
483    }
484
485    /// Obtain the output type if the generic arguments are parenthesized.
486    ///
487    /// Returns the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
488    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
489    pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
490        (self.parenthesized == GenericArgsParentheses::ParenSugar)
491            .then(|| self.paren_sugar_output_inner())
492    }
493
494    fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
495        let [constraint] = self.constraints.try_into().unwrap();
496        debug_assert_eq!(constraint.ident.name, sym::Output);
497        constraint.ty().unwrap()
498    }
499
500    pub fn has_err(&self) -> Option<ErrorGuaranteed> {
501        self.args
502            .iter()
503            .find_map(|arg| {
504                let GenericArg::Type(ty) = arg else { return None };
505                let TyKind::Err(guar) = ty.kind else { return None };
506                Some(guar)
507            })
508            .or_else(|| {
509                self.constraints.iter().find_map(|constraint| {
510                    let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
511                    Some(guar)
512                })
513            })
514    }
515
516    #[inline]
517    pub fn num_lifetime_params(&self) -> usize {
518        self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
519    }
520
521    #[inline]
522    pub fn has_lifetime_params(&self) -> bool {
523        self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
524    }
525
526    #[inline]
527    /// This function returns the number of type and const generic params.
528    /// It should only be used for diagnostics.
529    pub fn num_generic_params(&self) -> usize {
530        self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
531    }
532
533    /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets.
534    ///
535    /// Returns `None` if the span is empty (i.e., no brackets) or dummy.
536    ///
537    /// [^1]: Unless of the form `-> Ty` (see [`GenericArgsParentheses`]).
538    pub fn span(&self) -> Option<Span> {
539        let span_ext = self.span_ext()?;
540        Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
541    }
542
543    /// Returns span encompassing arguments and their surrounding `<>` or `()`
544    pub fn span_ext(&self) -> Option<Span> {
545        Some(self.span_ext).filter(|span| !span.is_empty())
546    }
547
548    pub fn is_empty(&self) -> bool {
549        self.args.is_empty()
550    }
551}
552
553#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
554pub enum GenericArgsParentheses {
555    No,
556    /// Bounds for `feature(return_type_notation)`, like `T: Trait<method(..): Send>`,
557    /// where the args are explicitly elided with `..`
558    ReturnTypeNotation,
559    /// parenthesized function-family traits, like `T: Fn(u32) -> i32`
560    ParenSugar,
561}
562
563/// The modifiers on a trait bound.
564#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
565pub struct TraitBoundModifiers {
566    pub constness: BoundConstness,
567    pub polarity: BoundPolarity,
568}
569
570impl TraitBoundModifiers {
571    pub const NONE: Self =
572        TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
573}
574
575#[derive(Clone, Copy, Debug, HashStable_Generic)]
576pub enum GenericBound<'hir> {
577    Trait(PolyTraitRef<'hir>),
578    Outlives(&'hir Lifetime),
579    Use(&'hir [PreciseCapturingArg<'hir>], Span),
580}
581
582impl GenericBound<'_> {
583    pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
584        match self {
585            GenericBound::Trait(data) => Some(&data.trait_ref),
586            _ => None,
587        }
588    }
589
590    pub fn span(&self) -> Span {
591        match self {
592            GenericBound::Trait(t, ..) => t.span,
593            GenericBound::Outlives(l) => l.ident.span,
594            GenericBound::Use(_, span) => *span,
595        }
596    }
597}
598
599pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
600
601#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
602pub enum MissingLifetimeKind {
603    /// An explicit `'_`.
604    Underscore,
605    /// An elided lifetime `&' ty`.
606    Ampersand,
607    /// An elided lifetime in brackets with written brackets.
608    Comma,
609    /// An elided lifetime with elided brackets.
610    Brackets,
611}
612
613#[derive(Copy, Clone, Debug, HashStable_Generic)]
614pub enum LifetimeParamKind {
615    // Indicates that the lifetime definition was explicitly declared (e.g., in
616    // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
617    Explicit,
618
619    // Indication that the lifetime was elided (e.g., in both cases in
620    // `fn foo(x: &u8) -> &'_ u8 { x }`).
621    Elided(MissingLifetimeKind),
622
623    // Indication that the lifetime name was somehow in error.
624    Error,
625}
626
627#[derive(Debug, Clone, Copy, HashStable_Generic)]
628pub enum GenericParamKind<'hir> {
629    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
630    Lifetime {
631        kind: LifetimeParamKind,
632    },
633    Type {
634        default: Option<&'hir Ty<'hir>>,
635        synthetic: bool,
636    },
637    Const {
638        ty: &'hir Ty<'hir>,
639        /// Optional default value for the const generic param
640        default: Option<&'hir ConstArg<'hir>>,
641        synthetic: bool,
642    },
643}
644
645#[derive(Debug, Clone, Copy, HashStable_Generic)]
646pub struct GenericParam<'hir> {
647    #[stable_hasher(ignore)]
648    pub hir_id: HirId,
649    pub def_id: LocalDefId,
650    pub name: ParamName,
651    pub span: Span,
652    pub pure_wrt_drop: bool,
653    pub kind: GenericParamKind<'hir>,
654    pub colon_span: Option<Span>,
655    pub source: GenericParamSource,
656}
657
658impl<'hir> GenericParam<'hir> {
659    /// Synthetic type-parameters are inserted after normal ones.
660    /// In order for normal parameters to be able to refer to synthetic ones,
661    /// scans them first.
662    pub fn is_impl_trait(&self) -> bool {
663        matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
664    }
665
666    /// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`.
667    ///
668    /// See `lifetime_to_generic_param` in `rustc_ast_lowering` for more information.
669    pub fn is_elided_lifetime(&self) -> bool {
670        matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
671    }
672}
673
674/// Records where the generic parameter originated from.
675///
676/// This can either be from an item's generics, in which case it's typically
677/// early-bound (but can be a late-bound lifetime in functions, for example),
678/// or from a `for<...>` binder, in which case it's late-bound (and notably,
679/// does not show up in the parent item's generics).
680#[derive(Debug, Clone, Copy, HashStable_Generic)]
681pub enum GenericParamSource {
682    // Early or late-bound parameters defined on an item
683    Generics,
684    // Late-bound parameters defined via a `for<...>`
685    Binder,
686}
687
688#[derive(Default)]
689pub struct GenericParamCount {
690    pub lifetimes: usize,
691    pub types: usize,
692    pub consts: usize,
693    pub infer: usize,
694}
695
696/// Represents lifetimes and type parameters attached to a declaration
697/// of a function, enum, trait, etc.
698#[derive(Debug, Clone, Copy, HashStable_Generic)]
699pub struct Generics<'hir> {
700    pub params: &'hir [GenericParam<'hir>],
701    pub predicates: &'hir [WherePredicate<'hir>],
702    pub has_where_clause_predicates: bool,
703    pub where_clause_span: Span,
704    pub span: Span,
705}
706
707impl<'hir> Generics<'hir> {
708    pub const fn empty() -> &'hir Generics<'hir> {
709        const NOPE: Generics<'_> = Generics {
710            params: &[],
711            predicates: &[],
712            has_where_clause_predicates: false,
713            where_clause_span: DUMMY_SP,
714            span: DUMMY_SP,
715        };
716        &NOPE
717    }
718
719    pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
720        self.params.iter().find(|&param| name == param.name.ident().name)
721    }
722
723    /// If there are generic parameters, return where to introduce a new one.
724    pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
725        if let Some(first) = self.params.first()
726            && self.span.contains(first.span)
727        {
728            // `fn foo<A>(t: impl Trait)`
729            //         ^ suggest `'a, ` here
730            Some(first.span.shrink_to_lo())
731        } else {
732            None
733        }
734    }
735
736    /// If there are generic parameters, return where to introduce a new one.
737    pub fn span_for_param_suggestion(&self) -> Option<Span> {
738        self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
739            // `fn foo<A>(t: impl Trait)`
740            //          ^ suggest `, T: Trait` here
741            self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
742        })
743    }
744
745    /// `Span` where further predicates would be suggested, accounting for trailing commas, like
746    ///  in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
747    pub fn tail_span_for_predicate_suggestion(&self) -> Span {
748        let end = self.where_clause_span.shrink_to_hi();
749        if self.has_where_clause_predicates {
750            self.predicates
751                .iter()
752                .rfind(|&p| p.kind.in_where_clause())
753                .map_or(end, |p| p.span)
754                .shrink_to_hi()
755                .to(end)
756        } else {
757            end
758        }
759    }
760
761    pub fn add_where_or_trailing_comma(&self) -> &'static str {
762        if self.has_where_clause_predicates {
763            ","
764        } else if self.where_clause_span.is_empty() {
765            " where"
766        } else {
767            // No where clause predicates, but we have `where` token
768            ""
769        }
770    }
771
772    pub fn bounds_for_param(
773        &self,
774        param_def_id: LocalDefId,
775    ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
776        self.predicates.iter().filter_map(move |pred| match pred.kind {
777            WherePredicateKind::BoundPredicate(bp)
778                if bp.is_param_bound(param_def_id.to_def_id()) =>
779            {
780                Some(bp)
781            }
782            _ => None,
783        })
784    }
785
786    pub fn outlives_for_param(
787        &self,
788        param_def_id: LocalDefId,
789    ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
790        self.predicates.iter().filter_map(move |pred| match pred.kind {
791            WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
792            _ => None,
793        })
794    }
795
796    /// Returns a suggestable empty span right after the "final" bound of the generic parameter.
797    ///
798    /// If that bound needs to be wrapped in parentheses to avoid ambiguity with
799    /// subsequent bounds, it also returns an empty span for an open parenthesis
800    /// as the second component.
801    ///
802    /// E.g., adding `+ 'static` after `Fn() -> dyn Future<Output = ()>` or
803    /// `Fn() -> &'static dyn Debug` requires parentheses:
804    /// `Fn() -> (dyn Future<Output = ()>) + 'static` and
805    /// `Fn() -> &'static (dyn Debug) + 'static`, respectively.
806    pub fn bounds_span_for_suggestions(
807        &self,
808        param_def_id: LocalDefId,
809    ) -> Option<(Span, Option<Span>)> {
810        self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
811            |bound| {
812                let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
813                    && let [.., segment] = trait_ref.path.segments
814                    && let Some(ret_ty) = segment.args().paren_sugar_output()
815                    && let ret_ty = ret_ty.peel_refs()
816                    && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
817                    && let TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar = tagged_ptr.tag()
818                    && ret_ty.span.can_be_used_for_suggestions()
819                {
820                    Some(ret_ty.span)
821                } else {
822                    None
823                };
824
825                span_for_parentheses.map_or_else(
826                    || {
827                        // We include bounds that come from a `#[derive(_)]` but point at the user's code,
828                        // as we use this method to get a span appropriate for suggestions.
829                        let bs = bound.span();
830                        bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
831                    },
832                    |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
833                )
834            },
835        )
836    }
837
838    pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
839        let predicate = &self.predicates[pos];
840        let span = predicate.span;
841
842        if !predicate.kind.in_where_clause() {
843            // <T: ?Sized, U>
844            //   ^^^^^^^^
845            return span;
846        }
847
848        // We need to find out which comma to remove.
849        if pos < self.predicates.len() - 1 {
850            let next_pred = &self.predicates[pos + 1];
851            if next_pred.kind.in_where_clause() {
852                // where T: ?Sized, Foo: Bar,
853                //       ^^^^^^^^^^^
854                return span.until(next_pred.span);
855            }
856        }
857
858        if pos > 0 {
859            let prev_pred = &self.predicates[pos - 1];
860            if prev_pred.kind.in_where_clause() {
861                // where Foo: Bar, T: ?Sized,
862                //               ^^^^^^^^^^^
863                return prev_pred.span.shrink_to_hi().to(span);
864            }
865        }
866
867        // This is the only predicate in the where clause.
868        // where T: ?Sized
869        // ^^^^^^^^^^^^^^^
870        self.where_clause_span
871    }
872
873    pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
874        let predicate = &self.predicates[predicate_pos];
875        let bounds = predicate.kind.bounds();
876
877        if bounds.len() == 1 {
878            return self.span_for_predicate_removal(predicate_pos);
879        }
880
881        let bound_span = bounds[bound_pos].span();
882        if bound_pos < bounds.len() - 1 {
883            // If there's another bound after the current bound
884            // include the following '+' e.g.:
885            //
886            //  `T: Foo + CurrentBound + Bar`
887            //            ^^^^^^^^^^^^^^^
888            bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
889        } else {
890            // If the current bound is the last bound
891            // include the preceding '+' E.g.:
892            //
893            //  `T: Foo + Bar + CurrentBound`
894            //               ^^^^^^^^^^^^^^^
895            bound_span.with_lo(bounds[bound_pos - 1].span().hi())
896        }
897    }
898}
899
900/// A single predicate in a where-clause.
901#[derive(Debug, Clone, Copy, HashStable_Generic)]
902pub struct WherePredicate<'hir> {
903    #[stable_hasher(ignore)]
904    pub hir_id: HirId,
905    pub span: Span,
906    pub kind: &'hir WherePredicateKind<'hir>,
907}
908
909/// The kind of a single predicate in a where-clause.
910#[derive(Debug, Clone, Copy, HashStable_Generic)]
911pub enum WherePredicateKind<'hir> {
912    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
913    BoundPredicate(WhereBoundPredicate<'hir>),
914    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
915    RegionPredicate(WhereRegionPredicate<'hir>),
916    /// An equality predicate (unsupported).
917    EqPredicate(WhereEqPredicate<'hir>),
918}
919
920impl<'hir> WherePredicateKind<'hir> {
921    pub fn in_where_clause(&self) -> bool {
922        match self {
923            WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
924            WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
925            WherePredicateKind::EqPredicate(_) => false,
926        }
927    }
928
929    pub fn bounds(&self) -> GenericBounds<'hir> {
930        match self {
931            WherePredicateKind::BoundPredicate(p) => p.bounds,
932            WherePredicateKind::RegionPredicate(p) => p.bounds,
933            WherePredicateKind::EqPredicate(_) => &[],
934        }
935    }
936}
937
938#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
939pub enum PredicateOrigin {
940    WhereClause,
941    GenericParam,
942    ImplTrait,
943}
944
945/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
946#[derive(Debug, Clone, Copy, HashStable_Generic)]
947pub struct WhereBoundPredicate<'hir> {
948    /// Origin of the predicate.
949    pub origin: PredicateOrigin,
950    /// Any generics from a `for` binding.
951    pub bound_generic_params: &'hir [GenericParam<'hir>],
952    /// The type being bounded.
953    pub bounded_ty: &'hir Ty<'hir>,
954    /// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
955    pub bounds: GenericBounds<'hir>,
956}
957
958impl<'hir> WhereBoundPredicate<'hir> {
959    /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
960    pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
961        self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
962    }
963}
964
965/// A lifetime predicate (e.g., `'a: 'b + 'c`).
966#[derive(Debug, Clone, Copy, HashStable_Generic)]
967pub struct WhereRegionPredicate<'hir> {
968    pub in_where_clause: bool,
969    pub lifetime: &'hir Lifetime,
970    pub bounds: GenericBounds<'hir>,
971}
972
973impl<'hir> WhereRegionPredicate<'hir> {
974    /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
975    fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
976        self.lifetime.res == LifetimeName::Param(param_def_id)
977    }
978}
979
980/// An equality predicate (e.g., `T = int`); currently unsupported.
981#[derive(Debug, Clone, Copy, HashStable_Generic)]
982pub struct WhereEqPredicate<'hir> {
983    pub lhs_ty: &'hir Ty<'hir>,
984    pub rhs_ty: &'hir Ty<'hir>,
985}
986
987/// HIR node coupled with its parent's id in the same HIR owner.
988///
989/// The parent is trash when the node is a HIR owner.
990#[derive(Clone, Copy, Debug)]
991pub struct ParentedNode<'tcx> {
992    pub parent: ItemLocalId,
993    pub node: Node<'tcx>,
994}
995
996/// Arguments passed to an attribute macro.
997#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
998pub enum AttrArgs {
999    /// No arguments: `#[attr]`.
1000    Empty,
1001    /// Delimited arguments: `#[attr()/[]/{}]`.
1002    Delimited(DelimArgs),
1003    /// Arguments of a key-value attribute: `#[attr = "value"]`.
1004    Eq {
1005        /// Span of the `=` token.
1006        eq_span: Span,
1007        /// The "value".
1008        expr: MetaItemLit,
1009    },
1010}
1011
1012#[derive(Clone, Debug, Encodable, Decodable)]
1013pub enum AttrKind {
1014    /// A normal attribute.
1015    Normal(Box<AttrItem>),
1016
1017    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
1018    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
1019    /// variant (which is much less compact and thus more expensive).
1020    DocComment(CommentKind, Symbol),
1021}
1022
1023#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1024pub struct AttrPath {
1025    pub segments: Box<[Ident]>,
1026    pub span: Span,
1027}
1028
1029#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1030pub struct AttrItem {
1031    pub unsafety: Safety,
1032    // Not lowered to hir::Path because we have no NodeId to resolve to.
1033    pub path: AttrPath,
1034    pub args: AttrArgs,
1035}
1036
1037#[derive(Clone, Debug, Encodable, Decodable)]
1038pub struct Attribute {
1039    pub kind: AttrKind,
1040    pub id: AttrId,
1041    /// Denotes if the attribute decorates the following construct (outer)
1042    /// or the construct this attribute is contained within (inner).
1043    pub style: AttrStyle,
1044    pub span: Span,
1045}
1046
1047impl Attribute {
1048    pub fn get_normal_item(&self) -> &AttrItem {
1049        match &self.kind {
1050            AttrKind::Normal(normal) => &normal,
1051            AttrKind::DocComment(..) => panic!("unexpected doc comment"),
1052        }
1053    }
1054
1055    pub fn unwrap_normal_item(self) -> AttrItem {
1056        match self.kind {
1057            AttrKind::Normal(normal) => *normal,
1058            AttrKind::DocComment(..) => panic!("unexpected doc comment"),
1059        }
1060    }
1061
1062    pub fn value_lit(&self) -> Option<&MetaItemLit> {
1063        match &self.kind {
1064            AttrKind::Normal(box AttrItem { args: AttrArgs::Eq { expr, .. }, .. }) => Some(expr),
1065            _ => None,
1066        }
1067    }
1068}
1069
1070impl AttributeExt for Attribute {
1071    fn id(&self) -> AttrId {
1072        self.id
1073    }
1074
1075    fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1076        match &self.kind {
1077            AttrKind::Normal(box AttrItem { args: AttrArgs::Delimited(d), .. }) => {
1078                ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1079            }
1080            _ => None,
1081        }
1082    }
1083
1084    fn value_str(&self) -> Option<Symbol> {
1085        self.value_lit().and_then(|x| x.value_str())
1086    }
1087
1088    fn value_span(&self) -> Option<Span> {
1089        self.value_lit().map(|i| i.span)
1090    }
1091
1092    /// For a single-segment attribute, returns its name; otherwise, returns `None`.
1093    fn ident(&self) -> Option<Ident> {
1094        match &self.kind {
1095            AttrKind::Normal(box AttrItem {
1096                path: AttrPath { segments: box [ident], .. }, ..
1097            }) => Some(*ident),
1098            _ => None,
1099        }
1100    }
1101
1102    fn path_matches(&self, name: &[Symbol]) -> bool {
1103        match &self.kind {
1104            AttrKind::Normal(n) => n.path.segments.iter().map(|segment| &segment.name).eq(name),
1105            AttrKind::DocComment(..) => false,
1106        }
1107    }
1108
1109    fn is_doc_comment(&self) -> bool {
1110        matches!(self.kind, AttrKind::DocComment(..))
1111    }
1112
1113    fn span(&self) -> Span {
1114        self.span
1115    }
1116
1117    fn is_word(&self) -> bool {
1118        matches!(self.kind, AttrKind::Normal(box AttrItem { args: AttrArgs::Empty, .. }))
1119    }
1120
1121    fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1122        match &self.kind {
1123            AttrKind::Normal(n) => Some(n.path.segments.iter().copied().collect()),
1124            AttrKind::DocComment(..) => None,
1125        }
1126    }
1127
1128    fn doc_str(&self) -> Option<Symbol> {
1129        match &self.kind {
1130            AttrKind::DocComment(.., data) => Some(*data),
1131            AttrKind::Normal(_) if self.has_name(sym::doc) => self.value_str(),
1132            _ => None,
1133        }
1134    }
1135    fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1136        match &self.kind {
1137            AttrKind::DocComment(kind, data) => Some((*data, *kind)),
1138            AttrKind::Normal(_) if self.name_or_empty() == sym::doc => {
1139                self.value_str().map(|s| (s, CommentKind::Line))
1140            }
1141            _ => None,
1142        }
1143    }
1144
1145    fn style(&self) -> AttrStyle {
1146        self.style
1147    }
1148}
1149
1150// FIXME(fn_delegation): use function delegation instead of manually forwarding
1151impl Attribute {
1152    pub fn id(&self) -> AttrId {
1153        AttributeExt::id(self)
1154    }
1155
1156    pub fn name_or_empty(&self) -> Symbol {
1157        AttributeExt::name_or_empty(self)
1158    }
1159
1160    pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1161        AttributeExt::meta_item_list(self)
1162    }
1163
1164    pub fn value_str(&self) -> Option<Symbol> {
1165        AttributeExt::value_str(self)
1166    }
1167
1168    pub fn value_span(&self) -> Option<Span> {
1169        AttributeExt::value_span(self)
1170    }
1171
1172    pub fn ident(&self) -> Option<Ident> {
1173        AttributeExt::ident(self)
1174    }
1175
1176    pub fn path_matches(&self, name: &[Symbol]) -> bool {
1177        AttributeExt::path_matches(self, name)
1178    }
1179
1180    pub fn is_doc_comment(&self) -> bool {
1181        AttributeExt::is_doc_comment(self)
1182    }
1183
1184    #[inline]
1185    pub fn has_name(&self, name: Symbol) -> bool {
1186        AttributeExt::has_name(self, name)
1187    }
1188
1189    pub fn span(&self) -> Span {
1190        AttributeExt::span(self)
1191    }
1192
1193    pub fn is_word(&self) -> bool {
1194        AttributeExt::is_word(self)
1195    }
1196
1197    pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1198        AttributeExt::path(self)
1199    }
1200
1201    pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1202        AttributeExt::ident_path(self)
1203    }
1204
1205    pub fn doc_str(&self) -> Option<Symbol> {
1206        AttributeExt::doc_str(self)
1207    }
1208
1209    pub fn is_proc_macro_attr(&self) -> bool {
1210        AttributeExt::is_proc_macro_attr(self)
1211    }
1212
1213    pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1214        AttributeExt::doc_str_and_comment_kind(self)
1215    }
1216
1217    pub fn style(&self) -> AttrStyle {
1218        AttributeExt::style(self)
1219    }
1220}
1221
1222/// Attributes owned by a HIR owner.
1223#[derive(Debug)]
1224pub struct AttributeMap<'tcx> {
1225    pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1226    // Only present when the crate hash is needed.
1227    pub opt_hash: Option<Fingerprint>,
1228}
1229
1230impl<'tcx> AttributeMap<'tcx> {
1231    pub const EMPTY: &'static AttributeMap<'static> =
1232        &AttributeMap { map: SortedMap::new(), opt_hash: Some(Fingerprint::ZERO) };
1233
1234    #[inline]
1235    pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1236        self.map.get(&id).copied().unwrap_or(&[])
1237    }
1238}
1239
1240/// Map of all HIR nodes inside the current owner.
1241/// These nodes are mapped by `ItemLocalId` alongside the index of their parent node.
1242/// The HIR tree, including bodies, is pre-hashed.
1243pub struct OwnerNodes<'tcx> {
1244    /// Pre-computed hash of the full HIR. Used in the crate hash. Only present
1245    /// when incr. comp. is enabled.
1246    pub opt_hash_including_bodies: Option<Fingerprint>,
1247    /// Full HIR for the current owner.
1248    // The zeroth node's parent should never be accessed: the owner's parent is computed by the
1249    // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
1250    // used.
1251    pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1252    /// Content of local bodies.
1253    pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1254}
1255
1256impl<'tcx> OwnerNodes<'tcx> {
1257    pub fn node(&self) -> OwnerNode<'tcx> {
1258        // Indexing must ensure it is an OwnerNode.
1259        self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1260    }
1261}
1262
1263impl fmt::Debug for OwnerNodes<'_> {
1264    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1265        f.debug_struct("OwnerNodes")
1266            // Do not print all the pointers to all the nodes, as it would be unreadable.
1267            .field("node", &self.nodes[ItemLocalId::ZERO])
1268            .field(
1269                "parents",
1270                &fmt::from_fn(|f| {
1271                    f.debug_list()
1272                        .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1273                            fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1274                        }))
1275                        .finish()
1276                }),
1277            )
1278            .field("bodies", &self.bodies)
1279            .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1280            .finish()
1281    }
1282}
1283
1284/// Full information resulting from lowering an AST node.
1285#[derive(Debug, HashStable_Generic)]
1286pub struct OwnerInfo<'hir> {
1287    /// Contents of the HIR.
1288    pub nodes: OwnerNodes<'hir>,
1289    /// Map from each nested owner to its parent's local id.
1290    pub parenting: LocalDefIdMap<ItemLocalId>,
1291    /// Collected attributes of the HIR nodes.
1292    pub attrs: AttributeMap<'hir>,
1293    /// Map indicating what traits are in scope for places where this
1294    /// is relevant; generated by resolve.
1295    pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1296}
1297
1298impl<'tcx> OwnerInfo<'tcx> {
1299    #[inline]
1300    pub fn node(&self) -> OwnerNode<'tcx> {
1301        self.nodes.node()
1302    }
1303}
1304
1305#[derive(Copy, Clone, Debug, HashStable_Generic)]
1306pub enum MaybeOwner<'tcx> {
1307    Owner(&'tcx OwnerInfo<'tcx>),
1308    NonOwner(HirId),
1309    /// Used as a placeholder for unused LocalDefId.
1310    Phantom,
1311}
1312
1313impl<'tcx> MaybeOwner<'tcx> {
1314    pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1315        match self {
1316            MaybeOwner::Owner(i) => Some(i),
1317            MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1318        }
1319    }
1320
1321    pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1322        self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1323    }
1324}
1325
1326/// The top-level data structure that stores the entire contents of
1327/// the crate currently being compiled.
1328///
1329/// For more details, see the [rustc dev guide].
1330///
1331/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
1332#[derive(Debug)]
1333pub struct Crate<'hir> {
1334    pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1335    // Only present when incr. comp. is enabled.
1336    pub opt_hir_hash: Option<Fingerprint>,
1337}
1338
1339#[derive(Debug, Clone, Copy, HashStable_Generic)]
1340pub struct Closure<'hir> {
1341    pub def_id: LocalDefId,
1342    pub binder: ClosureBinder,
1343    pub constness: Constness,
1344    pub capture_clause: CaptureBy,
1345    pub bound_generic_params: &'hir [GenericParam<'hir>],
1346    pub fn_decl: &'hir FnDecl<'hir>,
1347    pub body: BodyId,
1348    /// The span of the declaration block: 'move |...| -> ...'
1349    pub fn_decl_span: Span,
1350    /// The span of the argument block `|...|`
1351    pub fn_arg_span: Option<Span>,
1352    pub kind: ClosureKind,
1353}
1354
1355#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1356pub enum ClosureKind {
1357    /// This is a plain closure expression.
1358    Closure,
1359    /// This is a coroutine expression -- i.e. a closure expression in which
1360    /// we've found a `yield`. These can arise either from "plain" coroutine
1361    ///  usage (e.g. `let x = || { yield (); }`) or from a desugared expression
1362    /// (e.g. `async` and `gen` blocks).
1363    Coroutine(CoroutineKind),
1364    /// This is a coroutine-closure, which is a special sugared closure that
1365    /// returns one of the sugared coroutine (`async`/`gen`/`async gen`). It
1366    /// additionally allows capturing the coroutine's upvars by ref, and therefore
1367    /// needs to be specially treated during analysis and borrowck.
1368    CoroutineClosure(CoroutineDesugaring),
1369}
1370
1371/// A block of statements `{ .. }`, which may have a label (in this case the
1372/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
1373/// the `rules` being anything but `DefaultBlock`.
1374#[derive(Debug, Clone, Copy, HashStable_Generic)]
1375pub struct Block<'hir> {
1376    /// Statements in a block.
1377    pub stmts: &'hir [Stmt<'hir>],
1378    /// An expression at the end of the block
1379    /// without a semicolon, if any.
1380    pub expr: Option<&'hir Expr<'hir>>,
1381    #[stable_hasher(ignore)]
1382    pub hir_id: HirId,
1383    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
1384    pub rules: BlockCheckMode,
1385    /// The span includes the curly braces `{` and `}` around the block.
1386    pub span: Span,
1387    /// If true, then there may exist `break 'a` values that aim to
1388    /// break out of this block early.
1389    /// Used by `'label: {}` blocks and by `try {}` blocks.
1390    pub targeted_by_break: bool,
1391}
1392
1393impl<'hir> Block<'hir> {
1394    pub fn innermost_block(&self) -> &Block<'hir> {
1395        let mut block = self;
1396        while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1397            block = inner_block;
1398        }
1399        block
1400    }
1401}
1402
1403#[derive(Debug, Clone, Copy, HashStable_Generic)]
1404pub struct TyPat<'hir> {
1405    #[stable_hasher(ignore)]
1406    pub hir_id: HirId,
1407    pub kind: TyPatKind<'hir>,
1408    pub span: Span,
1409}
1410
1411#[derive(Debug, Clone, Copy, HashStable_Generic)]
1412pub struct Pat<'hir> {
1413    #[stable_hasher(ignore)]
1414    pub hir_id: HirId,
1415    pub kind: PatKind<'hir>,
1416    pub span: Span,
1417    /// Whether to use default binding modes.
1418    /// At present, this is false only for destructuring assignment.
1419    pub default_binding_modes: bool,
1420}
1421
1422impl<'hir> Pat<'hir> {
1423    fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1424        if !it(self) {
1425            return false;
1426        }
1427
1428        use PatKind::*;
1429        match self.kind {
1430            Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1431            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
1432            Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1433            TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1434            Slice(before, slice, after) => {
1435                before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1436            }
1437        }
1438    }
1439
1440    /// Walk the pattern in left-to-right order,
1441    /// short circuiting (with `.all(..)`) if `false` is returned.
1442    ///
1443    /// Note that when visiting e.g. `Tuple(ps)`,
1444    /// if visiting `ps[0]` returns `false`,
1445    /// then `ps[1]` will not be visited.
1446    pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1447        self.walk_short_(&mut it)
1448    }
1449
1450    fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1451        if !it(self) {
1452            return;
1453        }
1454
1455        use PatKind::*;
1456        match self.kind {
1457            Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1458            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1459            Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1460            TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1461            Slice(before, slice, after) => {
1462                before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1463            }
1464        }
1465    }
1466
1467    /// Walk the pattern in left-to-right order.
1468    ///
1469    /// If `it(pat)` returns `false`, the children are not visited.
1470    pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1471        self.walk_(&mut it)
1472    }
1473
1474    /// Walk the pattern in left-to-right order.
1475    ///
1476    /// If you always want to recurse, prefer this method over `walk`.
1477    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1478        self.walk(|p| {
1479            it(p);
1480            true
1481        })
1482    }
1483
1484    /// Whether this a never pattern.
1485    pub fn is_never_pattern(&self) -> bool {
1486        let mut is_never_pattern = false;
1487        self.walk(|pat| match &pat.kind {
1488            PatKind::Never => {
1489                is_never_pattern = true;
1490                false
1491            }
1492            PatKind::Or(s) => {
1493                is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1494                false
1495            }
1496            _ => true,
1497        });
1498        is_never_pattern
1499    }
1500}
1501
1502/// A single field in a struct pattern.
1503///
1504/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
1505/// are treated the same as` x: x, y: ref y, z: ref mut z`,
1506/// except `is_shorthand` is true.
1507#[derive(Debug, Clone, Copy, HashStable_Generic)]
1508pub struct PatField<'hir> {
1509    #[stable_hasher(ignore)]
1510    pub hir_id: HirId,
1511    /// The identifier for the field.
1512    pub ident: Ident,
1513    /// The pattern the field is destructured to.
1514    pub pat: &'hir Pat<'hir>,
1515    pub is_shorthand: bool,
1516    pub span: Span,
1517}
1518
1519#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1520pub enum RangeEnd {
1521    Included,
1522    Excluded,
1523}
1524
1525impl fmt::Display for RangeEnd {
1526    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1527        f.write_str(match self {
1528            RangeEnd::Included => "..=",
1529            RangeEnd::Excluded => "..",
1530        })
1531    }
1532}
1533
1534// Equivalent to `Option<usize>`. That type takes up 16 bytes on 64-bit, but
1535// this type only takes up 4 bytes, at the cost of being restricted to a
1536// maximum value of `u32::MAX - 1`. In practice, this is more than enough.
1537#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1538pub struct DotDotPos(u32);
1539
1540impl DotDotPos {
1541    /// Panics if n >= u32::MAX.
1542    pub fn new(n: Option<usize>) -> Self {
1543        match n {
1544            Some(n) => {
1545                assert!(n < u32::MAX as usize);
1546                Self(n as u32)
1547            }
1548            None => Self(u32::MAX),
1549        }
1550    }
1551
1552    pub fn as_opt_usize(&self) -> Option<usize> {
1553        if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1554    }
1555}
1556
1557impl fmt::Debug for DotDotPos {
1558    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1559        self.as_opt_usize().fmt(f)
1560    }
1561}
1562
1563#[derive(Debug, Clone, Copy, HashStable_Generic)]
1564pub struct PatExpr<'hir> {
1565    #[stable_hasher(ignore)]
1566    pub hir_id: HirId,
1567    pub span: Span,
1568    pub kind: PatExprKind<'hir>,
1569}
1570
1571#[derive(Debug, Clone, Copy, HashStable_Generic)]
1572pub enum PatExprKind<'hir> {
1573    Lit {
1574        lit: &'hir Lit,
1575        // FIXME: move this into `Lit` and handle negated literal expressions
1576        // once instead of matching on unop neg expressions everywhere.
1577        negated: bool,
1578    },
1579    ConstBlock(ConstBlock),
1580    /// A path pattern for a unit struct/variant or a (maybe-associated) constant.
1581    Path(QPath<'hir>),
1582}
1583
1584#[derive(Debug, Clone, Copy, HashStable_Generic)]
1585pub enum TyPatKind<'hir> {
1586    /// A range pattern (e.g., `1..=2` or `1..2`).
1587    Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
1588
1589    /// A placeholder for a pattern that wasn't well formed in some way.
1590    Err(ErrorGuaranteed),
1591}
1592
1593#[derive(Debug, Clone, Copy, HashStable_Generic)]
1594pub enum PatKind<'hir> {
1595    /// Represents a wildcard pattern (i.e., `_`).
1596    Wild,
1597
1598    /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
1599    /// The `HirId` is the canonical ID for the variable being bound,
1600    /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
1601    /// which is the pattern ID of the first `x`.
1602    Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1603
1604    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
1605    /// The `bool` is `true` in the presence of a `..`.
1606    Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
1607
1608    /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
1609    /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position.
1610    /// `0 <= position <= subpats.len()`
1611    TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1612
1613    /// An or-pattern `A | B | C`.
1614    /// Invariant: `pats.len() >= 2`.
1615    Or(&'hir [Pat<'hir>]),
1616
1617    /// A never pattern `!`.
1618    Never,
1619
1620    /// A tuple pattern (e.g., `(a, b)`).
1621    /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
1622    /// `0 <= position <= subpats.len()`
1623    Tuple(&'hir [Pat<'hir>], DotDotPos),
1624
1625    /// A `box` pattern.
1626    Box(&'hir Pat<'hir>),
1627
1628    /// A `deref` pattern (currently `deref!()` macro-based syntax).
1629    Deref(&'hir Pat<'hir>),
1630
1631    /// A reference pattern (e.g., `&mut (a, b)`).
1632    Ref(&'hir Pat<'hir>, Mutability),
1633
1634    /// A literal, const block or path.
1635    Expr(&'hir PatExpr<'hir>),
1636
1637    /// A guard pattern (e.g., `x if guard(x)`).
1638    Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1639
1640    /// A range pattern (e.g., `1..=2` or `1..2`).
1641    Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
1642
1643    /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
1644    ///
1645    /// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`.
1646    /// If `slice` exists, then `after` can be non-empty.
1647    ///
1648    /// The representation for e.g., `[a, b, .., c, d]` is:
1649    /// ```ignore (illustrative)
1650    /// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
1651    /// ```
1652    Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
1653
1654    /// A placeholder for a pattern that wasn't well formed in some way.
1655    Err(ErrorGuaranteed),
1656}
1657
1658/// A statement.
1659#[derive(Debug, Clone, Copy, HashStable_Generic)]
1660pub struct Stmt<'hir> {
1661    #[stable_hasher(ignore)]
1662    pub hir_id: HirId,
1663    pub kind: StmtKind<'hir>,
1664    pub span: Span,
1665}
1666
1667/// The contents of a statement.
1668#[derive(Debug, Clone, Copy, HashStable_Generic)]
1669pub enum StmtKind<'hir> {
1670    /// A local (`let`) binding.
1671    Let(&'hir LetStmt<'hir>),
1672
1673    /// An item binding.
1674    Item(ItemId),
1675
1676    /// An expression without a trailing semi-colon (must have unit type).
1677    Expr(&'hir Expr<'hir>),
1678
1679    /// An expression with a trailing semi-colon (may have any type).
1680    Semi(&'hir Expr<'hir>),
1681}
1682
1683/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`).
1684#[derive(Debug, Clone, Copy, HashStable_Generic)]
1685pub struct LetStmt<'hir> {
1686    pub pat: &'hir Pat<'hir>,
1687    /// Type annotation, if any (otherwise the type will be inferred).
1688    pub ty: Option<&'hir Ty<'hir>>,
1689    /// Initializer expression to set the value, if any.
1690    pub init: Option<&'hir Expr<'hir>>,
1691    /// Else block for a `let...else` binding.
1692    pub els: Option<&'hir Block<'hir>>,
1693    #[stable_hasher(ignore)]
1694    pub hir_id: HirId,
1695    pub span: Span,
1696    /// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
1697    /// desugaring, or `AssignDesugar` if it is the result of a complex
1698    /// assignment desugaring. Otherwise will be `Normal`.
1699    pub source: LocalSource,
1700}
1701
1702/// Represents a single arm of a `match` expression, e.g.
1703/// `<pat> (if <guard>) => <body>`.
1704#[derive(Debug, Clone, Copy, HashStable_Generic)]
1705pub struct Arm<'hir> {
1706    #[stable_hasher(ignore)]
1707    pub hir_id: HirId,
1708    pub span: Span,
1709    /// If this pattern and the optional guard matches, then `body` is evaluated.
1710    pub pat: &'hir Pat<'hir>,
1711    /// Optional guard clause.
1712    pub guard: Option<&'hir Expr<'hir>>,
1713    /// The expression the arm evaluates to if this arm matches.
1714    pub body: &'hir Expr<'hir>,
1715}
1716
1717/// Represents a `let <pat>[: <ty>] = <expr>` expression (not a [`LetStmt`]), occurring in an `if-let`
1718/// or `let-else`, evaluating to a boolean. Typically the pattern is refutable.
1719///
1720/// In an `if let`, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of
1721/// the desugaring to if-let. Only let-else supports the type annotation at present.
1722#[derive(Debug, Clone, Copy, HashStable_Generic)]
1723pub struct LetExpr<'hir> {
1724    pub span: Span,
1725    pub pat: &'hir Pat<'hir>,
1726    pub ty: Option<&'hir Ty<'hir>>,
1727    pub init: &'hir Expr<'hir>,
1728    /// `Recovered::Yes` when this let expressions is not in a syntactically valid location.
1729    /// Used to prevent building MIR in such situations.
1730    pub recovered: ast::Recovered,
1731}
1732
1733#[derive(Debug, Clone, Copy, HashStable_Generic)]
1734pub struct ExprField<'hir> {
1735    #[stable_hasher(ignore)]
1736    pub hir_id: HirId,
1737    pub ident: Ident,
1738    pub expr: &'hir Expr<'hir>,
1739    pub span: Span,
1740    pub is_shorthand: bool,
1741}
1742
1743#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1744pub enum BlockCheckMode {
1745    DefaultBlock,
1746    UnsafeBlock(UnsafeSource),
1747}
1748
1749#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1750pub enum UnsafeSource {
1751    CompilerGenerated,
1752    UserProvided,
1753}
1754
1755#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
1756pub struct BodyId {
1757    pub hir_id: HirId,
1758}
1759
1760/// The body of a function, closure, or constant value. In the case of
1761/// a function, the body contains not only the function body itself
1762/// (which is an expression), but also the argument patterns, since
1763/// those are something that the caller doesn't really care about.
1764///
1765/// # Examples
1766///
1767/// ```
1768/// fn foo((x, y): (u32, u32)) -> u32 {
1769///     x + y
1770/// }
1771/// ```
1772///
1773/// Here, the `Body` associated with `foo()` would contain:
1774///
1775/// - an `params` array containing the `(x, y)` pattern
1776/// - a `value` containing the `x + y` expression (maybe wrapped in a block)
1777/// - `coroutine_kind` would be `None`
1778///
1779/// All bodies have an **owner**, which can be accessed via the HIR
1780/// map using `body_owner_def_id()`.
1781#[derive(Debug, Clone, Copy, HashStable_Generic)]
1782pub struct Body<'hir> {
1783    pub params: &'hir [Param<'hir>],
1784    pub value: &'hir Expr<'hir>,
1785}
1786
1787impl<'hir> Body<'hir> {
1788    pub fn id(&self) -> BodyId {
1789        BodyId { hir_id: self.value.hir_id }
1790    }
1791}
1792
1793/// The type of source expression that caused this coroutine to be created.
1794#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1795pub enum CoroutineKind {
1796    /// A coroutine that comes from a desugaring.
1797    Desugared(CoroutineDesugaring, CoroutineSource),
1798
1799    /// A coroutine literal created via a `yield` inside a closure.
1800    Coroutine(Movability),
1801}
1802
1803impl CoroutineKind {
1804    pub fn movability(self) -> Movability {
1805        match self {
1806            CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
1807            | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
1808            CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
1809            CoroutineKind::Coroutine(mov) => mov,
1810        }
1811    }
1812}
1813
1814impl CoroutineKind {
1815    pub fn is_fn_like(self) -> bool {
1816        matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
1817    }
1818}
1819
1820impl fmt::Display for CoroutineKind {
1821    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1822        match self {
1823            CoroutineKind::Desugared(d, k) => {
1824                d.fmt(f)?;
1825                k.fmt(f)
1826            }
1827            CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
1828        }
1829    }
1830}
1831
1832/// In the case of a coroutine created as part of an async/gen construct,
1833/// which kind of async/gen construct caused it to be created?
1834///
1835/// This helps error messages but is also used to drive coercions in
1836/// type-checking (see #60424).
1837#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
1838pub enum CoroutineSource {
1839    /// An explicit `async`/`gen` block written by the user.
1840    Block,
1841
1842    /// An explicit `async`/`gen` closure written by the user.
1843    Closure,
1844
1845    /// The `async`/`gen` block generated as the body of an async/gen function.
1846    Fn,
1847}
1848
1849impl fmt::Display for CoroutineSource {
1850    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1851        match self {
1852            CoroutineSource::Block => "block",
1853            CoroutineSource::Closure => "closure body",
1854            CoroutineSource::Fn => "fn body",
1855        }
1856        .fmt(f)
1857    }
1858}
1859
1860#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1861pub enum CoroutineDesugaring {
1862    /// An explicit `async` block or the body of an `async` function.
1863    Async,
1864
1865    /// An explicit `gen` block or the body of a `gen` function.
1866    Gen,
1867
1868    /// An explicit `async gen` block or the body of an `async gen` function,
1869    /// which is able to both `yield` and `.await`.
1870    AsyncGen,
1871}
1872
1873impl fmt::Display for CoroutineDesugaring {
1874    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1875        match self {
1876            CoroutineDesugaring::Async => {
1877                if f.alternate() {
1878                    f.write_str("`async` ")?;
1879                } else {
1880                    f.write_str("async ")?
1881                }
1882            }
1883            CoroutineDesugaring::Gen => {
1884                if f.alternate() {
1885                    f.write_str("`gen` ")?;
1886                } else {
1887                    f.write_str("gen ")?
1888                }
1889            }
1890            CoroutineDesugaring::AsyncGen => {
1891                if f.alternate() {
1892                    f.write_str("`async gen` ")?;
1893                } else {
1894                    f.write_str("async gen ")?
1895                }
1896            }
1897        }
1898
1899        Ok(())
1900    }
1901}
1902
1903#[derive(Copy, Clone, Debug)]
1904pub enum BodyOwnerKind {
1905    /// Functions and methods.
1906    Fn,
1907
1908    /// Closures
1909    Closure,
1910
1911    /// Constants and associated constants, also including inline constants.
1912    Const { inline: bool },
1913
1914    /// Initializer of a `static` item.
1915    Static(Mutability),
1916}
1917
1918impl BodyOwnerKind {
1919    pub fn is_fn_or_closure(self) -> bool {
1920        match self {
1921            BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
1922            BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) => false,
1923        }
1924    }
1925}
1926
1927/// The kind of an item that requires const-checking.
1928#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1929pub enum ConstContext {
1930    /// A `const fn`.
1931    ConstFn,
1932
1933    /// A `static` or `static mut`.
1934    Static(Mutability),
1935
1936    /// A `const`, associated `const`, or other const context.
1937    ///
1938    /// Other contexts include:
1939    /// - Array length expressions
1940    /// - Enum discriminants
1941    /// - Const generics
1942    ///
1943    /// For the most part, other contexts are treated just like a regular `const`, so they are
1944    /// lumped into the same category.
1945    Const { inline: bool },
1946}
1947
1948impl ConstContext {
1949    /// A description of this const context that can appear between backticks in an error message.
1950    ///
1951    /// E.g. `const` or `static mut`.
1952    pub fn keyword_name(self) -> &'static str {
1953        match self {
1954            Self::Const { .. } => "const",
1955            Self::Static(Mutability::Not) => "static",
1956            Self::Static(Mutability::Mut) => "static mut",
1957            Self::ConstFn => "const fn",
1958        }
1959    }
1960}
1961
1962/// A colloquial, trivially pluralizable description of this const context for use in error
1963/// messages.
1964impl fmt::Display for ConstContext {
1965    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1966        match *self {
1967            Self::Const { .. } => write!(f, "constant"),
1968            Self::Static(_) => write!(f, "static"),
1969            Self::ConstFn => write!(f, "constant function"),
1970        }
1971    }
1972}
1973
1974// NOTE: `IntoDiagArg` impl for `ConstContext` lives in `rustc_errors`
1975// due to a cyclical dependency between hir and that crate.
1976
1977/// A literal.
1978pub type Lit = Spanned<LitKind>;
1979
1980/// A constant (expression) that's not an item or associated item,
1981/// but needs its own `DefId` for type-checking, const-eval, etc.
1982/// These are usually found nested inside types (e.g., array lengths)
1983/// or expressions (e.g., repeat counts), and also used to define
1984/// explicit discriminant values for enum variants.
1985///
1986/// You can check if this anon const is a default in a const param
1987/// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_def_id(..)`
1988#[derive(Copy, Clone, Debug, HashStable_Generic)]
1989pub struct AnonConst {
1990    #[stable_hasher(ignore)]
1991    pub hir_id: HirId,
1992    pub def_id: LocalDefId,
1993    pub body: BodyId,
1994    pub span: Span,
1995}
1996
1997/// An inline constant expression `const { something }`.
1998#[derive(Copy, Clone, Debug, HashStable_Generic)]
1999pub struct ConstBlock {
2000    #[stable_hasher(ignore)]
2001    pub hir_id: HirId,
2002    pub def_id: LocalDefId,
2003    pub body: BodyId,
2004}
2005
2006/// An expression.
2007///
2008/// For more details, see the [rust lang reference].
2009/// Note that the reference does not document nightly-only features.
2010/// There may be also slight differences in the names and representation of AST nodes between
2011/// the compiler and the reference.
2012///
2013/// [rust lang reference]: https://doc.rust-lang.org/reference/expressions.html
2014#[derive(Debug, Clone, Copy, HashStable_Generic)]
2015pub struct Expr<'hir> {
2016    #[stable_hasher(ignore)]
2017    pub hir_id: HirId,
2018    pub kind: ExprKind<'hir>,
2019    pub span: Span,
2020}
2021
2022impl Expr<'_> {
2023    pub fn precedence(&self) -> ExprPrecedence {
2024        match &self.kind {
2025            ExprKind::Closure(closure) => {
2026                match closure.fn_decl.output {
2027                    FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2028                    FnRetTy::Return(_) => ExprPrecedence::Unambiguous,
2029                }
2030            }
2031
2032            ExprKind::Break(..)
2033            | ExprKind::Ret(..)
2034            | ExprKind::Yield(..)
2035            | ExprKind::Become(..) => ExprPrecedence::Jump,
2036
2037            // Binop-like expr kinds, handled by `AssocOp`.
2038            ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(),
2039            ExprKind::Cast(..) => ExprPrecedence::Cast,
2040
2041            ExprKind::Assign(..) |
2042            ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2043
2044            // Unary, prefix
2045            ExprKind::AddrOf(..)
2046            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
2047            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
2048            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
2049            // but we need to print `(let _ = a) < b` as-is with parens.
2050            | ExprKind::Let(..)
2051            | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2052
2053            // Never need parens
2054            ExprKind::Array(_)
2055            | ExprKind::Block(..)
2056            | ExprKind::Call(..)
2057            | ExprKind::ConstBlock(_)
2058            | ExprKind::Continue(..)
2059            | ExprKind::Field(..)
2060            | ExprKind::If(..)
2061            | ExprKind::Index(..)
2062            | ExprKind::InlineAsm(..)
2063            | ExprKind::Lit(_)
2064            | ExprKind::Loop(..)
2065            | ExprKind::Match(..)
2066            | ExprKind::MethodCall(..)
2067            | ExprKind::OffsetOf(..)
2068            | ExprKind::Path(..)
2069            | ExprKind::Repeat(..)
2070            | ExprKind::Struct(..)
2071            | ExprKind::Tup(_)
2072            | ExprKind::Type(..)
2073            | ExprKind::UnsafeBinderCast(..)
2074            | ExprKind::Err(_) => ExprPrecedence::Unambiguous,
2075
2076            ExprKind::DropTemps(expr, ..) => expr.precedence(),
2077        }
2078    }
2079
2080    /// Whether this looks like a place expr, without checking for deref
2081    /// adjustments.
2082    /// This will return `true` in some potentially surprising cases such as
2083    /// `CONSTANT.field`.
2084    pub fn is_syntactic_place_expr(&self) -> bool {
2085        self.is_place_expr(|_| true)
2086    }
2087
2088    /// Whether this is a place expression.
2089    ///
2090    /// `allow_projections_from` should return `true` if indexing a field or index expression based
2091    /// on the given expression should be considered a place expression.
2092    pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2093        match self.kind {
2094            ExprKind::Path(QPath::Resolved(_, ref path)) => {
2095                matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2096            }
2097
2098            // Type ascription inherits its place expression kind from its
2099            // operand. See:
2100            // https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
2101            ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2102
2103            // Unsafe binder cast preserves place-ness of the sub-expression.
2104            ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2105
2106            ExprKind::Unary(UnOp::Deref, _) => true,
2107
2108            ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2109                allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2110            }
2111
2112            // Lang item paths cannot currently be local variables or statics.
2113            ExprKind::Path(QPath::LangItem(..)) => false,
2114
2115            // Partially qualified paths in expressions can only legally
2116            // refer to associated items which are always rvalues.
2117            ExprKind::Path(QPath::TypeRelative(..))
2118            | ExprKind::Call(..)
2119            | ExprKind::MethodCall(..)
2120            | ExprKind::Struct(..)
2121            | ExprKind::Tup(..)
2122            | ExprKind::If(..)
2123            | ExprKind::Match(..)
2124            | ExprKind::Closure { .. }
2125            | ExprKind::Block(..)
2126            | ExprKind::Repeat(..)
2127            | ExprKind::Array(..)
2128            | ExprKind::Break(..)
2129            | ExprKind::Continue(..)
2130            | ExprKind::Ret(..)
2131            | ExprKind::Become(..)
2132            | ExprKind::Let(..)
2133            | ExprKind::Loop(..)
2134            | ExprKind::Assign(..)
2135            | ExprKind::InlineAsm(..)
2136            | ExprKind::OffsetOf(..)
2137            | ExprKind::AssignOp(..)
2138            | ExprKind::Lit(_)
2139            | ExprKind::ConstBlock(..)
2140            | ExprKind::Unary(..)
2141            | ExprKind::AddrOf(..)
2142            | ExprKind::Binary(..)
2143            | ExprKind::Yield(..)
2144            | ExprKind::Cast(..)
2145            | ExprKind::DropTemps(..)
2146            | ExprKind::Err(_) => false,
2147        }
2148    }
2149
2150    /// Check if expression is an integer literal that can be used
2151    /// where `usize` is expected.
2152    pub fn is_size_lit(&self) -> bool {
2153        matches!(
2154            self.kind,
2155            ExprKind::Lit(Lit {
2156                node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2157                ..
2158            })
2159        )
2160    }
2161
2162    /// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
2163    /// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
2164    /// silent, only signaling the ownership system. By doing this, suggestions that check the
2165    /// `ExprKind` of any given `Expr` for presentation don't have to care about `DropTemps`
2166    /// beyond remembering to call this function before doing analysis on it.
2167    pub fn peel_drop_temps(&self) -> &Self {
2168        let mut expr = self;
2169        while let ExprKind::DropTemps(inner) = &expr.kind {
2170            expr = inner;
2171        }
2172        expr
2173    }
2174
2175    pub fn peel_blocks(&self) -> &Self {
2176        let mut expr = self;
2177        while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2178            expr = inner;
2179        }
2180        expr
2181    }
2182
2183    pub fn peel_borrows(&self) -> &Self {
2184        let mut expr = self;
2185        while let ExprKind::AddrOf(.., inner) = &expr.kind {
2186            expr = inner;
2187        }
2188        expr
2189    }
2190
2191    pub fn can_have_side_effects(&self) -> bool {
2192        match self.peel_drop_temps().kind {
2193            ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) => false,
2194            ExprKind::Type(base, _)
2195            | ExprKind::Unary(_, base)
2196            | ExprKind::Field(base, _)
2197            | ExprKind::Index(base, _, _)
2198            | ExprKind::AddrOf(.., base)
2199            | ExprKind::Cast(base, _)
2200            | ExprKind::UnsafeBinderCast(_, base, _) => {
2201                // This isn't exactly true for `Index` and all `Unary`, but we are using this
2202                // method exclusively for diagnostics and there's a *cultural* pressure against
2203                // them being used only for its side-effects.
2204                base.can_have_side_effects()
2205            }
2206            ExprKind::Struct(_, fields, init) => {
2207                let init_side_effects = match init {
2208                    StructTailExpr::Base(init) => init.can_have_side_effects(),
2209                    StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2210                };
2211                fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2212                    || init_side_effects
2213            }
2214
2215            ExprKind::Array(args)
2216            | ExprKind::Tup(args)
2217            | ExprKind::Call(
2218                Expr {
2219                    kind:
2220                        ExprKind::Path(QPath::Resolved(
2221                            None,
2222                            Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2223                        )),
2224                    ..
2225                },
2226                args,
2227            ) => args.iter().any(|arg| arg.can_have_side_effects()),
2228            ExprKind::If(..)
2229            | ExprKind::Match(..)
2230            | ExprKind::MethodCall(..)
2231            | ExprKind::Call(..)
2232            | ExprKind::Closure { .. }
2233            | ExprKind::Block(..)
2234            | ExprKind::Repeat(..)
2235            | ExprKind::Break(..)
2236            | ExprKind::Continue(..)
2237            | ExprKind::Ret(..)
2238            | ExprKind::Become(..)
2239            | ExprKind::Let(..)
2240            | ExprKind::Loop(..)
2241            | ExprKind::Assign(..)
2242            | ExprKind::InlineAsm(..)
2243            | ExprKind::AssignOp(..)
2244            | ExprKind::ConstBlock(..)
2245            | ExprKind::Binary(..)
2246            | ExprKind::Yield(..)
2247            | ExprKind::DropTemps(..)
2248            | ExprKind::Err(_) => true,
2249        }
2250    }
2251
2252    /// To a first-order approximation, is this a pattern?
2253    pub fn is_approximately_pattern(&self) -> bool {
2254        match &self.kind {
2255            ExprKind::Array(_)
2256            | ExprKind::Call(..)
2257            | ExprKind::Tup(_)
2258            | ExprKind::Lit(_)
2259            | ExprKind::Path(_)
2260            | ExprKind::Struct(..) => true,
2261            _ => false,
2262        }
2263    }
2264
2265    /// Whether this and the `other` expression are the same for purposes of an indexing operation.
2266    ///
2267    /// This is only used for diagnostics to see if we have things like `foo[i]` where `foo` is
2268    /// borrowed multiple times with `i`.
2269    pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2270        match (self.kind, other.kind) {
2271            (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2272            (
2273                ExprKind::Path(QPath::LangItem(item1, _)),
2274                ExprKind::Path(QPath::LangItem(item2, _)),
2275            ) => item1 == item2,
2276            (
2277                ExprKind::Path(QPath::Resolved(None, path1)),
2278                ExprKind::Path(QPath::Resolved(None, path2)),
2279            ) => path1.res == path2.res,
2280            (
2281                ExprKind::Struct(
2282                    QPath::LangItem(LangItem::RangeTo, _),
2283                    [val1],
2284                    StructTailExpr::None,
2285                ),
2286                ExprKind::Struct(
2287                    QPath::LangItem(LangItem::RangeTo, _),
2288                    [val2],
2289                    StructTailExpr::None,
2290                ),
2291            )
2292            | (
2293                ExprKind::Struct(
2294                    QPath::LangItem(LangItem::RangeToInclusive, _),
2295                    [val1],
2296                    StructTailExpr::None,
2297                ),
2298                ExprKind::Struct(
2299                    QPath::LangItem(LangItem::RangeToInclusive, _),
2300                    [val2],
2301                    StructTailExpr::None,
2302                ),
2303            )
2304            | (
2305                ExprKind::Struct(
2306                    QPath::LangItem(LangItem::RangeFrom, _),
2307                    [val1],
2308                    StructTailExpr::None,
2309                ),
2310                ExprKind::Struct(
2311                    QPath::LangItem(LangItem::RangeFrom, _),
2312                    [val2],
2313                    StructTailExpr::None,
2314                ),
2315            )
2316            | (
2317                ExprKind::Struct(
2318                    QPath::LangItem(LangItem::RangeFromCopy, _),
2319                    [val1],
2320                    StructTailExpr::None,
2321                ),
2322                ExprKind::Struct(
2323                    QPath::LangItem(LangItem::RangeFromCopy, _),
2324                    [val2],
2325                    StructTailExpr::None,
2326                ),
2327            ) => val1.expr.equivalent_for_indexing(val2.expr),
2328            (
2329                ExprKind::Struct(
2330                    QPath::LangItem(LangItem::Range, _),
2331                    [val1, val3],
2332                    StructTailExpr::None,
2333                ),
2334                ExprKind::Struct(
2335                    QPath::LangItem(LangItem::Range, _),
2336                    [val2, val4],
2337                    StructTailExpr::None,
2338                ),
2339            )
2340            | (
2341                ExprKind::Struct(
2342                    QPath::LangItem(LangItem::RangeCopy, _),
2343                    [val1, val3],
2344                    StructTailExpr::None,
2345                ),
2346                ExprKind::Struct(
2347                    QPath::LangItem(LangItem::RangeCopy, _),
2348                    [val2, val4],
2349                    StructTailExpr::None,
2350                ),
2351            )
2352            | (
2353                ExprKind::Struct(
2354                    QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2355                    [val1, val3],
2356                    StructTailExpr::None,
2357                ),
2358                ExprKind::Struct(
2359                    QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2360                    [val2, val4],
2361                    StructTailExpr::None,
2362                ),
2363            ) => {
2364                val1.expr.equivalent_for_indexing(val2.expr)
2365                    && val3.expr.equivalent_for_indexing(val4.expr)
2366            }
2367            _ => false,
2368        }
2369    }
2370
2371    pub fn method_ident(&self) -> Option<Ident> {
2372        match self.kind {
2373            ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2374            ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2375            _ => None,
2376        }
2377    }
2378}
2379
2380/// Checks if the specified expression is a built-in range literal.
2381/// (See: `LoweringContext::lower_expr()`).
2382pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2383    match expr.kind {
2384        // All built-in range literals but `..=` and `..` desugar to `Struct`s.
2385        ExprKind::Struct(ref qpath, _, _) => matches!(
2386            **qpath,
2387            QPath::LangItem(
2388                LangItem::Range
2389                    | LangItem::RangeTo
2390                    | LangItem::RangeFrom
2391                    | LangItem::RangeFull
2392                    | LangItem::RangeToInclusive
2393                    | LangItem::RangeCopy
2394                    | LangItem::RangeFromCopy
2395                    | LangItem::RangeInclusiveCopy,
2396                ..
2397            )
2398        ),
2399
2400        // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
2401        ExprKind::Call(ref func, _) => {
2402            matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2403        }
2404
2405        _ => false,
2406    }
2407}
2408
2409/// Checks if the specified expression needs parentheses for prefix
2410/// or postfix suggestions to be valid.
2411/// For example, `a + b` requires parentheses to suggest `&(a + b)`,
2412/// but just `a` does not.
2413/// Similarly, `(a + b).c()` also requires parentheses.
2414/// This should not be used for other types of suggestions.
2415pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2416    match expr.kind {
2417        // parenthesize if needed (Issue #46756)
2418        ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2419        // parenthesize borrows of range literals (Issue #54505)
2420        _ if is_range_literal(expr) => true,
2421        _ => false,
2422    }
2423}
2424
2425#[derive(Debug, Clone, Copy, HashStable_Generic)]
2426pub enum ExprKind<'hir> {
2427    /// Allow anonymous constants from an inline `const` block
2428    ConstBlock(ConstBlock),
2429    /// An array (e.g., `[a, b, c, d]`).
2430    Array(&'hir [Expr<'hir>]),
2431    /// A function call.
2432    ///
2433    /// The first field resolves to the function itself (usually an `ExprKind::Path`),
2434    /// and the second field is the list of arguments.
2435    /// This also represents calling the constructor of
2436    /// tuple-like ADTs such as tuple structs and enum variants.
2437    Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2438    /// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`).
2439    ///
2440    /// The `PathSegment` represents the method name and its generic arguments
2441    /// (within the angle brackets).
2442    /// The `&Expr` is the expression that evaluates
2443    /// to the object on which the method is being called on (the receiver),
2444    /// and the `&[Expr]` is the rest of the arguments.
2445    /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
2446    /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d], span)`.
2447    /// The final `Span` represents the span of the function and arguments
2448    /// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)`
2449    ///
2450    /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
2451    /// the `hir_id` of the `MethodCall` node itself.
2452    ///
2453    /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id
2454    MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2455    /// A tuple (e.g., `(a, b, c, d)`).
2456    Tup(&'hir [Expr<'hir>]),
2457    /// A binary operation (e.g., `a + b`, `a * b`).
2458    Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2459    /// A unary operation (e.g., `!x`, `*x`).
2460    Unary(UnOp, &'hir Expr<'hir>),
2461    /// A literal (e.g., `1`, `"foo"`).
2462    Lit(&'hir Lit),
2463    /// A cast (e.g., `foo as f64`).
2464    Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2465    /// A type ascription (e.g., `x: Foo`). See RFC 3307.
2466    Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2467    /// Wraps the expression in a terminating scope.
2468    /// This makes it semantically equivalent to `{ let _t = expr; _t }`.
2469    ///
2470    /// This construct only exists to tweak the drop order in AST lowering.
2471    /// An example of that is the desugaring of `for` loops.
2472    DropTemps(&'hir Expr<'hir>),
2473    /// A `let $pat = $expr` expression.
2474    ///
2475    /// These are not [`LetStmt`] and only occur as expressions.
2476    /// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`.
2477    Let(&'hir LetExpr<'hir>),
2478    /// An `if` block, with an optional else block.
2479    ///
2480    /// I.e., `if <expr> { <expr> } else { <expr> }`.
2481    If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2482    /// A conditionless loop (can be exited with `break`, `continue`, or `return`).
2483    ///
2484    /// I.e., `'label: loop { <block> }`.
2485    ///
2486    /// The `Span` is the loop header (`for x in y`/`while let pat = expr`).
2487    Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2488    /// A `match` block, with a source that indicates whether or not it is
2489    /// the result of a desugaring, and if so, which kind.
2490    Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2491    /// A closure (e.g., `move |a, b, c| {a + b + c}`).
2492    ///
2493    /// The `Span` is the argument block `|...|`.
2494    ///
2495    /// This may also be a coroutine literal or an `async block` as indicated by the
2496    /// `Option<Movability>`.
2497    Closure(&'hir Closure<'hir>),
2498    /// A block (e.g., `'label: { ... }`).
2499    Block(&'hir Block<'hir>, Option<Label>),
2500
2501    /// An assignment (e.g., `a = foo()`).
2502    Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2503    /// An assignment with an operator.
2504    ///
2505    /// E.g., `a += 1`.
2506    AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2507    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
2508    Field(&'hir Expr<'hir>, Ident),
2509    /// An indexing operation (`foo[2]`).
2510    /// Similar to [`ExprKind::MethodCall`], the final `Span` represents the span of the brackets
2511    /// and index.
2512    Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2513
2514    /// Path to a definition, possibly containing lifetime or type parameters.
2515    Path(QPath<'hir>),
2516
2517    /// A referencing operation (i.e., `&a` or `&mut a`).
2518    AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2519    /// A `break`, with an optional label to break.
2520    Break(Destination, Option<&'hir Expr<'hir>>),
2521    /// A `continue`, with an optional label.
2522    Continue(Destination),
2523    /// A `return`, with an optional value to be returned.
2524    Ret(Option<&'hir Expr<'hir>>),
2525    /// A `become`, with the value to be returned.
2526    Become(&'hir Expr<'hir>),
2527
2528    /// Inline assembly (from `asm!`), with its outputs and inputs.
2529    InlineAsm(&'hir InlineAsm<'hir>),
2530
2531    /// Field offset (`offset_of!`)
2532    OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2533
2534    /// A struct or struct-like variant literal expression.
2535    ///
2536    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
2537    /// where `base` is the `Option<Expr>`.
2538    Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2539
2540    /// An array literal constructed from one repeated element.
2541    ///
2542    /// E.g., `[1; 5]`. The first expression is the element
2543    /// to be repeated; the second is the number of times to repeat it.
2544    Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2545
2546    /// A suspension point for coroutines (i.e., `yield <expr>`).
2547    Yield(&'hir Expr<'hir>, YieldSource),
2548
2549    /// Operators which can be used to interconvert `unsafe` binder types.
2550    /// e.g. `unsafe<'a> &'a i32` <=> `&i32`.
2551    UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2552
2553    /// A placeholder for an expression that wasn't syntactically well formed in some way.
2554    Err(rustc_span::ErrorGuaranteed),
2555}
2556
2557#[derive(Debug, Clone, Copy, HashStable_Generic)]
2558pub enum StructTailExpr<'hir> {
2559    /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
2560    None,
2561    /// A struct expression with a "base", an expression of the same type as the outer struct that
2562    /// will be used to populate any fields not explicitly mentioned: `Foo { ..base }`
2563    Base(&'hir Expr<'hir>),
2564    /// A struct expression with a `..` tail but no "base" expression. The values from the struct
2565    /// fields' default values will be used to populate any fields not explicitly mentioned:
2566    /// `Foo { .. }`.
2567    DefaultFields(Span),
2568}
2569
2570/// Represents an optionally `Self`-qualified value/type path or associated extension.
2571///
2572/// To resolve the path to a `DefId`, call [`qpath_res`].
2573///
2574/// [`qpath_res`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res
2575#[derive(Debug, Clone, Copy, HashStable_Generic)]
2576pub enum QPath<'hir> {
2577    /// Path to a definition, optionally "fully-qualified" with a `Self`
2578    /// type, if the path points to an associated item in a trait.
2579    ///
2580    /// E.g., an unqualified path like `Clone::clone` has `None` for `Self`,
2581    /// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
2582    /// even though they both have the same two-segment `Clone::clone` `Path`.
2583    Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2584
2585    /// Type-related paths (e.g., `<T>::default` or `<T>::Output`).
2586    /// Will be resolved by type-checking to an associated item.
2587    ///
2588    /// UFCS source paths can desugar into this, with `Vec::new` turning into
2589    /// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
2590    /// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
2591    TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2592
2593    /// Reference to a `#[lang = "foo"]` item.
2594    LangItem(LangItem, Span),
2595}
2596
2597impl<'hir> QPath<'hir> {
2598    /// Returns the span of this `QPath`.
2599    pub fn span(&self) -> Span {
2600        match *self {
2601            QPath::Resolved(_, path) => path.span,
2602            QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2603            QPath::LangItem(_, span) => span,
2604        }
2605    }
2606
2607    /// Returns the span of the qself of this `QPath`. For example, `()` in
2608    /// `<() as Trait>::method`.
2609    pub fn qself_span(&self) -> Span {
2610        match *self {
2611            QPath::Resolved(_, path) => path.span,
2612            QPath::TypeRelative(qself, _) => qself.span,
2613            QPath::LangItem(_, span) => span,
2614        }
2615    }
2616}
2617
2618/// Hints at the original code for a let statement.
2619#[derive(Copy, Clone, Debug, HashStable_Generic)]
2620pub enum LocalSource {
2621    /// A `match _ { .. }`.
2622    Normal,
2623    /// When lowering async functions, we create locals within the `async move` so that
2624    /// all parameters are dropped after the future is polled.
2625    ///
2626    /// ```ignore (pseudo-Rust)
2627    /// async fn foo(<pattern> @ x: Type) {
2628    ///     async move {
2629    ///         let <pattern> = x;
2630    ///     }
2631    /// }
2632    /// ```
2633    AsyncFn,
2634    /// A desugared `<expr>.await`.
2635    AwaitDesugar,
2636    /// A desugared `expr = expr`, where the LHS is a tuple, struct, array or underscore expression.
2637    /// The span is that of the `=` sign.
2638    AssignDesugar(Span),
2639    /// A contract `#[ensures(..)]` attribute injects a let binding for the check that runs at point of return.
2640    Contract,
2641}
2642
2643/// Hints at the original code for a `match _ { .. }`.
2644#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2645pub enum MatchSource {
2646    /// A `match _ { .. }`.
2647    Normal,
2648    /// A `expr.match { .. }`.
2649    Postfix,
2650    /// A desugared `for _ in _ { .. }` loop.
2651    ForLoopDesugar,
2652    /// A desugared `?` operator.
2653    TryDesugar(HirId),
2654    /// A desugared `<expr>.await`.
2655    AwaitDesugar,
2656    /// A desugared `format_args!()`.
2657    FormatArgs,
2658}
2659
2660impl MatchSource {
2661    #[inline]
2662    pub const fn name(self) -> &'static str {
2663        use MatchSource::*;
2664        match self {
2665            Normal => "match",
2666            Postfix => ".match",
2667            ForLoopDesugar => "for",
2668            TryDesugar(_) => "?",
2669            AwaitDesugar => ".await",
2670            FormatArgs => "format_args!()",
2671        }
2672    }
2673}
2674
2675/// The loop type that yielded an `ExprKind::Loop`.
2676#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2677pub enum LoopSource {
2678    /// A `loop { .. }` loop.
2679    Loop,
2680    /// A `while _ { .. }` loop.
2681    While,
2682    /// A `for _ in _ { .. }` loop.
2683    ForLoop,
2684}
2685
2686impl LoopSource {
2687    pub fn name(self) -> &'static str {
2688        match self {
2689            LoopSource::Loop => "loop",
2690            LoopSource::While => "while",
2691            LoopSource::ForLoop => "for",
2692        }
2693    }
2694}
2695
2696#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
2697pub enum LoopIdError {
2698    OutsideLoopScope,
2699    UnlabeledCfInWhileCondition,
2700    UnresolvedLabel,
2701}
2702
2703impl fmt::Display for LoopIdError {
2704    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2705        f.write_str(match self {
2706            LoopIdError::OutsideLoopScope => "not inside loop scope",
2707            LoopIdError::UnlabeledCfInWhileCondition => {
2708                "unlabeled control flow (break or continue) in while condition"
2709            }
2710            LoopIdError::UnresolvedLabel => "label not found",
2711        })
2712    }
2713}
2714
2715#[derive(Copy, Clone, Debug, HashStable_Generic)]
2716pub struct Destination {
2717    /// This is `Some(_)` iff there is an explicit user-specified 'label
2718    pub label: Option<Label>,
2719
2720    /// These errors are caught and then reported during the diagnostics pass in
2721    /// `librustc_passes/loops.rs`
2722    pub target_id: Result<HirId, LoopIdError>,
2723}
2724
2725/// The yield kind that caused an `ExprKind::Yield`.
2726#[derive(Copy, Clone, Debug, HashStable_Generic)]
2727pub enum YieldSource {
2728    /// An `<expr>.await`.
2729    Await { expr: Option<HirId> },
2730    /// A plain `yield`.
2731    Yield,
2732}
2733
2734impl fmt::Display for YieldSource {
2735    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2736        f.write_str(match self {
2737            YieldSource::Await { .. } => "`await`",
2738            YieldSource::Yield => "`yield`",
2739        })
2740    }
2741}
2742
2743// N.B., if you change this, you'll probably want to change the corresponding
2744// type structure in middle/ty.rs as well.
2745#[derive(Debug, Clone, Copy, HashStable_Generic)]
2746pub struct MutTy<'hir> {
2747    pub ty: &'hir Ty<'hir>,
2748    pub mutbl: Mutability,
2749}
2750
2751/// Represents a function's signature in a trait declaration,
2752/// trait implementation, or a free function.
2753#[derive(Debug, Clone, Copy, HashStable_Generic)]
2754pub struct FnSig<'hir> {
2755    pub header: FnHeader,
2756    pub decl: &'hir FnDecl<'hir>,
2757    pub span: Span,
2758}
2759
2760// The bodies for items are stored "out of line", in a separate
2761// hashmap in the `Crate`. Here we just record the hir-id of the item
2762// so it can fetched later.
2763#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
2764pub struct TraitItemId {
2765    pub owner_id: OwnerId,
2766}
2767
2768impl TraitItemId {
2769    #[inline]
2770    pub fn hir_id(&self) -> HirId {
2771        // Items are always HIR owners.
2772        HirId::make_owner(self.owner_id.def_id)
2773    }
2774}
2775
2776/// Represents an item declaration within a trait declaration,
2777/// possibly including a default implementation. A trait item is
2778/// either required (meaning it doesn't have an implementation, just a
2779/// signature) or provided (meaning it has a default implementation).
2780#[derive(Debug, Clone, Copy, HashStable_Generic)]
2781pub struct TraitItem<'hir> {
2782    pub ident: Ident,
2783    pub owner_id: OwnerId,
2784    pub generics: &'hir Generics<'hir>,
2785    pub kind: TraitItemKind<'hir>,
2786    pub span: Span,
2787    pub defaultness: Defaultness,
2788}
2789
2790macro_rules! expect_methods_self_kind {
2791    ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
2792        $(
2793            #[track_caller]
2794            pub fn $name(&self) -> $ret_ty {
2795                let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
2796                $ret_val
2797            }
2798        )*
2799    }
2800}
2801
2802macro_rules! expect_methods_self {
2803    ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
2804        $(
2805            #[track_caller]
2806            pub fn $name(&self) -> $ret_ty {
2807                let $pat = self else { expect_failed(stringify!($ident), self) };
2808                $ret_val
2809            }
2810        )*
2811    }
2812}
2813
2814#[track_caller]
2815fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
2816    panic!("{ident}: found {found:?}")
2817}
2818
2819impl<'hir> TraitItem<'hir> {
2820    #[inline]
2821    pub fn hir_id(&self) -> HirId {
2822        // Items are always HIR owners.
2823        HirId::make_owner(self.owner_id.def_id)
2824    }
2825
2826    pub fn trait_item_id(&self) -> TraitItemId {
2827        TraitItemId { owner_id: self.owner_id }
2828    }
2829
2830    expect_methods_self_kind! {
2831        expect_const, (&'hir Ty<'hir>, Option<BodyId>),
2832            TraitItemKind::Const(ty, body), (ty, *body);
2833
2834        expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
2835            TraitItemKind::Fn(ty, trfn), (ty, trfn);
2836
2837        expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
2838            TraitItemKind::Type(bounds, ty), (bounds, *ty);
2839    }
2840}
2841
2842/// Represents a trait method's body (or just argument names).
2843#[derive(Debug, Clone, Copy, HashStable_Generic)]
2844pub enum TraitFn<'hir> {
2845    /// No default body in the trait, just a signature.
2846    Required(&'hir [Ident]),
2847
2848    /// Both signature and body are provided in the trait.
2849    Provided(BodyId),
2850}
2851
2852/// Represents a trait method or associated constant or type
2853#[derive(Debug, Clone, Copy, HashStable_Generic)]
2854pub enum TraitItemKind<'hir> {
2855    /// An associated constant with an optional value (otherwise `impl`s must contain a value).
2856    Const(&'hir Ty<'hir>, Option<BodyId>),
2857    /// An associated function with an optional body.
2858    Fn(FnSig<'hir>, TraitFn<'hir>),
2859    /// An associated type with (possibly empty) bounds and optional concrete
2860    /// type.
2861    Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
2862}
2863
2864// The bodies for items are stored "out of line", in a separate
2865// hashmap in the `Crate`. Here we just record the hir-id of the item
2866// so it can fetched later.
2867#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
2868pub struct ImplItemId {
2869    pub owner_id: OwnerId,
2870}
2871
2872impl ImplItemId {
2873    #[inline]
2874    pub fn hir_id(&self) -> HirId {
2875        // Items are always HIR owners.
2876        HirId::make_owner(self.owner_id.def_id)
2877    }
2878}
2879
2880/// Represents an associated item within an impl block.
2881///
2882/// Refer to [`Impl`] for an impl block declaration.
2883#[derive(Debug, Clone, Copy, HashStable_Generic)]
2884pub struct ImplItem<'hir> {
2885    pub ident: Ident,
2886    pub owner_id: OwnerId,
2887    pub generics: &'hir Generics<'hir>,
2888    pub kind: ImplItemKind<'hir>,
2889    pub defaultness: Defaultness,
2890    pub span: Span,
2891    pub vis_span: Span,
2892}
2893
2894impl<'hir> ImplItem<'hir> {
2895    #[inline]
2896    pub fn hir_id(&self) -> HirId {
2897        // Items are always HIR owners.
2898        HirId::make_owner(self.owner_id.def_id)
2899    }
2900
2901    pub fn impl_item_id(&self) -> ImplItemId {
2902        ImplItemId { owner_id: self.owner_id }
2903    }
2904
2905    expect_methods_self_kind! {
2906        expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
2907        expect_fn,    (&FnSig<'hir>, BodyId),   ImplItemKind::Fn(ty, body),    (ty, *body);
2908        expect_type,  &'hir Ty<'hir>,           ImplItemKind::Type(ty),        ty;
2909    }
2910}
2911
2912/// Represents various kinds of content within an `impl`.
2913#[derive(Debug, Clone, Copy, HashStable_Generic)]
2914pub enum ImplItemKind<'hir> {
2915    /// An associated constant of the given type, set to the constant result
2916    /// of the expression.
2917    Const(&'hir Ty<'hir>, BodyId),
2918    /// An associated function implementation with the given signature and body.
2919    Fn(FnSig<'hir>, BodyId),
2920    /// An associated type.
2921    Type(&'hir Ty<'hir>),
2922}
2923
2924/// A constraint on an associated item.
2925///
2926/// ### Examples
2927///
2928/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
2929/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
2930/// * the `A: Bound` in `Trait<A: Bound>`
2931/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
2932/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
2933/// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
2934#[derive(Debug, Clone, Copy, HashStable_Generic)]
2935pub struct AssocItemConstraint<'hir> {
2936    #[stable_hasher(ignore)]
2937    pub hir_id: HirId,
2938    pub ident: Ident,
2939    pub gen_args: &'hir GenericArgs<'hir>,
2940    pub kind: AssocItemConstraintKind<'hir>,
2941    pub span: Span,
2942}
2943
2944impl<'hir> AssocItemConstraint<'hir> {
2945    /// Obtain the type on the RHS of an assoc ty equality constraint if applicable.
2946    pub fn ty(self) -> Option<&'hir Ty<'hir>> {
2947        match self.kind {
2948            AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
2949            _ => None,
2950        }
2951    }
2952
2953    /// Obtain the const on the RHS of an assoc const equality constraint if applicable.
2954    pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
2955        match self.kind {
2956            AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
2957            _ => None,
2958        }
2959    }
2960}
2961
2962#[derive(Debug, Clone, Copy, HashStable_Generic)]
2963pub enum Term<'hir> {
2964    Ty(&'hir Ty<'hir>),
2965    Const(&'hir ConstArg<'hir>),
2966}
2967
2968impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
2969    fn from(ty: &'hir Ty<'hir>) -> Self {
2970        Term::Ty(ty)
2971    }
2972}
2973
2974impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
2975    fn from(c: &'hir ConstArg<'hir>) -> Self {
2976        Term::Const(c)
2977    }
2978}
2979
2980/// The kind of [associated item constraint][AssocItemConstraint].
2981#[derive(Debug, Clone, Copy, HashStable_Generic)]
2982pub enum AssocItemConstraintKind<'hir> {
2983    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
2984    ///
2985    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
2986    ///
2987    /// Furthermore, associated type equality constraints can also be referred to as *associated type
2988    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
2989    Equality { term: Term<'hir> },
2990    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
2991    Bound { bounds: &'hir [GenericBound<'hir>] },
2992}
2993
2994impl<'hir> AssocItemConstraintKind<'hir> {
2995    pub fn descr(&self) -> &'static str {
2996        match self {
2997            AssocItemConstraintKind::Equality { .. } => "binding",
2998            AssocItemConstraintKind::Bound { .. } => "constraint",
2999        }
3000    }
3001}
3002
3003/// An uninhabited enum used to make `Infer` variants on [`Ty`] and [`ConstArg`] be
3004/// unreachable. Zero-Variant enums are guaranteed to have the same layout as the never
3005/// type.
3006#[derive(Debug, Clone, Copy, HashStable_Generic)]
3007pub enum AmbigArg {}
3008
3009#[derive(Debug, Clone, Copy, HashStable_Generic)]
3010#[repr(C)]
3011/// Represents a type in the `HIR`.
3012///
3013/// The `Unambig` generic parameter represents whether the position this type is from is
3014/// unambiguously a type or ambiguous as to whether it is a type or a const. When in an
3015/// ambiguous context the parameter is instantiated with an uninhabited type making the
3016/// [`TyKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
3017pub struct Ty<'hir, Unambig = ()> {
3018    #[stable_hasher(ignore)]
3019    pub hir_id: HirId,
3020    pub span: Span,
3021    pub kind: TyKind<'hir, Unambig>,
3022}
3023
3024impl<'hir> Ty<'hir, AmbigArg> {
3025    /// Converts a `Ty` in an ambiguous position to one in an unambiguous position.
3026    ///
3027    /// Functions accepting an unambiguous types may expect the [`TyKind::Infer`] variant
3028    /// to be used. Care should be taken to separately handle infer types when calling this
3029    /// function as it cannot be handled by downstream code making use of the returned ty.
3030    ///
3031    /// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
3032    /// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
3033    ///
3034    /// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
3035    pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3036        // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
3037        // the same across different ZST type arguments.
3038        let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3039        unsafe { &*ptr }
3040    }
3041}
3042
3043impl<'hir> Ty<'hir> {
3044    /// Converts a `Ty` in an unambigous position to one in an ambiguous position. This is
3045    /// fallible as the [`TyKind::Infer`] variant is not present in ambiguous positions.
3046    ///
3047    /// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
3048    /// infer types are relevant to you then care should be taken to handle them separately.
3049    pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3050        if let TyKind::Infer(()) = self.kind {
3051            return None;
3052        }
3053
3054        // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
3055        // the same across different ZST type arguments. We also asserted that the `self` is
3056        // not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
3057        let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3058        Some(unsafe { &*ptr })
3059    }
3060}
3061
3062impl<'hir> Ty<'hir, AmbigArg> {
3063    pub fn peel_refs(&self) -> &Ty<'hir> {
3064        let mut final_ty = self.as_unambig_ty();
3065        while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3066            final_ty = ty;
3067        }
3068        final_ty
3069    }
3070}
3071
3072impl<'hir> Ty<'hir> {
3073    pub fn peel_refs(&self) -> &Self {
3074        let mut final_ty = self;
3075        while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3076            final_ty = ty;
3077        }
3078        final_ty
3079    }
3080
3081    /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
3082    pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3083        let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3084            return None;
3085        };
3086        let [segment] = &path.segments else {
3087            return None;
3088        };
3089        match path.res {
3090            Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3091                Some((def_id, segment.ident))
3092            }
3093            _ => None,
3094        }
3095    }
3096
3097    pub fn find_self_aliases(&self) -> Vec<Span> {
3098        use crate::intravisit::Visitor;
3099        struct MyVisitor(Vec<Span>);
3100        impl<'v> Visitor<'v> for MyVisitor {
3101            fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3102                if matches!(
3103                    &t.kind,
3104                    TyKind::Path(QPath::Resolved(
3105                        _,
3106                        Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3107                    ))
3108                ) {
3109                    self.0.push(t.span);
3110                    return;
3111                }
3112                crate::intravisit::walk_ty(self, t);
3113            }
3114        }
3115
3116        let mut my_visitor = MyVisitor(vec![]);
3117        my_visitor.visit_ty_unambig(self);
3118        my_visitor.0
3119    }
3120
3121    /// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
3122    /// use inference to provide suggestions for the appropriate type if possible.
3123    pub fn is_suggestable_infer_ty(&self) -> bool {
3124        fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3125            generic_args.iter().any(|arg| match arg {
3126                GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3127                GenericArg::Infer(_) => true,
3128                _ => false,
3129            })
3130        }
3131        debug!(?self);
3132        match &self.kind {
3133            TyKind::Infer(()) => true,
3134            TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3135            TyKind::Array(ty, length) => {
3136                ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3137            }
3138            TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3139            TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3140            TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3141                ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3142            }
3143            TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3144                ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3145                    || segments
3146                        .iter()
3147                        .any(|segment| are_suggestable_generic_args(segment.args().args))
3148            }
3149            _ => false,
3150        }
3151    }
3152}
3153
3154/// Not represented directly in the AST; referred to by name through a `ty_path`.
3155#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3156pub enum PrimTy {
3157    Int(IntTy),
3158    Uint(UintTy),
3159    Float(FloatTy),
3160    Str,
3161    Bool,
3162    Char,
3163}
3164
3165impl PrimTy {
3166    /// All of the primitive types
3167    pub const ALL: [Self; 19] = [
3168        // any changes here should also be reflected in `PrimTy::from_name`
3169        Self::Int(IntTy::I8),
3170        Self::Int(IntTy::I16),
3171        Self::Int(IntTy::I32),
3172        Self::Int(IntTy::I64),
3173        Self::Int(IntTy::I128),
3174        Self::Int(IntTy::Isize),
3175        Self::Uint(UintTy::U8),
3176        Self::Uint(UintTy::U16),
3177        Self::Uint(UintTy::U32),
3178        Self::Uint(UintTy::U64),
3179        Self::Uint(UintTy::U128),
3180        Self::Uint(UintTy::Usize),
3181        Self::Float(FloatTy::F16),
3182        Self::Float(FloatTy::F32),
3183        Self::Float(FloatTy::F64),
3184        Self::Float(FloatTy::F128),
3185        Self::Bool,
3186        Self::Char,
3187        Self::Str,
3188    ];
3189
3190    /// Like [`PrimTy::name`], but returns a &str instead of a symbol.
3191    ///
3192    /// Used by clippy.
3193    pub fn name_str(self) -> &'static str {
3194        match self {
3195            PrimTy::Int(i) => i.name_str(),
3196            PrimTy::Uint(u) => u.name_str(),
3197            PrimTy::Float(f) => f.name_str(),
3198            PrimTy::Str => "str",
3199            PrimTy::Bool => "bool",
3200            PrimTy::Char => "char",
3201        }
3202    }
3203
3204    pub fn name(self) -> Symbol {
3205        match self {
3206            PrimTy::Int(i) => i.name(),
3207            PrimTy::Uint(u) => u.name(),
3208            PrimTy::Float(f) => f.name(),
3209            PrimTy::Str => sym::str,
3210            PrimTy::Bool => sym::bool,
3211            PrimTy::Char => sym::char,
3212        }
3213    }
3214
3215    /// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32".
3216    /// Returns `None` if no matching type is found.
3217    pub fn from_name(name: Symbol) -> Option<Self> {
3218        let ty = match name {
3219            // any changes here should also be reflected in `PrimTy::ALL`
3220            sym::i8 => Self::Int(IntTy::I8),
3221            sym::i16 => Self::Int(IntTy::I16),
3222            sym::i32 => Self::Int(IntTy::I32),
3223            sym::i64 => Self::Int(IntTy::I64),
3224            sym::i128 => Self::Int(IntTy::I128),
3225            sym::isize => Self::Int(IntTy::Isize),
3226            sym::u8 => Self::Uint(UintTy::U8),
3227            sym::u16 => Self::Uint(UintTy::U16),
3228            sym::u32 => Self::Uint(UintTy::U32),
3229            sym::u64 => Self::Uint(UintTy::U64),
3230            sym::u128 => Self::Uint(UintTy::U128),
3231            sym::usize => Self::Uint(UintTy::Usize),
3232            sym::f16 => Self::Float(FloatTy::F16),
3233            sym::f32 => Self::Float(FloatTy::F32),
3234            sym::f64 => Self::Float(FloatTy::F64),
3235            sym::f128 => Self::Float(FloatTy::F128),
3236            sym::bool => Self::Bool,
3237            sym::char => Self::Char,
3238            sym::str => Self::Str,
3239            _ => return None,
3240        };
3241        Some(ty)
3242    }
3243}
3244
3245#[derive(Debug, Clone, Copy, HashStable_Generic)]
3246pub struct BareFnTy<'hir> {
3247    pub safety: Safety,
3248    pub abi: ExternAbi,
3249    pub generic_params: &'hir [GenericParam<'hir>],
3250    pub decl: &'hir FnDecl<'hir>,
3251    pub param_names: &'hir [Ident],
3252}
3253
3254#[derive(Debug, Clone, Copy, HashStable_Generic)]
3255pub struct UnsafeBinderTy<'hir> {
3256    pub generic_params: &'hir [GenericParam<'hir>],
3257    pub inner_ty: &'hir Ty<'hir>,
3258}
3259
3260#[derive(Debug, Clone, Copy, HashStable_Generic)]
3261pub struct OpaqueTy<'hir> {
3262    #[stable_hasher(ignore)]
3263    pub hir_id: HirId,
3264    pub def_id: LocalDefId,
3265    pub bounds: GenericBounds<'hir>,
3266    pub origin: OpaqueTyOrigin<LocalDefId>,
3267    pub span: Span,
3268}
3269
3270#[derive(Debug, Clone, Copy, HashStable_Generic)]
3271pub enum PreciseCapturingArg<'hir> {
3272    Lifetime(&'hir Lifetime),
3273    /// Non-lifetime argument (type or const)
3274    Param(PreciseCapturingNonLifetimeArg),
3275}
3276
3277impl PreciseCapturingArg<'_> {
3278    pub fn hir_id(self) -> HirId {
3279        match self {
3280            PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3281            PreciseCapturingArg::Param(param) => param.hir_id,
3282        }
3283    }
3284
3285    pub fn name(self) -> Symbol {
3286        match self {
3287            PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3288            PreciseCapturingArg::Param(param) => param.ident.name,
3289        }
3290    }
3291}
3292
3293/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param
3294/// resolution to. Lifetimes don't have this problem, and for them, it's actually
3295/// kind of detrimental to use a custom node type versus just using [`Lifetime`],
3296/// since resolve_bound_vars operates on `Lifetime`s.
3297#[derive(Debug, Clone, Copy, HashStable_Generic)]
3298pub struct PreciseCapturingNonLifetimeArg {
3299    #[stable_hasher(ignore)]
3300    pub hir_id: HirId,
3301    pub ident: Ident,
3302    pub res: Res,
3303}
3304
3305#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3306#[derive(HashStable_Generic, Encodable, Decodable)]
3307pub enum RpitContext {
3308    Trait,
3309    TraitImpl,
3310}
3311
3312/// From whence the opaque type came.
3313#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3314#[derive(HashStable_Generic, Encodable, Decodable)]
3315pub enum OpaqueTyOrigin<D> {
3316    /// `-> impl Trait`
3317    FnReturn {
3318        /// The defining function.
3319        parent: D,
3320        // Whether this is an RPITIT (return position impl trait in trait)
3321        in_trait_or_impl: Option<RpitContext>,
3322    },
3323    /// `async fn`
3324    AsyncFn {
3325        /// The defining function.
3326        parent: D,
3327        // Whether this is an AFIT (async fn in trait)
3328        in_trait_or_impl: Option<RpitContext>,
3329    },
3330    /// type aliases: `type Foo = impl Trait;`
3331    TyAlias {
3332        /// The type alias or associated type parent of the TAIT/ATPIT
3333        parent: D,
3334        /// associated types in impl blocks for traits.
3335        in_assoc_ty: bool,
3336    },
3337}
3338
3339#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3340pub enum InferDelegationKind {
3341    Input(usize),
3342    Output,
3343}
3344
3345/// The various kinds of types recognized by the compiler.
3346#[derive(Debug, Clone, Copy, HashStable_Generic)]
3347// SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
3348#[repr(u8, C)]
3349pub enum TyKind<'hir, Unambig = ()> {
3350    /// Actual type should be inherited from `DefId` signature
3351    InferDelegation(DefId, InferDelegationKind),
3352    /// A variable length slice (i.e., `[T]`).
3353    Slice(&'hir Ty<'hir>),
3354    /// A fixed length array (i.e., `[T; n]`).
3355    Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3356    /// A raw pointer (i.e., `*const T` or `*mut T`).
3357    Ptr(MutTy<'hir>),
3358    /// A reference (i.e., `&'a T` or `&'a mut T`).
3359    Ref(&'hir Lifetime, MutTy<'hir>),
3360    /// A bare function (e.g., `fn(usize) -> bool`).
3361    BareFn(&'hir BareFnTy<'hir>),
3362    /// An unsafe binder type (e.g. `unsafe<'a> Foo<'a>`).
3363    UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3364    /// The never type (`!`).
3365    Never,
3366    /// A tuple (`(A, B, C, D, ...)`).
3367    Tup(&'hir [Ty<'hir>]),
3368    /// A path to a type definition (`module::module::...::Type`), or an
3369    /// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
3370    ///
3371    /// Type parameters may be stored in each `PathSegment`.
3372    Path(QPath<'hir>),
3373    /// An opaque type definition itself. This is only used for `impl Trait`.
3374    OpaqueDef(&'hir OpaqueTy<'hir>),
3375    /// A trait ascription type, which is `impl Trait` within a local binding.
3376    TraitAscription(GenericBounds<'hir>),
3377    /// A trait object type `Bound1 + Bound2 + Bound3`
3378    /// where `Bound` is a trait or a lifetime.
3379    ///
3380    /// We use pointer tagging to represent a `&'hir Lifetime` and `TraitObjectSyntax` pair
3381    /// as otherwise this type being `repr(C)` would result in `TyKind` increasing in size.
3382    TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3383    /// Unused for now.
3384    Typeof(&'hir AnonConst),
3385    /// Placeholder for a type that has failed to be defined.
3386    Err(rustc_span::ErrorGuaranteed),
3387    /// Pattern types (`pattern_type!(u32 is 1..)`)
3388    Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3389    /// `TyKind::Infer` means the type should be inferred instead of it having been
3390    /// specified. This can appear anywhere in a type.
3391    ///
3392    /// This variant is not always used to represent inference types, sometimes
3393    /// [`GenericArg::Infer`] is used instead.
3394    Infer(Unambig),
3395}
3396
3397#[derive(Debug, Clone, Copy, HashStable_Generic)]
3398pub enum InlineAsmOperand<'hir> {
3399    In {
3400        reg: InlineAsmRegOrRegClass,
3401        expr: &'hir Expr<'hir>,
3402    },
3403    Out {
3404        reg: InlineAsmRegOrRegClass,
3405        late: bool,
3406        expr: Option<&'hir Expr<'hir>>,
3407    },
3408    InOut {
3409        reg: InlineAsmRegOrRegClass,
3410        late: bool,
3411        expr: &'hir Expr<'hir>,
3412    },
3413    SplitInOut {
3414        reg: InlineAsmRegOrRegClass,
3415        late: bool,
3416        in_expr: &'hir Expr<'hir>,
3417        out_expr: Option<&'hir Expr<'hir>>,
3418    },
3419    Const {
3420        anon_const: &'hir AnonConst,
3421    },
3422    SymFn {
3423        anon_const: &'hir AnonConst,
3424    },
3425    SymStatic {
3426        path: QPath<'hir>,
3427        def_id: DefId,
3428    },
3429    Label {
3430        block: &'hir Block<'hir>,
3431    },
3432}
3433
3434impl<'hir> InlineAsmOperand<'hir> {
3435    pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3436        match *self {
3437            Self::In { reg, .. }
3438            | Self::Out { reg, .. }
3439            | Self::InOut { reg, .. }
3440            | Self::SplitInOut { reg, .. } => Some(reg),
3441            Self::Const { .. }
3442            | Self::SymFn { .. }
3443            | Self::SymStatic { .. }
3444            | Self::Label { .. } => None,
3445        }
3446    }
3447
3448    pub fn is_clobber(&self) -> bool {
3449        matches!(
3450            self,
3451            InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3452        )
3453    }
3454}
3455
3456#[derive(Debug, Clone, Copy, HashStable_Generic)]
3457pub struct InlineAsm<'hir> {
3458    pub asm_macro: ast::AsmMacro,
3459    pub template: &'hir [InlineAsmTemplatePiece],
3460    pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3461    pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3462    pub options: InlineAsmOptions,
3463    pub line_spans: &'hir [Span],
3464}
3465
3466impl InlineAsm<'_> {
3467    pub fn contains_label(&self) -> bool {
3468        self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3469    }
3470}
3471
3472/// Represents a parameter in a function header.
3473#[derive(Debug, Clone, Copy, HashStable_Generic)]
3474pub struct Param<'hir> {
3475    #[stable_hasher(ignore)]
3476    pub hir_id: HirId,
3477    pub pat: &'hir Pat<'hir>,
3478    pub ty_span: Span,
3479    pub span: Span,
3480}
3481
3482/// Represents the header (not the body) of a function declaration.
3483#[derive(Debug, Clone, Copy, HashStable_Generic)]
3484pub struct FnDecl<'hir> {
3485    /// The types of the function's parameters.
3486    ///
3487    /// Additional argument data is stored in the function's [body](Body::params).
3488    pub inputs: &'hir [Ty<'hir>],
3489    pub output: FnRetTy<'hir>,
3490    pub c_variadic: bool,
3491    /// Does the function have an implicit self?
3492    pub implicit_self: ImplicitSelfKind,
3493    /// Is lifetime elision allowed.
3494    pub lifetime_elision_allowed: bool,
3495}
3496
3497impl<'hir> FnDecl<'hir> {
3498    pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3499        if let FnRetTy::Return(ty) = self.output
3500            && let TyKind::InferDelegation(sig_id, _) = ty.kind
3501        {
3502            return Some(sig_id);
3503        }
3504        None
3505    }
3506}
3507
3508/// Represents what type of implicit self a function has, if any.
3509#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3510pub enum ImplicitSelfKind {
3511    /// Represents a `fn x(self);`.
3512    Imm,
3513    /// Represents a `fn x(mut self);`.
3514    Mut,
3515    /// Represents a `fn x(&self);`.
3516    RefImm,
3517    /// Represents a `fn x(&mut self);`.
3518    RefMut,
3519    /// Represents when a function does not have a self argument or
3520    /// when a function has a `self: X` argument.
3521    None,
3522}
3523
3524impl ImplicitSelfKind {
3525    /// Does this represent an implicit self?
3526    pub fn has_implicit_self(&self) -> bool {
3527        !matches!(*self, ImplicitSelfKind::None)
3528    }
3529}
3530
3531#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3532pub enum IsAsync {
3533    Async(Span),
3534    NotAsync,
3535}
3536
3537impl IsAsync {
3538    pub fn is_async(self) -> bool {
3539        matches!(self, IsAsync::Async(_))
3540    }
3541}
3542
3543#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3544pub enum Defaultness {
3545    Default { has_value: bool },
3546    Final,
3547}
3548
3549impl Defaultness {
3550    pub fn has_value(&self) -> bool {
3551        match *self {
3552            Defaultness::Default { has_value } => has_value,
3553            Defaultness::Final => true,
3554        }
3555    }
3556
3557    pub fn is_final(&self) -> bool {
3558        *self == Defaultness::Final
3559    }
3560
3561    pub fn is_default(&self) -> bool {
3562        matches!(*self, Defaultness::Default { .. })
3563    }
3564}
3565
3566#[derive(Debug, Clone, Copy, HashStable_Generic)]
3567pub enum FnRetTy<'hir> {
3568    /// Return type is not specified.
3569    ///
3570    /// Functions default to `()` and
3571    /// closures default to inference. Span points to where return
3572    /// type would be inserted.
3573    DefaultReturn(Span),
3574    /// Everything else.
3575    Return(&'hir Ty<'hir>),
3576}
3577
3578impl<'hir> FnRetTy<'hir> {
3579    #[inline]
3580    pub fn span(&self) -> Span {
3581        match *self {
3582            Self::DefaultReturn(span) => span,
3583            Self::Return(ref ty) => ty.span,
3584        }
3585    }
3586
3587    pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3588        if let Self::Return(ty) = self
3589            && ty.is_suggestable_infer_ty()
3590        {
3591            return Some(*ty);
3592        }
3593        None
3594    }
3595}
3596
3597/// Represents `for<...>` binder before a closure
3598#[derive(Copy, Clone, Debug, HashStable_Generic)]
3599pub enum ClosureBinder {
3600    /// Binder is not specified.
3601    Default,
3602    /// Binder is specified.
3603    ///
3604    /// Span points to the whole `for<...>`.
3605    For { span: Span },
3606}
3607
3608#[derive(Debug, Clone, Copy, HashStable_Generic)]
3609pub struct Mod<'hir> {
3610    pub spans: ModSpans,
3611    pub item_ids: &'hir [ItemId],
3612}
3613
3614#[derive(Copy, Clone, Debug, HashStable_Generic)]
3615pub struct ModSpans {
3616    /// A span from the first token past `{` to the last token until `}`.
3617    /// For `mod foo;`, the inner span ranges from the first token
3618    /// to the last token in the external file.
3619    pub inner_span: Span,
3620    pub inject_use_span: Span,
3621}
3622
3623#[derive(Debug, Clone, Copy, HashStable_Generic)]
3624pub struct EnumDef<'hir> {
3625    pub variants: &'hir [Variant<'hir>],
3626}
3627
3628#[derive(Debug, Clone, Copy, HashStable_Generic)]
3629pub struct Variant<'hir> {
3630    /// Name of the variant.
3631    pub ident: Ident,
3632    /// Id of the variant (not the constructor, see `VariantData::ctor_hir_id()`).
3633    #[stable_hasher(ignore)]
3634    pub hir_id: HirId,
3635    pub def_id: LocalDefId,
3636    /// Fields and constructor id of the variant.
3637    pub data: VariantData<'hir>,
3638    /// Explicit discriminant (e.g., `Foo = 1`).
3639    pub disr_expr: Option<&'hir AnonConst>,
3640    /// Span
3641    pub span: Span,
3642}
3643
3644#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3645pub enum UseKind {
3646    /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
3647    /// Also produced for each element of a list `use`, e.g.
3648    /// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
3649    Single,
3650
3651    /// Glob import, e.g., `use foo::*`.
3652    Glob,
3653
3654    /// Degenerate list import, e.g., `use foo::{a, b}` produces
3655    /// an additional `use foo::{}` for performing checks such as
3656    /// unstable feature gating. May be removed in the future.
3657    ListStem,
3658}
3659
3660/// References to traits in impls.
3661///
3662/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all
3663/// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
3664/// trait being referred to but just a unique `HirId` that serves as a key
3665/// within the resolution map.
3666#[derive(Clone, Debug, Copy, HashStable_Generic)]
3667pub struct TraitRef<'hir> {
3668    pub path: &'hir Path<'hir>,
3669    // Don't hash the `ref_id`. It is tracked via the thing it is used to access.
3670    #[stable_hasher(ignore)]
3671    pub hir_ref_id: HirId,
3672}
3673
3674impl TraitRef<'_> {
3675    /// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias.
3676    pub fn trait_def_id(&self) -> Option<DefId> {
3677        match self.path.res {
3678            Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
3679            Res::Err => None,
3680            res => panic!("{res:?} did not resolve to a trait or trait alias"),
3681        }
3682    }
3683}
3684
3685#[derive(Clone, Debug, Copy, HashStable_Generic)]
3686pub struct PolyTraitRef<'hir> {
3687    /// The `'a` in `for<'a> Foo<&'a T>`.
3688    pub bound_generic_params: &'hir [GenericParam<'hir>],
3689
3690    /// The constness and polarity of the trait ref.
3691    ///
3692    /// The `async` modifier is lowered directly into a different trait for now.
3693    pub modifiers: TraitBoundModifiers,
3694
3695    /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
3696    pub trait_ref: TraitRef<'hir>,
3697
3698    pub span: Span,
3699}
3700
3701#[derive(Debug, Clone, Copy, HashStable_Generic)]
3702pub struct FieldDef<'hir> {
3703    pub span: Span,
3704    pub vis_span: Span,
3705    pub ident: Ident,
3706    #[stable_hasher(ignore)]
3707    pub hir_id: HirId,
3708    pub def_id: LocalDefId,
3709    pub ty: &'hir Ty<'hir>,
3710    pub safety: Safety,
3711    pub default: Option<&'hir AnonConst>,
3712}
3713
3714impl FieldDef<'_> {
3715    // Still necessary in couple of places
3716    pub fn is_positional(&self) -> bool {
3717        self.ident.as_str().as_bytes()[0].is_ascii_digit()
3718    }
3719}
3720
3721/// Fields and constructor IDs of enum variants and structs.
3722#[derive(Debug, Clone, Copy, HashStable_Generic)]
3723pub enum VariantData<'hir> {
3724    /// A struct variant.
3725    ///
3726    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
3727    Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
3728    /// A tuple variant.
3729    ///
3730    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
3731    Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
3732    /// A unit variant.
3733    ///
3734    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
3735    Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
3736}
3737
3738impl<'hir> VariantData<'hir> {
3739    /// Return the fields of this variant.
3740    pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
3741        match *self {
3742            VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
3743            _ => &[],
3744        }
3745    }
3746
3747    pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
3748        match *self {
3749            VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
3750            VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
3751            VariantData::Struct { .. } => None,
3752        }
3753    }
3754
3755    #[inline]
3756    pub fn ctor_kind(&self) -> Option<CtorKind> {
3757        self.ctor().map(|(kind, ..)| kind)
3758    }
3759
3760    /// Return the `HirId` of this variant's constructor, if it has one.
3761    #[inline]
3762    pub fn ctor_hir_id(&self) -> Option<HirId> {
3763        self.ctor().map(|(_, hir_id, _)| hir_id)
3764    }
3765
3766    /// Return the `LocalDefId` of this variant's constructor, if it has one.
3767    #[inline]
3768    pub fn ctor_def_id(&self) -> Option<LocalDefId> {
3769        self.ctor().map(|(.., def_id)| def_id)
3770    }
3771}
3772
3773// The bodies for items are stored "out of line", in a separate
3774// hashmap in the `Crate`. Here we just record the hir-id of the item
3775// so it can fetched later.
3776#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
3777pub struct ItemId {
3778    pub owner_id: OwnerId,
3779}
3780
3781impl ItemId {
3782    #[inline]
3783    pub fn hir_id(&self) -> HirId {
3784        // Items are always HIR owners.
3785        HirId::make_owner(self.owner_id.def_id)
3786    }
3787}
3788
3789/// An item
3790///
3791/// The name might be a dummy name in case of anonymous items
3792///
3793/// For more details, see the [rust lang reference].
3794/// Note that the reference does not document nightly-only features.
3795/// There may be also slight differences in the names and representation of AST nodes between
3796/// the compiler and the reference.
3797///
3798/// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
3799#[derive(Debug, Clone, Copy, HashStable_Generic)]
3800pub struct Item<'hir> {
3801    pub ident: Ident,
3802    pub owner_id: OwnerId,
3803    pub kind: ItemKind<'hir>,
3804    pub span: Span,
3805    pub vis_span: Span,
3806}
3807
3808impl<'hir> Item<'hir> {
3809    #[inline]
3810    pub fn hir_id(&self) -> HirId {
3811        // Items are always HIR owners.
3812        HirId::make_owner(self.owner_id.def_id)
3813    }
3814
3815    pub fn item_id(&self) -> ItemId {
3816        ItemId { owner_id: self.owner_id }
3817    }
3818
3819    /// Check if this is an [`ItemKind::Enum`], [`ItemKind::Struct`] or
3820    /// [`ItemKind::Union`].
3821    pub fn is_adt(&self) -> bool {
3822        matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
3823    }
3824
3825    /// Check if this is an [`ItemKind::Struct`] or [`ItemKind::Union`].
3826    pub fn is_struct_or_union(&self) -> bool {
3827        matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
3828    }
3829
3830    expect_methods_self_kind! {
3831        expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s;
3832
3833        expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
3834
3835        expect_static, (&'hir Ty<'hir>, Mutability, BodyId),
3836            ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body);
3837
3838        expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
3839            ItemKind::Const(ty, generics, body), (ty, generics, *body);
3840
3841        expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId),
3842            ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body);
3843
3844        expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk);
3845
3846        expect_mod, &'hir Mod<'hir>, ItemKind::Mod(m), m;
3847
3848        expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
3849            ItemKind::ForeignMod { abi, items }, (*abi, items);
3850
3851        expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm;
3852
3853        expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
3854            ItemKind::TyAlias(ty, generics), (ty, generics);
3855
3856        expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
3857
3858        expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
3859            ItemKind::Struct(data, generics), (data, generics);
3860
3861        expect_union, (&VariantData<'hir>, &'hir Generics<'hir>),
3862            ItemKind::Union(data, generics), (data, generics);
3863
3864        expect_trait,
3865            (IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
3866            ItemKind::Trait(is_auto, safety, generics, bounds, items),
3867            (*is_auto, *safety, generics, bounds, items);
3868
3869        expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>),
3870            ItemKind::TraitAlias(generics, bounds), (generics, bounds);
3871
3872        expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
3873    }
3874}
3875
3876#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
3877#[derive(Encodable, Decodable, HashStable_Generic)]
3878pub enum Safety {
3879    Unsafe,
3880    Safe,
3881}
3882
3883impl Safety {
3884    pub fn prefix_str(self) -> &'static str {
3885        match self {
3886            Self::Unsafe => "unsafe ",
3887            Self::Safe => "",
3888        }
3889    }
3890
3891    #[inline]
3892    pub fn is_unsafe(self) -> bool {
3893        !self.is_safe()
3894    }
3895
3896    #[inline]
3897    pub fn is_safe(self) -> bool {
3898        match self {
3899            Self::Unsafe => false,
3900            Self::Safe => true,
3901        }
3902    }
3903}
3904
3905impl fmt::Display for Safety {
3906    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3907        f.write_str(match *self {
3908            Self::Unsafe => "unsafe",
3909            Self::Safe => "safe",
3910        })
3911    }
3912}
3913
3914#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3915pub enum Constness {
3916    Const,
3917    NotConst,
3918}
3919
3920impl fmt::Display for Constness {
3921    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3922        f.write_str(match *self {
3923            Self::Const => "const",
3924            Self::NotConst => "non-const",
3925        })
3926    }
3927}
3928
3929/// The actualy safety specified in syntax. We may treat
3930/// its safety different within the type system to create a
3931/// "sound by default" system that needs checking this enum
3932/// explicitly to allow unsafe operations.
3933#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
3934pub enum HeaderSafety {
3935    /// A safe function annotated with `#[target_features]`.
3936    /// The type system treats this function as an unsafe function,
3937    /// but safety checking will check this enum to treat it as safe
3938    /// and allowing calling other safe target feature functions with
3939    /// the same features without requiring an additional unsafe block.
3940    SafeTargetFeatures,
3941    Normal(Safety),
3942}
3943
3944impl From<Safety> for HeaderSafety {
3945    fn from(v: Safety) -> Self {
3946        Self::Normal(v)
3947    }
3948}
3949
3950#[derive(Copy, Clone, Debug, HashStable_Generic)]
3951pub struct FnHeader {
3952    pub safety: HeaderSafety,
3953    pub constness: Constness,
3954    pub asyncness: IsAsync,
3955    pub abi: ExternAbi,
3956}
3957
3958impl FnHeader {
3959    pub fn is_async(&self) -> bool {
3960        matches!(self.asyncness, IsAsync::Async(_))
3961    }
3962
3963    pub fn is_const(&self) -> bool {
3964        matches!(self.constness, Constness::Const)
3965    }
3966
3967    pub fn is_unsafe(&self) -> bool {
3968        self.safety().is_unsafe()
3969    }
3970
3971    pub fn is_safe(&self) -> bool {
3972        self.safety().is_safe()
3973    }
3974
3975    pub fn safety(&self) -> Safety {
3976        match self.safety {
3977            HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
3978            HeaderSafety::Normal(safety) => safety,
3979        }
3980    }
3981}
3982
3983#[derive(Debug, Clone, Copy, HashStable_Generic)]
3984pub enum ItemKind<'hir> {
3985    /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
3986    ///
3987    /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
3988    ExternCrate(Option<Symbol>),
3989
3990    /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
3991    ///
3992    /// or just
3993    ///
3994    /// `use foo::bar::baz;` (with `as baz` implicitly on the right).
3995    Use(&'hir UsePath<'hir>, UseKind),
3996
3997    /// A `static` item.
3998    Static(&'hir Ty<'hir>, Mutability, BodyId),
3999    /// A `const` item.
4000    Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
4001    /// A function declaration.
4002    Fn {
4003        sig: FnSig<'hir>,
4004        generics: &'hir Generics<'hir>,
4005        body: BodyId,
4006        /// Whether this function actually has a body.
4007        /// For functions without a body, `body` is synthesized (to avoid ICEs all over the
4008        /// compiler), but that code should never be translated.
4009        has_body: bool,
4010    },
4011    /// A MBE macro definition (`macro_rules!` or `macro`).
4012    Macro(&'hir ast::MacroDef, MacroKind),
4013    /// A module.
4014    Mod(&'hir Mod<'hir>),
4015    /// An external module, e.g. `extern { .. }`.
4016    ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
4017    /// Module-level inline assembly (from `global_asm!`).
4018    GlobalAsm(&'hir InlineAsm<'hir>),
4019    /// A type alias, e.g., `type Foo = Bar<u8>`.
4020    TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
4021    /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
4022    Enum(EnumDef<'hir>, &'hir Generics<'hir>),
4023    /// A struct definition, e.g., `struct Foo<A> {x: A}`.
4024    Struct(VariantData<'hir>, &'hir Generics<'hir>),
4025    /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
4026    Union(VariantData<'hir>, &'hir Generics<'hir>),
4027    /// A trait definition.
4028    Trait(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
4029    /// A trait alias.
4030    TraitAlias(&'hir Generics<'hir>, GenericBounds<'hir>),
4031
4032    /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
4033    Impl(&'hir Impl<'hir>),
4034}
4035
4036/// Represents an impl block declaration.
4037///
4038/// E.g., `impl $Type { .. }` or `impl $Trait for $Type { .. }`
4039/// Refer to [`ImplItem`] for an associated item within an impl block.
4040#[derive(Debug, Clone, Copy, HashStable_Generic)]
4041pub struct Impl<'hir> {
4042    pub constness: Constness,
4043    pub safety: Safety,
4044    pub polarity: ImplPolarity,
4045    pub defaultness: Defaultness,
4046    // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
4047    // decoding as `Span`s cannot be decoded when a `Session` is not available.
4048    pub defaultness_span: Option<Span>,
4049    pub generics: &'hir Generics<'hir>,
4050
4051    /// The trait being implemented, if any.
4052    pub of_trait: Option<TraitRef<'hir>>,
4053
4054    pub self_ty: &'hir Ty<'hir>,
4055    pub items: &'hir [ImplItemRef],
4056}
4057
4058impl ItemKind<'_> {
4059    pub fn generics(&self) -> Option<&Generics<'_>> {
4060        Some(match self {
4061            ItemKind::Fn { generics, .. }
4062            | ItemKind::TyAlias(_, generics)
4063            | ItemKind::Const(_, generics, _)
4064            | ItemKind::Enum(_, generics)
4065            | ItemKind::Struct(_, generics)
4066            | ItemKind::Union(_, generics)
4067            | ItemKind::Trait(_, _, generics, _, _)
4068            | ItemKind::TraitAlias(generics, _)
4069            | ItemKind::Impl(Impl { generics, .. }) => generics,
4070            _ => return None,
4071        })
4072    }
4073
4074    pub fn descr(&self) -> &'static str {
4075        match self {
4076            ItemKind::ExternCrate(..) => "extern crate",
4077            ItemKind::Use(..) => "`use` import",
4078            ItemKind::Static(..) => "static item",
4079            ItemKind::Const(..) => "constant item",
4080            ItemKind::Fn { .. } => "function",
4081            ItemKind::Macro(..) => "macro",
4082            ItemKind::Mod(..) => "module",
4083            ItemKind::ForeignMod { .. } => "extern block",
4084            ItemKind::GlobalAsm(..) => "global asm item",
4085            ItemKind::TyAlias(..) => "type alias",
4086            ItemKind::Enum(..) => "enum",
4087            ItemKind::Struct(..) => "struct",
4088            ItemKind::Union(..) => "union",
4089            ItemKind::Trait(..) => "trait",
4090            ItemKind::TraitAlias(..) => "trait alias",
4091            ItemKind::Impl(..) => "implementation",
4092        }
4093    }
4094}
4095
4096/// A reference from an trait to one of its associated items. This
4097/// contains the item's id, naturally, but also the item's name and
4098/// some other high-level details (like whether it is an associated
4099/// type or method, and whether it is public). This allows other
4100/// passes to find the impl they want without loading the ID (which
4101/// means fewer edges in the incremental compilation graph).
4102#[derive(Debug, Clone, Copy, HashStable_Generic)]
4103pub struct TraitItemRef {
4104    pub id: TraitItemId,
4105    pub ident: Ident,
4106    pub kind: AssocItemKind,
4107    pub span: Span,
4108}
4109
4110/// A reference from an impl to one of its associated items. This
4111/// contains the item's ID, naturally, but also the item's name and
4112/// some other high-level details (like whether it is an associated
4113/// type or method, and whether it is public). This allows other
4114/// passes to find the impl they want without loading the ID (which
4115/// means fewer edges in the incremental compilation graph).
4116#[derive(Debug, Clone, Copy, HashStable_Generic)]
4117pub struct ImplItemRef {
4118    pub id: ImplItemId,
4119    pub ident: Ident,
4120    pub kind: AssocItemKind,
4121    pub span: Span,
4122    /// When we are in a trait impl, link to the trait-item's id.
4123    pub trait_item_def_id: Option<DefId>,
4124}
4125
4126#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4127pub enum AssocItemKind {
4128    Const,
4129    Fn { has_self: bool },
4130    Type,
4131}
4132
4133// The bodies for items are stored "out of line", in a separate
4134// hashmap in the `Crate`. Here we just record the hir-id of the item
4135// so it can fetched later.
4136#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4137pub struct ForeignItemId {
4138    pub owner_id: OwnerId,
4139}
4140
4141impl ForeignItemId {
4142    #[inline]
4143    pub fn hir_id(&self) -> HirId {
4144        // Items are always HIR owners.
4145        HirId::make_owner(self.owner_id.def_id)
4146    }
4147}
4148
4149/// A reference from a foreign block to one of its items. This
4150/// contains the item's ID, naturally, but also the item's name and
4151/// some other high-level details (like whether it is an associated
4152/// type or method, and whether it is public). This allows other
4153/// passes to find the impl they want without loading the ID (which
4154/// means fewer edges in the incremental compilation graph).
4155#[derive(Debug, Clone, Copy, HashStable_Generic)]
4156pub struct ForeignItemRef {
4157    pub id: ForeignItemId,
4158    pub ident: Ident,
4159    pub span: Span,
4160}
4161
4162#[derive(Debug, Clone, Copy, HashStable_Generic)]
4163pub struct ForeignItem<'hir> {
4164    pub ident: Ident,
4165    pub kind: ForeignItemKind<'hir>,
4166    pub owner_id: OwnerId,
4167    pub span: Span,
4168    pub vis_span: Span,
4169}
4170
4171impl ForeignItem<'_> {
4172    #[inline]
4173    pub fn hir_id(&self) -> HirId {
4174        // Items are always HIR owners.
4175        HirId::make_owner(self.owner_id.def_id)
4176    }
4177
4178    pub fn foreign_item_id(&self) -> ForeignItemId {
4179        ForeignItemId { owner_id: self.owner_id }
4180    }
4181}
4182
4183/// An item within an `extern` block.
4184#[derive(Debug, Clone, Copy, HashStable_Generic)]
4185pub enum ForeignItemKind<'hir> {
4186    /// A foreign function.
4187    Fn(FnSig<'hir>, &'hir [Ident], &'hir Generics<'hir>),
4188    /// A foreign static item (`static ext: u8`).
4189    Static(&'hir Ty<'hir>, Mutability, Safety),
4190    /// A foreign type.
4191    Type,
4192}
4193
4194/// A variable captured by a closure.
4195#[derive(Debug, Copy, Clone, HashStable_Generic)]
4196pub struct Upvar {
4197    /// First span where it is accessed (there can be multiple).
4198    pub span: Span,
4199}
4200
4201// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
4202// has length > 0 if the trait is found through an chain of imports, starting with the
4203// import/use statement in the scope where the trait is used.
4204#[derive(Debug, Clone, HashStable_Generic)]
4205pub struct TraitCandidate {
4206    pub def_id: DefId,
4207    pub import_ids: SmallVec<[LocalDefId; 1]>,
4208}
4209
4210#[derive(Copy, Clone, Debug, HashStable_Generic)]
4211pub enum OwnerNode<'hir> {
4212    Item(&'hir Item<'hir>),
4213    ForeignItem(&'hir ForeignItem<'hir>),
4214    TraitItem(&'hir TraitItem<'hir>),
4215    ImplItem(&'hir ImplItem<'hir>),
4216    Crate(&'hir Mod<'hir>),
4217    Synthetic,
4218}
4219
4220impl<'hir> OwnerNode<'hir> {
4221    pub fn ident(&self) -> Option<Ident> {
4222        match self {
4223            OwnerNode::Item(Item { ident, .. })
4224            | OwnerNode::ForeignItem(ForeignItem { ident, .. })
4225            | OwnerNode::ImplItem(ImplItem { ident, .. })
4226            | OwnerNode::TraitItem(TraitItem { ident, .. }) => Some(*ident),
4227            OwnerNode::Crate(..) | OwnerNode::Synthetic => None,
4228        }
4229    }
4230
4231    pub fn span(&self) -> Span {
4232        match self {
4233            OwnerNode::Item(Item { span, .. })
4234            | OwnerNode::ForeignItem(ForeignItem { span, .. })
4235            | OwnerNode::ImplItem(ImplItem { span, .. })
4236            | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4237            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4238            OwnerNode::Synthetic => unreachable!(),
4239        }
4240    }
4241
4242    pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4243        match self {
4244            OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4245            | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4246            | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4247            | OwnerNode::ForeignItem(ForeignItem {
4248                kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4249            }) => Some(fn_sig),
4250            _ => None,
4251        }
4252    }
4253
4254    pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4255        match self {
4256            OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4257            | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4258            | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4259            | OwnerNode::ForeignItem(ForeignItem {
4260                kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4261            }) => Some(fn_sig.decl),
4262            _ => None,
4263        }
4264    }
4265
4266    pub fn body_id(&self) -> Option<BodyId> {
4267        match self {
4268            OwnerNode::Item(Item {
4269                kind:
4270                    ItemKind::Static(_, _, body)
4271                    | ItemKind::Const(_, _, body)
4272                    | ItemKind::Fn { body, .. },
4273                ..
4274            })
4275            | OwnerNode::TraitItem(TraitItem {
4276                kind:
4277                    TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4278                ..
4279            })
4280            | OwnerNode::ImplItem(ImplItem {
4281                kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4282                ..
4283            }) => Some(*body),
4284            _ => None,
4285        }
4286    }
4287
4288    pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4289        Node::generics(self.into())
4290    }
4291
4292    pub fn def_id(self) -> OwnerId {
4293        match self {
4294            OwnerNode::Item(Item { owner_id, .. })
4295            | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4296            | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4297            | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4298            OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4299            OwnerNode::Synthetic => unreachable!(),
4300        }
4301    }
4302
4303    /// Check if node is an impl block.
4304    pub fn is_impl_block(&self) -> bool {
4305        matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4306    }
4307
4308    expect_methods_self! {
4309        expect_item,         &'hir Item<'hir>,        OwnerNode::Item(n),        n;
4310        expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4311        expect_impl_item,    &'hir ImplItem<'hir>,    OwnerNode::ImplItem(n),    n;
4312        expect_trait_item,   &'hir TraitItem<'hir>,   OwnerNode::TraitItem(n),   n;
4313    }
4314}
4315
4316impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4317    fn from(val: &'hir Item<'hir>) -> Self {
4318        OwnerNode::Item(val)
4319    }
4320}
4321
4322impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4323    fn from(val: &'hir ForeignItem<'hir>) -> Self {
4324        OwnerNode::ForeignItem(val)
4325    }
4326}
4327
4328impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4329    fn from(val: &'hir ImplItem<'hir>) -> Self {
4330        OwnerNode::ImplItem(val)
4331    }
4332}
4333
4334impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4335    fn from(val: &'hir TraitItem<'hir>) -> Self {
4336        OwnerNode::TraitItem(val)
4337    }
4338}
4339
4340impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4341    fn from(val: OwnerNode<'hir>) -> Self {
4342        match val {
4343            OwnerNode::Item(n) => Node::Item(n),
4344            OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4345            OwnerNode::ImplItem(n) => Node::ImplItem(n),
4346            OwnerNode::TraitItem(n) => Node::TraitItem(n),
4347            OwnerNode::Crate(n) => Node::Crate(n),
4348            OwnerNode::Synthetic => Node::Synthetic,
4349        }
4350    }
4351}
4352
4353#[derive(Copy, Clone, Debug, HashStable_Generic)]
4354pub enum Node<'hir> {
4355    Param(&'hir Param<'hir>),
4356    Item(&'hir Item<'hir>),
4357    ForeignItem(&'hir ForeignItem<'hir>),
4358    TraitItem(&'hir TraitItem<'hir>),
4359    ImplItem(&'hir ImplItem<'hir>),
4360    Variant(&'hir Variant<'hir>),
4361    Field(&'hir FieldDef<'hir>),
4362    AnonConst(&'hir AnonConst),
4363    ConstBlock(&'hir ConstBlock),
4364    ConstArg(&'hir ConstArg<'hir>),
4365    Expr(&'hir Expr<'hir>),
4366    ExprField(&'hir ExprField<'hir>),
4367    Stmt(&'hir Stmt<'hir>),
4368    PathSegment(&'hir PathSegment<'hir>),
4369    Ty(&'hir Ty<'hir>),
4370    AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4371    TraitRef(&'hir TraitRef<'hir>),
4372    OpaqueTy(&'hir OpaqueTy<'hir>),
4373    TyPat(&'hir TyPat<'hir>),
4374    Pat(&'hir Pat<'hir>),
4375    PatField(&'hir PatField<'hir>),
4376    /// Needed as its own node with its own HirId for tracking
4377    /// the unadjusted type of literals within patterns
4378    /// (e.g. byte str literals not being of slice type).
4379    PatExpr(&'hir PatExpr<'hir>),
4380    Arm(&'hir Arm<'hir>),
4381    Block(&'hir Block<'hir>),
4382    LetStmt(&'hir LetStmt<'hir>),
4383    /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
4384    /// with synthesized constructors.
4385    Ctor(&'hir VariantData<'hir>),
4386    Lifetime(&'hir Lifetime),
4387    GenericParam(&'hir GenericParam<'hir>),
4388    Crate(&'hir Mod<'hir>),
4389    Infer(&'hir InferArg),
4390    WherePredicate(&'hir WherePredicate<'hir>),
4391    PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4392    // Created by query feeding
4393    Synthetic,
4394    Err(Span),
4395}
4396
4397impl<'hir> Node<'hir> {
4398    /// Get the identifier of this `Node`, if applicable.
4399    ///
4400    /// # Edge cases
4401    ///
4402    /// Calling `.ident()` on a [`Node::Ctor`] will return `None`
4403    /// because `Ctor`s do not have identifiers themselves.
4404    /// Instead, call `.ident()` on the parent struct/variant, like so:
4405    ///
4406    /// ```ignore (illustrative)
4407    /// ctor
4408    ///     .ctor_hir_id()
4409    ///     .map(|ctor_id| tcx.parent_hir_node(ctor_id))
4410    ///     .and_then(|parent| parent.ident())
4411    /// ```
4412    pub fn ident(&self) -> Option<Ident> {
4413        match self {
4414            Node::TraitItem(TraitItem { ident, .. })
4415            | Node::ImplItem(ImplItem { ident, .. })
4416            | Node::ForeignItem(ForeignItem { ident, .. })
4417            | Node::Field(FieldDef { ident, .. })
4418            | Node::Variant(Variant { ident, .. })
4419            | Node::Item(Item { ident, .. })
4420            | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4421            Node::Lifetime(lt) => Some(lt.ident),
4422            Node::GenericParam(p) => Some(p.name.ident()),
4423            Node::AssocItemConstraint(c) => Some(c.ident),
4424            Node::PatField(f) => Some(f.ident),
4425            Node::ExprField(f) => Some(f.ident),
4426            Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4427            Node::Param(..)
4428            | Node::AnonConst(..)
4429            | Node::ConstBlock(..)
4430            | Node::ConstArg(..)
4431            | Node::Expr(..)
4432            | Node::Stmt(..)
4433            | Node::Block(..)
4434            | Node::Ctor(..)
4435            | Node::Pat(..)
4436            | Node::TyPat(..)
4437            | Node::PatExpr(..)
4438            | Node::Arm(..)
4439            | Node::LetStmt(..)
4440            | Node::Crate(..)
4441            | Node::Ty(..)
4442            | Node::TraitRef(..)
4443            | Node::OpaqueTy(..)
4444            | Node::Infer(..)
4445            | Node::WherePredicate(..)
4446            | Node::Synthetic
4447            | Node::Err(..) => None,
4448        }
4449    }
4450
4451    pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4452        match self {
4453            Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4454            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4455            | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4456            | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4457                Some(fn_sig.decl)
4458            }
4459            Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4460                Some(fn_decl)
4461            }
4462            _ => None,
4463        }
4464    }
4465
4466    /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`.
4467    pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4468        if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4469            && let Some(trait_ref) = impl_block.of_trait
4470            && let Some(trait_id) = trait_ref.trait_def_id()
4471            && trait_id == trait_def_id
4472        {
4473            Some(impl_block)
4474        } else {
4475            None
4476        }
4477    }
4478
4479    pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4480        match self {
4481            Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4482            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4483            | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4484            | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4485                Some(fn_sig)
4486            }
4487            _ => None,
4488        }
4489    }
4490
4491    /// Get the type for constants, assoc types, type aliases and statics.
4492    pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4493        match self {
4494            Node::Item(it) => match it.kind {
4495                ItemKind::TyAlias(ty, _)
4496                | ItemKind::Static(ty, _, _)
4497                | ItemKind::Const(ty, _, _) => Some(ty),
4498                ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4499                _ => None,
4500            },
4501            Node::TraitItem(it) => match it.kind {
4502                TraitItemKind::Const(ty, _) => Some(ty),
4503                TraitItemKind::Type(_, ty) => ty,
4504                _ => None,
4505            },
4506            Node::ImplItem(it) => match it.kind {
4507                ImplItemKind::Const(ty, _) => Some(ty),
4508                ImplItemKind::Type(ty) => Some(ty),
4509                _ => None,
4510            },
4511            _ => None,
4512        }
4513    }
4514
4515    pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4516        match self {
4517            Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty),
4518            _ => None,
4519        }
4520    }
4521
4522    #[inline]
4523    pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4524        match self {
4525            Node::Item(Item {
4526                owner_id,
4527                kind:
4528                    ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. },
4529                ..
4530            })
4531            | Node::TraitItem(TraitItem {
4532                owner_id,
4533                kind:
4534                    TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4535                ..
4536            })
4537            | Node::ImplItem(ImplItem {
4538                owner_id,
4539                kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4540                ..
4541            }) => Some((owner_id.def_id, *body)),
4542
4543            Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4544                Some((*def_id, *body))
4545            }
4546
4547            Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4548            Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4549
4550            _ => None,
4551        }
4552    }
4553
4554    pub fn body_id(&self) -> Option<BodyId> {
4555        Some(self.associated_body()?.1)
4556    }
4557
4558    pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4559        match self {
4560            Node::ForeignItem(ForeignItem {
4561                kind: ForeignItemKind::Fn(_, _, generics), ..
4562            })
4563            | Node::TraitItem(TraitItem { generics, .. })
4564            | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4565            Node::Item(item) => item.kind.generics(),
4566            _ => None,
4567        }
4568    }
4569
4570    pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4571        match self {
4572            Node::Item(i) => Some(OwnerNode::Item(i)),
4573            Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4574            Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4575            Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4576            Node::Crate(i) => Some(OwnerNode::Crate(i)),
4577            Node::Synthetic => Some(OwnerNode::Synthetic),
4578            _ => None,
4579        }
4580    }
4581
4582    pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4583        match self {
4584            Node::Item(i) => match i.kind {
4585                ItemKind::Fn { sig, generics, .. } => {
4586                    Some(FnKind::ItemFn(i.ident, generics, sig.header))
4587                }
4588                _ => None,
4589            },
4590            Node::TraitItem(ti) => match ti.kind {
4591                TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4592                _ => None,
4593            },
4594            Node::ImplItem(ii) => match ii.kind {
4595                ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4596                _ => None,
4597            },
4598            Node::Expr(e) => match e.kind {
4599                ExprKind::Closure { .. } => Some(FnKind::Closure),
4600                _ => None,
4601            },
4602            _ => None,
4603        }
4604    }
4605
4606    expect_methods_self! {
4607        expect_param,         &'hir Param<'hir>,        Node::Param(n),        n;
4608        expect_item,          &'hir Item<'hir>,         Node::Item(n),         n;
4609        expect_foreign_item,  &'hir ForeignItem<'hir>,  Node::ForeignItem(n),  n;
4610        expect_trait_item,    &'hir TraitItem<'hir>,    Node::TraitItem(n),    n;
4611        expect_impl_item,     &'hir ImplItem<'hir>,     Node::ImplItem(n),     n;
4612        expect_variant,       &'hir Variant<'hir>,      Node::Variant(n),      n;
4613        expect_field,         &'hir FieldDef<'hir>,     Node::Field(n),        n;
4614        expect_anon_const,    &'hir AnonConst,          Node::AnonConst(n),    n;
4615        expect_inline_const,  &'hir ConstBlock,         Node::ConstBlock(n),   n;
4616        expect_expr,          &'hir Expr<'hir>,         Node::Expr(n),         n;
4617        expect_expr_field,    &'hir ExprField<'hir>,    Node::ExprField(n),    n;
4618        expect_stmt,          &'hir Stmt<'hir>,         Node::Stmt(n),         n;
4619        expect_path_segment,  &'hir PathSegment<'hir>,  Node::PathSegment(n),  n;
4620        expect_ty,            &'hir Ty<'hir>,           Node::Ty(n),           n;
4621        expect_assoc_item_constraint,  &'hir AssocItemConstraint<'hir>,  Node::AssocItemConstraint(n),  n;
4622        expect_trait_ref,     &'hir TraitRef<'hir>,     Node::TraitRef(n),     n;
4623        expect_opaque_ty,     &'hir OpaqueTy<'hir>,     Node::OpaqueTy(n),     n;
4624        expect_pat,           &'hir Pat<'hir>,          Node::Pat(n),          n;
4625        expect_pat_field,     &'hir PatField<'hir>,     Node::PatField(n),     n;
4626        expect_arm,           &'hir Arm<'hir>,          Node::Arm(n),          n;
4627        expect_block,         &'hir Block<'hir>,        Node::Block(n),        n;
4628        expect_let_stmt,      &'hir LetStmt<'hir>,      Node::LetStmt(n),      n;
4629        expect_ctor,          &'hir VariantData<'hir>,  Node::Ctor(n),         n;
4630        expect_lifetime,      &'hir Lifetime,           Node::Lifetime(n),     n;
4631        expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
4632        expect_crate,         &'hir Mod<'hir>,          Node::Crate(n),        n;
4633        expect_infer,         &'hir InferArg,           Node::Infer(n),        n;
4634        expect_closure,       &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
4635    }
4636}
4637
4638// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
4639#[cfg(target_pointer_width = "64")]
4640mod size_asserts {
4641    use rustc_data_structures::static_assert_size;
4642
4643    use super::*;
4644    // tidy-alphabetical-start
4645    static_assert_size!(Block<'_>, 48);
4646    static_assert_size!(Body<'_>, 24);
4647    static_assert_size!(Expr<'_>, 64);
4648    static_assert_size!(ExprKind<'_>, 48);
4649    static_assert_size!(FnDecl<'_>, 40);
4650    static_assert_size!(ForeignItem<'_>, 88);
4651    static_assert_size!(ForeignItemKind<'_>, 56);
4652    static_assert_size!(GenericArg<'_>, 16);
4653    static_assert_size!(GenericBound<'_>, 64);
4654    static_assert_size!(Generics<'_>, 56);
4655    static_assert_size!(Impl<'_>, 80);
4656    static_assert_size!(ImplItem<'_>, 88);
4657    static_assert_size!(ImplItemKind<'_>, 40);
4658    static_assert_size!(Item<'_>, 88);
4659    static_assert_size!(ItemKind<'_>, 56);
4660    static_assert_size!(LetStmt<'_>, 64);
4661    static_assert_size!(Param<'_>, 32);
4662    static_assert_size!(Pat<'_>, 72);
4663    static_assert_size!(Path<'_>, 40);
4664    static_assert_size!(PathSegment<'_>, 48);
4665    static_assert_size!(PatKind<'_>, 48);
4666    static_assert_size!(QPath<'_>, 24);
4667    static_assert_size!(Res, 12);
4668    static_assert_size!(Stmt<'_>, 32);
4669    static_assert_size!(StmtKind<'_>, 16);
4670    static_assert_size!(TraitItem<'_>, 88);
4671    static_assert_size!(TraitItemKind<'_>, 48);
4672    static_assert_size!(Ty<'_>, 48);
4673    static_assert_size!(TyKind<'_>, 32);
4674    // tidy-alphabetical-end
4675}
4676
4677#[cfg(test)]
4678mod tests;