Skip to content

Commit 567b11f

Browse files
committed
only remove keys that mention skolemized regions
1 parent 974817d commit 567b11f

File tree

7 files changed

+57
-42
lines changed

7 files changed

+57
-42
lines changed

src/librustc/infer/higher_ranked/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
839839
debug!("pop_skolemized({:?})", skol_map);
840840
let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect();
841841
self.region_vars.pop_skolemized(&skol_regions, &snapshot.region_vars_snapshot);
842-
self.projection_cache.borrow_mut().partial_rollback(&snapshot.projection_cache_snapshot);
842+
if !skol_map.is_empty() {
843+
self.projection_cache.borrow_mut().rollback_skolemized(
844+
&snapshot.projection_cache_snapshot);
845+
}
843846
}
844847
}

src/librustc/traits/project.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1398,8 +1398,8 @@ impl<'tcx> ProjectionCache<'tcx> {
13981398
self.map.rollback_to(snapshot.snapshot);
13991399
}
14001400

1401-
pub fn partial_rollback(&mut self, snapshot: &ProjectionCacheSnapshot) {
1402-
self.map.partial_rollback(&snapshot.snapshot);
1401+
pub fn rollback_skolemized(&mut self, snapshot: &ProjectionCacheSnapshot) {
1402+
self.map.partial_rollback(&snapshot.snapshot, &|k| k.has_re_skol());
14031403
}
14041404

14051405
pub fn commit(&mut self, snapshot: ProjectionCacheSnapshot) {

src/librustc/ty/flags.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use ty::subst::Substs;
1212
use ty::{self, Ty, TypeFlags, TypeFoldable};
1313

14+
#[derive(Debug)]
1415
pub struct FlagComputation {
1516
pub flags: TypeFlags,
1617

@@ -182,24 +183,9 @@ impl FlagComputation {
182183
}
183184

184185
fn add_region(&mut self, r: &ty::Region) {
185-
match *r {
186-
ty::ReVar(..) => {
187-
self.add_flags(TypeFlags::HAS_RE_INFER);
188-
self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
189-
}
190-
ty::ReSkolemized(..) => {
191-
self.add_flags(TypeFlags::HAS_RE_INFER);
192-
self.add_flags(TypeFlags::HAS_RE_SKOL);
193-
self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
194-
}
195-
ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
196-
ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
197-
ty::ReStatic | ty::ReErased => {}
198-
_ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
199-
}
200-
201-
if !r.is_global() {
202-
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
186+
self.add_flags(r.type_flags());
187+
if let ty::ReLateBound(debruijn, _) = *r {
188+
self.add_depth(debruijn.depth);
203189
}
204190
}
205191

src/librustc/ty/fold.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
9191
fn needs_subst(&self) -> bool {
9292
self.has_type_flags(TypeFlags::NEEDS_SUBST)
9393
}
94+
fn has_re_skol(&self) -> bool {
95+
self.has_type_flags(TypeFlags::HAS_RE_SKOL)
96+
}
9497
fn has_closure_types(&self) -> bool {
9598
self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
9699
}
@@ -632,26 +635,15 @@ struct HasTypeFlagsVisitor {
632635

633636
impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
634637
fn visit_ty(&mut self, t: Ty) -> bool {
635-
t.flags.get().intersects(self.flags)
638+
let flags = t.flags.get();
639+
debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, flags, self.flags);
640+
flags.intersects(self.flags)
636641
}
637642

638643
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
639-
if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) {
640-
// does this represent a region that cannot be named
641-
// in a global way? used in fulfillment caching.
642-
match *r {
643-
ty::ReStatic | ty::ReEmpty | ty::ReErased => {}
644-
_ => return true,
645-
}
646-
}
647-
if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER |
648-
ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
649-
match *r {
650-
ty::ReVar(_) | ty::ReSkolemized(..) => { return true }
651-
_ => {}
652-
}
653-
}
654-
false
644+
let flags = r.type_flags();
645+
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
646+
flags.intersects(self.flags)
655647
}
656648
}
657649

src/librustc/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ bitflags! {
477477
TypeFlags::HAS_SELF.bits |
478478
TypeFlags::HAS_TY_INFER.bits |
479479
TypeFlags::HAS_RE_INFER.bits |
480+
TypeFlags::HAS_RE_SKOL.bits |
480481
TypeFlags::HAS_RE_EARLY_BOUND.bits |
481482
TypeFlags::HAS_FREE_REGIONS.bits |
482483
TypeFlags::HAS_TY_ERR.bits |

src/librustc/ty/sty.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl<T> Binder<T> {
406406

407407
impl fmt::Debug for TypeFlags {
408408
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409-
write!(f, "{}", self.bits)
409+
write!(f, "{:x}", self.bits)
410410
}
411411
}
412412

@@ -866,6 +866,35 @@ impl Region {
866866
r => r
867867
}
868868
}
869+
870+
pub fn type_flags(&self) -> TypeFlags {
871+
let mut flags = TypeFlags::empty();
872+
873+
match *self {
874+
ty::ReVar(..) => {
875+
flags = flags | TypeFlags::HAS_RE_INFER;
876+
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
877+
}
878+
ty::ReSkolemized(..) => {
879+
flags = flags | TypeFlags::HAS_RE_INFER;
880+
flags = flags | TypeFlags::HAS_RE_SKOL;
881+
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
882+
}
883+
ty::ReLateBound(..) => { }
884+
ty::ReEarlyBound(..) => { flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; }
885+
ty::ReStatic | ty::ReErased => { }
886+
_ => { flags = flags | TypeFlags::HAS_FREE_REGIONS; }
887+
}
888+
889+
match *self {
890+
ty::ReStatic | ty::ReEmpty | ty::ReErased => (),
891+
_ => flags = flags | TypeFlags::HAS_LOCAL_NAMES,
892+
}
893+
894+
debug!("type_flags({:?}) = {:?}", self, flags);
895+
896+
flags
897+
}
869898
}
870899

871900
// Type utilities

src/librustc_data_structures/snapshot_map/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,19 @@ impl<K, V> SnapshotMap<K, V>
102102
}
103103
}
104104

105-
pub fn partial_rollback(&mut self, snapshot: &Snapshot) {
105+
pub fn partial_rollback<F>(&mut self,
106+
snapshot: &Snapshot,
107+
should_revert_key: &F)
108+
where F: Fn(&K) -> bool
109+
{
106110
self.assert_open_snapshot(snapshot);
107111
for i in (snapshot.len + 1..self.undo_log.len()).rev() {
108112
let reverse = match self.undo_log[i] {
109113
UndoLog::OpenSnapshot => false,
110114
UndoLog::CommittedSnapshot => false,
111115
UndoLog::Noop => false,
112-
UndoLog::Inserted(..) => true,
113-
UndoLog::Overwrite(..) => true,
116+
UndoLog::Inserted(ref k) => should_revert_key(k),
117+
UndoLog::Overwrite(ref k, _) => should_revert_key(k),
114118
};
115119

116120
if reverse {

0 commit comments

Comments
 (0)