Skip to content

Commit

Permalink
Move leak_check into its own method, and ensure that all higher-ran…
Browse files Browse the repository at this point in the history
…ked code is in

`higher_ranked.rs`.
  • Loading branch information
nikomatsakis committed Dec 19, 2014
1 parent 1205fd8 commit 4f34524
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 16 deletions.
53 changes: 47 additions & 6 deletions src/librustc/middle/infer/higher_ranked/mod.rs
Expand Up @@ -11,7 +11,7 @@
//! Helper routines for higher-ranked things. See the `doc` module at
//! the end of the file for details.

use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType};
use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType, SkolemizationMap};
use super::combine::{Combine, Combineable};

use middle::ty::{mod, Binder};
Expand Down Expand Up @@ -81,7 +81,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C

// Presuming type comparison succeeds, we need to check
// that the skolemized regions do not "leak".
match leak_check(self.infcx(), &skol_map, snapshot) {
match self.infcx().leak_check(&skol_map, snapshot) {
Ok(()) => { }
Err((skol_br, tainted_region)) => {
if self.a_is_expected() {
Expand Down Expand Up @@ -455,11 +455,47 @@ impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
}
}

fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
snapshot: &CombinedSnapshot)
-> Result<(),(ty::BoundRegion,ty::Region)>
pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
binder: &ty::Binder<T>,
snapshot: &CombinedSnapshot)
-> (T, SkolemizationMap)
where T : TypeFoldable<'tcx> + Repr<'tcx>
{
/*!
* Replace all regions bound by `binder` with skolemized regions and
* return a map indicating which bound-region was replaced with what
* skolemized region. This is the first step of checking subtyping
* when higher-ranked things are involved. See `doc.rs` for more details.
*/

let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br, _| {
infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
});

debug!("skolemize_bound_regions(binder={}, result={}, map={})",
binder.repr(infcx.tcx),
result.repr(infcx.tcx),
map.repr(infcx.tcx));

(result, map)
}

pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
skol_map: &SkolemizationMap,
snapshot: &CombinedSnapshot)
-> Result<(),(ty::BoundRegion,ty::Region)>
{
/*!
* Searches the region constriants created since `snapshot` was started
* and checks to determine whether any of the skolemized regions created
* in `skol_map` would "escape" -- meaning that they are related to
* other regions in some way. If so, the higher-ranked subtyping doesn't
* hold. See `doc.rs` for more details.
*/

debug!("leak_check: skol_map={}",
skol_map.repr(infcx.tcx));

let new_vars = infcx.region_vars_confined_to_snapshot(snapshot);
for (&skol_br, &skol) in skol_map.iter() {
let tainted = infcx.tainted_regions(snapshot, skol);
Expand All @@ -475,6 +511,11 @@ fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
}
};

debug!("{} (which replaced {}) is tainted by {}",
skol.repr(infcx.tcx),
skol_br.repr(infcx.tcx),
tainted_region.repr(infcx.tcx));

// A is not as polymorphic as B:
return Err((skol_br, tainted_region));
}
Expand Down
23 changes: 13 additions & 10 deletions src/librustc/middle/infer/mod.rs
Expand Up @@ -52,7 +52,7 @@ pub mod doc;
pub mod equate;
pub mod error_reporting;
pub mod glb;
pub mod higher_ranked;
mod higher_ranked;
pub mod lattice;
pub mod lub;
pub mod region_inference;
Expand Down Expand Up @@ -90,7 +90,7 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
RegionVarBindings<'a, 'tcx>,
}

/// A map returned by `skolemize_bound_regions()` indicating the skolemized
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
/// region that each late-bound region was replaced with.
pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;

Expand Down Expand Up @@ -709,16 +709,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-> (T, SkolemizationMap)
where T : TypeFoldable<'tcx> + Repr<'tcx>
{
let (result, map) = replace_late_bound_regions(self.tcx, value, |br, _| {
self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
});
/*! See `higher_ranked::skolemize_late_bound_regions` */

debug!("skolemize_bound_regions(value={}, result={}, map={})",
value.repr(self.tcx),
result.repr(self.tcx),
map.repr(self.tcx));
higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
}

pub fn leak_check(&self,
skol_map: &SkolemizationMap,
snapshot: &CombinedSnapshot)
-> Result<(),(ty::BoundRegion,ty::Region)>
{
/*! See `higher_ranked::leak_check` */

(result, map)
higher_ranked::leak_check(self, skol_map, snapshot)
}

pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
Expand Down

0 comments on commit 4f34524

Please sign in to comment.