mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 10:45:18 +00:00
Fix ICE in WF checker when we encounter bound regions in object types.
This commit is contained in:
parent
5e21e17d96
commit
71cdf76240
@ -70,6 +70,13 @@ pub trait TypeFolder<'tcx> : Sized {
|
||||
/// 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)
|
||||
}
|
||||
@ -183,12 +190,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,6 +560,17 @@ impl<'tcx> TypeFoldable<'tcx> for ty::UnboxedClosureUpvar<'tcx> {
|
||||
//
|
||||
// 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> {
|
||||
|
@ -301,6 +301,18 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'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()));
|
||||
@ -361,19 +373,6 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'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);
|
||||
}
|
||||
|
26
src/test/run-pass/wf-bound-region-in-object-type.rs
Normal file
26
src/test/run-pass/wf-bound-region-in-object-type.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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() { }
|
Loading…
Reference in New Issue
Block a user