Move leak_check
into its own method, and ensure that all higher-ranked code is in
`higher_ranked.rs`.
This commit is contained in:
parent
1205fd88df
commit
4f34524fcb
2 changed files with 60 additions and 16 deletions
|
@ -11,7 +11,7 @@
|
||||||
//! Helper routines for higher-ranked things. See the `doc` module at
|
//! Helper routines for higher-ranked things. See the `doc` module at
|
||||||
//! the end of the file for details.
|
//! 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 super::combine::{Combine, Combineable};
|
||||||
|
|
||||||
use middle::ty::{mod, Binder};
|
use middle::ty::{mod, Binder};
|
||||||
|
@ -81,7 +81,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
||||||
|
|
||||||
// Presuming type comparison succeeds, we need to check
|
// Presuming type comparison succeeds, we need to check
|
||||||
// that the skolemized regions do not "leak".
|
// that the skolemized regions do not "leak".
|
||||||
match leak_check(self.infcx(), &skol_map, snapshot) {
|
match self.infcx().leak_check(&skol_map, snapshot) {
|
||||||
Ok(()) => { }
|
Ok(()) => { }
|
||||||
Err((skol_br, tainted_region)) => {
|
Err((skol_br, tainted_region)) => {
|
||||||
if self.a_is_expected() {
|
if self.a_is_expected() {
|
||||||
|
@ -455,11 +455,47 @@ impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
|
binder: &ty::Binder<T>,
|
||||||
snapshot: &CombinedSnapshot)
|
snapshot: &CombinedSnapshot)
|
||||||
-> Result<(),(ty::BoundRegion,ty::Region)>
|
-> (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);
|
let new_vars = infcx.region_vars_confined_to_snapshot(snapshot);
|
||||||
for (&skol_br, &skol) in skol_map.iter() {
|
for (&skol_br, &skol) in skol_map.iter() {
|
||||||
let tainted = infcx.tainted_regions(snapshot, skol);
|
let tainted = infcx.tainted_regions(snapshot, skol);
|
||||||
|
@ -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:
|
// A is not as polymorphic as B:
|
||||||
return Err((skol_br, tainted_region));
|
return Err((skol_br, tainted_region));
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub mod doc;
|
||||||
pub mod equate;
|
pub mod equate;
|
||||||
pub mod error_reporting;
|
pub mod error_reporting;
|
||||||
pub mod glb;
|
pub mod glb;
|
||||||
pub mod higher_ranked;
|
mod higher_ranked;
|
||||||
pub mod lattice;
|
pub mod lattice;
|
||||||
pub mod lub;
|
pub mod lub;
|
||||||
pub mod region_inference;
|
pub mod region_inference;
|
||||||
|
@ -90,7 +90,7 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
|
||||||
RegionVarBindings<'a, 'tcx>,
|
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.
|
/// region that each late-bound region was replaced with.
|
||||||
pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;
|
pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;
|
||||||
|
|
||||||
|
@ -709,16 +709,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
-> (T, SkolemizationMap)
|
-> (T, SkolemizationMap)
|
||||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
let (result, map) = replace_late_bound_regions(self.tcx, value, |br, _| {
|
/*! See `higher_ranked::skolemize_late_bound_regions` */
|
||||||
self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
|
|
||||||
});
|
|
||||||
|
|
||||||
debug!("skolemize_bound_regions(value={}, result={}, map={})",
|
higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
|
||||||
value.repr(self.tcx),
|
}
|
||||||
result.repr(self.tcx),
|
|
||||||
map.repr(self.tcx));
|
|
||||||
|
|
||||||
(result, map)
|
pub fn leak_check(&self,
|
||||||
|
skol_map: &SkolemizationMap,
|
||||||
|
snapshot: &CombinedSnapshot)
|
||||||
|
-> Result<(),(ty::BoundRegion,ty::Region)>
|
||||||
|
{
|
||||||
|
/*! See `higher_ranked::leak_check` */
|
||||||
|
|
||||||
|
higher_ranked::leak_check(self, skol_map, snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
|
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
|
||||||
|
|
Loading…
Reference in a new issue