From 1b24602ca083cc20169190556a51066af0438049 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 10 Dec 2014 18:27:04 -0500 Subject: [PATCH] Extract leak check into a distinct subroutine. --- .../middle/infer/higher_ranked/mod.rs | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index c1320b6042ab..ef8c2f414acf 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -84,30 +84,17 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C // Presuming type comparison succeeds, we need to check // that the skolemized regions do not "leak". - let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot); - for (&skol_br, &skol) in skol_map.iter() { - let tainted = self.infcx().tainted_regions(snapshot, skol); - for tainted_region in tainted.iter() { - // Each skolemized should only be relatable to itself - // or new variables: - match *tainted_region { - ty::ReInfer(ty::ReVar(ref vid)) => { - if new_vars.iter().any(|x| x == vid) { continue; } - } - _ => { - if *tainted_region == skol { continue; } - } - }; - - // A is not as polymorphic as B: + match leak_check(self.infcx(), &skol_map, snapshot) { + Ok(()) => { } + Err((skol_br, tainted_region)) => { if self.a_is_expected() { debug!("Not as polymorphic!"); return Err(ty::terr_regions_insufficiently_polymorphic(skol_br, - *tainted_region)); + tainted_region)); } else { debug!("Overly polymorphic!"); return Err(ty::terr_regions_overly_polymorphic(skol_br, - *tainted_region)); + tainted_region)); } } } @@ -548,3 +535,30 @@ fn skolemize_regions<'a,'tcx,HR>(infcx: &InferCtxt<'a,'tcx>, skol }) } + +fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, + skol_map: &FnvHashMap, + snapshot: &CombinedSnapshot) + -> Result<(),(ty::BoundRegion,ty::Region)> +{ + let new_vars = infcx.region_vars_confined_to_snapshot(snapshot); + for (&skol_br, &skol) in skol_map.iter() { + let tainted = infcx.tainted_regions(snapshot, skol); + for &tainted_region in tainted.iter() { + // Each skolemized should only be relatable to itself + // or new variables: + match tainted_region { + ty::ReInfer(ty::ReVar(vid)) => { + if new_vars.iter().any(|&x| x == vid) { continue; } + } + _ => { + if tainted_region == skol { continue; } + } + }; + + // A is not as polymorphic as B: + return Err((skol_br, tainted_region)); + } + } + Ok(()) +}