mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-03 21:47:36 +00:00
113 lines
4.4 KiB
Rust
113 lines
4.4 KiB
Rust
//! "Hooks" let you write `tcx` methods in downstream crates and call them in this crate, reducing
|
|
//! the amount of code that needs to be in this crate (which is already very big). This is somewhat
|
|
//! similar to queries, but queries come with a lot of machinery for caching and incremental
|
|
//! compilation, whereas hooks are just plain function pointers without any of the query magic.
|
|
|
|
use rustc_hir::def_id::{DefId, DefPathHash};
|
|
use rustc_session::StableCrateId;
|
|
use rustc_span::def_id::{CrateNum, LocalDefId};
|
|
use rustc_span::{ExpnHash, ExpnId};
|
|
|
|
use crate::mir;
|
|
use crate::ty::{Ty, TyCtxt};
|
|
|
|
macro_rules! declare_hooks {
|
|
($($(#[$attr:meta])*hook $name:ident($($arg:ident: $K:ty),*) -> $V:ty;)*) => {
|
|
|
|
impl<'tcx> TyCtxt<'tcx> {
|
|
$(
|
|
$(#[$attr])*
|
|
#[inline(always)]
|
|
pub fn $name(self, $($arg: $K,)*) -> $V
|
|
{
|
|
(self.hooks.$name)(self, $($arg,)*)
|
|
}
|
|
)*
|
|
}
|
|
|
|
pub struct Providers {
|
|
$(pub $name: for<'tcx> fn(
|
|
TyCtxt<'tcx>,
|
|
$($arg: $K,)*
|
|
) -> $V,)*
|
|
}
|
|
|
|
impl Default for Providers {
|
|
fn default() -> Self {
|
|
Providers {
|
|
$($name: |_, $($arg,)*| default_hook(stringify!($name), &($($arg,)*))),*
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Copy for Providers {}
|
|
impl Clone for Providers {
|
|
fn clone(&self) -> Self { *self }
|
|
}
|
|
};
|
|
}
|
|
|
|
declare_hooks! {
|
|
/// Tries to destructure an `mir::Const` ADT or array into its variant index
|
|
/// and its field values. This should only be used for pretty printing.
|
|
hook try_destructure_mir_constant_for_user_output(val: mir::ConstValue<'tcx>, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;
|
|
|
|
/// Getting a &core::panic::Location referring to a span.
|
|
hook const_caller_location(file: rustc_span::Symbol, line: u32, col: u32) -> mir::ConstValue<'tcx>;
|
|
|
|
/// Returns `true` if this def is a function-like thing that is eligible for
|
|
/// coverage instrumentation under `-Cinstrument-coverage`.
|
|
///
|
|
/// (Eligible functions might nevertheless be skipped for other reasons.)
|
|
hook is_eligible_for_coverage(key: LocalDefId) -> bool;
|
|
|
|
/// Imports all `SourceFile`s from the given crate into the current session.
|
|
/// This normally happens automatically when we decode a `Span` from
|
|
/// that crate's metadata - however, the incr comp cache needs
|
|
/// to trigger this manually when decoding a foreign `Span`
|
|
hook import_source_files(key: CrateNum) -> ();
|
|
|
|
hook expn_hash_to_expn_id(
|
|
cnum: CrateNum,
|
|
index_guess: u32,
|
|
hash: ExpnHash
|
|
) -> ExpnId;
|
|
|
|
/// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
|
|
/// session, if it still exists. This is used during incremental compilation to
|
|
/// turn a deserialized `DefPathHash` into its current `DefId`.
|
|
/// Will fetch a DefId from a DefPathHash for a foreign crate.
|
|
hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId;
|
|
|
|
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
|
|
/// can just link to the upstream crate and therefore don't need a mono item.
|
|
///
|
|
/// Note: this hook isn't called within `rustc_middle` but #127779 suggests it's a hook instead
|
|
/// of a normal function because external tools might want to override it.
|
|
hook should_codegen_locally(instance: crate::ty::Instance<'tcx>) -> bool;
|
|
|
|
hook alloc_self_profile_query_strings() -> ();
|
|
|
|
/// Saves and writes the DepGraph to the file system.
|
|
///
|
|
/// This function saves both the dep-graph and the query result cache,
|
|
/// and drops the result cache.
|
|
///
|
|
/// This function should only run after all queries have completed.
|
|
/// Trying to execute a query afterwards would attempt to read the result cache we just dropped.
|
|
hook save_dep_graph() -> ();
|
|
|
|
hook query_key_hash_verify_all() -> ();
|
|
|
|
/// Ensure the given scalar is valid for the given type.
|
|
/// This checks non-recursive runtime validity.
|
|
hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool;
|
|
}
|
|
|
|
#[cold]
|
|
fn default_hook(name: &str, args: &dyn std::fmt::Debug) -> ! {
|
|
bug!(
|
|
"`tcx.{name}{args:?}` cannot be called as `{name}` was never assigned to a provider function"
|
|
)
|
|
}
|