Use a hook to decouple rustc_mir_transform from rustc_mir_build

This commit is contained in:
Zalathar 2026-01-10 21:18:01 +11:00
parent 1b9ae9eddc
commit 539e855008
6 changed files with 16 additions and 8 deletions

View file

@ -4360,7 +4360,6 @@ dependencies = [
"rustc_infer",
"rustc_macros",
"rustc_middle",
"rustc_mir_build",
"rustc_mir_dataflow",
"rustc_session",
"rustc_span",

View file

@ -102,6 +102,11 @@ declare_hooks! {
/// 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;
/// **Do not call this directly; call the `mir_built` query instead.**
///
/// Creates the MIR for a given `DefId`, including unreachable code.
hook build_mir_inner_impl(def: LocalDefId) -> mir::Body<'tcx>;
}
#[cold]

View file

@ -64,9 +64,11 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
.collect()
}
/// Create the MIR for a given `DefId`, including unreachable code. Do not call
/// this directly; instead use the cached version via `mir_built`.
pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
/// Create the MIR for a given `DefId`, including unreachable code.
///
/// This is the implementation of hook `build_mir_inner_impl`, which should only
/// be called by the query `mir_built`.
pub(crate) fn build_mir_inner_impl<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
tcx.ensure_done().thir_abstract_const(def);
if let Err(e) = tcx.ensure_ok().check_match(def) {
return construct_error(tcx, def, e);

View file

@ -12,7 +12,7 @@
// The `builder` module used to be named `build`, but that was causing GitHub's
// "Go to file" feature to silently ignore all files in the module, probably
// because it assumes that "build" is a build-output directory. See #134365.
pub mod builder;
mod builder;
mod check_tail_calls;
mod check_unsafety;
mod errors;
@ -30,4 +30,5 @@ pub fn provide(providers: &mut Providers) {
providers.check_unsafety = check_unsafety::check_unsafety;
providers.check_tail_calls = check_tail_calls::check_tail_calls;
providers.thir_body = thir::cx::thir_body;
providers.hooks.build_mir_inner_impl = builder::build_mir_inner_impl;
}

View file

@ -20,7 +20,6 @@ rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_mir_build = { path = "../rustc_mir_build" }
rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }

View file

@ -30,7 +30,6 @@ use rustc_middle::mir::{
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_middle::util::Providers;
use rustc_middle::{bug, query, span_bug};
use rustc_mir_build::builder::build_mir;
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, sym};
use tracing::debug;
@ -378,8 +377,11 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
validator.qualifs_in_return_place()
}
/// Implementation of the `mir_built` query.
fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
let mut body = build_mir(tcx, def);
// Delegate to the main MIR building code in the `rustc_mir_build` crate.
// This is the one place that is allowed to call `build_mir_inner_impl`.
let mut body = tcx.build_mir_inner_impl(def);
// Identifying trivial consts based on their mir_built is easy, but a little wasteful.
// Trying to push this logic earlier in the compiler and never even produce the Body would