Skip to content

Commit 17dddea

Browse files
authored
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.
2 parents 63fc853 + 79b3963 commit 17dddea

File tree

1 file changed

+11
-3
lines changed
  • compiler/rustc_data_structures/src

1 file changed

+11
-3
lines changed

compiler/rustc_data_structures/src/steal.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::stable_hasher::{HashStable, StableHasher};
2-
use crate::sync::{MappedReadGuard, ReadGuard, RwLock};
2+
use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard};
33

44
/// The `Steal` struct is intended to used as the value for a query.
55
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
@@ -40,9 +40,17 @@ impl<T> Steal<T> {
4040
ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
4141
}
4242

43+
/// An escape hatch for rustc drivers to mutate `Steal` caches.
44+
///
45+
/// Use at your own risk. This can badly break incremental compilation
46+
/// and anything else that relies on the immutability of query caches.
4347
#[track_caller]
44-
pub fn get_mut(&mut self) -> &mut T {
45-
self.value.get_mut().as_mut().expect("attempt to read from stolen value")
48+
pub fn risky_hack_borrow_mut(&self) -> MappedWriteGuard<'_, T> {
49+
let borrow = self.value.borrow_mut();
50+
if borrow.is_none() {
51+
panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
52+
}
53+
WriteGuard::map(borrow, |opt| opt.as_mut().unwrap())
4654
}
4755

4856
#[track_caller]

0 commit comments

Comments
 (0)