@@ -37,6 +37,9 @@ pub struct Body {
3737 pub pats : Arena < Pat > ,
3838 pub bindings : Arena < Binding > ,
3939 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 > ,
4043 /// The patterns for the function's parameters. While the parameter types are
4144 /// part of the function signature, the patterns are not (they don't change
4245 /// the external type of the function).
@@ -206,14 +209,24 @@ impl Body {
206209 }
207210
208211 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 ;
211223 block_scopes. shrink_to_fit ( ) ;
212224 exprs. shrink_to_fit ( ) ;
213225 labels. shrink_to_fit ( ) ;
214226 params. shrink_to_fit ( ) ;
215227 pats. shrink_to_fit ( ) ;
216228 bindings. shrink_to_fit ( ) ;
229+ binding_owners. shrink_to_fit ( ) ;
217230 }
218231
219232 pub fn walk_bindings_in_pat ( & self , pat_id : PatId , mut f : impl FnMut ( BindingId ) ) {
@@ -257,6 +270,17 @@ impl Body {
257270 f ( pat_id) ;
258271 self . walk_pats_shallow ( pat_id, |p| self . walk_pats ( p, f) ) ;
259272 }
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+ }
260284}
261285
262286impl Default for Body {
@@ -269,6 +293,7 @@ impl Default for Body {
269293 labels : Default :: default ( ) ,
270294 params : Default :: default ( ) ,
271295 block_scopes : Default :: default ( ) ,
296+ binding_owners : Default :: default ( ) ,
272297 _c : Default :: default ( ) ,
273298 }
274299 }
0 commit comments