/// track the Debruijn index nesting level.
fn exit_region_binder(&mut self) { }
+ fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
+ where T : TypeFoldable<'tcx> + Repr<'tcx>
+ {
+ // TODO this should eventually replace `enter_region_binder`/`exit_region_binder` altogether.
+ super_fold_binder(self, t)
+ }
+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
super_fold_ty(self, t)
}
}
}
-impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
+impl<'tcx, T:TypeFoldable<'tcx>+Repr<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
- folder.enter_region_binder();
- let result = ty::Binder(self.0.fold_with(folder));
- folder.exit_region_binder();
- result
+ folder.fold_binder(self)
}
}
//
// They should invoke `foo.fold_with()` to do recursive folding.
+pub fn super_fold_binder<'tcx, T, U>(this: &mut T,
+ binder: &ty::Binder<U>)
+ -> ty::Binder<U>
+ where T : TypeFolder<'tcx>, U : TypeFoldable<'tcx>
+{
+ this.enter_region_binder();
+ let result = ty::Binder(binder.0.fold_with(this));
+ this.exit_region_binder();
+ result
+}
+
pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
ty: Ty<'tcx>)
-> Ty<'tcx> {
self.fcx.tcx()
}
+ fn fold_binder<T>(&mut self, binder: &ty::Binder<T>) -> ty::Binder<T>
+ where T : TypeFoldable<'tcx> + Repr<'tcx>
+ {
+ self.binding_count += 1;
+ let value = liberate_late_bound_regions(self.fcx.tcx(), self.scope, binder);
+ debug!("BoundsChecker::fold_binder: late-bound regions replaced: {}",
+ value.repr(self.tcx()));
+ let value = value.fold_with(self);
+ self.binding_count -= 1;
+ ty::Binder(value)
+ }
+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
debug!("BoundsChecker t={}",
t.repr(self.tcx()));
self.fold_substs(substs);
}
- ty::ty_bare_fn(_, &ty::BareFnTy{sig: ref fn_sig, ..}) |
- ty::ty_closure(box ty::ClosureTy{sig: ref fn_sig, ..}) => {
- self.binding_count += 1;
-
- let fn_sig = liberate_late_bound_regions(self.fcx.tcx(), self.scope, fn_sig);
-
- debug!("late-bound regions replaced: {}",
- fn_sig.repr(self.tcx()));
-
- self.fold_fn_sig(&fn_sig);
-
- self.binding_count -= 1;
- }
_ => {
super_fold_ty(self, t);
}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the `wf` checker properly handles bound regions in object
+// types. Compiling this code used to trigger an ICE.
+
+pub struct Context<'tcx> {
+ vec: &'tcx Vec<int>
+}
+
+pub type Cmd<'a> = &'a int;
+
+pub type DecodeInlinedItem<'a> =
+ Box<for<'tcx> FnMut(Cmd, &Context<'tcx>) -> Result<&'tcx int, ()> + 'a>;
+
+fn foo(d: DecodeInlinedItem) {
+}
+
+fn main() { }