Generalize the replace-late-bound-regions function to operate
over anything that is foldable, not just fn signatures.
This commit is contained in:
parent
5c505b75b1
commit
1562d8cbd8
|
@ -97,11 +97,8 @@ use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
|
||||||
use middle::typeck::astconv;
|
use middle::typeck::astconv;
|
||||||
use middle::typeck::check::_match::pat_ctxt;
|
use middle::typeck::check::_match::pat_ctxt;
|
||||||
use middle::typeck::check::method::{AutoderefReceiver};
|
use middle::typeck::check::method::{AutoderefReceiver};
|
||||||
use middle::typeck::check::method::{AutoderefReceiverFlag};
|
|
||||||
use middle::typeck::check::method::{CheckTraitsAndInherentMethods};
|
use middle::typeck::check::method::{CheckTraitsAndInherentMethods};
|
||||||
use middle::typeck::check::method::{DontAutoderefReceiver};
|
use middle::typeck::check::regionmanip::replace_late_bound_regions;
|
||||||
use middle::typeck::check::method::{IgnoreStaticMethods, ReportStaticMethods};
|
|
||||||
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
|
||||||
use middle::typeck::CrateCtxt;
|
use middle::typeck::CrateCtxt;
|
||||||
use middle::typeck::infer::{resolve_type, force_tvar};
|
use middle::typeck::infer::{resolve_type, force_tvar};
|
||||||
use middle::typeck::infer;
|
use middle::typeck::infer;
|
||||||
|
@ -529,7 +526,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
// First, we have to replace any bound regions in the fn type with free ones.
|
// First, we have to replace any bound regions in the fn type with free ones.
|
||||||
// The free region references will be bound the node_id of the body block.
|
// The free region references will be bound the node_id of the body block.
|
||||||
let (_, fn_sig) = replace_late_bound_regions_in_fn_sig(tcx, fn_sig, |br| {
|
let (_, fn_sig) = replace_late_bound_regions(tcx, fn_sig.binder_id, fn_sig, |br| {
|
||||||
ty::ReFree(ty::FreeRegion {scope_id: body.id, bound_region: br})
|
ty::ReFree(ty::FreeRegion {scope_id: body.id, bound_region: br})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1531,6 +1528,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&self.inh.infcx
|
&self.inh.infcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sess(&self) -> &Session {
|
||||||
|
&self.tcx().sess
|
||||||
|
}
|
||||||
|
|
||||||
pub fn err_count_since_creation(&self) -> uint {
|
pub fn err_count_since_creation(&self) -> uint {
|
||||||
self.ccx.tcx.sess.err_count() - self.err_count_on_creation
|
self.ccx.tcx.sess.err_count() - self.err_count_on_creation
|
||||||
}
|
}
|
||||||
|
@ -2890,7 +2891,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||||
|
|
||||||
// Replace any bound regions that appear in the function
|
// Replace any bound regions that appear in the function
|
||||||
// signature with region variables
|
// signature with region variables
|
||||||
let (_, fn_sig) = replace_late_bound_regions_in_fn_sig(fcx.tcx(), fn_sig, |br| {
|
let (_, fn_sig) = replace_late_bound_regions(fcx.tcx(), fn_sig.binder_id, fn_sig, |br| {
|
||||||
fcx.infcx().next_region_var(infer::LateBoundRegion(call_expr.span, br))
|
fcx.infcx().next_region_var(infer::LateBoundRegion(call_expr.span, br))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3346,8 +3347,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||||
match expected_sty {
|
match expected_sty {
|
||||||
Some(ty::ty_closure(ref cenv)) => {
|
Some(ty::ty_closure(ref cenv)) => {
|
||||||
let (_, sig) =
|
let (_, sig) =
|
||||||
replace_late_bound_regions_in_fn_sig(
|
replace_late_bound_regions(
|
||||||
tcx, &cenv.sig,
|
tcx, cenv.sig.binder_id, &cenv.sig,
|
||||||
|_| fcx.inh.infcx.fresh_bound_region(expr.id));
|
|_| fcx.inh.infcx.fresh_bound_region(expr.id));
|
||||||
let onceness = match (&store, &cenv.store) {
|
let onceness = match (&store, &cenv.store) {
|
||||||
// As the closure type and onceness go, only three
|
// As the closure type and onceness go, only three
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use middle::subst::{ParamSpace, Subst, Substs};
|
use middle::subst::{ParamSpace, Subst, Substs};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::ty_fold;
|
use middle::ty_fold;
|
||||||
use middle::ty_fold::TypeFolder;
|
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
|
@ -23,31 +23,34 @@ use util::ppaux::Repr;
|
||||||
|
|
||||||
// Helper functions related to manipulating region types.
|
// Helper functions related to manipulating region types.
|
||||||
|
|
||||||
pub fn replace_late_bound_regions_in_fn_sig(
|
pub fn replace_late_bound_regions<T>(
|
||||||
tcx: &ty::ctxt,
|
tcx: &ty::ctxt,
|
||||||
fn_sig: &ty::FnSig,
|
binder_id: ast::NodeId,
|
||||||
mapf: |ty::BoundRegion| -> ty::Region)
|
value: &T,
|
||||||
-> (HashMap<ty::BoundRegion,ty::Region>, ty::FnSig) {
|
map_fn: |ty::BoundRegion| -> ty::Region)
|
||||||
debug!("replace_late_bound_regions_in_fn_sig({})", fn_sig.repr(tcx));
|
-> (HashMap<ty::BoundRegion,ty::Region>, T)
|
||||||
|
where T : TypeFoldable + Repr
|
||||||
|
{
|
||||||
|
debug!("replace_late_bound_regions(binder_id={}, value={})",
|
||||||
|
binder_id, value.repr(tcx));
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
let fn_sig = {
|
let new_value = {
|
||||||
let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
|
let mut folder = ty_fold::RegionFolder::regions(tcx, |r| {
|
||||||
debug!("region r={}", r.to_string());
|
|
||||||
match r {
|
match r {
|
||||||
ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
|
ty::ReLateBound(s, br) if s == binder_id => {
|
||||||
* match map.entry(br) {
|
match map.entry(br) {
|
||||||
Vacant(entry) => entry.set(mapf(br)),
|
Vacant(entry) => *entry.set(map_fn(br)),
|
||||||
Occupied(entry) => entry.into_mut(),
|
Occupied(entry) => *entry.into_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => r
|
_ => r
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ty_fold::super_fold_sig(&mut f, fn_sig)
|
value.fold_with(&mut folder)
|
||||||
};
|
};
|
||||||
debug!("resulting map: {}", map);
|
debug!("resulting map: {}", map);
|
||||||
(map, fn_sig)
|
(map, new_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum WfConstraint {
|
pub enum WfConstraint {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use middle::ty;
|
||||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||||
use middle::typeck::astconv::AstConv;
|
use middle::typeck::astconv::AstConv;
|
||||||
use middle::typeck::check::{FnCtxt, Inherited, blank_fn_ctxt, vtable2, regionck};
|
use middle::typeck::check::{FnCtxt, Inherited, blank_fn_ctxt, vtable2, regionck};
|
||||||
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
use middle::typeck::check::regionmanip::replace_late_bound_regions;
|
||||||
use middle::typeck::CrateCtxt;
|
use middle::typeck::CrateCtxt;
|
||||||
use util::ppaux::Repr;
|
use util::ppaux::Repr;
|
||||||
|
|
||||||
|
@ -373,8 +373,8 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
|
||||||
self.binding_count += 1;
|
self.binding_count += 1;
|
||||||
|
|
||||||
let (_, fn_sig) =
|
let (_, fn_sig) =
|
||||||
replace_late_bound_regions_in_fn_sig(
|
replace_late_bound_regions(
|
||||||
self.fcx.tcx(), fn_sig,
|
self.fcx.tcx(), fn_sig.binder_id, fn_sig,
|
||||||
|br| ty::ReFree(ty::FreeRegion{scope_id: self.scope_id,
|
|br| ty::ReFree(ty::FreeRegion{scope_id: self.scope_id,
|
||||||
bound_region: br}));
|
bound_region: br}));
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::ty_fold;
|
use middle::ty_fold;
|
||||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||||
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
use middle::typeck::check::regionmanip::replace_late_bound_regions;
|
||||||
use std::cell::{RefCell};
|
use std::cell::{RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -962,7 +962,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
HashMap<ty::BoundRegion,
|
HashMap<ty::BoundRegion,
|
||||||
ty::Region>) {
|
ty::Region>) {
|
||||||
let (map, fn_sig) =
|
let (map, fn_sig) =
|
||||||
replace_late_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
|
replace_late_bound_regions(self.tcx, fsig.binder_id, fsig, |br| {
|
||||||
let rvar = self.next_region_var(
|
let rvar = self.next_region_var(
|
||||||
BoundRegionInFnType(trace.origin.span(), br));
|
BoundRegionInFnType(trace.origin.span(), br));
|
||||||
debug!("Bound region {} maps to {}",
|
debug!("Bound region {} maps to {}",
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
use middle::ty::{BuiltinBounds};
|
use middle::ty::{BuiltinBounds};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::ty::TyVar;
|
use middle::ty::TyVar;
|
||||||
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
|
use middle::typeck::check::regionmanip::replace_late_bound_regions;
|
||||||
use middle::typeck::infer::combine::*;
|
use middle::typeck::infer::combine::*;
|
||||||
use middle::typeck::infer::{cres, CresCompare};
|
use middle::typeck::infer::{cres, CresCompare};
|
||||||
use middle::typeck::infer::equate::Equate;
|
use middle::typeck::infer::equate::Equate;
|
||||||
|
@ -189,7 +189,7 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
|
||||||
// Second, we instantiate each bound region in the supertype with a
|
// Second, we instantiate each bound region in the supertype with a
|
||||||
// fresh concrete region.
|
// fresh concrete region.
|
||||||
let (skol_map, b_sig) = {
|
let (skol_map, b_sig) = {
|
||||||
replace_late_bound_regions_in_fn_sig(self.fields.infcx.tcx, b, |br| {
|
replace_late_bound_regions(self.fields.infcx.tcx, b.binder_id, b, |br| {
|
||||||
let skol = self.fields.infcx.region_vars.new_skolemized(br);
|
let skol = self.fields.infcx.region_vars.new_skolemized(br);
|
||||||
debug!("Bound region {} skolemized to {}",
|
debug!("Bound region {} skolemized to {}",
|
||||||
bound_region_to_string(self.fields.infcx.tcx, "", false, br),
|
bound_region_to_string(self.fields.infcx.tcx, "", false, br),
|
||||||
|
|
Loading…
Reference in New Issue