Skip to content

Commit cd3bf9f

Browse files
committed
Auto merge of #15076 - Veykril:bindings, r=Veykril
internal: Shrink size of hir::Binding
2 parents 5dccf30 + c318620 commit cd3bf9f

File tree

5 files changed

+43
-31
lines changed

5 files changed

+43
-31
lines changed

crates/hir-def/src/body.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -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

262286
impl 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
}

crates/hir-def/src/body/lower.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use hir_expand::{
1111
AstId, ExpandError, InFile,
1212
};
1313
use intern::Interned;
14-
use la_arena::Arena;
1514
use profile::Count;
1615
use rustc_hash::FxHashMap;
1716
use smallvec::SmallVec;
@@ -60,10 +59,11 @@ pub(super) fn lower(
6059
source_map: BodySourceMap::default(),
6160
ast_id_map: db.ast_id_map(expander.current_file_id),
6261
body: Body {
63-
exprs: Arena::default(),
64-
pats: Arena::default(),
65-
bindings: Arena::default(),
66-
labels: Arena::default(),
62+
exprs: Default::default(),
63+
pats: Default::default(),
64+
bindings: Default::default(),
65+
binding_owners: Default::default(),
66+
labels: Default::default(),
6767
params: Vec::new(),
6868
body_expr: dummy_expr_id(),
6969
block_scopes: Vec::new(),
@@ -1540,13 +1540,16 @@ impl ExprCollector<'_> {
15401540
}
15411541

15421542
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
1543-
self.body.bindings.alloc(Binding {
1543+
let binding = self.body.bindings.alloc(Binding {
15441544
name,
15451545
mode,
15461546
definitions: SmallVec::new(),
1547-
owner: self.current_binding_owner,
15481547
problems: None,
1549-
})
1548+
});
1549+
if let Some(owner) = self.current_binding_owner {
1550+
self.body.binding_owners.insert(binding, owner);
1551+
}
1552+
binding
15501553
}
15511554

15521555
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {

crates/hir-def/src/hir.rs

-16
Original file line numberDiff line numberDiff line change
@@ -501,25 +501,9 @@ pub struct Binding {
501501
pub name: Name,
502502
pub mode: BindingAnnotation,
503503
pub definitions: SmallVec<[PatId; 1]>,
504-
/// Id of the closure/generator that owns this binding. If it is owned by the
505-
/// top level expression, this field would be `None`.
506-
pub owner: Option<ExprId>,
507504
pub problems: Option<BindingProblems>,
508505
}
509506

510-
impl Binding {
511-
pub fn is_upvar(&self, relative_to: ExprId) -> bool {
512-
match self.owner {
513-
Some(x) => {
514-
// We assign expression ids in a way that outer closures will receive
515-
// a lower id
516-
x.into_raw() < relative_to.into_raw()
517-
}
518-
None => true,
519-
}
520-
}
521-
}
522-
523507
#[derive(Debug, Clone, Eq, PartialEq)]
524508
pub struct RecordFieldPat {
525509
pub name: Name,

crates/hir-ty/src/infer/closure.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -715,10 +715,9 @@ impl InferenceContext<'_> {
715715
}
716716

717717
fn is_upvar(&self, place: &HirPlace) -> bool {
718-
let b = &self.body[place.local];
719718
if let Some(c) = self.current_closure {
720719
let (_, root) = self.db.lookup_intern_closure(c.into());
721-
return b.is_upvar(root);
720+
return self.body.is_binding_upvar(place.local, root);
722721
}
723722
false
724723
}

crates/hir-ty/src/mir/lower.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1853,7 +1853,7 @@ pub fn mir_body_for_closure_query(
18531853
.result
18541854
.binding_locals
18551855
.into_iter()
1856-
.filter(|x| ctx.body[x.0].owner == Some(expr))
1856+
.filter(|it| ctx.body.binding_owners.get(&it.0).copied() == Some(expr))
18571857
.collect();
18581858
if let Some(err) = err {
18591859
return Err(MirLowerError::UnresolvedUpvar(err));
@@ -1909,10 +1909,11 @@ pub fn lower_to_mir(
19091909
// 0 is return local
19101910
ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) });
19111911
let binding_picker = |b: BindingId| {
1912+
let owner = ctx.body.binding_owners.get(&b).copied();
19121913
if root_expr == body.body_expr {
1913-
body[b].owner.is_none()
1914+
owner.is_none()
19141915
} else {
1915-
body[b].owner == Some(root_expr)
1916+
owner == Some(root_expr)
19161917
}
19171918
};
19181919
// 1 to param_len is for params

0 commit comments

Comments
 (0)