Skip to content

Commit 95c4305

Browse files
committed
Try using MIR promoted.
1 parent 979a2e9 commit 95c4305

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

prusti-interface/src/environment/body.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ impl<'tcx> EnvBody<'tcx> {
143143
/// Get local MIR body of spec or pure functions. Retrieves the body from
144144
/// the compiler (relatively cheap).
145145
fn load_local_mir(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> MirBody<'tcx> {
146-
// Throw away the borrowck facts
147-
Self::load_local_mir_with_facts(tcx, def_id).body
146+
// SAFETY: This is safe because we are feeding in the same `tcx`
147+
// that was used to store the data.
148+
let body = unsafe { mir_storage::retrieve_promoted_mir_body(tcx, def_id) };
149+
MirBody(Rc::new(body))
148150
}
149151

150152
fn get_monomorphised(

prusti-interface/src/environment/mir_storage.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77
//! `'tcx`.
88
99
use prusti_rustc_interface::{
10-
borrowck::consumers::BodyWithBorrowckFacts, data_structures::fx::FxHashMap,
11-
hir::def_id::LocalDefId, middle::ty::TyCtxt,
10+
borrowck::consumers::BodyWithBorrowckFacts,
11+
data_structures::fx::FxHashMap,
12+
hir::def_id::LocalDefId,
13+
middle::{mir, ty::TyCtxt},
1214
};
1315
use std::{cell::RefCell, thread_local};
1416

1517
thread_local! {
16-
pub static SHARED_STATE:
18+
pub static SHARED_STATE_WITH_FACTS:
1719
RefCell<FxHashMap<LocalDefId, BodyWithBorrowckFacts<'static>>> =
1820
RefCell::new(FxHashMap::default());
21+
pub static SHARED_STATE_WITHOUT_FACTS:
22+
RefCell<FxHashMap<LocalDefId, mir::Body<'static>>> =
23+
RefCell::new(FxHashMap::default());
1924
}
2025

2126
/// # Safety
@@ -29,7 +34,7 @@ pub unsafe fn store_mir_body<'tcx>(
2934
// SAFETY: See the module level comment.
3035
let body_with_facts: BodyWithBorrowckFacts<'static> =
3136
unsafe { std::mem::transmute(body_with_facts) };
32-
SHARED_STATE.with(|state| {
37+
SHARED_STATE_WITH_FACTS.with(|state| {
3338
let mut map = state.borrow_mut();
3439
assert!(map.insert(def_id, body_with_facts).is_none());
3540
});
@@ -46,10 +51,39 @@ pub(super) unsafe fn retrieve_mir_body<'tcx>(
4651
_tcx: TyCtxt<'tcx>,
4752
def_id: LocalDefId,
4853
) -> BodyWithBorrowckFacts<'tcx> {
49-
let body_with_facts: BodyWithBorrowckFacts<'static> = SHARED_STATE.with(|state| {
54+
let body_with_facts: BodyWithBorrowckFacts<'static> = SHARED_STATE_WITH_FACTS.with(|state| {
5055
let mut map = state.borrow_mut();
5156
map.remove(&def_id).unwrap()
5257
});
5358
// SAFETY: See the module level comment.
5459
unsafe { std::mem::transmute(body_with_facts) }
5560
}
61+
62+
/// # Safety
63+
///
64+
/// See the module level comment.
65+
pub unsafe fn store_promoted_mir_body<'tcx>(
66+
_tcx: TyCtxt<'tcx>,
67+
def_id: LocalDefId,
68+
body: mir::Body<'tcx>,
69+
) {
70+
// SAFETY: See the module level comment.
71+
let body: mir::Body<'static> = unsafe { std::mem::transmute(body) };
72+
SHARED_STATE_WITHOUT_FACTS.with(|state| {
73+
let mut map = state.borrow_mut();
74+
assert!(map.insert(def_id, body).is_none());
75+
});
76+
}
77+
78+
#[allow(clippy::needless_lifetimes)] // We want to be very explicit about lifetimes here.
79+
pub(super) unsafe fn retrieve_promoted_mir_body<'tcx>(
80+
_tcx: TyCtxt<'tcx>,
81+
def_id: LocalDefId,
82+
) -> mir::Body<'tcx> {
83+
let body_without_facts: mir::Body<'static> = SHARED_STATE_WITHOUT_FACTS.with(|state| {
84+
let mut map = state.borrow_mut();
85+
map.remove(&def_id).unwrap()
86+
});
87+
// SAFETY: See the module level comment.
88+
unsafe { std::mem::transmute(body_without_facts) }
89+
}

prusti/src/callbacks.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ use prusti_interface::{
66
};
77
use prusti_rustc_interface::{
88
borrowck::consumers,
9+
data_structures::steal::Steal,
910
driver::Compilation,
1011
hir::{def::DefKind, def_id::LocalDefId},
12+
index::IndexVec,
1113
interface::{interface::Compiler, Config, Queries},
1214
middle::{
13-
mir::BorrowCheckResult,
15+
mir::{self, BorrowCheckResult},
1416
query::{ExternProviders, Providers},
1517
ty::TyCtxt,
1618
},
@@ -50,12 +52,33 @@ fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &BorrowCheckResu
5052
original_mir_borrowck(tcx, def_id)
5153
}
5254

55+
#[allow(clippy::needless_lifetimes)]
56+
#[tracing::instrument(level = "debug", skip(tcx))]
57+
fn mir_promoted<'tcx>(
58+
tcx: TyCtxt<'tcx>,
59+
def_id: LocalDefId,
60+
) -> (
61+
&'tcx Steal<mir::Body<'tcx>>,
62+
&'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>,
63+
) {
64+
let original_mir_promoted =
65+
prusti_rustc_interface::interface::DEFAULT_QUERY_PROVIDERS.mir_promoted;
66+
let result = original_mir_promoted(tcx, def_id);
67+
// SAFETY: This is safe because we are feeding in the same `tcx` that is
68+
// going to be used as a witness when pulling out the data.
69+
unsafe {
70+
mir_storage::store_promoted_mir_body(tcx, def_id, result.0.borrow().clone());
71+
}
72+
result
73+
}
74+
5375
impl prusti_rustc_interface::driver::Callbacks for PrustiCompilerCalls {
5476
fn config(&mut self, config: &mut Config) {
5577
assert!(config.override_queries.is_none());
5678
config.override_queries = Some(
5779
|_session: &Session, providers: &mut Providers, _external: &mut ExternProviders| {
5880
providers.mir_borrowck = mir_borrowck;
81+
providers.mir_promoted = mir_promoted;
5982
},
6083
);
6184
}

0 commit comments

Comments
 (0)