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