Skip to content

Commit 8e7a338

Browse files
committed
BodyCollector
1 parent b46775a commit 8e7a338

File tree

3 files changed

+91
-77
lines changed

3 files changed

+91
-77
lines changed

src/tools/rust-analyzer/crates/hir-def/src/body.rs

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use crate::{
2525
db::DefDatabase,
2626
expander::Expander,
2727
hir::{
28-
dummy_expr_id, Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label,
29-
LabelId, Pat, PatId, RecordFieldPat, Statement,
28+
Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat,
29+
PatId, RecordFieldPat, Statement,
3030
},
3131
item_tree::AttrOwner,
3232
nameres::DefMap,
@@ -81,7 +81,7 @@ pub struct Body {
8181
pub body_expr: ExprId,
8282
pub types: TypesMap,
8383
/// Block expressions in this body that may contain inner items.
84-
block_scopes: Vec<BlockId>,
84+
block_scopes: Box<[BlockId]>,
8585

8686
/// A map from binding to its hygiene ID.
8787
///
@@ -98,6 +98,64 @@ pub struct Body {
9898
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
9999
}
100100

101+
/// The body of an item (function, const etc.).
102+
#[derive(Debug, Eq, PartialEq, Default)]
103+
pub struct BodyCollector {
104+
pub exprs: Arena<Expr>,
105+
pub pats: Arena<Pat>,
106+
pub bindings: Arena<Binding>,
107+
pub labels: Arena<Label>,
108+
pub binding_owners: FxHashMap<BindingId, ExprId>,
109+
pub types: TypesMap,
110+
block_scopes: Vec<BlockId>,
111+
binding_hygiene: FxHashMap<BindingId, HygieneId>,
112+
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
113+
}
114+
115+
impl BodyCollector {
116+
fn finish(
117+
self,
118+
body_expr: ExprId,
119+
self_param: Option<BindingId>,
120+
params: Box<[PatId]>,
121+
) -> Body {
122+
let Self {
123+
block_scopes,
124+
mut exprs,
125+
mut labels,
126+
mut pats,
127+
mut bindings,
128+
mut binding_owners,
129+
mut binding_hygiene,
130+
mut ident_hygiene,
131+
mut types,
132+
} = self;
133+
exprs.shrink_to_fit();
134+
labels.shrink_to_fit();
135+
pats.shrink_to_fit();
136+
bindings.shrink_to_fit();
137+
binding_owners.shrink_to_fit();
138+
binding_hygiene.shrink_to_fit();
139+
ident_hygiene.shrink_to_fit();
140+
types.shrink_to_fit();
141+
142+
Body {
143+
exprs,
144+
pats,
145+
bindings,
146+
labels,
147+
binding_owners,
148+
params,
149+
self_param,
150+
body_expr,
151+
types,
152+
block_scopes: block_scopes.into_boxed_slice(),
153+
binding_hygiene,
154+
ident_hygiene,
155+
}
156+
}
157+
}
158+
101159
pub type ExprPtr = AstPtr<ast::Expr>;
102160
pub type ExprSource = InFile<ExprPtr>;
103161

@@ -242,9 +300,8 @@ impl Body {
242300
};
243301
let module = def.module(db);
244302
let expander = Expander::new(db, file_id, module);
245-
let (mut body, mut source_map) =
303+
let (body, mut source_map) =
246304
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
247-
body.shrink_to_fit();
248305
source_map.shrink_to_fit();
249306

250307
(Arc::new(body), Arc::new(source_map))
@@ -304,32 +361,6 @@ impl Body {
304361
lower::lower(db, owner, expander, params, body, krate, is_async_fn)
305362
}
306363

307-
fn shrink_to_fit(&mut self) {
308-
let Self {
309-
body_expr: _,
310-
params: _,
311-
self_param: _,
312-
block_scopes,
313-
exprs,
314-
labels,
315-
pats,
316-
bindings,
317-
binding_owners,
318-
binding_hygiene,
319-
ident_hygiene,
320-
types,
321-
} = self;
322-
block_scopes.shrink_to_fit();
323-
exprs.shrink_to_fit();
324-
labels.shrink_to_fit();
325-
pats.shrink_to_fit();
326-
bindings.shrink_to_fit();
327-
binding_owners.shrink_to_fit();
328-
binding_hygiene.shrink_to_fit();
329-
ident_hygiene.shrink_to_fit();
330-
types.shrink_to_fit();
331-
}
332-
333364
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
334365
self.walk_pats(pat_id, &mut |pat| {
335366
if let Pat::Bind { id, .. } = &self[pat] {
@@ -670,25 +701,6 @@ impl Body {
670701
}
671702
}
672703

673-
impl Default for Body {
674-
fn default() -> Self {
675-
Self {
676-
body_expr: dummy_expr_id(),
677-
exprs: Default::default(),
678-
pats: Default::default(),
679-
bindings: Default::default(),
680-
labels: Default::default(),
681-
params: Default::default(),
682-
block_scopes: Default::default(),
683-
binding_owners: Default::default(),
684-
self_param: Default::default(),
685-
binding_hygiene: Default::default(),
686-
ident_hygiene: Default::default(),
687-
types: Default::default(),
688-
}
689-
}
690-
}
691-
692704
impl Index<ExprId> for Body {
693705
type Output = Expr;
694706

src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ use triomphe::Arc;
2929

3030
use crate::{
3131
attr::Attrs,
32-
body::{Body, BodyDiagnostic, BodySourceMap, ExprPtr, HygieneId, LabelPtr, PatPtr},
32+
body::{
33+
Body, BodyCollector, BodyDiagnostic, BodySourceMap, ExprPtr, HygieneId, LabelPtr, PatPtr,
34+
},
3335
builtin_type::BuiltinUint,
3436
data::adt::StructKind,
3537
db::DefDatabase,
@@ -82,7 +84,7 @@ pub(super) fn lower(
8284
def_map: expander.module.def_map(db),
8385
source_map: BodySourceMap::default(),
8486
ast_id_map: db.ast_id_map(expander.current_file_id()),
85-
body: Body::default(),
87+
body: BodyCollector::default(),
8688
expander,
8789
current_try_block_label: None,
8890
is_lowering_coroutine: false,
@@ -102,7 +104,7 @@ struct ExprCollector<'a> {
102104
def_map: Arc<DefMap>,
103105
ast_id_map: Arc<AstIdMap>,
104106
krate: CrateId,
105-
body: Body,
107+
body: BodyCollector,
106108
source_map: BodySourceMap,
107109

108110
is_lowering_coroutine: bool,
@@ -214,6 +216,9 @@ impl ExprCollector<'_> {
214216
body: Option<ast::Expr>,
215217
is_async_fn: bool,
216218
) -> (Body, BodySourceMap) {
219+
let mut self_param = None;
220+
let mut params = vec![];
221+
217222
let skip_body = match self.owner {
218223
DefWithBodyId::FunctionId(it) => self.db.attrs(it.into()),
219224
DefWithBodyId::StaticId(it) => self.db.attrs(it.into()),
@@ -226,29 +231,32 @@ impl ExprCollector<'_> {
226231
// If #[rust_analyzer::skip] annotated, only construct enough information for the signature
227232
// and skip the body.
228233
if skip_body {
229-
self.body.body_expr = self.missing_expr();
230234
if let Some((param_list, mut attr_enabled)) = param_list {
231-
if let Some(self_param) =
235+
if let Some(self_param_syn) =
232236
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
233237
{
234-
let is_mutable =
235-
self_param.mut_token().is_some() && self_param.amp_token().is_none();
238+
let is_mutable = self_param_syn.mut_token().is_some()
239+
&& self_param_syn.amp_token().is_none();
236240
let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
237241
Name::new_symbol_root(sym::self_.clone()),
238242
BindingAnnotation::new(is_mutable, false),
239243
);
240-
self.body.self_param = Some(binding_id);
244+
self_param = Some(binding_id);
241245
self.source_map.self_param =
242-
Some(self.expander.in_file(AstPtr::new(&self_param)));
246+
Some(self.expander.in_file(AstPtr::new(&self_param_syn)));
243247
}
244-
self.body.params = param_list
248+
params = param_list
245249
.params()
246250
.zip(attr_enabled)
247251
.filter(|(_, enabled)| *enabled)
248252
.map(|_| self.missing_pat())
249253
.collect();
250254
};
251-
return (self.body, self.source_map);
255+
let body_expr = self.missing_expr();
256+
return (
257+
self.body.finish(body_expr, self_param, params.into_boxed_slice()),
258+
self.source_map,
259+
);
252260
}
253261

254262
self.awaitable_context.replace(if is_async_fn {
@@ -264,35 +272,34 @@ impl ExprCollector<'_> {
264272
}
265273
});
266274
if let Some((param_list, mut attr_enabled)) = param_list {
267-
let mut params = vec![];
268-
if let Some(self_param) =
275+
if let Some(self_param_syn) =
269276
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
270277
{
271278
let is_mutable =
272-
self_param.mut_token().is_some() && self_param.amp_token().is_none();
279+
self_param_syn.mut_token().is_some() && self_param_syn.amp_token().is_none();
273280
let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
274281
Name::new_symbol_root(sym::self_.clone()),
275282
BindingAnnotation::new(is_mutable, false),
276283
);
277-
let hygiene = self_param
284+
let hygiene = self_param_syn
278285
.name()
279286
.map(|name| self.hygiene_id_for(name.syntax().text_range().start()))
280287
.unwrap_or(HygieneId::ROOT);
281288
if !hygiene.is_root() {
282289
self.body.binding_hygiene.insert(binding_id, hygiene);
283290
}
284-
self.body.self_param = Some(binding_id);
285-
self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param)));
291+
self_param = Some(binding_id);
292+
self.source_map.self_param =
293+
Some(self.expander.in_file(AstPtr::new(&self_param_syn)));
286294
}
287295

288296
for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled)
289297
{
290298
let param_pat = self.collect_pat_top(param.pat());
291299
params.push(param_pat);
292300
}
293-
self.body.params = params.into_boxed_slice();
294301
};
295-
self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
302+
let body_expr = self.with_label_rib(RibKind::Closure, |this| {
296303
if is_async_fn {
297304
match body {
298305
Some(e) => {
@@ -310,7 +317,7 @@ impl ExprCollector<'_> {
310317
}
311318
});
312319

313-
(self.body, self.source_map)
320+
(self.body.finish(body_expr, self_param, params.into_boxed_slice()), self.source_map)
314321
}
315322

316323
fn ctx(&mut self) -> LowerCtx<'_> {
@@ -1934,7 +1941,7 @@ impl ExprCollector<'_> {
19341941
f: impl FnOnce(&mut Self) -> T,
19351942
) -> T {
19361943
self.label_ribs.push(LabelRib::new(RibKind::Normal(
1937-
self.body[label].name.clone(),
1944+
self.body.labels[label].name.clone(),
19381945
label,
19391946
hygiene,
19401947
)));

src/tools/rust-analyzer/crates/hir-def/src/hir.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::fmt;
1919

2020
use hir_expand::{name::Name, MacroDefId};
2121
use intern::Symbol;
22-
use la_arena::{Idx, RawIdx};
22+
use la_arena::Idx;
2323
use rustc_apfloat::ieee::{Half as f16, Quad as f128};
2424
use syntax::ast;
2525
use type_ref::TypeRefId;
@@ -37,11 +37,6 @@ pub type BindingId = Idx<Binding>;
3737

3838
pub type ExprId = Idx<Expr>;
3939

40-
/// FIXME: this is a hacky function which should be removed
41-
pub(crate) fn dummy_expr_id() -> ExprId {
42-
ExprId::from_raw(RawIdx::from(u32::MAX))
43-
}
44-
4540
pub type PatId = Idx<Pat>;
4641

4742
// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts

0 commit comments

Comments
 (0)