@@ -37,6 +37,9 @@ pub struct Body {
37
37
pub pats : Arena < Pat > ,
38
38
pub bindings : Arena < Binding > ,
39
39
pub labels : Arena < Label > ,
40
+ /// Id of the closure/generator that owns the corresponding binding. If a binding is owned by the
41
+ /// top level expression, it will not be listed in here.
42
+ pub binding_owners : FxHashMap < BindingId , ExprId > ,
40
43
/// The patterns for the function's parameters. While the parameter types are
41
44
/// part of the function signature, the patterns are not (they don't change
42
45
/// the external type of the function).
@@ -206,14 +209,24 @@ impl Body {
206
209
}
207
210
208
211
fn shrink_to_fit ( & mut self ) {
209
- let Self { _c : _, body_expr : _, block_scopes, exprs, labels, params, pats, bindings } =
210
- self ;
212
+ let Self {
213
+ _c : _,
214
+ body_expr : _,
215
+ block_scopes,
216
+ exprs,
217
+ labels,
218
+ params,
219
+ pats,
220
+ bindings,
221
+ binding_owners,
222
+ } = self ;
211
223
block_scopes. shrink_to_fit ( ) ;
212
224
exprs. shrink_to_fit ( ) ;
213
225
labels. shrink_to_fit ( ) ;
214
226
params. shrink_to_fit ( ) ;
215
227
pats. shrink_to_fit ( ) ;
216
228
bindings. shrink_to_fit ( ) ;
229
+ binding_owners. shrink_to_fit ( ) ;
217
230
}
218
231
219
232
pub fn walk_bindings_in_pat ( & self , pat_id : PatId , mut f : impl FnMut ( BindingId ) ) {
@@ -257,6 +270,17 @@ impl Body {
257
270
f ( pat_id) ;
258
271
self . walk_pats_shallow ( pat_id, |p| self . walk_pats ( p, f) ) ;
259
272
}
273
+
274
+ pub fn is_binding_upvar ( & self , binding : BindingId , relative_to : ExprId ) -> bool {
275
+ match self . binding_owners . get ( & binding) {
276
+ Some ( x) => {
277
+ // We assign expression ids in a way that outer closures will receive
278
+ // a lower id
279
+ x. into_raw ( ) < relative_to. into_raw ( )
280
+ }
281
+ None => true ,
282
+ }
283
+ }
260
284
}
261
285
262
286
impl Default for Body {
@@ -269,6 +293,7 @@ impl Default for Body {
269
293
labels : Default :: default ( ) ,
270
294
params : Default :: default ( ) ,
271
295
block_scopes : Default :: default ( ) ,
296
+ binding_owners : Default :: default ( ) ,
272
297
_c : Default :: default ( ) ,
273
298
}
274
299
}
0 commit comments