Skip to content

Commit

Permalink
Rollup merge of rust-lang#114628 - cedihegi:master, r=oli-obk
Browse files Browse the repository at this point in the history
Allowing re-implementation of mir_drops_elaborated query

For our use case of the rust compiler interface (a rust verifier called [Prusti](https://github.com/viperproject/prusti-dev/)), it would be extremely useful if we were able to "copy" the implementation of the `mir_drops_elaborated_and_const_checked` query to override it. This would mean that the following items would need to be made public:
>https://github.com/rust-lang/rust/blob/6d55184d05c9bd3c46b294dcad3bfb1d0907e871/compiler/rustc_mir_transform/src/lib.rs#L434
>https://github.com/rust-lang/rust/blob/6d55184d05c9bd3c46b294dcad3bfb1d0907e871/compiler/rustc_mir_transform/src/inline.rs#L32
(for the latter its module needs to be public or it needs to be re-exported)

To explain why (we think) this is necessary: I am currently working on a new feature, where we try to modify the generated executables by inserting certain additional checks, and potentially perform some optimizations based on verification results.
We are using the rust compiler interface and most of our goals can be achieved by overriding queries, in our case this is currently `mir_drops_elaborated_and_const_checked`.

However, at the moment this approach is somewhat limited. When overriding queries, we can call and steal the base-query and then modify the results before allocating and returning those.
The problem is that the verification works with a copy of `mir_promoted`. For the modifications we want to make to the mir, we would often want to rely on results of the verifier that refer to Locations in the `mir_promoted`. We can not modify the `mir_promoted` query using these results, because to run the verification we also need the results of `mir_borrowck()`, which means `mir_promoted` will already be constructed and cached.
The Locations we get from the verifier are also no longer usable to modify `mir_drops_elaborated_and_const_checked`, because the MIR obviously changes between those 2 phases. Tracking all Locations between the two seems to be pretty much unfeasible, and would also be extremely unstable.

By being able to override the query with its original implementation, we could modify the MIR before drop elaboration and the various other passes are performed.

I have spent quite a bit of time investigating other solutions, and didn't find any other way solving this problem. If I still missed something I would of course be happy to hear any suggestions that do not require exposing more internal compiler functionality. However, I think being able to re-implement certain queries could also benefit other use cases in the future, for example in PR rust-lang#108328 one of the approaches discussed involved doing the same thing for `mir_promoted`.
  • Loading branch information
matthiaskrgr authored Aug 8, 2023
2 parents 5c5ae6c + 0166092 commit acf3791
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mod errors;
mod ffi_unwind_calls;
mod function_item_references;
mod generator;
mod inline;
pub mod inline;
mod instsimplify;
mod large_enums;
mod lower_intrinsics;
Expand Down Expand Up @@ -431,7 +431,9 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
tcx.alloc_steal_mir(body)
}

fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves.
pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
let did = body.source.def_id();

Expand Down

0 comments on commit acf3791

Please sign in to comment.