@@ -20,7 +20,7 @@ fn replace_bound_regions_in_fn_ty(
20
20
all_tys. map { |t| ty_to_str ( tcx, t) } ] ;
21
21
let _i = indenter ( ) ;
22
22
23
- let isr = collect_bound_regions_in_tys ( tcx, isr, all_tys) { |br|
23
+ let isr = create_bound_region_mapping ( tcx, isr, all_tys) { |br|
24
24
#debug[ "br=%?" , br] ;
25
25
mapf ( br)
26
26
} ;
@@ -36,47 +36,105 @@ fn replace_bound_regions_in_fn_ty(
36
36
ret { isr : isr,
37
37
self_ty : t_self,
38
38
fn_ty : alt check ty:: get ( t_fn) . struct { ty:: ty_fn ( o) { o} } } ;
39
- }
40
39
41
- // Takes `isr`, a mapping from in-scope region names ("isr"s) to their
42
- // corresponding regions (possibly produced by a call to
43
- // collect_bound_regions_in_tys; and `ty`, a type. Returns an updated
44
- // version of `ty`, in which bound regions in `ty` have been replaced
45
- // with the corresponding bindings in `isr`.
46
- fn replace_bound_regions (
47
- tcx : ty:: ctxt ,
48
- isr : isr_alist ,
49
- ty : ty:: t ) -> ty:: t {
50
-
51
- ty:: fold_regions ( tcx, ty) { |r, in_fn|
52
- alt r {
53
- // As long as we are not within a fn() type, `&T` is mapped to the
54
- // free region anon_r. But within a fn type, it remains bound.
55
- ty : : re_bound ( ty:: br_anon) if in_fn { r }
56
-
57
- ty:: re_bound ( br) {
58
- alt isr. find ( br) {
59
- // In most cases, all named, bound regions will be mapped to
60
- // some free region.
61
- some ( fr) { fr }
62
-
63
- // But in the case of a fn() type, there may be named regions
64
- // within that remain bound:
65
- none if in_fn { r }
66
- none {
67
- tcx. sess . bug (
68
- #fmt[ "Bound region not found in \
69
- in_scope_regions list: %s",
70
- region_to_str ( tcx, r) ] ) ;
40
+
41
+ // Takes `isr`, a (possibly empty) mapping from in-scope region
42
+ // names ("isr"s) to their corresponding regions; `tys`, a list of
43
+ // types, and `to_r`, a closure that takes a bound_region and
44
+ // returns a region. Returns an updated version of `isr`,
45
+ // extended with the in-scope region names from all of the bound
46
+ // regions appearing in the types in the `tys` list (if they're
47
+ // not in `isr` already), with each of those in-scope region names
48
+ // mapped to a region that's the result of applying `to_r` to
49
+ // itself.
50
+ fn create_bound_region_mapping (
51
+ tcx : ty:: ctxt ,
52
+ isr : isr_alist ,
53
+ tys : [ ty:: t ] ,
54
+ to_r : fn ( ty:: bound_region ) -> ty:: region ) -> isr_alist {
55
+
56
+ // Takes `isr` (described above), `to_r` (described above),
57
+ // and `r`, a region. If `r` is anything other than a bound
58
+ // region, or if it's a bound region that already appears in
59
+ // `isr`, then we return `isr` unchanged. If `r` is a bound
60
+ // region that doesn't already appear in `isr`, we return an
61
+ // updated isr_alist that now contains a mapping from `r` to
62
+ // the result of calling `to_r` on it.
63
+ fn append_isr ( isr : isr_alist ,
64
+ to_r : fn ( ty:: bound_region ) -> ty:: region ,
65
+ r : ty:: region ) -> isr_alist {
66
+ alt r {
67
+ ty : : re_free ( _, _) | ty:: re_static | ty:: re_scope ( _) |
68
+ ty:: re_var ( _) {
69
+ isr
70
+ }
71
+ ty:: re_bound ( br) {
72
+ alt isr. find ( br) {
73
+ some ( _) { isr }
74
+ none { @cons( ( br, to_r ( br) ) , isr) }
75
+ }
71
76
}
72
77
}
73
- }
78
+ }
79
+
80
+ // For each type `ty` in `tys`...
81
+ tys. foldl ( isr) { |isr, ty|
82
+ let mut isr = isr;
83
+
84
+ // Using fold_regions is inefficient, because it
85
+ // constructs new types, but it avoids code duplication in
86
+ // terms of locating all the regions within the various
87
+ // kinds of types. This had already caused me several
88
+ // bugs so I decided to switch over.
89
+ ty:: fold_regions ( tcx, ty) { |r, in_fn|
90
+ if !in_fn { isr = append_isr ( isr, to_r, r) ; }
91
+ r
92
+ } ;
93
+
94
+ isr
95
+ }
96
+ }
97
+
98
+ // Takes `isr`, a mapping from in-scope region names ("isr"s) to
99
+ // their corresponding regions; and `ty`, a type. Returns an
100
+ // updated version of `ty`, in which bound regions in `ty` have
101
+ // been replaced with the corresponding bindings in `isr`.
102
+ fn replace_bound_regions (
103
+ tcx : ty:: ctxt ,
104
+ isr : isr_alist ,
105
+ ty : ty:: t ) -> ty:: t {
106
+
107
+ ty:: fold_regions ( tcx, ty) { |r, in_fn|
108
+ alt r {
109
+ // As long as we are not within a fn() type, `&T` is
110
+ // mapped to the free region anon_r. But within a fn
111
+ // type, it remains bound.
112
+ ty : : re_bound ( ty:: br_anon) if in_fn { r }
113
+
114
+ ty:: re_bound ( br) {
115
+ alt isr. find ( br) {
116
+ // In most cases, all named, bound regions will be
117
+ // mapped to some free region.
118
+ some ( fr) { fr }
119
+
120
+ // But in the case of a fn() type, there may be
121
+ // named regions within that remain bound:
122
+ none if in_fn { r }
123
+ none {
124
+ tcx. sess . bug (
125
+ #fmt[ "Bound region not found in \
126
+ in_scope_regions list: %s",
127
+ region_to_str ( tcx, r) ] ) ;
128
+ }
129
+ }
130
+ }
74
131
75
- // Free regions like these just stay the same:
76
- ty:: re_static |
77
- ty:: re_scope ( _) |
78
- ty:: re_free ( _, _) |
79
- ty:: re_var ( _) { r }
132
+ // Free regions like these just stay the same:
133
+ ty:: re_static |
134
+ ty:: re_scope ( _) |
135
+ ty:: re_free ( _, _) |
136
+ ty:: re_var ( _) { r }
137
+ }
80
138
}
81
139
}
82
140
}
@@ -149,71 +207,3 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
149
207
}
150
208
}
151
209
}
152
-
153
- // Takes `isr`, a (possibly empty) mapping from in-scope region names ("isr"s)
154
- // to their corresponding regions; `tys`, a list of types, and `to_r`, a
155
- // closure that takes a bound_region and returns a region. Returns an updated
156
- // version of `isr`, extended with the in-scope region names from all of the
157
- // bound regions appearing in the types in the `tys` list (if they're not in
158
- // `isr` already), with each of those in-scope region names mapped to a region
159
- // that's the result of applying `to_r` to itself.
160
-
161
- // "collect" is something of a misnomer -- we're not merely collecting
162
- // a list of the bound regions, but also doing the work of applying
163
- // `to_r` to them!
164
- fn collect_bound_regions_in_tys (
165
- tcx : ty:: ctxt ,
166
- isr : isr_alist ,
167
- tys : [ ty:: t ] ,
168
- to_r : fn ( ty:: bound_region ) -> ty:: region ) -> isr_alist {
169
-
170
- // Takes `isr` (described above), `to_r` (described above), and `r`, a
171
- // region. If `r` is anything other than a bound region, or if it's a
172
- // bound region that already appears in `isr`, then we return `isr`
173
- // unchanged. If `r` is a bound region that doesn't already appear in
174
- // `isr`, we return an updated isr_alist that now contains a mapping from
175
- // `r` to the result of calling `to_r` on it.
176
- fn append_isr ( isr : isr_alist ,
177
- to_r : fn ( ty:: bound_region ) -> ty:: region ,
178
- r : ty:: region ) -> isr_alist {
179
- alt r {
180
- ty : : re_free ( _, _) | ty:: re_static | ty:: re_scope ( _) |
181
- ty:: re_var ( _) {
182
- isr
183
- }
184
- ty:: re_bound ( br) {
185
- alt isr. find ( br) {
186
- some ( _) { isr }
187
- none { @cons( ( br, to_r ( br) ) , isr) }
188
- }
189
- }
190
- }
191
- }
192
-
193
- // For each region in `t`, apply the `append_isr` function to that
194
- // region, accumulating and returning the results in an isr_alist.
195
- fn fold_over_regions_in_type (
196
- tcx : ty:: ctxt ,
197
- isr : isr_alist ,
198
- ty : ty:: t ,
199
- to_r : fn ( ty:: bound_region ) -> ty:: region ) -> isr_alist {
200
-
201
- let mut isr = isr;
202
-
203
- // Using fold_regions is inefficient, because it constructs new types,
204
- // but it avoids code duplication in terms of locating all the regions
205
- // within the various kinds of types. This had already caused me
206
- // several bugs so I decided to switch over.
207
- ty:: fold_regions ( tcx, ty) { |r, in_fn|
208
- if !in_fn { isr = append_isr ( isr, to_r, r) ; }
209
- r
210
- } ;
211
-
212
- ret isr;
213
- }
214
-
215
- // For each type `t` in `tys`...
216
- tys. foldl ( isr) { |isr, t|
217
- fold_over_regions_in_type ( tcx, isr, t, to_r)
218
- }
219
- }
0 commit comments