diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2020-01-18 07:59:16 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2020-02-06 15:58:01 -0500 |
| commit | e9c78947dcd947709f41d52feaaf2eb6ea2711c8 (patch) | |
| tree | 6d5bed3965a0f0c4f060bca7217ef909e2be7a56 | |
| parent | 5e0197f13a28d2b3d9aadbc6c5d48506ab4d696f (diff) | |
| download | rust-e9c78947dcd947709f41d52feaaf2eb6ea2711c8.tar.gz rust-e9c78947dcd947709f41d52feaaf2eb6ea2711c8.zip | |
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.
| -rw-r--r-- | src/librustc/infer/higher_ranked/mod.rs | 10 | ||||
| -rw-r--r-- | src/librustc/infer/mod.rs | 27 | ||||
| -rw-r--r-- | src/librustc/infer/region_constraints/leak_check.rs | 12 |
3 files changed, 37 insertions, 12 deletions
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index bbca4823431..d25d186f4d7 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -128,6 +128,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { placeholder_map: &PlaceholderMap<'tcx>, snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> RelateResult<'tcx, ()> { + // If the user gave `-Zno-leak-check`, or we have been + // configured to skip the leak check, then skip the leak check + // completely. The leak check is deprecated. Any legitimate + // subtyping errors that it would have caught will now be + // caught later on, during region checking. However, we + // continue to use it for a transition period. + if self.tcx.sess.opts.debugging_opts.no_leak_check || self.skip_leak_check.get() { + return Ok(()); + } + self.borrow_region_constraints().leak_check( self.tcx, overly_polymorphic, diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index f6edccc8ed7..35863a3a89a 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -125,6 +125,13 @@ pub struct InferCtxt<'a, 'tcx> { /// order, represented by its upper and lower bounds. pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>, + /// If set, this flag causes us to skip the 'leak check' during + /// higher-ranked subtyping operations. This flag is a temporary one used + /// to manage the removal of the leak-check: for the time being, we still run the + /// leak-check, but we issue warnings. This flag can only be set to true + /// when entering a snapshot. + skip_leak_check: Cell<bool>, + /// Map from const parameter variable to the kind of const it represents. const_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::ConstVid<'tcx>>>>, @@ -550,6 +557,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { tainted_by_errors_flag: Cell::new(false), err_count_on_creation: tcx.sess.err_count(), in_snapshot: Cell::new(false), + skip_leak_check: Cell::new(false), region_obligations: RefCell::new(vec![]), universe: Cell::new(ty::UniverseIndex::ROOT), }) @@ -593,6 +601,7 @@ pub struct CombinedSnapshot<'a, 'tcx> { region_obligations_snapshot: usize, universe: ty::UniverseIndex, was_in_snapshot: bool, + was_skip_leak_check: bool, _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>, } @@ -720,6 +729,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot: self.region_obligations.borrow().len(), universe: self.universe(), was_in_snapshot: in_snapshot, + was_skip_leak_check: self.skip_leak_check.get(), // Borrow tables "in progress" (i.e., during typeck) // to ban writes from within a snapshot to them. _in_progress_tables: self.in_progress_tables.map(|tables| tables.borrow()), @@ -738,11 +748,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot, universe, was_in_snapshot, + was_skip_leak_check, _in_progress_tables, } = snapshot; self.in_snapshot.set(was_in_snapshot); self.universe.set(universe); + self.skip_leak_check.set(was_skip_leak_check); self.projection_cache.borrow_mut().rollback_to(projection_cache_snapshot); self.type_variables.borrow_mut().rollback_to(type_snapshot); @@ -765,10 +777,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_obligations_snapshot: _, universe: _, was_in_snapshot, + was_skip_leak_check, _in_progress_tables, } = snapshot; self.in_snapshot.set(was_in_snapshot); + self.skip_leak_check.set(was_skip_leak_check); self.projection_cache.borrow_mut().commit(projection_cache_snapshot); self.type_variables.borrow_mut().commit(type_snapshot); @@ -822,6 +836,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { r } + /// Execute `f` then unroll any bindings it creates. + pub fn skip_leak_check<R, F>(&self, f: F) -> R + where + F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, + { + debug!("probe()"); + let snapshot = self.start_snapshot(); + self.skip_leak_check.set(true); + let r = f(&snapshot); + self.rollback_to("probe", snapshot); + r + } + /// Scan the constraints produced since `snapshot` began and returns: /// /// - `None` -- if none of them involve "region outlives" constraints diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs index 3b3a464ba55..29290cef2d2 100644 --- a/src/librustc/infer/region_constraints/leak_check.rs +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -33,18 +33,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); - // If the user gave `-Zno-leak-check`, then skip the leak - // check completely. This is wildly unsound and also not - // unlikely to cause an ICE or two. It is intended for use - // only during a transition period, in which the MIR typeck - // uses the "universe-style" check, and the rest of typeck - // uses the more conservative leak check. Since the leak - // check is more conservative, we can't test the - // universe-style check without disabling it. - if tcx.sess.opts.debugging_opts.no_leak_check { - return Ok(()); - } - // Go through each placeholder that we created. for (_, &placeholder_region) in placeholder_map { // Find the universe this placeholder inhabits. |
