Auto merge of #15076 - Veykril:bindings, r=Veykril
internal: Shrink size of hir::Binding
This commit is contained in:
commit
cd3bf9fe51
5 changed files with 43 additions and 31 deletions
|
@ -37,6 +37,9 @@ pub struct Body {
|
||||||
pub pats: Arena<Pat>,
|
pub pats: Arena<Pat>,
|
||||||
pub bindings: Arena<Binding>,
|
pub bindings: Arena<Binding>,
|
||||||
pub labels: Arena<Label>,
|
pub labels: Arena<Label>,
|
||||||
|
/// Id of the closure/generator that owns the corresponding binding. If a binding is owned by the
|
||||||
|
/// top level expression, it will not be listed in here.
|
||||||
|
pub binding_owners: FxHashMap<BindingId, ExprId>,
|
||||||
/// The patterns for the function's parameters. While the parameter types are
|
/// The patterns for the function's parameters. While the parameter types are
|
||||||
/// part of the function signature, the patterns are not (they don't change
|
/// part of the function signature, the patterns are not (they don't change
|
||||||
/// the external type of the function).
|
/// the external type of the function).
|
||||||
|
@ -206,14 +209,24 @@ impl Body {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shrink_to_fit(&mut self) {
|
fn shrink_to_fit(&mut self) {
|
||||||
let Self { _c: _, body_expr: _, block_scopes, exprs, labels, params, pats, bindings } =
|
let Self {
|
||||||
self;
|
_c: _,
|
||||||
|
body_expr: _,
|
||||||
|
block_scopes,
|
||||||
|
exprs,
|
||||||
|
labels,
|
||||||
|
params,
|
||||||
|
pats,
|
||||||
|
bindings,
|
||||||
|
binding_owners,
|
||||||
|
} = self;
|
||||||
block_scopes.shrink_to_fit();
|
block_scopes.shrink_to_fit();
|
||||||
exprs.shrink_to_fit();
|
exprs.shrink_to_fit();
|
||||||
labels.shrink_to_fit();
|
labels.shrink_to_fit();
|
||||||
params.shrink_to_fit();
|
params.shrink_to_fit();
|
||||||
pats.shrink_to_fit();
|
pats.shrink_to_fit();
|
||||||
bindings.shrink_to_fit();
|
bindings.shrink_to_fit();
|
||||||
|
binding_owners.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
|
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
|
||||||
|
@ -257,6 +270,17 @@ impl Body {
|
||||||
f(pat_id);
|
f(pat_id);
|
||||||
self.walk_pats_shallow(pat_id, |p| self.walk_pats(p, f));
|
self.walk_pats_shallow(pat_id, |p| self.walk_pats(p, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_binding_upvar(&self, binding: BindingId, relative_to: ExprId) -> bool {
|
||||||
|
match self.binding_owners.get(&binding) {
|
||||||
|
Some(x) => {
|
||||||
|
// We assign expression ids in a way that outer closures will receive
|
||||||
|
// a lower id
|
||||||
|
x.into_raw() < relative_to.into_raw()
|
||||||
|
}
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Body {
|
impl Default for Body {
|
||||||
|
@ -269,6 +293,7 @@ impl Default for Body {
|
||||||
labels: Default::default(),
|
labels: Default::default(),
|
||||||
params: Default::default(),
|
params: Default::default(),
|
||||||
block_scopes: Default::default(),
|
block_scopes: Default::default(),
|
||||||
|
binding_owners: Default::default(),
|
||||||
_c: Default::default(),
|
_c: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ use hir_expand::{
|
||||||
AstId, ExpandError, InFile,
|
AstId, ExpandError, InFile,
|
||||||
};
|
};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::Arena;
|
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -60,10 +59,11 @@ pub(super) fn lower(
|
||||||
source_map: BodySourceMap::default(),
|
source_map: BodySourceMap::default(),
|
||||||
ast_id_map: db.ast_id_map(expander.current_file_id),
|
ast_id_map: db.ast_id_map(expander.current_file_id),
|
||||||
body: Body {
|
body: Body {
|
||||||
exprs: Arena::default(),
|
exprs: Default::default(),
|
||||||
pats: Arena::default(),
|
pats: Default::default(),
|
||||||
bindings: Arena::default(),
|
bindings: Default::default(),
|
||||||
labels: Arena::default(),
|
binding_owners: Default::default(),
|
||||||
|
labels: Default::default(),
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
body_expr: dummy_expr_id(),
|
body_expr: dummy_expr_id(),
|
||||||
block_scopes: Vec::new(),
|
block_scopes: Vec::new(),
|
||||||
|
@ -1540,13 +1540,16 @@ impl ExprCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
|
fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId {
|
||||||
self.body.bindings.alloc(Binding {
|
let binding = self.body.bindings.alloc(Binding {
|
||||||
name,
|
name,
|
||||||
mode,
|
mode,
|
||||||
definitions: SmallVec::new(),
|
definitions: SmallVec::new(),
|
||||||
owner: self.current_binding_owner,
|
|
||||||
problems: None,
|
problems: None,
|
||||||
})
|
});
|
||||||
|
if let Some(owner) = self.current_binding_owner {
|
||||||
|
self.body.binding_owners.insert(binding, owner);
|
||||||
|
}
|
||||||
|
binding
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
|
fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId {
|
||||||
|
|
|
@ -501,25 +501,9 @@ pub struct Binding {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub mode: BindingAnnotation,
|
pub mode: BindingAnnotation,
|
||||||
pub definitions: SmallVec<[PatId; 1]>,
|
pub definitions: SmallVec<[PatId; 1]>,
|
||||||
/// Id of the closure/generator that owns this binding. If it is owned by the
|
|
||||||
/// top level expression, this field would be `None`.
|
|
||||||
pub owner: Option<ExprId>,
|
|
||||||
pub problems: Option<BindingProblems>,
|
pub problems: Option<BindingProblems>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Binding {
|
|
||||||
pub fn is_upvar(&self, relative_to: ExprId) -> bool {
|
|
||||||
match self.owner {
|
|
||||||
Some(x) => {
|
|
||||||
// We assign expression ids in a way that outer closures will receive
|
|
||||||
// a lower id
|
|
||||||
x.into_raw() < relative_to.into_raw()
|
|
||||||
}
|
|
||||||
None => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct RecordFieldPat {
|
pub struct RecordFieldPat {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
|
|
|
@ -715,10 +715,9 @@ impl InferenceContext<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_upvar(&self, place: &HirPlace) -> bool {
|
fn is_upvar(&self, place: &HirPlace) -> bool {
|
||||||
let b = &self.body[place.local];
|
|
||||||
if let Some(c) = self.current_closure {
|
if let Some(c) = self.current_closure {
|
||||||
let (_, root) = self.db.lookup_intern_closure(c.into());
|
let (_, root) = self.db.lookup_intern_closure(c.into());
|
||||||
return b.is_upvar(root);
|
return self.body.is_binding_upvar(place.local, root);
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1853,7 +1853,7 @@ pub fn mir_body_for_closure_query(
|
||||||
.result
|
.result
|
||||||
.binding_locals
|
.binding_locals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| ctx.body[x.0].owner == Some(expr))
|
.filter(|it| ctx.body.binding_owners.get(&it.0).copied() == Some(expr))
|
||||||
.collect();
|
.collect();
|
||||||
if let Some(err) = err {
|
if let Some(err) = err {
|
||||||
return Err(MirLowerError::UnresolvedUpvar(err));
|
return Err(MirLowerError::UnresolvedUpvar(err));
|
||||||
|
@ -1909,10 +1909,11 @@ pub fn lower_to_mir(
|
||||||
// 0 is return local
|
// 0 is return local
|
||||||
ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) });
|
ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) });
|
||||||
let binding_picker = |b: BindingId| {
|
let binding_picker = |b: BindingId| {
|
||||||
|
let owner = ctx.body.binding_owners.get(&b).copied();
|
||||||
if root_expr == body.body_expr {
|
if root_expr == body.body_expr {
|
||||||
body[b].owner.is_none()
|
owner.is_none()
|
||||||
} else {
|
} else {
|
||||||
body[b].owner == Some(root_expr)
|
owner == Some(root_expr)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 1 to param_len is for params
|
// 1 to param_len is for params
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue