Skip to main content

rustc_middle/hir/
mod.rs

1//! HIR datatypes. See the [rustc dev guide] for more info.
2//!
3//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
4
5pub mod map;
6pub mod nested_filter;
7pub mod place;
8
9use rustc_attr_ir::Attribute;
10use rustc_attr_ir::lang_items::LangItem;
11use rustc_data_structures::fingerprint::Fingerprint;
12use rustc_data_structures::sorted_map::SortedMap;
13use rustc_data_structures::stable_hash::{StableHash, StableHasher};
14use rustc_data_structures::steal::Steal;
15use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
16use rustc_hir::def::{DefKind, Res};
17use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap, LocalModId};
18use rustc_hir::lints::DelayedLints;
19use rustc_hir::*;
20use rustc_macros::{Decodable, Encodable, StableHash};
21use rustc_span::{ErrorGuaranteed, ExpnId, Span, bug, span_bug};
22
23use crate::query::Providers;
24use crate::ty::TyCtxt;
25
26/// Gather the LocalDefId for each item-like within a module, including items contained within
27/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
28#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ModuleItems {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["add_root", "submodules", "free_items", "trait_items",
                        "impl_items", "foreign_items", "opaques", "body_owners",
                        "nested_bodies", "eiis", "proc_macro_decls"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.add_root, &self.submodules, &self.free_items,
                        &self.trait_items, &self.impl_items, &self.foreign_items,
                        &self.opaques, &self.body_owners, &self.nested_bodies,
                        &self.eiis, &&self.proc_macro_decls];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "ModuleItems",
            names, values)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for ModuleItems
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    ModuleItems {
                        add_root: ref __binding_0,
                        submodules: ref __binding_1,
                        free_items: ref __binding_2,
                        trait_items: ref __binding_3,
                        impl_items: ref __binding_4,
                        foreign_items: ref __binding_5,
                        opaques: ref __binding_6,
                        body_owners: ref __binding_7,
                        nested_bodies: ref __binding_8,
                        eiis: ref __binding_9,
                        proc_macro_decls: ref __binding_10 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                        { __binding_8.stable_hash(__hcx, __hasher); }
                        { __binding_9.stable_hash(__hcx, __hasher); }
                        { __binding_10.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for ModuleItems {
            fn encode(&self, __encoder: &mut __E) {
                let ModuleItems {
                        add_root: ref __binding_0,
                        submodules: ref __binding_1,
                        free_items: ref __binding_2,
                        trait_items: ref __binding_3,
                        impl_items: ref __binding_4,
                        foreign_items: ref __binding_5,
                        opaques: ref __binding_6,
                        body_owners: ref __binding_7,
                        nested_bodies: ref __binding_8,
                        eiis: ref __binding_9,
                        proc_macro_decls: ref __binding_10 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_8,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_9,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_10,
                    __encoder);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for ModuleItems {
            fn decode(__decoder: &mut __D) -> Self {
                ModuleItems {
                    add_root: ::rustc_serialize::Decodable::decode(__decoder),
                    submodules: ::rustc_serialize::Decodable::decode(__decoder),
                    free_items: ::rustc_serialize::Decodable::decode(__decoder),
                    trait_items: ::rustc_serialize::Decodable::decode(__decoder),
                    impl_items: ::rustc_serialize::Decodable::decode(__decoder),
                    foreign_items: ::rustc_serialize::Decodable::decode(__decoder),
                    opaques: ::rustc_serialize::Decodable::decode(__decoder),
                    body_owners: ::rustc_serialize::Decodable::decode(__decoder),
                    nested_bodies: ::rustc_serialize::Decodable::decode(__decoder),
                    eiis: ::rustc_serialize::Decodable::decode(__decoder),
                    proc_macro_decls: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
29pub struct ModuleItems {
30    /// Whether this represents the whole crate, in which case we need to add `CRATE_OWNER_ID` to
31    /// the iterators if we want to account for the crate root.
32    add_root: bool,
33    submodules: Box<[LocalModId]>,
34    free_items: Box<[ItemId]>,
35    trait_items: Box<[TraitItemId]>,
36    impl_items: Box<[ImplItemId]>,
37    foreign_items: Box<[ForeignItemId]>,
38    opaques: Box<[LocalDefId]>,
39    body_owners: Box<[LocalDefId]>,
40    nested_bodies: Box<[LocalDefId]>,
41
42    /// Statics and functions with an `EiiImpls` or `EiiExternTarget` attribute
43    eiis: Box<[LocalDefId]>,
44
45    // only filled with hir_crate_items, not with hir_module_items
46    proc_macro_decls: Option<LocalDefId>,
47}
48
49impl ModuleItems {
50    /// Returns all non-associated locally defined items in all modules.
51    ///
52    /// Note that this does *not* include associated items of `impl` blocks! It also does not
53    /// include foreign items. If you want to e.g. get all functions, use `definitions()` below.
54    ///
55    /// However, this does include the `impl` blocks themselves.
56    pub fn free_items(&self) -> impl Iterator<Item = ItemId> {
57        self.free_items.iter().copied()
58    }
59
60    pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> {
61        self.trait_items.iter().copied()
62    }
63
64    #[inline]
65    pub fn proc_macro_decls(&self) -> Option<LocalDefId> {
66        self.proc_macro_decls
67    }
68
69    pub fn eiis(&self) -> impl Iterator<Item = LocalDefId> {
70        self.eiis.iter().copied()
71    }
72
73    /// Returns all items that are associated with some `impl` block (both inherent and trait impl
74    /// blocks).
75    pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
76        self.impl_items.iter().copied()
77    }
78
79    pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> {
80        self.foreign_items.iter().copied()
81    }
82
83    pub fn owners(&self) -> impl Iterator<Item = OwnerId> {
84        self.add_root
85            .then_some(CRATE_OWNER_ID)
86            .into_iter()
87            .chain(self.free_items.iter().map(|id| id.owner_id))
88            .chain(self.trait_items.iter().map(|id| id.owner_id))
89            .chain(self.impl_items.iter().map(|id| id.owner_id))
90            .chain(self.foreign_items.iter().map(|id| id.owner_id))
91    }
92
93    pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> {
94        self.opaques.iter().copied()
95    }
96
97    /// Closures and inline consts
98    pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
99        self.nested_bodies.iter().copied()
100    }
101
102    pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> {
103        self.owners().map(|id| id.def_id)
104    }
105
106    /// Closures and inline consts
107    pub fn par_nested_bodies(
108        &self,
109        f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
110    ) -> Result<(), ErrorGuaranteed> {
111        try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id))
112    }
113
114    pub fn par_items(
115        &self,
116        f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
117    ) -> Result<(), ErrorGuaranteed> {
118        try_par_for_each_in(&self.free_items[..], |&&id| f(id))
119    }
120
121    pub fn par_trait_items(
122        &self,
123        f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
124    ) -> Result<(), ErrorGuaranteed> {
125        try_par_for_each_in(&self.trait_items[..], |&&id| f(id))
126    }
127
128    pub fn par_impl_items(
129        &self,
130        f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
131    ) -> Result<(), ErrorGuaranteed> {
132        try_par_for_each_in(&self.impl_items[..], |&&id| f(id))
133    }
134
135    pub fn par_foreign_items(
136        &self,
137        f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
138    ) -> Result<(), ErrorGuaranteed> {
139        try_par_for_each_in(&self.foreign_items[..], |&&id| f(id))
140    }
141
142    pub fn par_opaques(
143        &self,
144        f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
145    ) -> Result<(), ErrorGuaranteed> {
146        try_par_for_each_in(&self.opaques[..], |&&id| f(id))
147    }
148}
149
150impl<'tcx> TyCtxt<'tcx> {
151    pub fn parent_module(self, id: HirId) -> LocalModId {
152        if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
153            LocalModId::new_unchecked(id.owner.def_id)
154        } else {
155            self.parent_module_from_def_id(id.owner.def_id)
156        }
157    }
158
159    pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalModId {
160        while let Some(parent) = self.opt_local_parent(id) {
161            id = parent;
162            if self.def_kind(id) == DefKind::Mod {
163                break;
164            }
165        }
166        LocalModId::new_unchecked(id)
167    }
168
169    /// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
170    pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
171        self.opt_parent(def_id.into())
172            .is_some_and(|parent| #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(parent) {
    DefKind::ForeignMod => true,
    _ => false,
}matches!(self.def_kind(parent), DefKind::ForeignMod))
173    }
174
175    pub fn hash_owner_nodes(
176        self,
177        node: OwnerNode<'_>,
178        bodies: &SortedMap<ItemLocalId, &Body<'_>>,
179        attrs: &SortedMap<ItemLocalId, &[Attribute]>,
180        define_opaque: Option<&[(Span, LocalDefId)]>,
181    ) -> Hashes {
182        if !self.needs_hir_hash() {
183            return Hashes { bodies_hash: None, attrs_hash: None };
184        }
185
186        self.with_stable_hashing_context(|mut hcx| {
187            let mut stable_hasher = StableHasher::new();
188            node.stable_hash(&mut hcx, &mut stable_hasher);
189            // Bodies are stored out of line, so we need to pull them explicitly in the hash.
190            bodies.stable_hash(&mut hcx, &mut stable_hasher);
191            let h1 = stable_hasher.finish();
192
193            let mut stable_hasher = StableHasher::new();
194            attrs.stable_hash(&mut hcx, &mut stable_hasher);
195
196            // Hash the defined opaque types, which are not present in the attrs.
197            define_opaque.stable_hash(&mut hcx, &mut stable_hasher);
198
199            let h2 = stable_hasher.finish();
200
201            Hashes { bodies_hash: Some(h1), attrs_hash: Some(h2) }
202        })
203    }
204
205    pub fn qpath_is_lang_item(self, qpath: QPath<'_>, lang_item: LangItem) -> bool {
206        self.qpath_lang_item(qpath) == Some(lang_item)
207    }
208
209    /// This does not use typeck results since this is intended to be used with generated code.
210    pub fn qpath_lang_item(self, qpath: QPath<'_>) -> Option<LangItem> {
211        if let QPath::Resolved(_, path) = qpath
212            && let Res::Def(_, def_id) = path.res
213        {
214            return self.lang_items().from_def_id(def_id);
215        }
216        None
217    }
218
219    /// Whether this expression constitutes a read of value of the type that
220    /// it evaluates to.
221    ///
222    /// This is used to determine if we should consider the block to diverge
223    /// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
224    /// coercion for values of type `!`.
225    ///
226    /// This function generally returns `false` if the expression is a place
227    /// expression and the *parent* expression is the scrutinee of a match or
228    /// the pointee of an `&` addr-of expression, since both of those parent
229    /// expressions take a *place* and not a value.
230    pub fn expr_guaranteed_to_constitute_read_for_never(self, expr: &Expr<'_>) -> bool {
231        // We only care about place exprs. Anything else returns an immediate
232        // which would constitute a read. We don't care about distinguishing
233        // "syntactic" place exprs since if the base of a field projection is
234        // not a place then it would've been UB to read from it anyways since
235        // that constitutes a read.
236        if !expr.is_syntactic_place_expr() {
237            return true;
238        }
239
240        let parent_node = self.parent_hir_node(expr.hir_id);
241        match parent_node {
242            Node::Expr(parent_expr) => {
243                match parent_expr.kind {
244                    // Addr-of, field projections, and LHS of assignment don't constitute reads.
245                    // Assignment does call `drop_glue`, though, but its safety requirements are
246                    // not the same.
247                    ExprKind::AddrOf(..) | ExprKind::Field(..) => false,
248
249                    // Place-preserving expressions only constitute reads if their
250                    // parent expression constitutes a read.
251                    ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
252                        self.expr_guaranteed_to_constitute_read_for_never(parent_expr)
253                    }
254
255                    ExprKind::Assign(lhs, _, _) => {
256                        // Only the LHS does not constitute a read
257                        expr.hir_id != lhs.hir_id
258                    }
259
260                    // See note on `PatKind::Or` in `Pat::is_guaranteed_to_constitute_read_for_never`
261                    // for why this is `all`.
262                    ExprKind::Match(scrutinee, arms, _) => {
263                        {
    match (&scrutinee.hir_id, &expr.hir_id) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(scrutinee.hir_id, expr.hir_id);
264                        arms.iter().all(|arm| arm.pat.is_guaranteed_to_constitute_read_for_never())
265                    }
266                    ExprKind::Let(LetExpr { init, pat, .. }) => {
267                        {
    match (&init.hir_id, &expr.hir_id) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(init.hir_id, expr.hir_id);
268                        pat.is_guaranteed_to_constitute_read_for_never()
269                    }
270
271                    // Any expression child of these expressions constitute reads.
272                    ExprKind::Array(_)
273                    | ExprKind::Call(_, _)
274                    | ExprKind::Use(_, _)
275                    | ExprKind::MethodCall(_, _, _, _)
276                    | ExprKind::Tup(_)
277                    | ExprKind::Binary(_, _, _)
278                    | ExprKind::Unary(_, _)
279                    | ExprKind::Cast(_, _)
280                    | ExprKind::DropTemps(_)
281                    | ExprKind::If(_, _, _)
282                    | ExprKind::Closure(_)
283                    | ExprKind::Block(_, _)
284                    | ExprKind::AssignOp(_, _, _)
285                    | ExprKind::Index(_, _, _)
286                    | ExprKind::Break(_, _)
287                    | ExprKind::Ret(_)
288                    | ExprKind::Become(_)
289                    | ExprKind::InlineAsm(_)
290                    | ExprKind::Struct(_, _, _)
291                    | ExprKind::Repeat(_, _)
292                    | ExprKind::Yield(_, _) => true,
293
294                    // These expressions have no (direct) sub-exprs.
295                    ExprKind::ConstBlock(_)
296                    | ExprKind::Loop(_, _, _, _)
297                    | ExprKind::Lit(_)
298                    | ExprKind::Path(_)
299                    | ExprKind::Continue(_)
300                    | ExprKind::OffsetOf(_, _)
301                    | ExprKind::Err(_) => {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("no sub-expr expected for {0:?}", expr.kind)));
}unreachable!("no sub-expr expected for {:?}", expr.kind),
302                }
303            }
304
305            // If we have a subpattern that performs a read, we want to consider this
306            // to diverge for compatibility to support something like `let x: () = *never_ptr;`.
307            Node::LetStmt(LetStmt { init: Some(target), pat, .. }) => {
308                {
    match (&target.hir_id, &expr.hir_id) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(target.hir_id, expr.hir_id);
309                pat.is_guaranteed_to_constitute_read_for_never()
310            }
311
312            // These nodes (if they have a sub-expr) do constitute a read.
313            Node::Block(_)
314            | Node::Arm(_)
315            | Node::ExprField(_)
316            | Node::AnonConst(_)
317            | Node::ConstBlock(_)
318            | Node::ConstArg(_)
319            | Node::Stmt(_)
320            | Node::Item(Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
321            | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
322            | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => true,
323
324            Node::TyPat(_) | Node::Pat(_) => {
325                self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
326                true
327            }
328
329            // These nodes do not have direct sub-exprs.
330            Node::Param(_)
331            | Node::Item(_)
332            | Node::ForeignItem(_)
333            | Node::TraitItem(_)
334            | Node::ImplItem(_)
335            | Node::Variant(_)
336            | Node::Field(_)
337            | Node::PathSegment(_)
338            | Node::Ty(_)
339            | Node::AssocItemConstraint(_)
340            | Node::TraitRef(_)
341            | Node::PatField(_)
342            | Node::PatExpr(_)
343            | Node::LetStmt(_)
344            | Node::Synthetic
345            | Node::Err(_)
346            | Node::Ctor(_)
347            | Node::NestedUseTree(_)
348            | Node::Lifetime(_)
349            | Node::GenericParam(_)
350            | Node::Crate(_)
351            | Node::Infer(_)
352            | Node::WherePredicate(_)
353            | Node::PreciseCapturingNonLifetimeArg(_)
354            | Node::ConstArgExprField(_)
355            | Node::OpaqueTy(_)
356            | Node::TestBinderForall(_)
357            | Node::TestBinderExists(_)
358            | Node::TestBinderBoundTypeConstraint(_) => {
359                {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("no sub-expr expected for {0:?}", parent_node)));
}unreachable!("no sub-expr expected for {parent_node:?}")
360            }
361        }
362    }
363
364    #[inline]
365    fn hir_owner_parent_impl(self, owner_id: OwnerId) -> HirId {
366        self.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
367            let parent_owner_id = self.local_def_id_to_hir_id(parent_def_id).owner;
368            HirId {
369                owner: parent_owner_id,
370                local_id: self
371                    .hir_owner(parent_owner_id.def_id)
372                    .unwrap()
373                    .parenting
374                    .get(&owner_id.def_id)
375                    .copied()
376                    .unwrap_or(ItemLocalId::ZERO),
377            }
378        })
379    }
380
381    /// Optimization of `hir_owner_parent` query as an inlined function
382    /// in case of non-incremental build. The query itself renamed to `hir_owner_parent_q`.
383    #[inline]
384    pub fn hir_owner_parent(self, owner_id: OwnerId) -> HirId {
385        if self.dep_graph.is_fully_enabled() {
386            self.hir_owner_parent_q(owner_id)
387        } else {
388            self.hir_owner_parent_impl(owner_id)
389        }
390    }
391}
392
393/// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary.
394#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Hashes { }
#[automatically_derived]
impl ::core::clone::Clone for Hashes {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Option<Fingerprint>>;
        let _: ::core::clone::AssertParamIsClone<Option<Fingerprint>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Hashes { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Hashes {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Hashes",
            "bodies_hash", &self.bodies_hash, "attrs_hash", &&self.attrs_hash)
    }
}Debug)]
395pub struct Hashes {
396    pub bodies_hash: Option<Fingerprint>,
397    pub attrs_hash: Option<Fingerprint>,
398}
399
400/// Unites some of `OwnerInfo`'s fields into same struct that is used by `hir_owner` query.
401/// `AttributeMap` is handled separately as placing it in this struct led to perf regressions:
402/// <https://github.com/rust-lang/rust/pull/155678#issuecomment-4304597871>.
403/// This struct is created mainly for uniting/splitting fields of `OwnerInfo` so they are
404/// stored/invalidated together in incremental compilation.
405/// For comments about each field see `OwnerInfo` struct.
406#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for ProjectedOwnerInfo<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ProjectedOwnerInfo<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'tcx OwnerNodes<'tcx>>;
        let _:
                ::core::clone::AssertParamIsClone<&'tcx LocalDefIdMap<ItemLocalId>>;
        let _:
                ::core::clone::AssertParamIsClone<&'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>>;
        let _: ::core::clone::AssertParamIsClone<&'tcx Steal<DelayedLints>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ProjectedOwnerInfo<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ProjectedOwnerInfo<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "ProjectedOwnerInfo", "nodes", &self.nodes, "parenting",
            &self.parenting, "trait_map", &self.trait_map, "delayed_lints",
            &&self.delayed_lints)
    }
}Debug, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            ProjectedOwnerInfo<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    ProjectedOwnerInfo {
                        nodes: ref __binding_0,
                        parenting: ref __binding_1,
                        trait_map: ref __binding_2,
                        delayed_lints: ref __binding_3 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        {}
                    }
                }
            }
        }
    };StableHash)]
407pub struct ProjectedOwnerInfo<'tcx> {
408    nodes: &'tcx OwnerNodes<'tcx>,
409    parenting: &'tcx LocalDefIdMap<ItemLocalId>,
410    trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>,
411
412    #[stable_hash(ignore)]
413    delayed_lints: &'tcx Steal<DelayedLints>,
414}
415
416impl<'tcx> ProjectedOwnerInfo<'tcx> {
417    pub fn new(
418        nodes: &'tcx OwnerNodes<'tcx>,
419        parenting: &'tcx LocalDefIdMap<ItemLocalId>,
420        trait_map: &'tcx ItemLocalMap<&'tcx [TraitCandidate<'tcx>]>,
421        delayed_lints: &'tcx Steal<DelayedLints>,
422    ) -> ProjectedOwnerInfo<'tcx> {
423        ProjectedOwnerInfo { nodes, parenting, trait_map, delayed_lints }
424    }
425}
426
427#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for ProjectedMaybeOwner<'tcx> {
}
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ProjectedMaybeOwner<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<ProjectedOwnerInfo<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<HirId>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ProjectedMaybeOwner<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ProjectedMaybeOwner<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Owner(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Owner",
                    &__self_0),
            Self::NonOwner(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "NonOwner", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
            ProjectedMaybeOwner<'tcx> {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    ProjectedMaybeOwner::Owner(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ProjectedMaybeOwner::NonOwner(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
428pub enum ProjectedMaybeOwner<'tcx> {
429    Owner(ProjectedOwnerInfo<'tcx>),
430    NonOwner(HirId),
431}
432
433impl<'tcx> ProjectedMaybeOwner<'tcx> {
434    pub fn new(value: MaybeOwner<'tcx>) -> Self {
435        match value {
436            MaybeOwner::Owner(o) => ProjectedMaybeOwner::Owner(ProjectedOwnerInfo {
437                nodes: &o.nodes,
438                parenting: &o.parenting,
439                trait_map: &o.trait_map,
440                delayed_lints: &o.delayed_lints,
441            }),
442            MaybeOwner::NonOwner(hir_id) => ProjectedMaybeOwner::NonOwner(hir_id),
443        }
444    }
445
446    pub fn as_owner(&self) -> Option<&ProjectedOwnerInfo<'tcx>> {
447        match self {
448            ProjectedMaybeOwner::Owner(i) => Some(i),
449            ProjectedMaybeOwner::NonOwner(_) => None,
450        }
451    }
452
453    pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> {
454        self.as_owner().unwrap_or_else(|| { ::core::panicking::panic_fmt(format_args!("Not a HIR owner")); }panic!("Not a HIR owner"))
455    }
456}
457
458pub fn provide(providers: &mut Providers) {
459    providers.hir_crate_items = map::hir_crate_items;
460    providers.crate_hash = map::crate_hash;
461    providers.hir_module_items = map::hir_module_items;
462    providers.hir_attr_map =
463        |tcx, id| tcx.lower_to_hir(id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs);
464    providers.hir_owner = |tcx, def_id| ProjectedMaybeOwner::new(tcx.lower_to_hir(def_id));
465    providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id);
466    providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id));
467    providers.def_ident_span = |tcx, def_id| {
468        let hir_id = tcx.local_def_id_to_hir_id(def_id);
469        tcx.hir_opt_ident_span(hir_id)
470    };
471    providers.ty_span = |tcx, def_id| {
472        let node = tcx.hir_node_by_def_id(def_id);
473        match node.ty() {
474            Some(ty) => ty.span,
475            None => ::rustc_span::macros::bug_impl(None,
    format_args!("{0:?} doesn\'t have a type: {1:#?}", def_id, node),
    Location::caller())bug!("{def_id:?} doesn't have a type: {node:#?}"),
476        }
477    };
478    providers.fn_arg_idents = |tcx, def_id| {
479        let node = tcx.hir_node_by_def_id(def_id);
480        if let Some(body_id) = node.body_id() {
481            tcx.arena.alloc_from_iter(tcx.hir_body_param_idents(body_id))
482        } else if let Node::TraitItem(&TraitItem {
483            kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
484            ..
485        })
486        | Node::ForeignItem(&ForeignItem {
487            kind: ForeignItemKind::Fn(_, idents, _),
488            ..
489        }) = node
490        {
491            idents
492        } else {
493            ::rustc_span::macros::bug_impl(Some(tcx.hir_span(tcx.local_def_id_to_hir_id(def_id))),
    format_args!("fn_arg_idents: unexpected item {0:?}", def_id),
    Location::caller());span_bug!(
494                tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)),
495                "fn_arg_idents: unexpected item {:?}",
496                def_id
497            );
498        }
499    };
500    providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;
501    providers.local_trait_impls =
502        |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]);
503    providers.expn_that_defined =
504        |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root());
505}