// 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
}
!self.set.insert(p.clone())
}
}
-
-
|br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
}
- pub fn count_late_bound_regions<T>(&self, value: &Binder<T>) -> 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<T>(&self, value: &Binder<T>) -> 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<T>(&self, bound2_value: &Binder<Binder<T>>)
}
pub fn no_late_bound_regions<T>(&self, value: &Binder<T>) -> Option<T>
- 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())
}
}
+impl<T:RegionEscape> RegionEscape for Vec<T> {
+ 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<T> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
self.iter_enumerated().any(|(space, _, t)| {
}
}
+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)
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)
}
}