Store Option<Region> as value for RegionVid
This commit is contained in:
parent
e8c284ff28
commit
61157b341e
14 changed files with 172 additions and 84 deletions
|
@ -304,6 +304,15 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let r = self
|
||||
.infcx
|
||||
.unwrap()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_region(tcx, r);
|
||||
|
||||
match *r {
|
||||
ty::ReLateBound(index, ..) => {
|
||||
if index >= self.binder_index {
|
||||
|
@ -313,22 +322,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::ReVar(vid) => {
|
||||
let resolved_vid = self
|
||||
.infcx
|
||||
.unwrap()
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(vid);
|
||||
debug!(
|
||||
"canonical: region var found with vid {:?}, \
|
||||
opportunistically resolved to {:?}",
|
||||
vid, r
|
||||
);
|
||||
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
||||
self.canonicalize_region_mode.canonicalize_free_region(self, r)
|
||||
}
|
||||
ty::ReVar(_) => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||
|
||||
ty::ReStatic
|
||||
| ty::ReEarlyBound(..)
|
||||
|
|
|
@ -11,9 +11,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::undo_log::UndoLogs;
|
||||
use rustc_data_structures::unify as ut;
|
||||
use rustc_data_structures::unify::UnifyKey;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
|
||||
use rustc_middle::ty::ReStatic;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ReLateBound, ReVar};
|
||||
|
@ -47,13 +47,13 @@ pub struct RegionConstraintStorage<'tcx> {
|
|||
|
||||
/// When we add a R1 == R2 constriant, we currently add (a) edges
|
||||
/// R1 <= R2 and R2 <= R1 and (b) we unify the two regions in this
|
||||
/// table. You can then call `opportunistic_resolve_var` early
|
||||
/// table. You can then call `opportunistic_resolve_region` early
|
||||
/// which will map R1 and R2 to some common region (i.e., either
|
||||
/// R1 or R2). This is important when fulfillment, dropck and other such
|
||||
/// code is iterating to a fixed point, because otherwise we sometimes
|
||||
/// would wind up with a fresh stream of region variables that have been
|
||||
/// equated but appear distinct.
|
||||
pub(super) unification_table: ut::UnificationTableStorage<ty::RegionVid>,
|
||||
pub(super) unification_table: ut::UnificationTableStorage<RegionVidKey<'tcx>>,
|
||||
|
||||
/// a flag set to true when we perform any unifications; this is used
|
||||
/// to micro-optimize `take_and_reset_data`
|
||||
|
@ -406,8 +406,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
// `RegionConstraintData` contains the relationship here.
|
||||
if *any_unifications {
|
||||
*any_unifications = false;
|
||||
self.unification_table()
|
||||
.reset_unifications(|_| ());
|
||||
self.unification_table().reset_unifications(|_| UnifiedRegion(None));
|
||||
}
|
||||
|
||||
data
|
||||
|
@ -434,8 +433,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
) -> RegionVid {
|
||||
let vid = self.var_infos.push(RegionVariableInfo { origin, universe });
|
||||
|
||||
let u_vid = self.unification_table().new_key(());
|
||||
assert_eq!(vid, u_vid);
|
||||
let u_vid = self.unification_table().new_key(UnifiedRegion(None));
|
||||
assert_eq!(vid, u_vid.vid);
|
||||
self.undo_log.push(AddVar(vid));
|
||||
debug!("created new region variable {:?} in {:?} with origin {:?}", vid, universe, origin);
|
||||
vid
|
||||
|
@ -497,10 +496,18 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
self.make_subregion(origin.clone(), sub, sup);
|
||||
self.make_subregion(origin, sup, sub);
|
||||
|
||||
if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) {
|
||||
debug!("make_eqregion: uniying {:?} with {:?}", sub, sup);
|
||||
self.unification_table().union(sub, sup);
|
||||
self.any_unifications = true;
|
||||
match (sub, sup) {
|
||||
(&ty::ReVar(sub), &ty::ReVar(sup)) => {
|
||||
debug!("make_eqregion: unifying {:?} with {:?}", sub, sup);
|
||||
self.unification_table().union(sub, sup);
|
||||
self.any_unifications = true;
|
||||
}
|
||||
(&ty::ReVar(vid), value) | (value, &ty::ReVar(vid)) => {
|
||||
debug!("make_eqregion: unifying {:?} with {:?}", vid, value);
|
||||
self.unification_table().union_value(vid, UnifiedRegion(Some(value)));
|
||||
self.any_unifications = true;
|
||||
}
|
||||
(_, _) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -616,8 +623,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn opportunistic_resolve_var(&mut self, rid: RegionVid) -> ty::RegionVid {
|
||||
self.unification_table().find(rid)
|
||||
pub fn opportunistic_resolve_region(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
match region {
|
||||
ty::ReVar(rid) => {
|
||||
let unified_region = self.unification_table().probe_value(*rid);
|
||||
unified_region.0.unwrap_or_else(|| {
|
||||
let root = self.unification_table().find(*rid).vid;
|
||||
tcx.reuse_or_mk_region(region, ty::ReVar(root))
|
||||
})
|
||||
}
|
||||
_ => region,
|
||||
}
|
||||
}
|
||||
|
||||
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
|
||||
|
@ -672,8 +692,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
&self,
|
||||
value_count: usize,
|
||||
) -> (Range<RegionVid>, Vec<RegionVariableOrigin>) {
|
||||
let range = RegionVid::from_index(value_count as u32)
|
||||
..RegionVid::from_index(self.unification_table.len() as u32);
|
||||
let range = RegionVid::from(value_count as u32)
|
||||
..RegionVid::from(self.unification_table.len() as u32);
|
||||
(
|
||||
range.clone(),
|
||||
(range.start.index()..range.end.index())
|
||||
|
@ -695,7 +715,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn unification_table(&mut self) -> super::UnificationTable<'_, 'tcx, ty::RegionVid> {
|
||||
fn unification_table(&mut self) -> super::UnificationTable<'_, 'tcx, RegionVidKey<'tcx>> {
|
||||
ut::UnificationTable::with_log(&mut self.storage.unification_table, self.undo_log)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,18 +84,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
ty::ReVar(rid) => {
|
||||
let resolved = self
|
||||
.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(rid);
|
||||
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
|
||||
}
|
||||
_ => r,
|
||||
}
|
||||
let tcx = self.tcx();
|
||||
self.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_region(tcx, r)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::marker::PhantomData;
|
|||
use rustc_data_structures::snapshot_vec as sv;
|
||||
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
|
||||
use rustc_data_structures::unify as ut;
|
||||
use rustc_middle::infer::unify_key::RegionVidKey;
|
||||
use rustc_middle::ty;
|
||||
|
||||
use crate::{
|
||||
|
@ -22,7 +23,7 @@ pub(crate) enum UndoLog<'tcx> {
|
|||
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
|
||||
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
|
||||
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<ty::RegionVid>>),
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
|
||||
ProjectionCache(traits::UndoLog<'tcx>),
|
||||
PushRegionObligation,
|
||||
}
|
||||
|
@ -55,7 +56,7 @@ impl_from! {
|
|||
|
||||
ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
|
||||
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<ty::RegionVid>>),
|
||||
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
|
||||
ProjectionCache(traits::UndoLog<'tcx>),
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue