Skip to content

Commit

Permalink
rewrite leak check to be based on universes
Browse files Browse the repository at this point in the history
In the new leak check, instead of getting a list of placeholders to
track, we look for any placeholder that is part of a universe which
was created during the snapshot.

We are looking for the following error patterns:

* P1: P2, where P1 != P2
* P1: R, where R is in some universe that cannot name P1

This new leak check is more precise than before, in that it accepts
this patterns:

* R: P1, even if R cannot name P1, because R = 'static is a valid
sol'n
* R: P1, R: P2, as above

Note that this leak check, when running during subtyping, is less
efficient than before in some sense because it is going to check and
re-check all the universes created since the snapshot. We're going to
move when the leak check runs to try and correct that.
  • Loading branch information
nikomatsakis committed Jun 22, 2020
1 parent 4199b3a commit f2cf994
Show file tree
Hide file tree
Showing 29 changed files with 571 additions and 319 deletions.
7 changes: 3 additions & 4 deletions src/librustc_infer/infer/higher_ranked/mod.rs
Expand Up @@ -33,7 +33,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
self.infcx.commit_if_ok(|snapshot| {
// First, we instantiate each bound region in the supertype with a
// fresh placeholder region.
let (b_prime, placeholder_map) = self.infcx.replace_bound_vars_with_placeholders(b);
let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b);

// Next, we instantiate each bound region in the subtype
// with a fresh region variable. These region variables --
Expand All @@ -48,7 +48,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
// Compare types now that bound regions have been replaced.
let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?;

self.infcx.leak_check(!a_is_expected, &placeholder_map, snapshot)?;
self.infcx.leak_check(!a_is_expected, snapshot)?;

debug!("higher_ranked_sub: OK result={:?}", result);

Expand Down Expand Up @@ -119,7 +119,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn leak_check(
&self,
overly_polymorphic: bool,
placeholder_map: &PlaceholderMap<'tcx>,
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> RelateResult<'tcx, ()> {
// If the user gave `-Zno-leak-check`, or we have been
Expand All @@ -135,7 +134,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().leak_check(
self.tcx,
overly_polymorphic,
placeholder_map,
self.universe(),
snapshot,
)
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_infer/infer/mod.rs
Expand Up @@ -992,12 +992,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

Some(self.commit_if_ok(|snapshot| {
let (ty::SubtypePredicate { a_is_expected, a, b }, placeholder_map) =
let (ty::SubtypePredicate { a_is_expected, a, b }, _) =
self.replace_bound_vars_with_placeholders(&predicate);

let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;

self.leak_check(false, &placeholder_map, snapshot)?;
self.leak_check(false, snapshot)?;

Ok(ok.unit())
}))
Expand All @@ -1009,13 +1009,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
) -> UnitResult<'tcx> {
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
let (ty::OutlivesPredicate(r_a, r_b), _) =
self.replace_bound_vars_with_placeholders(&predicate);
let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span)
});
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
self.leak_check(false, &placeholder_map, snapshot)?;
self.leak_check(false, snapshot)?;
Ok(())
})
}
Expand Down

0 comments on commit f2cf994

Please sign in to comment.