Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1aadd9d

Browse files
committed
internal: Use itemtree for variant and field attribute collection
1 parent 10c7ee7 commit 1aadd9d

File tree

2 files changed

+75
-23
lines changed

2 files changed

+75
-23
lines changed

crates/hir-def/src/adt.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ impl EnumData {
136136

137137
let enum_ = &item_tree[loc.id.value];
138138
let mut variants = Arena::new();
139-
for var_id in enum_.variants.clone() {
140-
if item_tree.attrs(db, krate, var_id.into()).is_cfg_enabled(&cfg_options) {
141-
let var = &item_tree[var_id];
139+
for tree_id in enum_.variants.clone() {
140+
if item_tree.attrs(db, krate, tree_id.into()).is_cfg_enabled(&cfg_options) {
141+
let var = &item_tree[tree_id];
142142
let var_data = lower_fields(
143143
db,
144144
krate,

crates/hir-def/src/attr.rs

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cfg::{CfgExpr, CfgOptions};
77
use either::Either;
88
use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
99
use itertools::Itertools;
10-
use la_arena::ArenaMap;
10+
use la_arena::{ArenaMap, Idx, RawIdx};
1111
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
1212
use smallvec::{smallvec, SmallVec};
1313
use syntax::{
@@ -19,12 +19,12 @@ use tt::Subtree;
1919
use crate::{
2020
db::DefDatabase,
2121
intern::Interned,
22-
item_tree::{ItemTreeId, ItemTreeNode},
22+
item_tree::{Fields, ItemTreeId, ItemTreeNode},
2323
nameres::ModuleSource,
2424
path::{ModPath, PathKind},
2525
src::{HasChildSource, HasSource},
26-
AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup,
27-
MacroId, VariantId,
26+
AdtId, AttrDefId, EnumId, GenericParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroId,
27+
VariantId,
2828
};
2929

3030
/// Holds documentation
@@ -201,15 +201,22 @@ impl Attrs {
201201
db: &dyn DefDatabase,
202202
e: EnumId,
203203
) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> {
204-
let krate = e.lookup(db).container.krate;
205-
let src = e.child_source(db);
206204
let mut res = ArenaMap::default();
207205

208-
for (id, var) in src.value.iter() {
209-
let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn ast::HasAttrs))
210-
.filter(db, krate);
211-
212-
res.insert(id, attrs)
206+
let loc = e.lookup(db);
207+
let krate = loc.container.krate;
208+
let item_tree = loc.id.item_tree(db);
209+
let enum_ = &item_tree[loc.id.value];
210+
let crate_graph = db.crate_graph();
211+
let cfg_options = &crate_graph[krate].cfg_options;
212+
213+
let mut idx = 0;
214+
for variant in enum_.variants.clone() {
215+
let attrs = item_tree.attrs(db, krate, variant.into());
216+
if attrs.is_cfg_enabled(cfg_options) {
217+
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
218+
idx += 1;
219+
}
213220
}
214221

215222
Arc::new(res)
@@ -219,18 +226,63 @@ impl Attrs {
219226
db: &dyn DefDatabase,
220227
v: VariantId,
221228
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
222-
let krate = v.module(db).krate;
223-
let src = v.child_source(db);
224229
let mut res = ArenaMap::default();
225230

226-
for (id, fld) in src.value.iter() {
227-
let owner: &dyn HasAttrs = match fld {
228-
Either::Left(tuple) => tuple,
229-
Either::Right(record) => record,
230-
};
231-
let attrs = RawAttrs::from_attrs_owner(db, src.with_value(owner)).filter(db, krate);
231+
let crate_graph = db.crate_graph();
232+
let (fields, item_tree, krate) = match v {
233+
VariantId::EnumVariantId(it) => {
234+
let e = it.parent;
235+
let loc = e.lookup(db);
236+
let krate = loc.container.krate;
237+
let item_tree = loc.id.item_tree(db);
238+
let enum_ = &item_tree[loc.id.value];
239+
240+
let cfg_options = &crate_graph[krate].cfg_options;
241+
let variant = 'tri: loop {
242+
let mut idx = 0;
243+
for variant in enum_.variants.clone() {
244+
let attrs = item_tree.attrs(db, krate, variant.into());
245+
if attrs.is_cfg_enabled(cfg_options) {
246+
if it.local_id == Idx::from_raw(RawIdx::from(idx)) {
247+
break 'tri variant;
248+
}
249+
idx += 1;
250+
}
251+
}
252+
return Arc::new(res);
253+
};
254+
(item_tree[variant].fields.clone(), item_tree, krate)
255+
}
256+
VariantId::StructId(it) => {
257+
let loc = it.lookup(db);
258+
let krate = loc.container.krate;
259+
let item_tree = loc.id.item_tree(db);
260+
let struct_ = &item_tree[loc.id.value];
261+
(struct_.fields.clone(), item_tree, krate)
262+
}
263+
VariantId::UnionId(it) => {
264+
let loc = it.lookup(db);
265+
let krate = loc.container.krate;
266+
let item_tree = loc.id.item_tree(db);
267+
let union_ = &item_tree[loc.id.value];
268+
(union_.fields.clone(), item_tree, krate)
269+
}
270+
};
232271

233-
res.insert(id, attrs);
272+
let fields = match fields {
273+
Fields::Record(fields) | Fields::Tuple(fields) => fields,
274+
Fields::Unit => return Arc::new(res),
275+
};
276+
277+
let cfg_options = &crate_graph[krate].cfg_options;
278+
279+
let mut idx = 0;
280+
for field in fields {
281+
let attrs = item_tree.attrs(db, krate, field.into());
282+
if attrs.is_cfg_enabled(cfg_options) {
283+
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
284+
idx += 1;
285+
}
234286
}
235287

236288
Arc::new(res)

0 commit comments

Comments
 (0)