Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move leak-check to during coherence, candidate eval #72493

Merged
merged 13 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/librustc_infer/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {

let span = self.trace.cause.span;

self.infcx.commit_if_ok(|snapshot| {
self.infcx.commit_if_ok(|_| {
// 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,8 +48,6 @@ 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)?;

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

Ok(ty::Binder::bind(result))
Expand All @@ -75,7 +73,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
where
Copy link
Contributor

@matthewjasper matthewjasper Jun 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lcnr had some questions about this function. The doc comment appears to be outdated.
Also, the returned PlaceholderMap appears to be unused.

T: TypeFoldable<'tcx>,
{
let next_universe = self.create_next_universe();
// Figure out what the next universe will be, but don't actually create
// it until after we've done the substitution (in particular there may
// be no bound variables). This is a performance optimization, since the
// leak check for example can be skipped if no new universes are created
// (i.e., if there are no placeholders).
let next_universe = self.universe().next_universe();

let fld_r = |br| {
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
Expand Down Expand Up @@ -103,6 +106,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {

let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);

// If there were higher-ranked regions to replace, then actually create
// the next universe (this avoids needlessly creating universes).
if !map.is_empty() {
let n_u = self.create_next_universe();
assert_eq!(n_u, next_universe);
}

debug!(
"replace_bound_vars_with_placeholders(\
next_universe={:?}, \
Expand All @@ -119,7 +129,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 +144,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
11 changes: 4 additions & 7 deletions src/librustc_infer/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,14 +991,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return None;
}

Some(self.commit_if_ok(|snapshot| {
let (ty::SubtypePredicate { a_is_expected, a, b }, placeholder_map) =
Some(self.commit_if_ok(|_snapshot| {
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)?;

Ok(ok.unit())
}))
}
Expand All @@ -1008,14 +1006,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
cause: &traits::ObligationCause<'tcx>,
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
) -> UnitResult<'tcx> {
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
self.commit_if_ok(|_snapshot| {
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)?;
Ok(())
})
}
Expand Down
8 changes: 7 additions & 1 deletion src/librustc_infer/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,13 @@ where
}

if a == b {
return Ok(a);
// Subtle: if a or b has a bound variable that we are lazilly
// substituting, then even if a == b, it could be that the values we
// will substitute for those bound variables are *not* the same, and
// hence returning `Ok(a)` is incorrect.
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
return Ok(a);
}
}

match (&a.kind, &b.kind) {
Expand Down
Loading