Skip to content

Commit e11742d

Browse files
committed
More refactoring on a quest to understand region types.
1 parent 269bc6f commit e11742d

File tree

2 files changed

+62
-22
lines changed

2 files changed

+62
-22
lines changed

src/rustc/middle/typeck/check/regionmanip.rs

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import syntax::print::pprust::{expr_to_str};
55
// Extracts the bound regions from bound_tys and then replaces those same
66
// regions in `sty` with fresh region variables, returning the resulting type.
77
// Does not descend into fn types. This is used when deciding whether an impl
8-
// applies at a given call site. See also universally_quantify_before_call().
8+
// applies at a given call site.
99
fn universally_quantify_from_sty(fcx: @fn_ctxt,
1010
span: span,
1111
bound_tys: [ty::t],
@@ -31,6 +31,11 @@ fn universally_quantify_from_sty(fcx: @fn_ctxt,
3131
}
3232
}
3333

34+
// Takes `isr`, a mapping from in-scope region names ("isr"s) to their
35+
// corresponding regions (possibly produced by a call to
36+
// collect_bound_regions_in_tys; and `ty`, a type. Returns an updated
37+
// version of `ty`, in which bound regions in `ty` have been replaced
38+
// with the corresponding bindings in `isr`.
3439
fn replace_bound_regions(
3540
tcx: ty::ctxt,
3641
span: span,
@@ -140,23 +145,29 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
140145
}
141146
}
142147

148+
// Takes `isr`, a (possibly empty) mapping from in-scope region names ("isr"s)
149+
// to their corresponding regions; `tys`, a list of types, and `to_r`, a
150+
// closure that takes a bound_region and returns a region. Returns an updated
151+
// version of `isr`, extended with the in-scope region names from all of the
152+
// bound regions appearing in the types in the `tys` list (if they're not in
153+
// `isr` already), with each of those in-scope region names mapped to a region
154+
// that's the result of applying `to_r` to itself.
155+
156+
// "collect" is something of a misnomer -- we're not merely collecting
157+
// a list of the bound regions, but also doing the work of applying
158+
// `to_r` to them!
143159
fn collect_bound_regions_in_tys(
144160
tcx: ty::ctxt,
145161
isr: isr_alist,
146162
tys: [ty::t],
147163
to_r: fn(ty::bound_region) -> ty::region) -> isr_alist {
148164

149-
tys.foldl(isr) { |isr, t|
150-
collect_bound_regions_in_ty(tcx, isr, t, to_r)
151-
}
152-
}
153-
154-
fn collect_bound_regions_in_ty(
155-
tcx: ty::ctxt,
156-
isr: isr_alist,
157-
ty: ty::t,
158-
to_r: fn(ty::bound_region) -> ty::region) -> isr_alist {
159-
165+
// Takes `isr` (described above), `to_r` (described above), and `r`, a
166+
// region. If `r` is anything other than a bound region, or if it's a
167+
// bound region that already appears in `isr`, then we return `isr`
168+
// unchanged. If `r` is a bound region that doesn't already appear in
169+
// `isr`, we return an updated isr_alist that now contains a mapping from
170+
// `r` to the result of calling `to_r` on it.
160171
fn append_isr(isr: isr_alist,
161172
to_r: fn(ty::bound_region) -> ty::region,
162173
r: ty::region) -> isr_alist {
@@ -174,16 +185,30 @@ fn collect_bound_regions_in_ty(
174185
}
175186
}
176187

177-
let mut isr = isr;
188+
// For each region in `t`, apply the `append_isr` function to that
189+
// region, accumulating and returning the results in an isr_alist.
190+
fn fold_over_regions_in_type(
191+
tcx: ty::ctxt,
192+
isr: isr_alist,
193+
ty: ty::t,
194+
to_r: fn(ty::bound_region) -> ty::region) -> isr_alist {
195+
196+
let mut isr = isr;
197+
198+
// Using fold_regions is inefficient, because it constructs new types,
199+
// but it avoids code duplication in terms of locating all the regions
200+
// within the various kinds of types. This had already caused me
201+
// several bugs so I decided to switch over.
202+
ty::fold_regions(tcx, ty) { |r, in_fn|
203+
if !in_fn { isr = append_isr(isr, to_r, r); }
204+
r
205+
};
178206

179-
// Using fold_regions is inefficient, because it constructs new types, but
180-
// it avoids code duplication in terms of locating all the regions within
181-
// the various kinds of types. This had already caused me several bugs
182-
// so I decided to switch over.
183-
ty::fold_regions(tcx, ty) { |r, in_fn|
184-
if !in_fn { isr = append_isr(isr, to_r, r); }
185-
r
186-
};
207+
ret isr;
208+
}
187209

188-
ret isr;
210+
// For each type `t` in `tys`...
211+
tys.foldl(isr) { |isr, t|
212+
fold_over_regions_in_type(tcx, isr, t, to_r)
213+
}
189214
}

src/rustc/middle/typeck/infer.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,11 +1618,23 @@ impl of combine for sub {
16181618

16191619
// First, we instantiate each bound region in the subtype with a fresh
16201620
// region variable.
1621+
1622+
// FIXME: This code is kinda redundant with
1623+
// regionmanip::universally_quantify_from_sty, except for the
1624+
// `sty` part. Fix somehow?
1625+
1626+
// a_isr is a mapping from all the bound regions in `a` to
1627+
// freshly created region variables for them.
16211628
let a_isr =
16221629
collect_bound_regions_in_tys(self.tcx,
16231630
@nil,
16241631
tys_in_fn_ty(a)) {
16251632
|br|
1633+
1634+
// N.B.: The name of the bound region doesn't have
1635+
// anything to do with the region variable that's created
1636+
// for it. The only thing we're doing with `br` here is
1637+
// using it in the debug message.
16261638
let rvar = self.infcx().next_region_var();
16271639
#debug["Bound region %s maps to %s",
16281640
bound_region_to_str(self.tcx, br),
@@ -1638,6 +1650,9 @@ impl of combine for sub {
16381650

16391651
// Second, we instantiate each bound region in the supertype with a
16401652
// fresh concrete region.
1653+
1654+
// a_isr is a mapping from all the bound regions in `b` to
1655+
// the result of calling re_bound on them.
16411656
let b_isr =
16421657
collect_bound_regions_in_tys(self.tcx,
16431658
@nil,

0 commit comments

Comments
 (0)