about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-09 19:09:29 +0200
committerGitHub <noreply@github.com>2024-05-09 19:09:29 +0200
commitebeedf05cb2208c2cb8156f4582524ba232ef702 (patch)
tree173981694bf47907812ae6fbdad7a62e36f5af35
parent8c7c151a7a03d92cc5c75c49aa82a658ec1fe4ff (diff)
parentd4c6c772c39780769786a299df7b522503d86fca (diff)
downloadrust-ebeedf05cb2208c2cb8156f4582524ba232ef702.tar.gz
rust-ebeedf05cb2208c2cb8156f4582524ba232ef702.zip
Rollup merge of #124893 - xldenis:public-region-apis, r=lcnr
Make a minimal amount of region APIs public

Tools like Creusot, Prusti or Gillian-Rust need to access information about the loans and regions that exist in MIR programs. While `rustc` provides information about loans, there is currently no public way to reason about the regions present in a MIR program. In particular, we to know which regions are actually equal to each other and which ones outlive each other. Currently, `rustc` provides access to `RegionInferenceContext` but the public api hides that last portion of the information.

This PR proposes to make a few apis public, allowing verifiers to reason about the lifetimes present in Rust programs:
- [eval_equal](https://doc.rust-lang.org/beta/nightly-rustc/rustc_borrowck/region_infer/struct.RegionInferenceContext.html#method.eval_equal)
- [eval_outlives](https://doc.rust-lang.org/beta/nightly-rustc/rustc_borrowck/region_infer/struct.RegionInferenceContext.html#method.eval_outlives)
- (Optional) [constraint_sccs](https://doc.rust-lang.org/beta/nightly-rustc/rustc_borrowck/region_infer/struct.RegionInferenceContext.html#method.constraint_sccs)

The first two functions would allow us to compare regions and from this we can construct the set of `RegionVid` which are actually equal to each other, and then recover the inclusions between those regions, while the second allows for more direct, but _low level_ access to that information.
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs19
1 files changed, 14 insertions, 5 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 54574446b55..27933536166 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1326,14 +1326,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         })
     }
 
-    // Evaluate whether `sup_region == sub_region`.
-    fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
+    /// Evaluate whether `sup_region == sub_region`.
+    ///
+    /// Panics if called before `solve()` executes,
+    // This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
+    pub fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
         self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1)
     }
 
-    // Evaluate whether `sup_region: sub_region`.
+    /// Evaluate whether `sup_region: sub_region`.
+    ///
+    /// Panics if called before `solve()` executes,
+    // This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
     #[instrument(skip(self), level = "debug", ret)]
-    fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
+    pub fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
         debug!(
             "sup_region's value = {:?} universal={:?}",
             self.region_value_str(sup_region),
@@ -2246,7 +2252,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Access to the SCC constraint graph.
-    pub(crate) fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
+    /// This can be used to quickly under-approximate the regions which are equal to each other
+    /// and their relative orderings.
+    // This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
+    pub fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
         self.constraint_sccs.as_ref()
     }