mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
only remove keys that mention skolemized regions
This commit is contained in:
@@ -839,6 +839,9 @@ pub fn pop_skolemized(&self,
|
||||
debug!("pop_skolemized({:?})", skol_map);
|
||||
let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect();
|
||||
self.region_vars.pop_skolemized(&skol_regions, &snapshot.region_vars_snapshot);
|
||||
self.projection_cache.borrow_mut().partial_rollback(&snapshot.projection_cache_snapshot);
|
||||
if !skol_map.is_empty() {
|
||||
self.projection_cache.borrow_mut().rollback_skolemized(
|
||||
&snapshot.projection_cache_snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1398,8 +1398,8 @@ pub fn rollback_to(&mut self, snapshot: ProjectionCacheSnapshot) {
|
||||
self.map.rollback_to(snapshot.snapshot);
|
||||
}
|
||||
|
||||
pub fn partial_rollback(&mut self, snapshot: &ProjectionCacheSnapshot) {
|
||||
self.map.partial_rollback(&snapshot.snapshot);
|
||||
pub fn rollback_skolemized(&mut self, snapshot: &ProjectionCacheSnapshot) {
|
||||
self.map.partial_rollback(&snapshot.snapshot, &|k| k.has_re_skol());
|
||||
}
|
||||
|
||||
pub fn commit(&mut self, snapshot: ProjectionCacheSnapshot) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, Ty, TypeFlags, TypeFoldable};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FlagComputation {
|
||||
pub flags: TypeFlags,
|
||||
|
||||
@@ -182,24 +183,9 @@ fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) {
|
||||
}
|
||||
|
||||
fn add_region(&mut self, r: &ty::Region) {
|
||||
match *r {
|
||||
ty::ReVar(..) => {
|
||||
self.add_flags(TypeFlags::HAS_RE_INFER);
|
||||
self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
|
||||
}
|
||||
ty::ReSkolemized(..) => {
|
||||
self.add_flags(TypeFlags::HAS_RE_INFER);
|
||||
self.add_flags(TypeFlags::HAS_RE_SKOL);
|
||||
self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
|
||||
}
|
||||
ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
|
||||
ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
|
||||
ty::ReStatic | ty::ReErased => {}
|
||||
_ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
|
||||
}
|
||||
|
||||
if !r.is_global() {
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
self.add_flags(r.type_flags());
|
||||
if let ty::ReLateBound(debruijn, _) = *r {
|
||||
self.add_depth(debruijn.depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-17
@@ -91,6 +91,9 @@ fn needs_infer(&self) -> bool {
|
||||
fn needs_subst(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::NEEDS_SUBST)
|
||||
}
|
||||
fn has_re_skol(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_SKOL)
|
||||
}
|
||||
fn has_closure_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
|
||||
}
|
||||
@@ -632,26 +635,15 @@ struct HasTypeFlagsVisitor {
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
||||
fn visit_ty(&mut self, t: Ty) -> bool {
|
||||
t.flags.get().intersects(self.flags)
|
||||
let flags = t.flags.get();
|
||||
debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, flags, self.flags);
|
||||
flags.intersects(self.flags)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
||||
if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) {
|
||||
// does this represent a region that cannot be named
|
||||
// in a global way? used in fulfillment caching.
|
||||
match *r {
|
||||
ty::ReStatic | ty::ReEmpty | ty::ReErased => {}
|
||||
_ => return true,
|
||||
}
|
||||
}
|
||||
if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER |
|
||||
ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
|
||||
match *r {
|
||||
ty::ReVar(_) | ty::ReSkolemized(..) => { return true }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
false
|
||||
let flags = r.type_flags();
|
||||
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
|
||||
flags.intersects(self.flags)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -477,6 +477,7 @@ pub enum FragmentInfo {
|
||||
TypeFlags::HAS_SELF.bits |
|
||||
TypeFlags::HAS_TY_INFER.bits |
|
||||
TypeFlags::HAS_RE_INFER.bits |
|
||||
TypeFlags::HAS_RE_SKOL.bits |
|
||||
TypeFlags::HAS_RE_EARLY_BOUND.bits |
|
||||
TypeFlags::HAS_FREE_REGIONS.bits |
|
||||
TypeFlags::HAS_TY_ERR.bits |
|
||||
|
||||
+30
-1
@@ -406,7 +406,7 @@ pub fn map_bound<F,U>(self, f: F) -> Binder<U>
|
||||
|
||||
impl fmt::Debug for TypeFlags {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.bits)
|
||||
write!(f, "{:x}", self.bits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,6 +866,35 @@ pub fn from_depth(&self, depth: u32) -> Region {
|
||||
r => r
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_flags(&self) -> TypeFlags {
|
||||
let mut flags = TypeFlags::empty();
|
||||
|
||||
match *self {
|
||||
ty::ReVar(..) => {
|
||||
flags = flags | TypeFlags::HAS_RE_INFER;
|
||||
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
|
||||
}
|
||||
ty::ReSkolemized(..) => {
|
||||
flags = flags | TypeFlags::HAS_RE_INFER;
|
||||
flags = flags | TypeFlags::HAS_RE_SKOL;
|
||||
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
|
||||
}
|
||||
ty::ReLateBound(..) => { }
|
||||
ty::ReEarlyBound(..) => { flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; }
|
||||
ty::ReStatic | ty::ReErased => { }
|
||||
_ => { flags = flags | TypeFlags::HAS_FREE_REGIONS; }
|
||||
}
|
||||
|
||||
match *self {
|
||||
ty::ReStatic | ty::ReEmpty | ty::ReErased => (),
|
||||
_ => flags = flags | TypeFlags::HAS_LOCAL_NAMES,
|
||||
}
|
||||
|
||||
debug!("type_flags({:?}) = {:?}", self, flags);
|
||||
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
||||
// Type utilities
|
||||
|
||||
@@ -102,15 +102,19 @@ pub fn commit(&mut self, snapshot: Snapshot) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn partial_rollback(&mut self, snapshot: &Snapshot) {
|
||||
pub fn partial_rollback<F>(&mut self,
|
||||
snapshot: &Snapshot,
|
||||
should_revert_key: &F)
|
||||
where F: Fn(&K) -> bool
|
||||
{
|
||||
self.assert_open_snapshot(snapshot);
|
||||
for i in (snapshot.len + 1..self.undo_log.len()).rev() {
|
||||
let reverse = match self.undo_log[i] {
|
||||
UndoLog::OpenSnapshot => false,
|
||||
UndoLog::CommittedSnapshot => false,
|
||||
UndoLog::Noop => false,
|
||||
UndoLog::Inserted(..) => true,
|
||||
UndoLog::Overwrite(..) => true,
|
||||
UndoLog::Inserted(ref k) => should_revert_key(k),
|
||||
UndoLog::Overwrite(ref k, _) => should_revert_key(k),
|
||||
};
|
||||
|
||||
if reverse {
|
||||
|
||||
Reference in New Issue
Block a user