//!
//! # The rustc Query System: Query Definitions and Modifiers
//!
//! The core processes in rustc are shipped as queries. Each query is a demand-driven function from some key to a value.
//! The execution result of the function is cached and directly read during the next request, thereby improving compilation efficiency.
//! Some results are saved locally and directly read during the next compilation, which are core of incremental compilation.
//!
//! ## How to Read This Module
//!
//! Each `query` block in this file defines a single query, specifying its key and value types, along with various modifiers.
//! These query definitions are processed by the [`rustc_macros`], which expands them into the necessary boilerplate code
//! for the query system—including the [`Providers`] struct (a function table for all query implementations, where each field is
//! a function pointer to the actual provider), caching, and dependency graph integration.
//! **Note:** The `Providers` struct is not a Rust trait, but a struct generated by the `rustc_macros` to hold all provider functions.
//! The `rustc_macros` also supports a set of **query modifiers** (see below) that control the behavior of each query.
//!
//! The actual provider functions are implemented in various modules and registered into the `Providers` struct
//! during compiler initialization (see [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]).
//!
//! [`rustc_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/index.html
//! [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]: ../../rustc_interface/passes/static.DEFAULT_QUERY_PROVIDERS.html
//!
//! ## Query Modifiers
//!
//! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros`
//! The main modifiers are:
//!
//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query.
//! - `arena_cache`: Use an arena for in-memory caching of the query result.
//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true.
//! - `fatal_cycle`: If a dependency cycle is detected, abort compilation with a fatal error.
//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
//! - `depth_limit`: Impose a recursion depth limit on the query to prevent stack overflows.
//! - `separate_provide_extern`: Use separate provider functions for local and external crates.
//! - `feedable`: Allow the query result to be set from another query ("fed" externally).
//! - `return_result_from_ensure_ok`: When called via `tcx.ensure_ok()`, return `Result<(), ErrorGuaranteed>` instead of `()`.
//!   If the query needs to be executed and returns an error, the error is returned to the caller.
//!   Only valid for queries returning `Result<_, ErrorGuaranteed>`.
//!
//! For the up-to-date list, see the `QueryModifiers` struct in
//! [`rustc_macros/src/query.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_macros/src/query.rs)
//! and for more details in incremental compilation, see the
//! [Query modifiers in incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation-in-detail.html#query-modifiers) section of the rustc-dev-guide.
//!
//! ## Query Expansion and Code Generation
//!
//! The [`rustc_macros::rustc_queries`] macro expands each query definition into:
//! - A method on [`TyCtxt`] (and [`TyCtxtAt`]) for invoking the query.
//! - Provider traits and structs for supplying the query's value.
//! - Caching and dependency graph integration.
//! - Support for incremental compilation, disk caching, and arena allocation as controlled by the modifiers.
//!
//! [`rustc_macros::rustc_queries`]: ../../rustc_macros/macro.rustc_queries.html
//!
//! The macro-based approach allows the query system to be highly flexible and maintainable, while minimizing boilerplate.
//!
//! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html).

#![allow(unused_parens)]

use std::ffi::OsStr;
use std::mem;
use std::path::PathBuf;
use std::sync::Arc;

use rustc_abi::Align;
use rustc_arena::TypedArena;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::attrs::StrippedCfgItem;
use rustc_hir::def::{DefKind, DocLinkResMap};
use rustc_hir::def_id::{
    CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate};
use rustc_index::IndexVec;
use rustc_lint_defs::LintId;
use rustc_macros::rustc_queries;
use rustc_query_system::ich::StableHashingContext;
use rustc_query_system::query::{QueryMode, QueryStackDeferred, QueryState};
use rustc_session::Limits;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::cstore::{
    CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib,
};
use rustc_session::lint::LintExpectationId;
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, Span, Symbol};
use rustc_target::spec::{PanicStrategy, SanitizerSet};
use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir};

pub use self::keys::{AsLocalKey, Key, LocalCrate};
pub use self::plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk};
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintExpectation;
use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::middle::deduced_param_attrs::DeducedParamAttrs;
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::EffectiveVisibilities;
use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
use crate::middle::stability::DeprecationEntry;
use crate::mir::interpret::{
    EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
    EvalToValTreeResult, GlobalId, LitToConstInput,
};
use crate::mir::mono::{
    CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono,
};
use crate::query::erase::{Erase, erase, restore};
use crate::query::plumbing::{CyclePlaceholder, DynamicQuery};
use crate::traits::query::{
    CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
    CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
    CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint,
    DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
    OutlivesBound,
};
use crate::traits::{
    CodegenObligationError, DynCompatibilityViolation, EvaluationResult, ImplSource,
    ObligationCause, OverflowError, WellFormedLoc, solve, specialization_graph,
};
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::layout::ValidityRequirement;
use crate::ty::print::PrintTraitRefExt;
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{
    self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, SizedTraitKind, Ty,
    TyCtxt, TyCtxtFeed,
};
use crate::{dep_graph, mir, thir};

mod arena_cached;
pub mod erase;
pub(crate) mod inner;
mod keys;
pub mod on_disk_cache;
#[macro_use]
pub mod plumbing;

// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
// which memoizes and does dep-graph tracking, wrapping around the actual
// `Providers` that the driver creates (using several `rustc_*` crates).
//
// The result type of each query must implement `Clone`, and additionally
// `ty::query::values::Value`, which produces an appropriate placeholder
// (error) value if the query resulted in a query cycle.
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.
rustc_queries! {
    /// This exists purely for testing the interactions between delayed bugs and incremental.
    query trigger_delayed_bug(key: DefId) {
        desc { "triggering a delayed bug for testing incremental" }
    }

    /// Collects the list of all tools registered using `#![register_tool]`.
    query registered_tools(_: ()) -> &'tcx ty::RegisteredTools {
        arena_cache
        desc { "compute registered tools for crate" }
    }

    query early_lint_checks(_: ()) {
        desc { "perform lints prior to AST lowering" }
    }

    /// Tracked access to environment variables.
    ///
    /// Useful for the implementation of `std::env!`, `proc-macro`s change
    /// detection and other changes in the compiler's behaviour that is easier
    /// to control with an environment variable than a flag.
    ///
    /// NOTE: This currently does not work with dependency info in the
    /// analysis, codegen and linking passes, place extra code at the top of
    /// `rustc_interface::passes::write_dep_info` to make that work.
    query env_var_os(key: &'tcx OsStr) -> Option<&'tcx OsStr> {
        // Environment variables are global state
        eval_always
        desc { "get the value of an environment variable" }
    }

    query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt {
        desc { "getting the resolver outputs" }
    }

    query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)>, &'tcx ty::ResolverGlobalCtxt) {
        eval_always
        no_hash
        desc { "getting the resolver for lowering" }
    }

    /// Return the span for a definition.
    ///
    /// Contrary to `def_span` below, this query returns the full absolute span of the definition.
    /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside
    /// of rustc_middle::hir::source_map.
    query source_span(key: LocalDefId) -> Span {
        // Accesses untracked data
        eval_always
        desc { "getting the source span" }
    }

    /// Represents crate as a whole (as distinct from the top-level crate module).
    ///
    /// If you call `tcx.hir_crate(())` we will have to assume that any change
    /// means that you need to be recompiled. This is because the `hir_crate`
    /// query gives you access to all other items. To avoid this fate, do not
    /// call `tcx.hir_crate(())`; instead, prefer wrappers like
    /// [`TyCtxt::hir_visit_all_item_likes_in_crate`].
    query hir_crate(key: ()) -> &'tcx Crate<'tcx> {
        arena_cache
        eval_always
        desc { "getting the crate HIR" }
    }

    /// All items in the crate.
    query hir_crate_items(_: ()) -> &'tcx rustc_middle::hir::ModuleItems {
        arena_cache
        eval_always
        desc { "getting HIR crate items" }
    }

    /// The items in a module.
    ///
    /// This can be conveniently accessed by `tcx.hir_visit_item_likes_in_module`.
    /// Avoid calling this query directly.
    query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems {
        arena_cache
        desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { true }
    }

    /// Returns HIR ID for the given `LocalDefId`.
    query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
        desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) }
        feedable
    }

    /// Gives access to the HIR node's parent for the HIR owner `key`.
    ///
    /// This can be conveniently accessed by `tcx.hir_*` methods.
    /// Avoid calling this query directly.
    query hir_owner_parent(key: hir::OwnerId) -> hir::HirId {
        desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) }
    }

    /// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner.
    ///
    /// This can be conveniently accessed by `tcx.hir_*` methods.
    /// Avoid calling this query directly.
    query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
        desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) }
        feedable
    }

    /// Gives access to the HIR attributes inside the HIR owner `key`.
    ///
    /// This can be conveniently accessed by `tcx.hir_*` methods.
    /// Avoid calling this query directly.
    query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
        desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) }
        feedable
    }

    /// Gives access to lints emitted during ast lowering.
    ///
    /// This can be conveniently accessed by `tcx.hir_*` methods.
    /// Avoid calling this query directly.
    query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx hir::lints::DelayedLints> {
        desc { |tcx| "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) }
    }

    /// Returns the *default* of the const pararameter given by `DefId`.
    ///
    /// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`.
    query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> {
        desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param)  }
        cache_on_disk_if { param.is_local() }
        separate_provide_extern
    }

    /// Returns the *type* of the definition given by `DefId`.
    ///
    /// For type aliases (whether eager or lazy) and associated types, this returns
    /// the underlying aliased type (not the corresponding [alias type]).
    ///
    /// For opaque types, this returns and thus reveals the hidden type! If you
    /// want to detect cycle errors use `type_of_opaque` instead.
    ///
    /// To clarify, for type definitions, this does *not* return the "type of a type"
    /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns
    /// the type primarily *associated with* it.
    ///
    /// # Panics
    ///
    /// This query will panic if the given definition doesn't (and can't
    /// conceptually) have an (underlying) type.
    ///
    /// [alias type]: rustc_middle::ty::AliasTy
    query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
        desc { |tcx|
            "{action} `{path}`",
            action = match tcx.def_kind(key) {
                DefKind::TyAlias => "expanding type alias",
                DefKind::TraitAlias => "expanding trait alias",
                _ => "computing type of",
            },
            path = tcx.def_path_str(key),
        }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred.
    ///
    /// This is a specialized instance of [`Self::type_of`] that detects query cycles.
    /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead.
    /// This is used to improve the error message in cases where revealing the hidden type
    /// for auto-trait leakage cycles.
    ///
    /// # Panics
    ///
    /// This query will panic if the given definition is not an opaque type.
    query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> {
        desc { |tcx|
            "computing type of opaque `{path}`",
            path = tcx.def_path_str(key),
        }
        cycle_stash
    }
    query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
        desc { |tcx|
            "computing type of opaque `{path}` via HIR typeck",
            path = tcx.def_path_str(key),
        }
    }

    /// Returns whether the type alias given by `DefId` is lazy.
    ///
    /// I.e., if the type alias expands / ought to expand to a [free] [alias type]
    /// instead of the underlying aliased type.
    ///
    /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`.
    ///
    /// # Panics
    ///
    /// This query *may* panic if the given definition is not a type alias.
    ///
    /// [free]: rustc_middle::ty::Free
    /// [alias type]: rustc_middle::ty::AliasTy
    query type_alias_is_lazy(key: DefId) -> bool {
        desc { |tcx|
            "computing whether the type alias `{path}` is lazy",
            path = tcx.def_path_str(key),
        }
        separate_provide_extern
    }

    query collect_return_position_impl_trait_in_trait_tys(key: DefId)
        -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed>
    {
        desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    query opaque_ty_origin(key: DefId) -> hir::OpaqueTyOrigin<DefId>
    {
        desc { "determine where the opaque originates from" }
        separate_provide_extern
    }

    query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32>
    {
        arena_cache
        desc { |tcx|
            "determining what parameters of `{}` can participate in unsizing",
            tcx.def_path_str(key),
        }
    }

    /// The root query triggering all analysis passes like typeck or borrowck.
    query analysis(key: ()) {
        eval_always
        desc { |tcx|
            "running analysis passes on crate `{}`",
            tcx.crate_name(LOCAL_CRATE),
        }
    }

    /// This query checks the fulfillment of collected lint expectations.
    /// All lint emitting queries have to be done before this is executed
    /// to ensure that all expectations can be fulfilled.
    ///
    /// This is an extra query to enable other drivers (like rustdoc) to
    /// only execute a small subset of the `analysis` query, while allowing
    /// lints to be expected. In rustc, this query will be executed as part of
    /// the `analysis` query and doesn't have to be called a second time.
    ///
    /// Tools can additionally pass in a tool filter. That will restrict the
    /// expectations to only trigger for lints starting with the listed tool
    /// name. This is useful for cases were not all linting code from rustc
    /// was called. With the default `None` all registered lints will also
    /// be checked for expectation fulfillment.
    query check_expectations(key: Option<Symbol>) {
        eval_always
        desc { "checking lint expectations (RFC 2383)" }
    }

    /// Returns the *generics* of the definition given by `DefId`.
    query generics_of(key: DefId) -> &'tcx ty::Generics {
        desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) }
        arena_cache
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the (elaborated) *predicates* of the definition given by `DefId`
    /// that must be proven true at usage sites (and which can be assumed at definition site).
    ///
    /// This is almost always *the* "predicates query" that you want.
    ///
    /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print
    /// the result of this query for use in UI tests or for debugging purposes.
    query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
        desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
    }

    query opaque_types_defined_by(
        key: LocalDefId
    ) -> &'tcx ty::List<LocalDefId> {
        desc {
            |tcx| "computing the opaque types defined by `{}`",
            tcx.def_path_str(key.to_def_id())
        }
    }

    /// A list of all bodies inside of `key`, nested bodies are always stored
    /// before their parent.
    query nested_bodies_within(
        key: LocalDefId
    ) -> &'tcx ty::List<LocalDefId> {
        desc {
            |tcx| "computing the coroutines defined within `{}`",
            tcx.def_path_str(key.to_def_id())
        }
    }

    /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId`
    /// that must be proven true at definition site (and which can be assumed at usage sites).
    ///
    /// For associated types, these must be satisfied for an implementation
    /// to be well-formed, and for opaque types, these are required to be
    /// satisfied by the hidden type of the opaque.
    ///
    /// Bounds from the parent (e.g. with nested `impl Trait`) are not included.
    ///
    /// Syntactially, these are the bounds written on associated types in trait
    /// definitions, or those after the `impl` keyword for an opaque:
    ///
    /// ```ignore (illustrative)
    /// trait Trait { type X: Bound + 'lt; }
    /// //                    ^^^^^^^^^^^
    /// fn function() -> impl Debug + Display { /*...*/ }
    /// //                    ^^^^^^^^^^^^^^^
    /// ```
    query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the explicitly user-written *bounds* that share the `Self` type of the item.
    ///
    /// These are a subset of the [explicit item bounds] that may explicitly be used for things
    /// like closure signature deduction.
    ///
    /// [explicit item bounds]: Self::explicit_item_bounds
    query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId`
    /// that must be proven true at definition site (and which can be assumed at usage sites).
    ///
    /// Bounds from the parent (e.g. with nested `impl Trait`) are not included.
    ///
    /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print
    /// the result of this query for use in UI tests or for debugging purposes.
    ///
    /// # Examples
    ///
    /// ```
    /// trait Trait { type Assoc: Eq + ?Sized; }
    /// ```
    ///
    /// While [`Self::explicit_item_bounds`] returns `[<Self as Trait>::Assoc: Eq]`
    /// here, `item_bounds` returns:
    ///
    /// ```text
    /// [
    ///     <Self as Trait>::Assoc: Eq,
    ///     <Self as Trait>::Assoc: PartialEq<<Self as Trait>::Assoc>
    /// ]
    /// ```
    query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
        desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
    }

    query item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
        desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
    }

    query item_non_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
        desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
    }

    query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
        desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) }
    }

    /// Look up all native libraries this crate depends on.
    /// These are assembled from the following places:
    /// - `extern` blocks (depending on their `link` attributes)
    /// - the `libs` (`-l`) option
    query native_libraries(_: CrateNum) -> &'tcx Vec<NativeLib> {
        arena_cache
        desc { "looking up the native libraries of a linked crate" }
        separate_provide_extern
    }

    query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap {
        arena_cache
        desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) }
    }

    query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> {
        arena_cache
        desc { "computing `#[expect]`ed lints in this crate" }
    }

    query lints_that_dont_need_to_run(_: ()) -> &'tcx UnordSet<LintId> {
        arena_cache
        desc { "Computing all lints that are explicitly enabled or with a default level greater than Allow" }
    }

    query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
        desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) }
        separate_provide_extern
    }

    query is_panic_runtime(_: CrateNum) -> bool {
        fatal_cycle
        desc { "checking if the crate is_panic_runtime" }
        separate_provide_extern
    }

    /// Checks whether a type is representable or infinitely sized
    query representability(_: LocalDefId) -> rustc_middle::ty::Representability {
        desc { "checking if `{}` is representable", tcx.def_path_str(key) }
        // infinitely sized types will cause a cycle
        cycle_delay_bug
        // we don't want recursive representability calls to be forced with
        // incremental compilation because, if a cycle occurs, we need the
        // entire cycle to be in memory for diagnostics
        anon
    }

    /// An implementation detail for the `representability` query
    query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability {
        desc { "checking if `{}` is representable", key }
        cycle_delay_bug
        anon
    }

    /// Set of param indexes for type params that are in the type's representation
    query params_in_repr(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> {
        desc { "finding type parameters in the representation" }
        arena_cache
        no_hash
        separate_provide_extern
    }

    /// Fetch the THIR for a given body. The THIR body gets stolen by unsafety checking unless
    /// `-Zno-steal-thir` is on.
    query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
        // Perf tests revealed that hashing THIR is inefficient (see #85729).
        no_hash
        desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) }
    }

    /// Set of all the `DefId`s in this crate that have MIR associated with
    /// them. This includes all the body owners, but also things like struct
    /// constructors.
    query mir_keys(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexSet<LocalDefId> {
        arena_cache
        desc { "getting a list of all mir_keys" }
    }

    /// Maps DefId's that have an associated `mir::Body` to the result
    /// of the MIR const-checking pass. This is the set of qualifs in
    /// the final value of a `const`.
    query mir_const_qualif(key: DefId) -> mir::ConstQualifs {
        desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// Build the MIR for a given `DefId` and prepare it for const qualification.
    ///
    /// See the [rustc dev guide] for more info.
    ///
    /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html
    query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
        desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) }
        feedable
    }

    /// Try to build an abstract representation of the given constant.
    query thir_abstract_const(
        key: DefId
    ) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> {
        desc {
            |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
        }
        separate_provide_extern
    }

    query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
        no_hash
        desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) }
    }

    query mir_for_ctfe(
        key: DefId
    ) -> &'tcx mir::Body<'tcx> {
        desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    query mir_promoted(key: LocalDefId) -> (
        &'tcx Steal<mir::Body<'tcx>>,
        &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
    ) {
        no_hash
        desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) }
    }

    query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> {
        desc {
            |tcx| "finding symbols for captures of closure `{}`",
            tcx.def_path_str(key)
        }
    }

    /// Returns names of captured upvars for closures and coroutines.
    ///
    /// Here are some examples:
    ///  - `name__field1__field2` when the upvar is captured by value.
    ///  - `_ref__name__field` when the upvar is captured by reference.
    ///
    /// For coroutines this only contains upvars that are shared by all states.
    query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec<abi::FieldIdx, Symbol> {
        arena_cache
        desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> {
        arena_cache
        desc { |tcx| "coroutine witness types for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    /// Used in case `mir_borrowck` fails to prove an obligation. We generally assume that
    /// all goals we prove in MIR type check hold as we've already checked them in HIR typeck.
    ///
    /// However, we replace each free region in the MIR body with a unique region inference
    /// variable. As we may rely on structural identity when proving goals this may cause a
    /// goal to no longer hold. We store obligations for which this may happen during HIR
    /// typeck in the `TypeckResults`. We then uniquify and reprove them in case MIR typeck
    /// encounters an unexpected error. We expect this to result in an error when used and
    /// delay a bug if it does not.
    query check_potentially_region_dependent_goals(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc {
            |tcx| "reproving potentially region dependent HIR typeck goals for `{}",
            tcx.def_path_str(key)
        }
    }

    /// MIR after our optimization passes have run. This is MIR that is ready
    /// for codegen. This is also the only query that can fetch non-local MIR, at present.
    query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> {
        desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on
    /// this def and any enclosing defs, up to the crate root.
    ///
    /// Returns `false` if `#[coverage(off)]` was found, or `true` if
    /// either `#[coverage(on)]` or no coverage attribute was found.
    query coverage_attr_on(key: LocalDefId) -> bool {
        desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) }
        feedable
    }

    /// Scans through a function's MIR after MIR optimizations, to prepare the
    /// information needed by codegen when `-Cinstrument-coverage` is active.
    ///
    /// This includes the details of where to insert `llvm.instrprof.increment`
    /// intrinsics, and the expression tables to be embedded in the function's
    /// coverage metadata.
    ///
    /// FIXME(Zalathar): This query's purpose has drifted a bit and should
    /// probably be renamed, but that can wait until after the potential
    /// follow-ups to #136053 have settled down.
    ///
    /// Returns `None` for functions that were not instrumented.
    query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> {
        desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
        arena_cache
    }

    /// The `DefId` is the `DefId` of the containing MIR body. Promoteds do not have their own
    /// `DefId`. This function returns all promoteds in the specified body. The body references
    /// promoteds by the `DefId` and the `mir::Promoted` index. This is necessary, because
    /// after inlining a body may refer to promoteds from other bodies. In that case you still
    /// need to use the `DefId` of the original body.
    query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
        desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// Erases regions from `ty` to yield a new type.
    /// Normally you would just use `tcx.erase_and_anonymize_regions(value)`,
    /// however, which uses this query as a kind of cache.
    query erase_and_anonymize_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
        // This query is not expected to have input -- as a result, it
        // is not a good candidates for "replay" because it is essentially a
        // pure function of its input (and hence the expectation is that
        // no caller would be green **apart** from just these
        // queries). Making it anonymous avoids hashing the result, which
        // may save a bit of time.
        anon
        desc { "erasing regions from `{}`", ty }
    }

    query wasm_import_module_map(_: CrateNum) -> &'tcx DefIdMap<String> {
        arena_cache
        desc { "getting wasm import module map" }
    }

    /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`.
    ///
    /// Traits are unusual, because predicates on associated types are
    /// converted into bounds on that type for backwards compatibility:
    ///
    /// ```
    /// trait X where Self::U: Copy { type U; }
    /// ```
    ///
    /// becomes
    ///
    /// ```
    /// trait X { type U: Copy; }
    /// ```
    ///
    /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will
    /// then take the appropriate subsets of the predicates here.
    ///
    /// # Panics
    ///
    /// This query will panic if the given definition is not a trait.
    query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> {
        desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) }
    }

    /// Returns the explicitly user-written *predicates* of the definition given by `DefId`
    /// that must be proven true at usage sites (and which can be assumed at definition site).
    ///
    /// You should probably use [`Self::predicates_of`] unless you're looking for
    /// predicates with explicit spans for diagnostics purposes.
    query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
        desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the *inferred outlives-predicates* of the item given by `DefId`.
    ///
    /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`.
    ///
    /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the
    /// result of this query for use in UI tests or for debugging purposes.
    query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] {
        desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`.
    ///
    /// These predicates are unelaborated and consequently don't contain transitive super-predicates.
    ///
    /// This is a subset of the full list of predicates. We store these in a separate map
    /// because we must evaluate them even during type conversion, often before the full
    /// predicates are available (note that super-predicates must not be cyclic).
    query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// The predicates of the trait that are implied during elaboration.
    ///
    /// This is a superset of the super-predicates of the trait, but a subset of the predicates
    /// of the trait. For regular traits, this includes all super-predicates and their
    /// associated type bounds. For trait aliases, currently, this includes all of the
    /// predicates of the trait alias.
    query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// The Ident is the name of an associated type.The query returns only the subset
    /// of supertraits that define the given associated type. This is used to avoid
    /// cycles in resolving type-dependent associated item paths like `T::Item`.
    query explicit_supertraits_containing_assoc_item(
        key: (DefId, rustc_span::Ident)
    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "computing the super traits of `{}` with associated type name `{}`",
            tcx.def_path_str(key.0),
            key.1
        }
    }

    /// Compute the conditions that need to hold for a conditionally-const item to be const.
    /// That is, compute the set of `[const]` where clauses for a given item.
    ///
    /// This can be thought of as the `[const]` equivalent of `predicates_of`. These are the
    /// predicates that need to be proven at usage sites, and can be assumed at definition.
    ///
    /// This query also computes the `[const]` where clauses for associated types, which are
    /// not "const", but which have item bounds which may be `[const]`. These must hold for
    /// the `[const]` item bound to hold.
    query const_conditions(
        key: DefId
    ) -> ty::ConstConditions<'tcx> {
        desc { |tcx| "computing the conditions for `{}` to be considered const",
            tcx.def_path_str(key)
        }
        separate_provide_extern
    }

    /// Compute the const bounds that are implied for a conditionally-const item.
    ///
    /// This can be though of as the `[const]` equivalent of `explicit_item_bounds`. These
    /// are the predicates that need to proven at definition sites, and can be assumed at
    /// usage sites.
    query explicit_implied_const_bounds(
        key: DefId
    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
        desc { |tcx| "computing the implied `[const]` bounds for `{}`",
            tcx.def_path_str(key)
        }
        separate_provide_extern
    }

    /// To avoid cycles within the predicates of a single item we compute
    /// per-type-parameter predicates for resolving `T::AssocTy`.
    query type_param_predicates(
        key: (LocalDefId, LocalDefId, rustc_span::Ident)
    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
        desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) }
    }

    query trait_def(key: DefId) -> &'tcx ty::TraitDef {
        desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) }
        arena_cache
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }
    query adt_def(key: DefId) -> ty::AdtDef<'tcx> {
        desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }
    query adt_destructor(key: DefId) -> Option<ty::Destructor> {
        desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }
    query adt_async_destructor(key: DefId) -> Option<ty::AsyncDestructor> {
        desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }
    query adt_sizedness_constraint(
        key: (DefId, SizedTraitKind)
    ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
        desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) }
    }

    query adt_dtorck_constraint(
        key: DefId
    ) -> &'tcx DropckConstraint<'tcx> {
        desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
    }

    /// Returns the constness of the function-like[^1] definition given by `DefId`.
    ///
    /// Tuple struct/variant constructors are *always* const, foreign functions are
    /// *never* const. The rest is const iff marked with keyword `const` (or rather
    /// its parent in the case of associated functions).
    ///
    /// <div class="warning">
    ///
    /// **Do not call this query** directly. It is only meant to cache the base data for the
    /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead.
    ///
    /// Also note that neither of them takes into account feature gates, stability and
    /// const predicates/conditions!
    ///
    /// </div>
    ///
    /// # Panics
    ///
    /// This query will panic if the given definition is not function-like[^1].
    ///
    /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions.
    query constness(key: DefId) -> hir::Constness {
        desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) }
        separate_provide_extern
        feedable
    }

    query asyncness(key: DefId) -> ty::Asyncness {
        desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
        separate_provide_extern
    }

    /// Returns `true` if calls to the function may be promoted.
    ///
    /// This is either because the function is e.g., a tuple-struct or tuple-variant
    /// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should
    /// be removed in the future in favour of some form of check which figures out whether the
    /// function does not inspect the bits of any of its arguments (so is essentially just a
    /// constructor function).
    query is_promotable_const_fn(key: DefId) -> bool {
        desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) }
    }

    /// The body of the coroutine, modified to take its upvars by move rather than by ref.
    ///
    /// This is used by coroutine-closures, which must return a different flavor of coroutine
    /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which
    /// is run right after building the initial MIR, and will only be populated for coroutines
    /// which come out of the async closure desugaring.
    query coroutine_by_move_body_def_id(def_id: DefId) -> DefId {
        desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine.
    query coroutine_kind(def_id: DefId) -> Option<hir::CoroutineKind> {
        desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
        feedable
    }

    query coroutine_for_closure(def_id: DefId) -> DefId {
        desc { |_tcx| "Given a coroutine-closure def id, return the def id of the coroutine returned by it" }
        separate_provide_extern
    }

    query coroutine_hidden_types(
        def_id: DefId,
    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
        desc { "looking up the hidden types stored across await points in a coroutine" }
    }

    /// Gets a map with the variances of every item in the local crate.
    ///
    /// <div class="warning">
    ///
    /// **Do not call this query** directly, use [`Self::variances_of`] instead.
    ///
    /// </div>
    query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> {
        arena_cache
        desc { "computing the variances for items in this crate" }
    }

    /// Returns the (inferred) variances of the item given by `DefId`.
    ///
    /// The list of variances corresponds to the list of (early-bound) generic
    /// parameters of the item (including its parents).
    ///
    /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the
    /// result of this query for use in UI tests or for debugging purposes.
    query variances_of(def_id: DefId) -> &'tcx [ty::Variance] {
        desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
        cycle_delay_bug
    }

    /// Gets a map with the inferred outlives-predicates of every item in the local crate.
    ///
    /// <div class="warning">
    ///
    /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead.
    ///
    /// </div>
    query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> {
        arena_cache
        desc { "computing the inferred outlives-predicates for items in this crate" }
    }

    /// Maps from an impl/trait or struct/variant `DefId`
    /// to a list of the `DefId`s of its associated items or fields.
    query associated_item_def_ids(key: DefId) -> &'tcx [DefId] {
        desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    /// Maps from a trait/impl item to the trait/impl item "descriptor".
    query associated_item(key: DefId) -> ty::AssocItem {
        desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Collects the associated items defined on a trait or impl.
    query associated_items(key: DefId) -> &'tcx ty::AssocItems {
        arena_cache
        desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
    }

    /// Maps from associated items on a trait to the corresponding associated
    /// item on the impl specified by `impl_id`.
    ///
    /// For example, with the following code
    ///
    /// ```
    /// struct Type {}
    ///                         // DefId
    /// trait Trait {           // trait_id
    ///     fn f();             // trait_f
    ///     fn g() {}           // trait_g
    /// }
    ///
    /// impl Trait for Type {   // impl_id
    ///     fn f() {}           // impl_f
    ///     fn g() {}           // impl_g
    /// }
    /// ```
    ///
    /// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be
    ///`{ trait_f: impl_f, trait_g: impl_g }`
    query impl_item_implementor_ids(impl_id: DefId) -> &'tcx DefIdMap<DefId> {
        arena_cache
        desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
    }

    /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id
    /// to its associated type items that correspond to the RPITITs in its signature.
    query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> {
        arena_cache
        desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) }
        separate_provide_extern
    }

    /// Given an `impl_id`, return the trait it implements along with some header information.
    query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> {
        desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
        cache_on_disk_if { impl_id.is_local() }
        separate_provide_extern
    }

    /// Given an `impl_def_id`, return true if the self type is guaranteed to be unsized due
    /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct
    /// whose tail is one of those types.
    query impl_self_is_guaranteed_unsized(impl_def_id: DefId) -> bool {
        desc { |tcx| "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) }
    }

    /// Maps a `DefId` of a type to a list of its inherent impls.
    /// Contains implementations of methods that are inherent to a type.
    /// Methods in these implementations don't need to be exported.
    query inherent_impls(key: DefId) -> &'tcx [DefId] {
        desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] {
        desc { |tcx| "collecting all inherent impls for `{:?}`", key }
    }

    /// Unsafety-check this `LocalDefId`.
    query check_transmutes(key: LocalDefId) {
        desc { |tcx| "check transmute calls inside `{}`", tcx.def_path_str(key) }
    }

    /// Unsafety-check this `LocalDefId`.
    query check_unsafety(key: LocalDefId) {
        desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
    }

    /// Checks well-formedness of tail calls (`become f()`).
    query check_tail_calls(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
        desc { |tcx| "tail-call-checking `{}`", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    /// Returns the types assumed to be well formed while "inside" of the given item.
    ///
    /// Note that we've liberated the late bound regions of function signatures, so
    /// this can not be used to check whether these types are well formed.
    query assumed_wf_types(key: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] {
        desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
    }

    /// We need to store the assumed_wf_types for an RPITIT so that impls of foreign
    /// traits with return-position impl trait in traits can inherit the right wf types.
    query assumed_wf_types_for_rpitit(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] {
        desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
        separate_provide_extern
    }

    /// Computes the signature of the function.
    query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
        desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        cycle_delay_bug
    }

    /// Performs lint checking for the module.
    query lint_mod(key: LocalModDefId) {
        desc { |tcx| "linting {}", describe_as_module(key, tcx) }
    }

    query check_unused_traits(_: ()) {
        desc { "checking unused trait imports in crate" }
    }

    /// Checks the attributes in the module.
    query check_mod_attrs(key: LocalModDefId) {
        desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
    }

    /// Checks for uses of unstable APIs in the module.
    query check_mod_unstable_api_usage(key: LocalModDefId) {
        desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
    }

    query check_mod_privacy(key: LocalModDefId) {
        desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
    }

    query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet<abi::FieldIdx> {
        arena_cache
        desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) }
        cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
    }

    /// Return the live symbols in the crate for dead code check.
    ///
    /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone).
    query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx Result<(
        LocalDefIdSet,
        LocalDefIdMap<FxIndexSet<DefId>>,
    ), ErrorGuaranteed> {
        arena_cache
        desc { "finding live symbols in crate" }
    }

    query check_mod_deathness(key: LocalModDefId) {
        desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
    }

    query check_type_wf(key: ()) -> Result<(), ErrorGuaranteed> {
        desc { "checking that types are well-formed" }
        return_result_from_ensure_ok
    }

    /// Caches `CoerceUnsized` kinds for impls on custom types.
    query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> {
        desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        return_result_from_ensure_ok
    }

    query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
        desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) }
        cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) }
    }

    query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> {
        desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { true }
    }

    query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) }
        return_result_from_ensure_ok
    }

    /// Borrow-checks the given typeck root, e.g. functions, const/static items,
    /// and its children, e.g. closures, inline consts.
    query mir_borrowck(key: LocalDefId) -> Result<
        &'tcx FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
        ErrorGuaranteed
    > {
        desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
    }

    /// Gets a complete map from all types to their inherent impls.
    ///
    /// <div class="warning">
    ///
    /// **Not meant to be used** directly outside of coherence.
    ///
    /// </div>
    query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) {
        desc { "finding all inherent impls defined in crate" }
    }

    /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
    ///
    /// <div class="warning">
    ///
    /// **Not meant to be used** directly outside of coherence.
    ///
    /// </div>
    query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> {
        desc { "check for inherent impls that should not be defined in crate" }
        return_result_from_ensure_ok
    }

    /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
    ///
    /// <div class="warning">
    ///
    /// **Not meant to be used** directly outside of coherence.
    ///
    /// </div>
    query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> {
        desc { "check for overlap between inherent impls defined in this crate" }
        return_result_from_ensure_ok
    }

    /// Checks whether all impls in the crate pass the overlap check, returning
    /// which impls fail it. If all impls are correct, the returned slice is empty.
    query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx|
            "checking whether impl `{}` follows the orphan rules",
            tcx.def_path_str(key),
        }
        return_result_from_ensure_ok
    }

    /// Return the set of (transitive) callees that may result in a recursive call to `key`.
    query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> {
        fatal_cycle
        arena_cache
        desc { |tcx|
            "computing (transitive) callees of `{}` that may recurse",
            tcx.def_path_str(key),
        }
        cache_on_disk_if { true }
    }

    /// Obtain all the calls into other local functions
    query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] {
        fatal_cycle
        desc { |tcx|
            "computing all local function calls in `{}`",
            tcx.def_path_str(key.def_id()),
        }
    }

    /// Computes the tag (if any) for a given type and variant.
    ///
    /// `None` means that the variant doesn't need a tag (because it is niched).
    ///
    /// # Panics
    ///
    /// This query will panic for uninhabited variants and if the passed type is not an enum.
    query tag_for_variant(
        key: PseudoCanonicalInput<'tcx, (Ty<'tcx>, abi::VariantIdx)>,
    ) -> Option<ty::ScalarInt> {
        desc { "computing variant tag for enum" }
    }

    /// Evaluates a constant and returns the computed allocation.
    ///
    /// <div class="warning">
    ///
    /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or
    /// [`Self::eval_to_valtree`] instead.
    ///
    /// </div>
    query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>)
        -> EvalToAllocationRawResult<'tcx> {
        desc { |tcx|
            "const-evaluating + checking `{}`",
            key.value.display(tcx)
        }
        cache_on_disk_if { true }
    }

    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
    query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> {
        desc { |tcx|
            "evaluating initializer of static `{}`",
            tcx.def_path_str(key)
        }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
        feedable
    }

    /// Evaluates const items or anonymous constants[^1] into a representation
    /// suitable for the type system and const generics.
    ///
    /// <div class="warning">
    ///
    /// **Do not call this** directly, use one of the following wrappers:
    /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`],
    /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`].
    ///
    /// </div>
    ///
    /// [^1]: Such as enum variant explicit discriminants or array lengths.
    query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>)
        -> EvalToConstValueResult<'tcx> {
        desc { |tcx|
            "simplifying constant for the type system `{}`",
            key.value.display(tcx)
        }
        depth_limit
        cache_on_disk_if { true }
    }

    /// Evaluate a constant and convert it to a type level constant or
    /// return `None` if that is not possible.
    query eval_to_valtree(
        key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>
    ) -> EvalToValTreeResult<'tcx> {
        desc { "evaluating type-level constant" }
    }

    /// Converts a type-level constant value into a MIR constant value.
    query valtree_to_const_val(key: ty::Value<'tcx>) -> mir::ConstValue {
        desc { "converting type-level constant value to MIR constant value"}
    }

    /// Destructures array, ADT or tuple constants into the constants
    /// of their fields.
    query destructure_const(key: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> {
        desc { "destructuring type level constant"}
    }

    // FIXME get rid of this with valtrees
    query lit_to_const(
        key: LitToConstInput<'tcx>
    ) -> ty::Const<'tcx> {
        desc { "converting literal to const" }
    }

    query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
        desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    /// Performs part of the privacy check and computes effective visibilities.
    query effective_visibilities(_: ()) -> &'tcx EffectiveVisibilities {
        eval_always
        desc { "checking effective visibilities" }
    }
    query check_private_in_public(module_def_id: LocalModDefId) {
        desc { |tcx|
            "checking for private elements in public interfaces for {}",
            describe_as_module(module_def_id, tcx)
        }
    }

    query reachable_set(_: ()) -> &'tcx LocalDefIdSet {
        arena_cache
        desc { "reachability" }
        cache_on_disk_if { true }
    }

    /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body;
    /// in the case of closures, this will be redirected to the enclosing function.
    query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree {
        desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) }
    }

    /// Generates a MIR body for the shim.
    query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> {
        arena_cache
        desc {
            |tcx| "generating MIR shim for `{}`, instance={:?}",
            tcx.def_path_str(key.def_id()),
            key
        }
    }

    /// The `symbol_name` query provides the symbol name for calling a
    /// given instance from the local crate. In particular, it will also
    /// look up the correct symbol name of instances from upstream crates.
    query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName<'tcx> {
        desc { "computing the symbol for `{}`", key }
        cache_on_disk_if { true }
    }

    query def_kind(def_id: DefId) -> DefKind {
        desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
        feedable
    }

    /// Gets the span for the definition.
    query def_span(def_id: DefId) -> Span {
        desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
        feedable
    }

    /// Gets the span for the identifier of the definition.
    query def_ident_span(def_id: DefId) -> Option<Span> {
        desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
        feedable
    }

    /// Gets the span for the type of the definition.
    /// Panics if it is not a definition that has a single type.
    query ty_span(def_id: LocalDefId) -> Span {
        desc { |tcx| "looking up span for `{}`'s type", tcx.def_path_str(def_id) }
        cache_on_disk_if { true }
    }

    query lookup_stability(def_id: DefId) -> Option<hir::Stability> {
        desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
    }

    query lookup_const_stability(def_id: DefId) -> Option<hir::ConstStability> {
        desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
    }

    query lookup_default_body_stability(def_id: DefId) -> Option<hir::DefaultBodyStability> {
        desc { |tcx| "looking up default body stability of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query should_inherit_track_caller(def_id: DefId) -> bool {
        desc { |tcx| "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) }
    }

    query inherited_align(def_id: DefId) -> Option<Align> {
        desc { |tcx| "computing inherited_align of `{}`", tcx.def_path_str(def_id) }
    }

    query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> {
        desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
    }

    /// Determines whether an item is annotated with `#[doc(hidden)]`.
    query is_doc_hidden(def_id: DefId) -> bool {
        desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Determines whether an item is annotated with `#[doc(notable_trait)]`.
    query is_doc_notable_trait(def_id: DefId) -> bool {
        desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) }
    }

    /// Returns the attributes on the item at `def_id`.
    ///
    /// Do not use this directly, use `tcx.get_attrs` instead.
    query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] {
        desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Returns the `CodegenFnAttrs` for the item at `def_id`.
    ///
    /// If possible, use `tcx.codegen_instance_attrs` instead. That function takes the
    /// instance kind into account.
    ///
    /// For example, the `#[naked]` attribute should be applied for `InstanceKind::Item`,
    /// but should not be applied if the instance kind is `InstanceKind::ReifyShim`.
    /// Using this query would include the attribute regardless of the actual instance
    /// kind at the call site.
    query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs {
        desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) }
        arena_cache
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
        feedable
    }

    query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
        desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
    }

    query fn_arg_idents(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] {
        desc { |tcx| "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Gets the rendered value of the specified constant or associated constant.
    /// Used by rustdoc.
    query rendered_const(def_id: DefId) -> &'tcx String {
        arena_cache
        desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Gets the rendered precise capturing args for an opaque for use in rustdoc.
    query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
        desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query impl_parent(def_id: DefId) -> Option<DefId> {
        desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query is_ctfe_mir_available(key: DefId) -> bool {
        desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }
    query is_mir_available(key: DefId) -> bool {
        desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) }
        cache_on_disk_if { key.is_local() }
        separate_provide_extern
    }

    query own_existential_vtable_entries(
        key: DefId
    ) -> &'tcx [DefId] {
        desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) }
    }

    query vtable_entries(key: ty::TraitRef<'tcx>)
                        -> &'tcx [ty::VtblEntry<'tcx>] {
        desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) }
    }

    query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize {
        desc { |tcx| "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() }
    }

    query supertrait_vtable_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> {
        desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable",
            key.1, key.0 }
    }

    query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
        desc { |tcx| "vtable const allocation for <{} as {}>",
            key.0,
            key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or_else(|| "_".to_owned())
        }
    }

    query codegen_select_candidate(
        key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>>
    ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
        cache_on_disk_if { true }
        desc { |tcx| "computing candidate for `{}`", key.value }
    }

    /// Return all `impl` blocks in the current crate.
    query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap<DefId, Vec<LocalDefId>> {
        desc { "finding local trait impls" }
    }

    /// Return all `impl` blocks of the given trait in the current crate.
    query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] {
        desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) }
    }

    /// Given a trait `trait_id`, return all known `impl` blocks.
    query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls {
        arena_cache
        desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) }
    }

    query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
        desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
        cache_on_disk_if { true }
        return_result_from_ensure_ok
    }
    query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] {
        desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) }
    }
    query is_dyn_compatible(trait_id: DefId) -> bool {
        desc { |tcx| "checking if trait `{}` is dyn-compatible", tcx.def_path_str(trait_id) }
    }

    /// Gets the ParameterEnvironment for a given item; this environment
    /// will be in "user-facing" mode, meaning that it is suitable for
    /// type-checking etc, and it does not normalize specializable
    /// associated types.
    ///
    /// You should almost certainly not use this. If you already have an InferCtxt, then
    /// you should also probably have a `ParamEnv` from when it was built. If you don't,
    /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly.
    query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> {
        desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) }
        feedable
    }

    /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been
    /// replaced with their hidden type. This is used in the old trait solver
    /// when in `PostAnalysis` mode and should not be called directly.
    query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> {
        desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) }
    }

    /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`,
    /// `ty.is_copy()`, etc, since that will prune the environment where possible.
    query is_copy_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is `Copy`", env.value }
    }
    /// Trait selection queries. These are best used by invoking `ty.is_use_cloned_modulo_regions()`,
    /// `ty.is_use_cloned()`, etc, since that will prune the environment where possible.
    query is_use_cloned_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is `UseCloned`", env.value }
    }
    /// Query backing `Ty::is_sized`.
    query is_sized_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is `Sized`", env.value }
    }
    /// Query backing `Ty::is_freeze`.
    query is_freeze_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is freeze", env.value }
    }
    /// Query backing `Ty::is_unpin`.
    query is_unpin_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is `Unpin`", env.value }
    }
    /// Query backing `Ty::is_async_drop`.
    query is_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` is `AsyncDrop`", env.value }
    }
    /// Query backing `Ty::needs_drop`.
    query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` needs drop", env.value }
    }
    /// Query backing `Ty::needs_async_drop`.
    query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` needs async drop", env.value }
    }
    /// Query backing `Ty::has_significant_drop_raw`.
    query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
        desc { "computing whether `{}` has a significant drop", env.value }
    }

    /// Query backing `Ty::is_structural_eq_shallow`.
    ///
    /// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types
    /// correctly.
    query has_structural_eq_impl(ty: Ty<'tcx>) -> bool {
        desc {
            "computing whether `{}` implements `StructuralPartialEq`",
            ty
        }
    }

    /// A list of types where the ADT requires drop if and only if any of
    /// those types require drop. If the ADT is known to always need drop
    /// then `Err(AlwaysRequiresDrop)` is returned.
    query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
        desc { |tcx| "computing when `{}` needs drop", tcx.def_path_str(def_id) }
        cache_on_disk_if { true }
    }

    /// A list of types where the ADT requires async drop if and only if any of
    /// those types require async drop. If the ADT is known to always need async drop
    /// then `Err(AlwaysRequiresDrop)` is returned.
    query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
        desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) }
        cache_on_disk_if { true }
    }

    /// A list of types where the ADT requires drop if and only if any of those types
    /// has significant drop. A type marked with the attribute `rustc_insignificant_dtor`
    /// is considered to not be significant. A drop is significant if it is implemented
    /// by the user or does anything that will have any observable behavior (other than
    /// freeing up memory). If the ADT is known to have a significant destructor then
    /// `Err(AlwaysRequiresDrop)` is returned.
    query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
        desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) }
    }

    /// Returns a list of types which (a) have a potentially significant destructor
    /// and (b) may be dropped as a result of dropping a value of some type `ty`
    /// (in the given environment).
    ///
    /// The idea of "significant" drop is somewhat informal and is used only for
    /// diagnostics and edition migrations. The idea is that a significant drop may have
    /// some visible side-effect on execution; freeing memory is NOT considered a side-effect.
    /// The rules are as follows:
    /// * Type with no explicit drop impl do not have significant drop.
    /// * Types with a drop impl are assumed to have significant drop unless they have a `#[rustc_insignificant_dtor]` annotation.
    ///
    /// Note that insignificant drop is a "shallow" property. A type like `Vec<LockGuard>` does not
    /// have significant drop but the type `LockGuard` does, and so if `ty  = Vec<LockGuard>`
    /// then the return value would be `&[LockGuard]`.
    /// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed,
    /// because this query partially depends on that query.
    /// Otherwise, there is a risk of query cycles.
    query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> {
        desc { |tcx| "computing when `{}` has a significant destructor", ty.value }
    }

    /// Computes the layout of a type. Note that this implicitly
    /// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
    query layout_of(
        key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>
    ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
        depth_limit
        desc { "computing layout of `{}`", key.value }
        // we emit our own error during query cycle handling
        cycle_delay_bug
    }

    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
    ///
    /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
    /// instead, where the instance is an `InstanceKind::Virtual`.
    query fn_abi_of_fn_ptr(
        key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
    ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
        desc { "computing call ABI of `{}` function pointers", key.value.0 }
    }

    /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
    /// direct calls to an `fn`.
    ///
    /// NB: that includes virtual calls, which are represented by "direct calls"
    /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
    query fn_abi_of_instance(
        key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
    ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
        desc { "computing call ABI of `{}`", key.value.0 }
    }

    query dylib_dependency_formats(_: CrateNum)
                                    -> &'tcx [(CrateNum, LinkagePreference)] {
        desc { "getting dylib dependency formats of crate" }
        separate_provide_extern
    }

    query dependency_formats(_: ()) -> &'tcx Arc<crate::middle::dependency_format::Dependencies> {
        arena_cache
        desc { "getting the linkage format of all dependencies" }
    }

    query is_compiler_builtins(_: CrateNum) -> bool {
        fatal_cycle
        desc { "checking if the crate is_compiler_builtins" }
        separate_provide_extern
    }
    query has_global_allocator(_: CrateNum) -> bool {
        // This query depends on untracked global state in CStore
        eval_always
        fatal_cycle
        desc { "checking if the crate has_global_allocator" }
        separate_provide_extern
    }
    query has_alloc_error_handler(_: CrateNum) -> bool {
        // This query depends on untracked global state in CStore
        eval_always
        fatal_cycle
        desc { "checking if the crate has_alloc_error_handler" }
        separate_provide_extern
    }
    query has_panic_handler(_: CrateNum) -> bool {
        fatal_cycle
        desc { "checking if the crate has_panic_handler" }
        separate_provide_extern
    }
    query is_profiler_runtime(_: CrateNum) -> bool {
        fatal_cycle
        desc { "checking if a crate is `#![profiler_runtime]`" }
        separate_provide_extern
    }
    query has_ffi_unwind_calls(key: LocalDefId) -> bool {
        desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) }
        cache_on_disk_if { true }
    }
    query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
        fatal_cycle
        desc { "getting a crate's required panic strategy" }
        separate_provide_extern
    }
    query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy {
        fatal_cycle
        desc { "getting a crate's configured panic-in-drop strategy" }
        separate_provide_extern
    }
    query is_no_builtins(_: CrateNum) -> bool {
        fatal_cycle
        desc { "getting whether a crate has `#![no_builtins]`" }
        separate_provide_extern
    }
    query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion {
        fatal_cycle
        desc { "getting a crate's symbol mangling version" }
        separate_provide_extern
    }

    query extern_crate(def_id: CrateNum) -> Option<&'tcx ExternCrate> {
        eval_always
        desc { "getting crate's ExternCrateData" }
        separate_provide_extern
    }

    query specialization_enabled_in(cnum: CrateNum) -> bool {
        desc { "checking whether the crate enabled `specialization`/`min_specialization`" }
        separate_provide_extern
    }

    query specializes(_: (DefId, DefId)) -> bool {
        desc { "computing whether impls specialize one another" }
    }
    query in_scope_traits_map(_: hir::OwnerId)
        -> Option<&'tcx ItemLocalMap<Box<[TraitCandidate]>>> {
        desc { "getting traits in scope at a block" }
    }

    /// Returns whether the impl or associated function has the `default` keyword.
    /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`.
    query defaultness(def_id: DefId) -> hir::Defaultness {
        desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) }
        separate_provide_extern
        feedable
    }

    /// Returns whether the field corresponding to the `DefId` has a default field value.
    query default_field(def_id: DefId) -> Option<DefId> {
        desc { |tcx| "looking up the `const` corresponding to the default for `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    // The `DefId`s of all non-generic functions and statics in the given crate
    // that can be reached from outside the crate.
    //
    // We expect this items to be available for being linked to.
    //
    // This query can also be called for `LOCAL_CRATE`. In this case it will
    // compute which items will be reachable to other crates, taking into account
    // the kind of crate that is currently compiled. Crates with only a
    // C interface have fewer reachable things.
    //
    // Does not include external symbols that don't have a corresponding DefId,
    // like the compiler-generated `main` function and so on.
    query reachable_non_generics(_: CrateNum)
        -> &'tcx DefIdMap<SymbolExportInfo> {
        arena_cache
        desc { "looking up the exported symbols of a crate" }
        separate_provide_extern
    }
    query is_reachable_non_generic(def_id: DefId) -> bool {
        desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
    }
    query is_unreachable_local_definition(def_id: LocalDefId) -> bool {
        desc { |tcx|
            "checking whether `{}` is reachable from outside the crate",
            tcx.def_path_str(def_id),
        }
    }

    /// The entire set of monomorphizations the local crate can safely
    /// link to because they are exported from upstream crates. Do
    /// not depend on this directly, as its value changes anytime
    /// a monomorphization gets added or removed in any upstream
    /// crate. Instead use the narrower `upstream_monomorphizations_for`,
    /// `upstream_drop_glue_for`, `upstream_async_drop_glue_for`, or,
    /// even better, `Instance::upstream_monomorphization()`.
    query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> {
        arena_cache
        desc { "collecting available upstream monomorphizations" }
    }

    /// Returns the set of upstream monomorphizations available for the
    /// generic function identified by the given `def_id`. The query makes
    /// sure to make a stable selection if the same monomorphization is
    /// available in multiple upstream crates.
    ///
    /// You likely want to call `Instance::upstream_monomorphization()`
    /// instead of invoking this query directly.
    query upstream_monomorphizations_for(def_id: DefId)
        -> Option<&'tcx UnordMap<GenericArgsRef<'tcx>, CrateNum>>
    {
        desc { |tcx|
            "collecting available upstream monomorphizations for `{}`",
            tcx.def_path_str(def_id),
        }
        separate_provide_extern
    }

    /// Returns the upstream crate that exports drop-glue for the given
    /// type (`args` is expected to be a single-item list containing the
    /// type one wants drop-glue for).
    ///
    /// This is a subset of `upstream_monomorphizations_for` in order to
    /// increase dep-tracking granularity. Otherwise adding or removing any
    /// type with drop-glue in any upstream crate would invalidate all
    /// functions calling drop-glue of an upstream type.
    ///
    /// You likely want to call `Instance::upstream_monomorphization()`
    /// instead of invoking this query directly.
    ///
    /// NOTE: This query could easily be extended to also support other
    ///       common functions that have are large set of monomorphizations
    ///       (like `Clone::clone` for example).
    query upstream_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> {
        desc { "available upstream drop-glue for `{:?}`", args }
    }

    /// Returns the upstream crate that exports async-drop-glue for
    /// the given type (`args` is expected to be a single-item list
    /// containing the type one wants async-drop-glue for).
    ///
    /// This is a subset of `upstream_monomorphizations_for` in order
    /// to increase dep-tracking granularity. Otherwise adding or
    /// removing any type with async-drop-glue in any upstream crate
    /// would invalidate all functions calling async-drop-glue of an
    /// upstream type.
    ///
    /// You likely want to call `Instance::upstream_monomorphization()`
    /// instead of invoking this query directly.
    ///
    /// NOTE: This query could easily be extended to also support other
    ///       common functions that have are large set of monomorphizations
    ///       (like `Clone::clone` for example).
    query upstream_async_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> {
        desc { "available upstream async-drop-glue for `{:?}`", args }
    }

    /// Returns a list of all `extern` blocks of a crate.
    query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> {
        arena_cache
        desc { "looking up the foreign modules of a linked crate" }
        separate_provide_extern
    }

    /// Lint against `extern fn` declarations having incompatible types.
    query clashing_extern_declarations(_: ()) {
        desc { "checking `extern fn` declarations are compatible" }
    }

    /// Identifies the entry-point (e.g., the `main` function) for a given
    /// crate, returning `None` if there is no entry point (such as for library crates).
    query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> {
        desc { "looking up the entry function of a crate" }
    }

    /// Finds the `rustc_proc_macro_decls` item of a crate.
    query proc_macro_decls_static(_: ()) -> Option<LocalDefId> {
        desc { "looking up the proc macro declarations for a crate" }
    }

    // The macro which defines `rustc_metadata::provide_extern` depends on this query's name.
    // Changing the name should cause a compiler error, but in case that changes, be aware.
    //
    // The hash should not be calculated before the `analysis` pass is complete, specifically
    // until `tcx.untracked().definitions.freeze()` has been called, otherwise if incremental
    // compilation is enabled calculating this hash can freeze this structure too early in
    // compilation and cause subsequent crashes when attempting to write to `definitions`
    query crate_hash(_: CrateNum) -> Svh {
        eval_always
        desc { "looking up the hash a crate" }
        separate_provide_extern
    }

    /// Gets the hash for the host proc macro. Used to support -Z dual-proc-macro.
    query crate_host_hash(_: CrateNum) -> Option<Svh> {
        eval_always
        desc { "looking up the hash of a host version of a crate" }
        separate_provide_extern
    }

    /// Gets the extra data to put in each output filename for a crate.
    /// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file.
    query extra_filename(_: CrateNum) -> &'tcx String {
        arena_cache
        eval_always
        desc { "looking up the extra filename for a crate" }
        separate_provide_extern
    }

    /// Gets the paths where the crate came from in the file system.
    query crate_extern_paths(_: CrateNum) -> &'tcx Vec<PathBuf> {
        arena_cache
        eval_always
        desc { "looking up the paths for extern crates" }
        separate_provide_extern
    }

    /// Given a crate and a trait, look up all impls of that trait in the crate.
    /// Return `(impl_id, self_ty)`.
    query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option<SimplifiedType>)] {
        desc { "looking up implementations of a trait in a crate" }
        separate_provide_extern
    }

    /// Collects all incoherent impls for the given crate and type.
    ///
    /// Do not call this directly, but instead use the `incoherent_impls` query.
    /// This query is only used to get the data necessary for that query.
    query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] {
        desc { |tcx| "collecting all impls for a type in a crate" }
        separate_provide_extern
    }

    /// Get the corresponding native library from the `native_libraries` query
    query native_library(def_id: DefId) -> Option<&'tcx NativeLib> {
        desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) }
    }

    query inherit_sig_for_delegation_item(def_id: LocalDefId) -> &'tcx [Ty<'tcx>] {
        desc { "inheriting delegation signature" }
    }

    /// Does lifetime resolution on items. Importantly, we can't resolve
    /// lifetimes directly on things like trait methods, because of trait params.
    /// See `rustc_resolve::late::lifetimes` for details.
    query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars {
        arena_cache
        desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) }
    }
    query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> {
        desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) }
    }
    query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
        desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) }
    }
    /// Returns the *default lifetime* to be used if a trait object type were to be passed for
    /// the type parameter given by `DefId`.
    ///
    /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically
    /// print the result of this query for use in UI tests or for debugging purposes.
    ///
    /// # Examples
    ///
    /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)`
    /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty`
    ///
    /// # Panics
    ///
    /// This query will panic if the given definition is not a type parameter.
    query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault {
        desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }
    query late_bound_vars_map(owner_id: hir::OwnerId)
        -> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>> {
        desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) }
    }
    /// For an opaque type, return the list of (captured lifetime, inner generic param).
    /// ```ignore (illustrative)
    /// fn foo<'a: 'a, 'b, T>(&'b u8) -> impl Into<Self> + 'b { ... }
    /// ```
    ///
    /// We would return `[('a, '_a), ('b, '_b)]`, with `'a` early-bound and `'b` late-bound.
    ///
    /// After hir_ty_lowering, we get:
    /// ```ignore (pseudo-code)
    /// opaque foo::<'a>::opaque<'_a, '_b>: Into<Foo<'_a>> + '_b;
    ///                          ^^^^^^^^ inner generic params
    /// fn foo<'a>: for<'b> fn(&'b u8) -> foo::<'a>::opaque::<'a, 'b>
    ///                                                       ^^^^^^ captured lifetimes
    /// ```
    query opaque_captured_lifetimes(def_id: LocalDefId) -> &'tcx [(ResolvedArg, LocalDefId)] {
        desc { |tcx| "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) }
    }

    /// Computes the visibility of the provided `def_id`.
    ///
    /// If the item from the `def_id` doesn't have a visibility, it will panic. For example
    /// a generic type parameter will panic if you call this method on it:
    ///
    /// ```
    /// use std::fmt::Debug;
    ///
    /// pub trait Foo<T: Debug> {}
    /// ```
    ///
    /// In here, if you call `visibility` on `T`, it'll panic.
    query visibility(def_id: DefId) -> ty::Visibility<DefId> {
        desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
        feedable
    }

    query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
        desc { "computing the uninhabited predicate of `{:?}`", key }
    }

    /// Do not call this query directly: invoke `Ty::inhabited_predicate` instead.
    query inhabited_predicate_type(key: Ty<'tcx>) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
        desc { "computing the uninhabited predicate of `{}`", key }
    }

    query dep_kind(_: CrateNum) -> CrateDepKind {
        eval_always
        desc { "fetching what a dependency looks like" }
        separate_provide_extern
    }

    /// Gets the name of the crate.
    query crate_name(_: CrateNum) -> Symbol {
        feedable
        desc { "fetching what a crate is named" }
        separate_provide_extern
    }
    query module_children(def_id: DefId) -> &'tcx [ModChild] {
        desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    /// Gets the number of definitions in a foreign crate.
    ///
    /// This allows external tools to iterate over all definitions in a foreign crate.
    ///
    /// This should never be used for the local crate, instead use `iter_local_def_id`.
    query num_extern_def_ids(_: CrateNum) -> usize {
        desc { "fetching the number of definitions in a crate" }
        separate_provide_extern
    }

    query lib_features(_: CrateNum) -> &'tcx LibFeatures {
        desc { "calculating the lib features defined in a crate" }
        separate_provide_extern
        arena_cache
    }
    /// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]`
    /// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute
    /// exists, then this map will have a `impliee -> implier` entry.
    ///
    /// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should
    /// specify their implications (both `implies` and `implied_by`). If only one of the two
    /// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this
    /// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is
    /// reported, only the `#[stable]` attribute information is available, so the map is necessary
    /// to know that the feature implies another feature. If it were reversed, and the `#[stable]`
    /// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of
    /// unstable feature" error for a feature that was implied.
    query stability_implications(_: CrateNum) -> &'tcx UnordMap<Symbol, Symbol> {
        arena_cache
        desc { "calculating the implications between `#[unstable]` features defined in a crate" }
        separate_provide_extern
    }
    /// Whether the function is an intrinsic
    query intrinsic_raw(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> {
        desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) }
        separate_provide_extern
    }
    /// Returns the lang items defined in another crate by loading it from metadata.
    query get_lang_items(_: ()) -> &'tcx LanguageItems {
        arena_cache
        eval_always
        desc { "calculating the lang items map" }
    }

    /// Returns all diagnostic items defined in all crates.
    query all_diagnostic_items(_: ()) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems {
        arena_cache
        eval_always
        desc { "calculating the diagnostic items map" }
    }

    /// Returns the lang items defined in another crate by loading it from metadata.
    query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, LangItem)] {
        desc { "calculating the lang items defined in a crate" }
        separate_provide_extern
    }

    /// Returns the diagnostic items defined in a crate.
    query diagnostic_items(_: CrateNum) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems {
        arena_cache
        desc { "calculating the diagnostic items map in a crate" }
        separate_provide_extern
    }

    query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] {
        desc { "calculating the missing lang items in a crate" }
        separate_provide_extern
    }

    /// The visible parent map is a map from every item to a visible parent.
    /// It prefers the shortest visible path to an item.
    /// Used for diagnostics, for example path trimming.
    /// The parents are modules, enums or traits.
    query visible_parent_map(_: ()) -> &'tcx DefIdMap<DefId> {
        arena_cache
        desc { "calculating the visible parent map" }
    }
    /// Collects the "trimmed", shortest accessible paths to all items for diagnostics.
    /// See the [provider docs](`rustc_middle::ty::print::trimmed_def_paths`) for more info.
    query trimmed_def_paths(_: ()) -> &'tcx DefIdMap<Symbol> {
        arena_cache
        desc { "calculating trimmed def paths" }
    }
    query missing_extern_crate_item(_: CrateNum) -> bool {
        eval_always
        desc { "seeing if we're missing an `extern crate` item for this crate" }
        separate_provide_extern
    }
    query used_crate_source(_: CrateNum) -> &'tcx Arc<CrateSource> {
        arena_cache
        eval_always
        desc { "looking at the source for a crate" }
        separate_provide_extern
    }

    /// Returns the debugger visualizers defined for this crate.
    /// NOTE: This query has to be marked `eval_always` because it reads data
    ///       directly from disk that is not tracked anywhere else. I.e. it
    ///       represents a genuine input to the query system.
    query debugger_visualizers(_: CrateNum) -> &'tcx Vec<DebuggerVisualizerFile> {
        arena_cache
        desc { "looking up the debugger visualizers for this crate" }
        separate_provide_extern
        eval_always
    }

    query postorder_cnums(_: ()) -> &'tcx [CrateNum] {
        eval_always
        desc { "generating a postorder list of CrateNums" }
    }
    /// Returns whether or not the crate with CrateNum 'cnum'
    /// is marked as a private dependency
    query is_private_dep(c: CrateNum) -> bool {
        eval_always
        desc { "checking whether crate `{}` is a private dependency", c }
        separate_provide_extern
    }
    query allocator_kind(_: ()) -> Option<AllocatorKind> {
        eval_always
        desc { "getting the allocator kind for the current crate" }
    }
    query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> {
        eval_always
        desc { "alloc error handler kind for the current crate" }
    }

    query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
        desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }
    }

    /// All available crates in the graph, including those that should not be user-facing
    /// (such as private crates).
    query crates(_: ()) -> &'tcx [CrateNum] {
        eval_always
        desc { "fetching all foreign CrateNum instances" }
    }
    // Crates that are loaded non-speculatively (not for diagnostics or doc links).
    // FIXME: This is currently only used for collecting lang items, but should be used instead of
    // `crates` in most other cases too.
    query used_crates(_: ()) -> &'tcx [CrateNum] {
        eval_always
        desc { "fetching `CrateNum`s for all crates loaded non-speculatively" }
    }

    /// A list of all traits in a crate, used by rustdoc and error reporting.
    query traits(_: CrateNum) -> &'tcx [DefId] {
        desc { "fetching all traits in a crate" }
        separate_provide_extern
    }

    query trait_impls_in_crate(_: CrateNum) -> &'tcx [DefId] {
        desc { "fetching all trait impls in a crate" }
        separate_provide_extern
    }

    query stable_order_of_exportable_impls(_: CrateNum) -> &'tcx FxIndexMap<DefId, usize> {
        desc { "fetching the stable impl's order" }
        separate_provide_extern
    }

    query exportable_items(_: CrateNum) -> &'tcx [DefId] {
        desc { "fetching all exportable items in a crate" }
        separate_provide_extern
    }

    /// The list of non-generic symbols exported from the given crate.
    ///
    /// This is separate from exported_generic_symbols to avoid having
    /// to deserialize all non-generic symbols too for upstream crates
    /// in the upstream_monomorphizations query.
    ///
    /// - All names contained in `exported_non_generic_symbols(cnum)` are
    ///   guaranteed to correspond to a publicly visible symbol in `cnum`
    ///   machine code.
    /// - The `exported_non_generic_symbols` and `exported_generic_symbols`
    ///   sets of different crates do not intersect.
    query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
        desc { "collecting exported non-generic symbols for crate `{}`", cnum}
        cache_on_disk_if { *cnum == LOCAL_CRATE }
        separate_provide_extern
    }

    /// The list of generic symbols exported from the given crate.
    ///
    /// - All names contained in `exported_generic_symbols(cnum)` are
    ///   guaranteed to correspond to a publicly visible symbol in `cnum`
    ///   machine code.
    /// - The `exported_non_generic_symbols` and `exported_generic_symbols`
    ///   sets of different crates do not intersect.
    query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
        desc { "collecting exported generic symbols for crate `{}`", cnum}
        cache_on_disk_if { *cnum == LOCAL_CRATE }
        separate_provide_extern
    }

    query collect_and_partition_mono_items(_: ()) -> MonoItemPartitions<'tcx> {
        eval_always
        desc { "collect_and_partition_mono_items" }
    }

    query is_codegened_item(def_id: DefId) -> bool {
        desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
    }

    query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> {
        desc { "getting codegen unit `{sym}`" }
    }

    query backend_optimization_level(_: ()) -> OptLevel {
        desc { "optimization level used by backend" }
    }

    /// Return the filenames where output artefacts shall be stored.
    ///
    /// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt`
    /// has been destroyed.
    query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> {
        feedable
        desc { "getting output filenames" }
        arena_cache
    }

    /// <div class="warning">
    ///
    /// Do not call this query directly: Invoke `normalize` instead.
    ///
    /// </div>
    query normalize_canonicalized_projection_ty(
        goal: CanonicalAliasGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{}`", goal.canonical.value.value }
    }

    /// <div class="warning">
    ///
    /// Do not call this query directly: Invoke `normalize` instead.
    ///
    /// </div>
    query normalize_canonicalized_free_alias(
        goal: CanonicalAliasGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{}`", goal.canonical.value.value }
    }

    /// <div class="warning">
    ///
    /// Do not call this query directly: Invoke `normalize` instead.
    ///
    /// </div>
    query normalize_canonicalized_inherent_projection_ty(
        goal: CanonicalAliasGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{}`", goal.canonical.value.value }
    }

    /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
    query try_normalize_generic_arg_after_erasing_regions(
        goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>>
    ) -> Result<GenericArg<'tcx>, NoSolution> {
        desc { "normalizing `{}`", goal.value }
    }

    query implied_outlives_bounds(
        key: (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool)
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
        NoSolution,
    > {
        desc { "computing implied outlives bounds for `{}` (hack disabled = {:?})", key.0.canonical.value.value.ty, key.1 }
    }

    /// Do not call this query directly:
    /// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead.
    query dropck_outlives(
        goal: CanonicalDropckOutlivesGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>,
        NoSolution,
    > {
        desc { "computing dropck types for `{}`", goal.canonical.value.value.dropped_ty }
    }

    /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
    /// `infcx.predicate_must_hold()` instead.
    query evaluate_obligation(
        goal: CanonicalPredicateGoal<'tcx>
    ) -> Result<EvaluationResult, OverflowError> {
        desc { "evaluating trait selection obligation `{}`", goal.canonical.value.value }
    }

    /// Do not call this query directly: part of the `Eq` type-op
    query type_op_ascribe_user_type(
        goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
        NoSolution,
    > {
        desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.canonical.value.value }
    }

    /// Do not call this query directly: part of the `ProvePredicate` type-op
    query type_op_prove_predicate(
        goal: CanonicalTypeOpProvePredicateGoal<'tcx>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
        NoSolution,
    > {
        desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.canonical.value.value }
    }

    /// Do not call this query directly: part of the `Normalize` type-op
    query type_op_normalize_ty(
        goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{}`", goal.canonical.value.value.value }
    }

    /// Do not call this query directly: part of the `Normalize` type-op
    query type_op_normalize_clause(
        goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Clause<'tcx>>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Clause<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{:?}`", goal.canonical.value.value.value }
    }

    /// Do not call this query directly: part of the `Normalize` type-op
    query type_op_normalize_poly_fn_sig(
        goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{:?}`", goal.canonical.value.value.value }
    }

    /// Do not call this query directly: part of the `Normalize` type-op
    query type_op_normalize_fn_sig(
        goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>
    ) -> Result<
        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>,
        NoSolution,
    > {
        desc { "normalizing `{:?}`", goal.canonical.value.value.value }
    }

    query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool {
        desc { |tcx|
            "checking impossible instantiated predicates: `{}`",
            tcx.def_path_str(key.0)
        }
    }

    query is_impossible_associated_item(key: (DefId, DefId)) -> bool {
        desc { |tcx|
            "checking if `{}` is impossible to reference within `{}`",
            tcx.def_path_str(key.1),
            tcx.def_path_str(key.0),
        }
    }

    query method_autoderef_steps(
        goal: CanonicalMethodAutoderefStepsGoal<'tcx>
    ) -> MethodAutoderefStepsResult<'tcx> {
        desc { "computing autoderef types for `{}`", goal.canonical.value.value.self_ty }
    }

    /// Used by `-Znext-solver` to compute proof trees.
    query evaluate_root_goal_for_proof_tree_raw(
        goal: solve::CanonicalInput<'tcx>,
    ) -> (solve::QueryResult<'tcx>, &'tcx solve::inspect::Probe<TyCtxt<'tcx>>) {
        no_hash
        desc { "computing proof tree for `{}`", goal.canonical.value.goal.predicate }
    }

    /// Returns the Rust target features for the current target. These are not always the same as LLVM target features!
    query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::Stability> {
        arena_cache
        eval_always
        desc { "looking up Rust target features" }
    }

    query implied_target_features(feature: Symbol) -> &'tcx Vec<Symbol> {
        arena_cache
        eval_always
        desc { "looking up implied target features" }
    }

    query features_query(_: ()) -> &'tcx rustc_feature::Features {
        feedable
        desc { "looking up enabled feature gates" }
    }

    query crate_for_resolver((): ()) -> &'tcx Steal<(rustc_ast::Crate, rustc_ast::AttrVec)> {
        feedable
        no_hash
        desc { "the ast before macro expansion and name resolution" }
    }

    /// Attempt to resolve the given `DefId` to an `Instance`, for the
    /// given generics args (`GenericArgsRef`), returning one of:
    ///  * `Ok(Some(instance))` on success
    ///  * `Ok(None)` when the `GenericArgsRef` are still too generic,
    ///    and therefore don't allow finding the final `Instance`
    ///  * `Err(ErrorGuaranteed)` when the `Instance` resolution process
    ///    couldn't complete due to errors elsewhere - this is distinct
    ///    from `Ok(None)` to avoid misleading diagnostics when an error
    ///    has already been/will be emitted, for the original cause.
    query resolve_instance_raw(
        key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
    ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
        desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) }
    }

    query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
        desc { "revealing opaque types in `{:?}`", key }
    }

    query limits(key: ()) -> Limits {
        desc { "looking up limits" }
    }

    /// Performs an HIR-based well-formed check on the item with the given `HirId`. If
    /// we get an `Unimplemented` error that matches the provided `Predicate`, return
    /// the cause of the newly created obligation.
    ///
    /// This is only used by error-reporting code to get a better cause (in particular, a better
    /// span) for an *existing* error. Therefore, it is best-effort, and may never handle
    /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
    /// because the `ty::Ty`-based wfcheck is always run.
    query diagnostic_hir_wf_check(
        key: (ty::Predicate<'tcx>, WellFormedLoc)
    ) -> Option<&'tcx ObligationCause<'tcx>> {
        arena_cache
        eval_always
        no_hash
        desc { "performing HIR wf-checking for predicate `{:?}` at item `{:?}`", key.0, key.1 }
    }

    /// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
    /// `--target` and similar).
    query global_backend_features(_: ()) -> &'tcx Vec<String> {
        arena_cache
        eval_always
        desc { "computing the backend features for CLI flags" }
    }

    query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
        desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
    }

    /// This takes the def-id of an associated item from a impl of a trait,
    /// and checks its validity against the trait item it corresponds to.
    ///
    /// Any other def id will ICE.
    query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
        desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) }
        return_result_from_ensure_ok
    }

    query deduced_param_attrs(def_id: DefId) -> &'tcx [DeducedParamAttrs] {
        desc { |tcx| "deducing parameter attributes for {}", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query doc_link_resolutions(def_id: DefId) -> &'tcx DocLinkResMap {
        eval_always
        desc { "resolutions for documentation links for a module" }
        separate_provide_extern
    }

    query doc_link_traits_in_scope(def_id: DefId) -> &'tcx [DefId] {
        eval_always
        desc { "traits in scope for documentation links for a module" }
        separate_provide_extern
    }

    /// Get all item paths that were stripped by a `#[cfg]` in a particular crate.
    /// Should not be called for the local crate before the resolver outputs are created, as it
    /// is only fed there.
    query stripped_cfg_items(cnum: CrateNum) -> &'tcx [StrippedCfgItem] {
        desc { "getting cfg-ed out item names" }
        separate_provide_extern
    }

    query generics_require_sized_self(def_id: DefId) -> bool {
        desc { "check whether the item has a `where Self: Sized` bound" }
    }

    query cross_crate_inlinable(def_id: DefId) -> bool {
        desc { "whether the item should be made inlinable across crates" }
        separate_provide_extern
    }

    /// Perform monomorphization-time checking on this item.
    /// This is used for lints/errors that can only be checked once the instance is fully
    /// monomorphized.
    query check_mono_item(key: ty::Instance<'tcx>) {
        desc { "monomorphization-time checking" }
    }

    /// Builds the set of functions that should be skipped for the move-size check.
    query skip_move_check_fns(_: ()) -> &'tcx FxIndexSet<DefId> {
        arena_cache
        desc { "functions to skip for move-size check" }
    }

    query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), NormalizationErrorInMono> {
        desc { "collecting items used by `{}`", key.0 }
        cache_on_disk_if { true }
    }

    query size_estimate(key: ty::Instance<'tcx>) -> usize {
        desc { "estimating codegen size of `{}`", key }
        cache_on_disk_if { true }
    }

    query anon_const_kind(def_id: DefId) -> ty::AnonConstKind {
        desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) }
        separate_provide_extern
    }

    query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> {
        desc { |tcx| "checking if `{}` is a trivial const", tcx.def_path_str(def_id) }
        cache_on_disk_if { def_id.is_local() }
        separate_provide_extern
    }

    /// Checks for the nearest `#[sanitize(xyz = "off")]` or
    /// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the
    /// crate root.
    ///
    /// Returns the set of sanitizers that is explicitly disabled for this def.
    query disabled_sanitizers_for(key: LocalDefId) -> SanitizerSet {
        desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) }
        feedable
    }
}

rustc_with_all_queries! { define_callbacks! }
rustc_feedable_queries! { define_feedable! }

fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String {
    let def_id = def_id.into();
    if def_id.is_top_level_module() {
        "top-level module".to_string()
    } else {
        format!("module `{}`", tcx.def_path_str(def_id))
    }
}
