Skip to content

Commit e9c7894

Browse files
committed
add the ability to skip leak check within a snapshot
The intention is that coherence code will skip the leak check and determine whether two impls *would have* overlapped, and then issue a warning.
1 parent 5e0197f commit e9c7894

File tree

3 files changed

+37
-12
lines changed

3 files changed

+37
-12
lines changed

src/librustc/infer/higher_ranked/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
128128
placeholder_map: &PlaceholderMap<'tcx>,
129129
snapshot: &CombinedSnapshot<'_, 'tcx>,
130130
) -> RelateResult<'tcx, ()> {
131+
// If the user gave `-Zno-leak-check`, or we have been
132+
// configured to skip the leak check, then skip the leak check
133+
// completely. The leak check is deprecated. Any legitimate
134+
// subtyping errors that it would have caught will now be
135+
// caught later on, during region checking. However, we
136+
// continue to use it for a transition period.
137+
if self.tcx.sess.opts.debugging_opts.no_leak_check || self.skip_leak_check.get() {
138+
return Ok(());
139+
}
140+
131141
self.borrow_region_constraints().leak_check(
132142
self.tcx,
133143
overly_polymorphic,

src/librustc/infer/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ pub struct InferCtxt<'a, 'tcx> {
125125
/// order, represented by its upper and lower bounds.
126126
pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
127127

128+
/// If set, this flag causes us to skip the 'leak check' during
129+
/// higher-ranked subtyping operations. This flag is a temporary one used
130+
/// to manage the removal of the leak-check: for the time being, we still run the
131+
/// leak-check, but we issue warnings. This flag can only be set to true
132+
/// when entering a snapshot.
133+
skip_leak_check: Cell<bool>,
134+
128135
/// Map from const parameter variable to the kind of const it represents.
129136
const_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::ConstVid<'tcx>>>>,
130137

@@ -550,6 +557,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
550557
tainted_by_errors_flag: Cell::new(false),
551558
err_count_on_creation: tcx.sess.err_count(),
552559
in_snapshot: Cell::new(false),
560+
skip_leak_check: Cell::new(false),
553561
region_obligations: RefCell::new(vec![]),
554562
universe: Cell::new(ty::UniverseIndex::ROOT),
555563
})
@@ -593,6 +601,7 @@ pub struct CombinedSnapshot<'a, 'tcx> {
593601
region_obligations_snapshot: usize,
594602
universe: ty::UniverseIndex,
595603
was_in_snapshot: bool,
604+
was_skip_leak_check: bool,
596605
_in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
597606
}
598607

@@ -720,6 +729,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
720729
region_obligations_snapshot: self.region_obligations.borrow().len(),
721730
universe: self.universe(),
722731
was_in_snapshot: in_snapshot,
732+
was_skip_leak_check: self.skip_leak_check.get(),
723733
// Borrow tables "in progress" (i.e., during typeck)
724734
// to ban writes from within a snapshot to them.
725735
_in_progress_tables: self.in_progress_tables.map(|tables| tables.borrow()),
@@ -738,11 +748,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
738748
region_obligations_snapshot,
739749
universe,
740750
was_in_snapshot,
751+
was_skip_leak_check,
741752
_in_progress_tables,
742753
} = snapshot;
743754

744755
self.in_snapshot.set(was_in_snapshot);
745756
self.universe.set(universe);
757+
self.skip_leak_check.set(was_skip_leak_check);
746758

747759
self.projection_cache.borrow_mut().rollback_to(projection_cache_snapshot);
748760
self.type_variables.borrow_mut().rollback_to(type_snapshot);
@@ -765,10 +777,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
765777
region_obligations_snapshot: _,
766778
universe: _,
767779
was_in_snapshot,
780+
was_skip_leak_check,
768781
_in_progress_tables,
769782
} = snapshot;
770783

771784
self.in_snapshot.set(was_in_snapshot);
785+
self.skip_leak_check.set(was_skip_leak_check);
772786

773787
self.projection_cache.borrow_mut().commit(projection_cache_snapshot);
774788
self.type_variables.borrow_mut().commit(type_snapshot);
@@ -822,6 +836,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
822836
r
823837
}
824838

839+
/// Execute `f` then unroll any bindings it creates.
840+
pub fn skip_leak_check<R, F>(&self, f: F) -> R
841+
where
842+
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
843+
{
844+
debug!("probe()");
845+
let snapshot = self.start_snapshot();
846+
self.skip_leak_check.set(true);
847+
let r = f(&snapshot);
848+
self.rollback_to("probe", snapshot);
849+
r
850+
}
851+
825852
/// Scan the constraints produced since `snapshot` began and returns:
826853
///
827854
/// - `None` -- if none of them involve "region outlives" constraints

src/librustc/infer/region_constraints/leak_check.rs

-12
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
3333

3434
assert!(self.in_snapshot());
3535

36-
// If the user gave `-Zno-leak-check`, then skip the leak
37-
// check completely. This is wildly unsound and also not
38-
// unlikely to cause an ICE or two. It is intended for use
39-
// only during a transition period, in which the MIR typeck
40-
// uses the "universe-style" check, and the rest of typeck
41-
// uses the more conservative leak check. Since the leak
42-
// check is more conservative, we can't test the
43-
// universe-style check without disabling it.
44-
if tcx.sess.opts.debugging_opts.no_leak_check {
45-
return Ok(());
46-
}
47-
4836
// Go through each placeholder that we created.
4937
for (_, &placeholder_region) in placeholder_map {
5038
// Find the universe this placeholder inhabits.

0 commit comments

Comments
 (0)