diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index bbca4823431e..d25d186f4d74 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 f6edccc8ed76..35863a3a89a7 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>, + /// 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, + /// Map from const parameter variable to the kind of const it represents. const_unification_table: RefCell>>>, @@ -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>>, } @@ -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(&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 3b3a464ba557..29290cef2d28 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.