Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0702a42

Browse files
committed
Rejigger handling of VerifyIfEq
1 parent e143ec4 commit 0702a42

File tree

3 files changed

+40
-31
lines changed

3 files changed

+40
-31
lines changed

compiler/rustc_borrowck/src/eliminate_placeholders.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ use rustc_data_structures::fx::FxHashSet;
1212
use rustc_data_structures::graph::scc::{self, Sccs};
1313
use rustc_index::IndexVec;
1414
use rustc_infer::infer::NllRegionVariableOrigin;
15-
use rustc_infer::infer::outlives::test_type_match;
15+
use rustc_infer::infer::outlives::test_type_match::MatchAgainstHigherRankedOutlives;
1616
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
17-
use rustc_middle::ty::{Region, RegionVid, TyCtxt, UniverseIndex};
17+
use rustc_infer::infer::relate::TypeRelation;
18+
use rustc_middle::ty::{self, Region, RegionVid, TyCtxt, UniverseIndex};
1819
use rustc_span::Span;
19-
use tracing::{debug, info, instrument, trace};
20+
use tracing::{debug, instrument, trace};
2021

2122
use crate::constraints::graph::{ConstraintGraph, Normal};
2223
use crate::constraints::{ConstraintSccIndex, OutlivesConstraintSet};
@@ -617,31 +618,39 @@ fn rewrite_verify_bound<'t>(
617618
// equality, and it does -- except that we do not track placeholders,
618619
// and so in the event that you have two empty regions, one of which is
619620
// in an unnameable universe, they would compare equal since they
620-
// are both empty. This bit checks if we
621-
VerifyBound::IfEq(binder) => {
622-
match test_type_match::extract_verify_if_eq(tcx, &binder, generic_kind.to_ty(tcx)) {
623-
Some(r) => {
624-
let r_vid = universal_regions.to_region_vid(r);
625-
let r_scc = scc_annotations[sccs.scc(r_vid)];
626-
let l_scc = scc_annotations[lower_scc];
627-
let in_same_universe = r_scc.universe_compatible_with(l_scc)
628-
&& l_scc.universe_compatible_with(r_scc);
629-
let reaches_same_placeholders =
630-
r_scc.reachable_placeholders == l_scc.reachable_placeholders;
631-
632-
if in_same_universe && reaches_same_placeholders {
633-
Either::Left(bound)
634-
} else {
635-
Either::Right(RewrittenVerifyBound::Unsatisfied)
636-
}
637-
}
638-
None => {
639-
info!(
640-
"Failed to extract type from {:#?}; assuming we are fine!",
641-
generic_kind.to_ty(tcx)
642-
);
643-
Either::Left(bound)
621+
// are both empty. This bit ensures that whatever comes out of the
622+
// bound also matches the placeholder reachability of the lower bound.
623+
VerifyBound::IfEq(verify_if_eq_b) => {
624+
let mut m = MatchAgainstHigherRankedOutlives::new(tcx);
625+
let verify_if_eq = verify_if_eq_b.skip_binder();
626+
// We ignore the error here because we are not concerned with if the
627+
// match actually held -- we can't tell that yet -- we just want to
628+
// see if the resulting region can't match for universe-related
629+
// reasons.
630+
let _what_error = m.relate(verify_if_eq.ty, generic_kind.to_ty(tcx));
631+
632+
let r = if let ty::RegionKind::ReBound(depth, br) = verify_if_eq.bound.kind() {
633+
assert!(depth == ty::INNERMOST);
634+
match m.map.get(&br) {
635+
Some(&r) => r,
636+
None => tcx.lifetimes.re_static,
644637
}
638+
} else {
639+
verify_if_eq.bound
640+
};
641+
642+
let r_vid = universal_regions.to_region_vid(r);
643+
let r_scc = scc_annotations[sccs.scc(r_vid)];
644+
let l_scc = scc_annotations[lower_scc];
645+
let in_same_universe =
646+
r_scc.universe_compatible_with(l_scc) && l_scc.universe_compatible_with(r_scc);
647+
let reaches_same_placeholders =
648+
r_scc.reachable_placeholders == l_scc.reachable_placeholders;
649+
650+
if in_same_universe && reaches_same_placeholders {
651+
Either::Left(bound)
652+
} else {
653+
Either::Right(RewrittenVerifyBound::Unsatisfied)
645654
}
646655
}
647656
// Rewrite an outlives bound to an outlives-static bound upon referencing

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2060,7 +2060,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20602060
}
20612061

20622062
/// Returns the representative `RegionVid` for a given SCC.
2063-
/// See [`RegionTracker`] for how a region variable ID is chosen.
2063+
/// See [`crate::eliminate_placeholders`] for how a region variable ID is chosen.
20642064
///
20652065
/// It is a hacky way to manage checking regions for equality,
20662066
/// since we can 'canonicalize' each region to the representative

compiler/rustc_infer/src/infer/outlives/test_type_match.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ pub(super) fn can_match_erased_ty<'tcx>(
8686
}
8787
}
8888

89-
struct MatchAgainstHigherRankedOutlives<'tcx> {
89+
pub struct MatchAgainstHigherRankedOutlives<'tcx> {
9090
tcx: TyCtxt<'tcx>,
9191
pattern_depth: ty::DebruijnIndex,
92-
map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
92+
pub map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
9393
}
9494

9595
impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
96-
fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstHigherRankedOutlives<'tcx> {
96+
pub fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstHigherRankedOutlives<'tcx> {
9797
MatchAgainstHigherRankedOutlives {
9898
tcx,
9999
pattern_depth: ty::INNERMOST,

0 commit comments

Comments
 (0)