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::check::_match::pat_ctxt;
|
||||
use middle::typeck::check::method::{AutoderefReceiver};
|
||||
use middle::typeck::check::method::{AutoderefReceiverFlag};
|
||||
use middle::typeck::check::method::{CheckTraitsAndInherentMethods};
|
||||
use middle::typeck::check::method::{DontAutoderefReceiver};
|
||||
use middle::typeck::check::method::{IgnoreStaticMethods, ReportStaticMethods};
|
||||
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::infer::{resolve_type, force_tvar};
|
||||
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.
|
||||
// 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})
|
||||
});
|
||||
|
||||
|
@ -1531,6 +1528,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self.inh.infcx
|
||||
}
|
||||
|
||||
pub fn sess(&self) -> &Session {
|
||||
&self.tcx().sess
|
||||
}
|
||||
|
||||
pub fn err_count_since_creation(&self) -> uint {
|
||||
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
|
||||
// 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))
|
||||
});
|
||||
|
||||
|
@ -3346,8 +3347,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
match expected_sty {
|
||||
Some(ty::ty_closure(ref cenv)) => {
|
||||
let (_, sig) =
|
||||
replace_late_bound_regions_in_fn_sig(
|
||||
tcx, &cenv.sig,
|
||||
replace_late_bound_regions(
|
||||
tcx, cenv.sig.binder_id, &cenv.sig,
|
||||
|_| fcx.inh.infcx.fresh_bound_region(expr.id));
|
||||
let onceness = match (&store, &cenv.store) {
|
||||
// As the closure type and onceness go, only three
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
use middle::subst::{ParamSpace, Subst, Substs};
|
||||
use middle::ty;
|
||||
use middle::ty_fold;
|
||||
use middle::ty_fold::TypeFolder;
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
|
||||
use syntax::ast;
|
||||
|
||||
|
@ -23,31 +23,34 @@ use util::ppaux::Repr;
|
|||
|
||||
// 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,
|
||||
fn_sig: &ty::FnSig,
|
||||
mapf: |ty::BoundRegion| -> ty::Region)
|
||||
-> (HashMap<ty::BoundRegion,ty::Region>, ty::FnSig) {
|
||||
debug!("replace_late_bound_regions_in_fn_sig({})", fn_sig.repr(tcx));
|
||||
binder_id: ast::NodeId,
|
||||
value: &T,
|
||||
map_fn: |ty::BoundRegion| -> ty::Region)
|
||||
-> (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 fn_sig = {
|
||||
let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
|
||||
debug!("region r={}", r.to_string());
|
||||
let new_value = {
|
||||
let mut folder = ty_fold::RegionFolder::regions(tcx, |r| {
|
||||
match r {
|
||||
ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
|
||||
* match map.entry(br) {
|
||||
Vacant(entry) => entry.set(mapf(br)),
|
||||
Occupied(entry) => entry.into_mut(),
|
||||
ty::ReLateBound(s, br) if s == binder_id => {
|
||||
match map.entry(br) {
|
||||
Vacant(entry) => *entry.set(map_fn(br)),
|
||||
Occupied(entry) => *entry.into_mut(),
|
||||
}
|
||||
}
|
||||
_ => r
|
||||
}
|
||||
});
|
||||
ty_fold::super_fold_sig(&mut f, fn_sig)
|
||||
value.fold_with(&mut folder)
|
||||
};
|
||||
debug!("resulting map: {}", map);
|
||||
(map, fn_sig)
|
||||
(map, new_value)
|
||||
}
|
||||
|
||||
pub enum WfConstraint {
|
||||
|
|
|
@ -15,7 +15,7 @@ use middle::ty;
|
|||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
use middle::typeck::astconv::AstConv;
|
||||
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 util::ppaux::Repr;
|
||||
|
||||
|
@ -373,8 +373,8 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
|
|||
self.binding_count += 1;
|
||||
|
||||
let (_, fn_sig) =
|
||||
replace_late_bound_regions_in_fn_sig(
|
||||
self.fcx.tcx(), fn_sig,
|
||||
replace_late_bound_regions(
|
||||
self.fcx.tcx(), fn_sig.binder_id, fn_sig,
|
||||
|br| ty::ReFree(ty::FreeRegion{scope_id: self.scope_id,
|
||||
bound_region: br}));
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
|
|||
use middle::ty;
|
||||
use middle::ty_fold;
|
||||
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::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
@ -962,7 +962,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
HashMap<ty::BoundRegion,
|
||||
ty::Region>) {
|
||||
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(
|
||||
BoundRegionInFnType(trace.origin.span(), br));
|
||||
debug!("Bound region {} maps to {}",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
use middle::ty::{BuiltinBounds};
|
||||
use middle::ty;
|
||||
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::{cres, CresCompare};
|
||||
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
|
||||
// fresh concrete region.
|
||||
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);
|
||||
debug!("Bound region {} skolemized to {}",
|
||||
bound_region_to_string(self.fields.infcx.tcx, "", false, br),
|
||||
|
|
Loading…
Reference in New Issue