Skip to content

Commit

Permalink
Generalize the replace-late-bound-regions function to operate
Browse files Browse the repository at this point in the history
over anything that is foldable, not just fn signatures.
  • Loading branch information
nikomatsakis committed Oct 21, 2014
1 parent 5c505b7 commit 1562d8c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 31 deletions.
17 changes: 9 additions & 8 deletions src/librustc/middle/typeck/check/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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})
});

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

Expand Down Expand Up @@ -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
Expand Down
35 changes: 19 additions & 16 deletions src/librustc/middle/typeck/check/regionmanip.rs
Expand Up @@ -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;

Expand All @@ -23,31 +23,34 @@ use util::ppaux::Repr;

// Helper functions related to manipulating region types.

pub fn replace_late_bound_regions_in_fn_sig(
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));
pub fn replace_late_bound_regions<T>(
tcx: &ty::ctxt,
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 {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/check/wf.rs
Expand Up @@ -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;

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

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/infer/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {}",
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/infer/sub.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit 1562d8c

Please sign in to comment.