Rollup merge of #148480 - Lysxia:steal-mut, r=davidtwco

Add `Steal::risky_hack_borrow_mut`

I'm working on a rustc driver (Creusot) which needs to modify the MIR read by two queries, `mir_borrowck` and `check_liveness`, in different ways for each query. Both of these queries use `mir_promoted` to read the MIR, which is immutable (until it is stolen).

This adds an escape hatch so rustc drivers can mutate MIR for specific queries. And this removes `get_mut` which is unused and also unusable now that there's no way to get a `&mut Steal` from the rustc API.

Another approach may be to override the queries to modify the MIR after having read it from `mir_promoted`. However the implementation of queries is largely hidden, so I can't just copy their code to then modify it. A solution would be to parameterize the queries with callbacks which get instantiated with `mir_promoted` by default, but that seems more involved and ad hoc. That's why I'm proposing this smaller change instead.
This commit is contained in:
Stuart Cook
2025-11-11 21:09:36 +11:00
committed by GitHub
+11 -3
View File
@@ -1,5 +1,5 @@
use crate::stable_hasher::{HashStable, StableHasher};
use crate::sync::{MappedReadGuard, ReadGuard, RwLock};
use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard};
/// The `Steal` struct is intended to used as the value for a query.
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
@@ -40,9 +40,17 @@ pub fn borrow(&self) -> MappedReadGuard<'_, T> {
ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
}
/// An escape hatch for rustc drivers to mutate `Steal` caches.
///
/// Use at your own risk. This can badly break incremental compilation
/// and anything else that relies on the immutability of query caches.
#[track_caller]
pub fn get_mut(&mut self) -> &mut T {
self.value.get_mut().as_mut().expect("attempt to read from stolen value")
pub fn risky_hack_borrow_mut(&self) -> MappedWriteGuard<'_, T> {
let borrow = self.value.borrow_mut();
if borrow.is_none() {
panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
}
WriteGuard::map(borrow, |opt| opt.as_mut().unwrap())
}
#[track_caller]