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

Commit 3205ed7

Browse files
committed
simplify storing generic parameter attributes in item tree
1 parent 37a8493 commit 3205ed7

File tree

2 files changed

+33
-41
lines changed

2 files changed

+33
-41
lines changed

crates/hir-def/src/generics.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
db::DefDatabase,
2222
dyn_map::{keys, DynMap},
2323
expander::Expander,
24-
item_tree::ItemTree,
24+
item_tree::{AttrOwner, ItemTree},
2525
lower::LowerCtx,
2626
nameres::{DefMap, MacroSubNs},
2727
src::{HasChildSource, HasSource},
@@ -215,9 +215,14 @@ impl GenericParams {
215215
}
216216
}
217217

218-
pub(crate) fn fill(&mut self, lower_ctx: &LowerCtx<'_>, node: &dyn HasGenericParams) {
218+
pub(crate) fn fill(
219+
&mut self,
220+
lower_ctx: &LowerCtx<'_>,
221+
node: &dyn HasGenericParams,
222+
add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
223+
) {
219224
if let Some(params) = node.generic_param_list() {
220-
self.fill_params(lower_ctx, params)
225+
self.fill_params(lower_ctx, params, add_param_attrs)
221226
}
222227
if let Some(where_clause) = node.where_clause() {
223228
self.fill_where_predicates(lower_ctx, where_clause);
@@ -235,7 +240,12 @@ impl GenericParams {
235240
}
236241
}
237242

238-
fn fill_params(&mut self, lower_ctx: &LowerCtx<'_>, params: ast::GenericParamList) {
243+
fn fill_params(
244+
&mut self,
245+
lower_ctx: &LowerCtx<'_>,
246+
params: ast::GenericParamList,
247+
mut add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
248+
) {
239249
for type_or_const_param in params.type_or_const_params() {
240250
match type_or_const_param {
241251
ast::TypeOrConstParam::Type(type_param) => {
@@ -249,13 +259,14 @@ impl GenericParams {
249259
default,
250260
provenance: TypeParamProvenance::TypeParamList,
251261
};
252-
self.type_or_consts.alloc(param.into());
262+
let idx = self.type_or_consts.alloc(param.into());
253263
let type_ref = TypeRef::Path(name.into());
254264
self.fill_bounds(
255265
lower_ctx,
256266
type_param.type_bound_list(),
257267
Either::Left(type_ref),
258268
);
269+
add_param_attrs(idx.into(), ast::GenericParam::TypeParam(type_param));
259270
}
260271
ast::TypeOrConstParam::Const(const_param) => {
261272
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
@@ -267,21 +278,23 @@ impl GenericParams {
267278
ty: Interned::new(ty),
268279
has_default: const_param.default_val().is_some(),
269280
};
270-
self.type_or_consts.alloc(param.into());
281+
let idx = self.type_or_consts.alloc(param.into());
282+
add_param_attrs(idx.into(), ast::GenericParam::ConstParam(const_param));
271283
}
272284
}
273285
}
274286
for lifetime_param in params.lifetime_params() {
275287
let name =
276288
lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(&lt));
277289
let param = LifetimeParamData { name: name.clone() };
278-
self.lifetimes.alloc(param);
290+
let idx = self.lifetimes.alloc(param);
279291
let lifetime_ref = LifetimeRef::new_name(name);
280292
self.fill_bounds(
281293
lower_ctx,
282294
lifetime_param.type_bound_list(),
283295
Either::Right(lifetime_ref),
284296
);
297+
add_param_attrs(idx.into(), ast::GenericParam::LifetimeParam(lifetime_param));
285298
}
286299
}
287300

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

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -602,44 +602,23 @@ impl<'a> Ctx<'a> {
602602
generics.fill_bounds(&self.body_ctx, bounds, Either::Left(self_param));
603603
}
604604

605-
generics.fill(&self.body_ctx, node);
606-
607-
generics.shrink_to_fit();
608-
609-
if let Some(params) = node.generic_param_list() {
610-
let params_by_name: FxHashMap<_, _> = params
611-
.generic_params()
612-
.filter_map(|param| {
613-
let name = match &param {
614-
ast::GenericParam::ConstParam(param) => param.name()?.as_name(),
615-
ast::GenericParam::LifetimeParam(param) => {
616-
Name::new_lifetime(&param.lifetime()?)
617-
}
618-
ast::GenericParam::TypeParam(param) => param.name()?.as_name(),
619-
};
620-
Some((name, param))
621-
})
622-
.collect();
623-
for (idx, param) in generics.type_or_consts.iter() {
624-
if let Some(name) = param.name() {
625-
if let Some(param) = params_by_name.get(name) {
626-
self.add_attrs(
627-
idx.into(),
628-
RawAttrs::new(self.db.upcast(), param, self.hygiene()),
629-
);
630-
}
605+
let add_param_attrs = |item, param| {
606+
let attrs = RawAttrs::new(self.db.upcast(), &param, self.body_ctx.hygiene());
607+
// This is identical to the body of `Ctx::add_attrs()` but we can't call that here
608+
// because it requires `&mut self` and the call to `generics.fill()` below also
609+
// references `self`.
610+
match self.tree.attrs.entry(item) {
611+
Entry::Occupied(mut entry) => {
612+
*entry.get_mut() = entry.get().merge(attrs);
631613
}
632-
}
633-
for (idx, param) in generics.lifetimes.iter() {
634-
if let Some(param) = params_by_name.get(&param.name) {
635-
self.add_attrs(
636-
idx.into(),
637-
RawAttrs::new(self.db.upcast(), param, self.hygiene()),
638-
);
614+
Entry::Vacant(entry) => {
615+
entry.insert(attrs);
639616
}
640617
}
641-
}
618+
};
619+
generics.fill(&self.body_ctx, node, add_param_attrs);
642620

621+
generics.shrink_to_fit();
643622
Interned::new(generics)
644623
}
645624

0 commit comments

Comments
 (0)