2023-09-30 20:33:22 +00:00
|
|
|
//! "Hooks" provide a way for `tcx` functionality to be provided by some downstream crate without
|
|
|
|
//! everything in rustc having to depend on that crate. 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.
|
|
|
|
|
2023-09-22 09:14:39 +00:00
|
|
|
use crate::mir;
|
|
|
|
use crate::query::TyCtxtAt;
|
|
|
|
use crate::ty::{Ty, TyCtxt};
|
2024-03-26 15:53:05 +00:00
|
|
|
use rustc_hir::def_id::{DefId, DefPathHash};
|
|
|
|
use rustc_session::StableCrateId;
|
2024-03-26 12:06:07 +00:00
|
|
|
use rustc_span::def_id::{CrateNum, LocalDefId};
|
2024-03-26 12:31:41 +00:00
|
|
|
use rustc_span::{ExpnHash, ExpnId, DUMMY_SP};
|
2023-09-22 09:14:39 +00:00
|
|
|
|
|
|
|
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.at(DUMMY_SP).$name($($arg,)*)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> TyCtxtAt<'tcx> {
|
|
|
|
$(
|
|
|
|
$(#[$attr])*
|
|
|
|
#[inline(always)]
|
2023-09-22 09:25:38 +00:00
|
|
|
#[instrument(level = "debug", skip(self), ret)]
|
2023-09-22 09:14:39 +00:00
|
|
|
pub fn $name(self, $($arg: $K,)*) -> $V
|
|
|
|
{
|
|
|
|
(self.tcx.hooks.$name)(self, $($arg,)*)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Providers {
|
|
|
|
$(pub $name: for<'tcx> fn(
|
|
|
|
TyCtxtAt<'tcx>,
|
|
|
|
$($arg: $K,)*
|
|
|
|
) -> $V,)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Providers {
|
|
|
|
fn default() -> Self {
|
|
|
|
Providers {
|
|
|
|
$($name: |_, $($arg,)*| bug!(
|
|
|
|
"`tcx.{}{:?}` cannot be called as `{}` was never assigned to a provider function.\n",
|
|
|
|
stringify!($name),
|
|
|
|
($($arg,)*),
|
|
|
|
stringify!($name),
|
|
|
|
),)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
2023-10-31 17:38:41 +00:00
|
|
|
hook try_destructure_mir_constant_for_user_output(val: mir::ConstValue<'tcx>, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;
|
2023-10-30 09:58:54 +00:00
|
|
|
|
|
|
|
/// Getting a &core::panic::Location referring to a span.
|
|
|
|
hook const_caller_location(file: rustc_span::Symbol, line: u32, col: u32) -> mir::ConstValue<'tcx>;
|
2024-02-08 01:21:22 +00:00
|
|
|
|
|
|
|
/// 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;
|
2024-03-19 10:17:15 +00:00
|
|
|
|
|
|
|
/// Create the MIR for a given `DefId` - this includes
|
|
|
|
/// unreachable code.
|
|
|
|
/// You do not want to call this yourself, instead use the cached version
|
2024-03-20 09:05:22 +00:00
|
|
|
/// via `mir_built`
|
2024-03-19 10:17:15 +00:00
|
|
|
hook build_mir(key: LocalDefId) -> mir::Body<'tcx>;
|
2024-03-26 12:06:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
/// 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) -> ();
|
2024-03-26 12:31:41 +00:00
|
|
|
|
|
|
|
hook expn_hash_to_expn_id(
|
|
|
|
cnum: CrateNum,
|
|
|
|
index_guess: u32,
|
|
|
|
hash: ExpnHash
|
|
|
|
) -> ExpnId;
|
2024-03-26 15:53:05 +00:00
|
|
|
|
|
|
|
/// 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;
|
2023-09-22 09:14:39 +00:00
|
|
|
}
|