From a5e21daa1909f538ddd696f7baffad4603f38a5d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 02:24:46 +0300 Subject: [PATCH] Kill count_late_bound_regions No, it didn't show up in my profiler. It still needs to die. --- src/librustc/middle/traits/fulfill.rs | 24 ++++++++--------- src/librustc/middle/ty.rs | 39 ++++++++++++++++----------- src/librustc_typeck/astconv.rs | 8 +++--- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 5e274dcec70..dc3ccd417b8 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -421,16 +421,18 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, // regions. If there are, we will call this obligation an // error. Eventually we should be able to support some // cases here, I imagine (e.g., `for<'a> int : 'a`). - if selcx.tcx().count_late_bound_regions(binder) != 0 { - errors.push( - FulfillmentError::new( - obligation.clone(), - CodeSelectionError(Unimplemented))); - } else { - let ty::OutlivesPredicate(t_a, r_b) = binder.0; - register_region_obligation(t_a, r_b, - obligation.cause.clone(), - region_obligations); + match selcx.tcx().no_late_bound_regions(binder) { + None => { + errors.push( + FulfillmentError::new( + obligation.clone(), + CodeSelectionError(Unimplemented))) + } + Some(ty::OutlivesPredicate(t_a, r_b)) => { + register_region_obligation(t_a, r_b, + obligation.cause.clone(), + region_obligations); + } } true } @@ -501,5 +503,3 @@ impl<'tcx> FulfilledPredicates<'tcx> { !self.set.insert(p.clone()) } } - - diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 1bed9c4e0a8..fe52fba49c6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -6853,19 +6853,6 @@ impl<'tcx> ctxt<'tcx> { |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0 } - pub fn count_late_bound_regions(&self, value: &Binder) -> usize - where T : TypeFoldable<'tcx> - { - let (_, skol_map) = ty_fold::replace_late_bound_regions(self, value, |_| ty::ReStatic); - skol_map.len() - } - - pub fn binds_late_bound_regions(&self, value: &Binder) -> bool - where T : TypeFoldable<'tcx> - { - self.count_late_bound_regions(value) > 0 - } - /// Flattens two binding levels into one. So `for<'a> for<'b> Foo` /// becomes `for<'a,'b> Foo`. pub fn flatten_late_bound_regions(&self, bound2_value: &Binder>) @@ -6890,9 +6877,9 @@ impl<'tcx> ctxt<'tcx> { } pub fn no_late_bound_regions(&self, value: &Binder) -> Option - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + RegionEscape { - if self.binds_late_bound_regions(value) { + if value.0.has_escaping_regions() { None } else { Some(value.0.clone()) @@ -7052,6 +7039,19 @@ impl<'tcx> RegionEscape for Substs<'tcx> { } } +impl RegionEscape for Vec { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.iter().any(|t| t.has_regions_escaping_depth(depth)) + } +} + +impl<'tcx> RegionEscape for FnSig<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.inputs.has_regions_escaping_depth(depth) || + self.output.has_regions_escaping_depth(depth) + } +} + impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.iter_enumerated().any(|(space, _, t)| { @@ -7124,6 +7124,15 @@ impl<'tcx,T:RegionEscape> RegionEscape for Binder { } } +impl<'tcx> RegionEscape for FnOutput<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + match *self { + FnConverging(t) => t.has_regions_escaping_depth(depth), + FnDiverging => false + } + } +} + impl<'tcx> RegionEscape for EquatePredicate<'tcx> { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a55a8ff109e..00b7f420614 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -125,14 +125,14 @@ pub trait AstConv<'tcx> { item_name: ast::Name) -> Ty<'tcx> { - if self.tcx().binds_late_bound_regions(&poly_trait_ref) { + if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) { + self.projected_ty(span, trait_ref, item_name) + } else { + // no late-bound regions, we can just ignore the binder span_err!(self.tcx().sess, span, E0212, "cannot extract an associated type from a higher-ranked trait bound \ in this context"); self.tcx().types.err - } else { - // no late-bound regions, we can just ignore the binder - self.projected_ty(span, poly_trait_ref.0.clone(), item_name) } }