Skip to content

Commit

Permalink
only remove keys that mention skolemized regions
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Oct 21, 2016
1 parent 974817d commit 567b11f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 42 deletions.
5 changes: 4 additions & 1 deletion src/librustc/infer/higher_ranked/mod.rs
Expand Up @@ -839,6 +839,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
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);
}
}
}
4 changes: 2 additions & 2 deletions src/librustc/traits/project.rs
Expand Up @@ -1398,8 +1398,8 @@ impl<'tcx> ProjectionCache<'tcx> {
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) {
Expand Down
22 changes: 4 additions & 18 deletions src/librustc/ty/flags.rs
Expand Up @@ -11,6 +11,7 @@
use ty::subst::Substs;
use ty::{self, Ty, TypeFlags, TypeFoldable};

#[derive(Debug)]
pub struct FlagComputation {
pub flags: TypeFlags,

Expand Down Expand Up @@ -182,24 +183,9 @@ impl FlagComputation {
}

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);
}
}

Expand Down
26 changes: 9 additions & 17 deletions src/librustc/ty/fold.rs
Expand Up @@ -91,6 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
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)
}
Expand Down Expand Up @@ -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)
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/mod.rs
Expand Up @@ -477,6 +477,7 @@ bitflags! {
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 |
Expand Down
31 changes: 30 additions & 1 deletion src/librustc/ty/sty.rs
Expand Up @@ -406,7 +406,7 @@ impl<T> Binder<T> {

impl fmt::Debug for TypeFlags {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.bits)
write!(f, "{:x}", self.bits)
}
}

Expand Down Expand Up @@ -866,6 +866,35 @@ impl 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
Expand Down
10 changes: 7 additions & 3 deletions src/librustc_data_structures/snapshot_map/mod.rs
Expand Up @@ -102,15 +102,19 @@ impl<K, V> SnapshotMap<K, V>
}
}

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 {
Expand Down

0 comments on commit 567b11f

Please sign in to comment.