Optionally don't steal the THIR

This commit is contained in:
Nadrieril
2025-06-01 17:29:33 +02:00
parent 9b0268a43b
commit 1e169d8dc4
5 changed files with 25 additions and 4 deletions

View File

@@ -715,6 +715,7 @@ fn test_unstable_options_tracking_hash() {
untracked!(no_analysis, true); untracked!(no_analysis, true);
untracked!(no_leak_check, true); untracked!(no_leak_check, true);
untracked!(no_parallel_backend, true); untracked!(no_parallel_backend, true);
untracked!(no_steal_thir, true);
untracked!(parse_crate_root_only, true); untracked!(parse_crate_root_only, true);
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`. // `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]); untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);

View File

@@ -535,7 +535,8 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
/// Fetch the THIR for a given body. /// 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> { query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
// Perf tests revealed that hashing THIR is inefficient (see #85729). // Perf tests revealed that hashing THIR is inefficient (see #85729).
no_hash no_hash

View File

@@ -201,9 +201,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
/// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body. /// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body.
fn visit_inner_body(&mut self, def: LocalDefId) { fn visit_inner_body(&mut self, def: LocalDefId) {
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) { if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
// Runs all other queries that depend on THIR. // Run all other queries that depend on THIR.
self.tcx.ensure_done().mir_built(def); self.tcx.ensure_done().mir_built(def);
let inner_thir = &inner_thir.steal(); let inner_thir = if self.tcx.sess.opts.unstable_opts.no_steal_thir {
&inner_thir.borrow()
} else {
// We don't have other use for the THIR. Steal it to reduce memory usage.
&inner_thir.steal()
};
let hir_context = self.tcx.local_def_id_to_hir_id(def); let hir_context = self.tcx.local_def_id_to_hir_id(def);
let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe); let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
let mut inner_visitor = UnsafetyVisitor { let mut inner_visitor = UnsafetyVisitor {
@@ -1157,7 +1162,12 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
let Ok((thir, expr)) = tcx.thir_body(def) else { return }; let Ok((thir, expr)) = tcx.thir_body(def) else { return };
// Runs all other queries that depend on THIR. // Runs all other queries that depend on THIR.
tcx.ensure_done().mir_built(def); tcx.ensure_done().mir_built(def);
let thir = &thir.steal(); let thir = if tcx.sess.opts.unstable_opts.no_steal_thir {
&thir.borrow()
} else {
// We don't have other use for the THIR. Steal it to reduce memory usage.
&thir.steal()
};
let hir_id = tcx.local_def_id_to_hir_id(def); let hir_id = tcx.local_def_id_to_hir_id(def);
let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {

View File

@@ -2366,6 +2366,8 @@ options! {
"run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
no_profiler_runtime: bool = (false, parse_no_value, [TRACKED], no_profiler_runtime: bool = (false, parse_no_value, [TRACKED],
"prevent automatic injection of the profiler_builtins crate"), "prevent automatic injection of the profiler_builtins crate"),
no_steal_thir: bool = (false, parse_bool, [UNTRACKED],
"don't steal the THIR when we're done with it; useful for rustc drivers (default: no)"),
no_trait_vptr: bool = (false, parse_no_value, [TRACKED], no_trait_vptr: bool = (false, parse_no_value, [TRACKED],
"disable generation of trait vptr in vtable for upcasting"), "disable generation of trait vptr in vtable for upcasting"),
no_unique_section_names: bool = (false, parse_bool, [TRACKED], no_unique_section_names: bool = (false, parse_bool, [TRACKED],

View File

@@ -0,0 +1,7 @@
# `no-steal-thir`
By default, to save on memory, the THIR body (obtained from the `tcx.thir_body` query) is stolen
once no longer used. This is inconvenient for authors of rustc drivers who want to access the THIR.
This option disables the stealing. This has no observable effect on compiler behavior, only on
memory usage.