Generalize the replace-late-bound-regions function to operate

over anything that is foldable, not just fn signatures.
This commit is contained in:
Niko Matsakis 2014-10-17 08:56:27 -04:00
parent 5c505b75b1
commit 1562d8cbd8
5 changed files with 35 additions and 31 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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}));

View File

@ -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 {}",

View File

@ -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),