//!
//! # 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/master/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_attr_data_structures::StrippedCfgItem;
use rustc_data_structures::fingerprint::Fingerprint;
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::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::{
    QueryCache, QueryMode, QueryStackDeferred, QueryState, try_get_cached,
};
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;
use {rustc_abi as abi, rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};

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::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};
use crate::query::erase::{Erase, erase, restore};
use crate::query::plumbing::{
    CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
};
use crate::traits::query::{
    CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
    CanonicalPredicateGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
    CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint,
    DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
    OutlivesBound,
};
use crate::traits::{
    CodegenObligationError, DynCompatibilityViolation, EvaluationResult, ImplSource,
    ObligationCause, OverflowError, WellFormedLoc, specialization_graph,
};
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::layout::ValidityRequirement;
use crate::ty::print::{PrintTraitRefExt, describe_as_module};
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;
mod keys;
pub use keys::{AsLocalKey, Key, LocalCrate};
pub mod on_disk_cache;
#[macro_use]
pub mod plumbing;
pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk};

// 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 { "running analysis passes on this 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())
        }
    }

    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
    }

    /// 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_regions(value)`,
    /// however, which uses this query as a kind of cache.
    query erase_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.
    /// Return `None` if this is an inherent impl.
    query impl_trait_header(impl_id: DefId) -> Option<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_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) {
        desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) }
    }

    /// 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) and
    /// their respective impl (i.e., part of the derive macro)
    query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx (
        LocalDefIdSet,
        LocalDefIdMap<FxIndexSet<(DefId, DefId)>>
    ) {
        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 mir::ConcreteOpaqueTypes<'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<'tcx> {
        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(_: ()) {
        eval_always
        desc { "checking for private elements in public interfaces" }
    }

    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<attr::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<attr::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<attr::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.
    query defaultness(def_id: DefId) -> hir::Defaultness {
        desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) }
        separate_provide_extern
        feedable
    }

    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
    }
    query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
        desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
    }

    /// 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) }
    }
    query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
        desc { "fetching potentially unused trait imports" }
    }

    /// 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: CanonicalTyGoal<'tcx>
    ) -> MethodAutoderefStepsResult<'tcx> {
        desc { "computing autoderef types for `{}`", goal.canonical.value.value }
    }

    /// 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 [ty::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)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
        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
    }
}

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