Skip to content

Commit 7c0c713

Browse files
Intern GenericParams
Also share the same instance between `ItemTree` and `generic_params` query.
1 parent adcf18e commit 7c0c713

File tree

9 files changed

+47
-82
lines changed

9 files changed

+47
-82
lines changed

crates/hir_def/src/db.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
1414
generics::GenericParams,
1515
import_map::ImportMap,
16+
intern::Interned,
1617
item_tree::ItemTree,
1718
lang_item::{LangItemTarget, LangItems},
1819
nameres::DefMap,
@@ -113,7 +114,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
113114
fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>;
114115

115116
#[salsa::invoke(GenericParams::generic_params_query)]
116-
fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
117+
fn generic_params(&self, def: GenericDefId) -> Interned<GenericParams>;
117118

118119
#[salsa::invoke(Attrs::variants_attrs_query)]
119120
fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>;

crates/hir_def/src/generics.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! structs, impls, traits, etc. This module provides a common HIR for these
33
//! generic parameters. See also the `Generics` type and the `generics_of` query
44
//! in rustc.
5-
use std::sync::Arc;
65
76
use base_db::FileId;
87
use either::Either;
@@ -27,35 +26,35 @@ use crate::{
2726
};
2827

2928
/// Data about a generic type parameter (to a function, struct, impl, ...).
30-
#[derive(Clone, PartialEq, Eq, Debug)]
29+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
3130
pub struct TypeParamData {
3231
pub name: Option<Name>,
3332
pub default: Option<Interned<TypeRef>>,
3433
pub provenance: TypeParamProvenance,
3534
}
3635

3736
/// Data about a generic lifetime parameter (to a function, struct, impl, ...).
38-
#[derive(Clone, PartialEq, Eq, Debug)]
37+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
3938
pub struct LifetimeParamData {
4039
pub name: Name,
4140
}
4241

4342
/// Data about a generic const parameter (to a function, struct, impl, ...).
44-
#[derive(Clone, PartialEq, Eq, Debug)]
43+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
4544
pub struct ConstParamData {
4645
pub name: Name,
4746
pub ty: Interned<TypeRef>,
4847
}
4948

50-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
49+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
5150
pub enum TypeParamProvenance {
5251
TypeParamList,
5352
TraitSelf,
5453
ArgumentImplTrait,
5554
}
5655

5756
/// Data about the generic parameters of a function, struct, impl, etc.
58-
#[derive(Clone, PartialEq, Eq, Debug, Default)]
57+
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
5958
pub struct GenericParams {
6059
pub types: Arena<TypeParamData>,
6160
pub lifetimes: Arena<LifetimeParamData>,
@@ -67,14 +66,14 @@ pub struct GenericParams {
6766
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
6867
/// It might still result in multiple actual predicates though, because of
6968
/// associated type bindings like `Iterator<Item = u32>`.
70-
#[derive(Clone, PartialEq, Eq, Debug)]
69+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
7170
pub enum WherePredicate {
7271
TypeBound { target: WherePredicateTypeTarget, bound: TypeBound },
7372
Lifetime { target: LifetimeRef, bound: LifetimeRef },
7473
ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound },
7574
}
7675

77-
#[derive(Clone, PartialEq, Eq, Debug)]
76+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
7877
pub enum WherePredicateTypeTarget {
7978
TypeRef(Interned<TypeRef>),
8079
/// For desugared where predicates that can directly refer to a type param.
@@ -92,55 +91,57 @@ impl GenericParams {
9291
pub(crate) fn generic_params_query(
9392
db: &dyn DefDatabase,
9493
def: GenericDefId,
95-
) -> Arc<GenericParams> {
94+
) -> Interned<GenericParams> {
9695
let _p = profile::span("generic_params_query");
9796

9897
let generics = match def {
9998
GenericDefId::FunctionId(id) => {
10099
let id = id.lookup(db).id;
101100
let tree = id.item_tree(db);
102101
let item = &tree[id.value];
103-
tree[item.generic_params].clone()
102+
item.generic_params.clone()
104103
}
105104
GenericDefId::AdtId(AdtId::StructId(id)) => {
106105
let id = id.lookup(db).id;
107106
let tree = id.item_tree(db);
108107
let item = &tree[id.value];
109-
tree[item.generic_params].clone()
108+
item.generic_params.clone()
110109
}
111110
GenericDefId::AdtId(AdtId::EnumId(id)) => {
112111
let id = id.lookup(db).id;
113112
let tree = id.item_tree(db);
114113
let item = &tree[id.value];
115-
tree[item.generic_params].clone()
114+
item.generic_params.clone()
116115
}
117116
GenericDefId::AdtId(AdtId::UnionId(id)) => {
118117
let id = id.lookup(db).id;
119118
let tree = id.item_tree(db);
120119
let item = &tree[id.value];
121-
tree[item.generic_params].clone()
120+
item.generic_params.clone()
122121
}
123122
GenericDefId::TraitId(id) => {
124123
let id = id.lookup(db).id;
125124
let tree = id.item_tree(db);
126125
let item = &tree[id.value];
127-
tree[item.generic_params].clone()
126+
item.generic_params.clone()
128127
}
129128
GenericDefId::TypeAliasId(id) => {
130129
let id = id.lookup(db).id;
131130
let tree = id.item_tree(db);
132131
let item = &tree[id.value];
133-
tree[item.generic_params].clone()
132+
item.generic_params.clone()
134133
}
135134
GenericDefId::ImplId(id) => {
136135
let id = id.lookup(db).id;
137136
let tree = id.item_tree(db);
138137
let item = &tree[id.value];
139-
tree[item.generic_params].clone()
138+
item.generic_params.clone()
139+
}
140+
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
141+
Interned::new(GenericParams::default())
140142
}
141-
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => GenericParams::default(),
142143
};
143-
Arc::new(generics)
144+
generics
144145
}
145146

146147
fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {

crates/hir_def/src/intern.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use dashmap::{lock::RwLockWriteGuard, DashMap, SharedValue};
1414
use once_cell::sync::OnceCell;
1515
use rustc_hash::FxHasher;
1616

17+
use crate::generics::GenericParams;
18+
1719
type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
1820
type Guard<T> =
1921
RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>;
@@ -194,4 +196,10 @@ macro_rules! impl_internable {
194196
)+ };
195197
}
196198

197-
impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath, str);
199+
impl_internable!(
200+
crate::type_ref::TypeRef,
201+
crate::type_ref::TraitRef,
202+
crate::path::ModPath,
203+
GenericParams,
204+
str
205+
);

crates/hir_def/src/item_tree.rs

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,6 @@ impl fmt::Debug for RawVisibilityId {
5858
}
5959
}
6060

61-
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
62-
pub struct GenericParamsId(u32);
63-
64-
impl GenericParamsId {
65-
pub const EMPTY: Self = GenericParamsId(u32::max_value());
66-
}
67-
6861
/// The item tree of a source file.
6962
#[derive(Debug, Default, Eq, PartialEq)]
7063
pub struct ItemTree {
@@ -146,7 +139,6 @@ impl ItemTree {
146139
macro_rules,
147140
macro_defs,
148141
vis,
149-
generics,
150142
inner_items,
151143
} = &mut **data;
152144

@@ -170,7 +162,6 @@ impl ItemTree {
170162
macro_defs.shrink_to_fit();
171163

172164
vis.arena.shrink_to_fit();
173-
generics.arena.shrink_to_fit();
174165

175166
inner_items.shrink_to_fit();
176167
}
@@ -241,32 +232,6 @@ static VIS_PUB: RawVisibility = RawVisibility::Public;
241232
static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)));
242233
static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
243234

244-
#[derive(Default, Debug, Eq, PartialEq)]
245-
struct GenericParamsStorage {
246-
arena: Arena<GenericParams>,
247-
}
248-
249-
impl GenericParamsStorage {
250-
fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
251-
if params.types.is_empty()
252-
&& params.lifetimes.is_empty()
253-
&& params.consts.is_empty()
254-
&& params.where_predicates.is_empty()
255-
{
256-
return GenericParamsId::EMPTY;
257-
}
258-
259-
GenericParamsId(self.arena.alloc(params).into_raw().into())
260-
}
261-
}
262-
263-
static EMPTY_GENERICS: GenericParams = GenericParams {
264-
types: Arena::new(),
265-
lifetimes: Arena::new(),
266-
consts: Arena::new(),
267-
where_predicates: Vec::new(),
268-
};
269-
270235
#[derive(Default, Debug, Eq, PartialEq)]
271236
struct ItemTreeData {
272237
imports: Arena<Import>,
@@ -289,7 +254,6 @@ struct ItemTreeData {
289254
macro_defs: Arena<MacroDef>,
290255

291256
vis: ItemVisibilities,
292-
generics: GenericParamsStorage,
293257

294258
inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
295259
}
@@ -508,17 +472,6 @@ impl Index<RawVisibilityId> for ItemTree {
508472
}
509473
}
510474

511-
impl Index<GenericParamsId> for ItemTree {
512-
type Output = GenericParams;
513-
514-
fn index(&self, index: GenericParamsId) -> &Self::Output {
515-
match index {
516-
GenericParamsId::EMPTY => &EMPTY_GENERICS,
517-
_ => &self.data().generics.arena[Idx::from_raw(index.0.into())],
518-
}
519-
}
520-
}
521-
522475
impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
523476
type Output = N;
524477
fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -555,7 +508,7 @@ pub struct ExternCrate {
555508
pub struct Function {
556509
pub name: Name,
557510
pub visibility: RawVisibilityId,
558-
pub generic_params: GenericParamsId,
511+
pub generic_params: Interned<GenericParams>,
559512
pub abi: Option<Interned<str>>,
560513
pub params: IdRange<Param>,
561514
pub ret_type: Interned<TypeRef>,
@@ -590,7 +543,7 @@ impl FnFlags {
590543
pub struct Struct {
591544
pub name: Name,
592545
pub visibility: RawVisibilityId,
593-
pub generic_params: GenericParamsId,
546+
pub generic_params: Interned<GenericParams>,
594547
pub fields: Fields,
595548
pub ast_id: FileAstId<ast::Struct>,
596549
pub kind: StructDefKind,
@@ -610,7 +563,7 @@ pub enum StructDefKind {
610563
pub struct Union {
611564
pub name: Name,
612565
pub visibility: RawVisibilityId,
613-
pub generic_params: GenericParamsId,
566+
pub generic_params: Interned<GenericParams>,
614567
pub fields: Fields,
615568
pub ast_id: FileAstId<ast::Union>,
616569
}
@@ -619,7 +572,7 @@ pub struct Union {
619572
pub struct Enum {
620573
pub name: Name,
621574
pub visibility: RawVisibilityId,
622-
pub generic_params: GenericParamsId,
575+
pub generic_params: Interned<GenericParams>,
623576
pub variants: IdRange<Variant>,
624577
pub ast_id: FileAstId<ast::Enum>,
625578
}
@@ -648,7 +601,7 @@ pub struct Static {
648601
pub struct Trait {
649602
pub name: Name,
650603
pub visibility: RawVisibilityId,
651-
pub generic_params: GenericParamsId,
604+
pub generic_params: Interned<GenericParams>,
652605
pub is_auto: bool,
653606
pub is_unsafe: bool,
654607
pub bounds: Box<[TypeBound]>,
@@ -658,7 +611,7 @@ pub struct Trait {
658611

659612
#[derive(Debug, Clone, Eq, PartialEq)]
660613
pub struct Impl {
661-
pub generic_params: GenericParamsId,
614+
pub generic_params: Interned<GenericParams>,
662615
pub target_trait: Option<Interned<TraitRef>>,
663616
pub self_ty: Interned<TypeRef>,
664617
pub is_negative: bool,
@@ -672,7 +625,7 @@ pub struct TypeAlias {
672625
pub visibility: RawVisibilityId,
673626
/// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
674627
pub bounds: Box<[TypeBound]>,
675-
pub generic_params: GenericParamsId,
628+
pub generic_params: Interned<GenericParams>,
676629
pub type_ref: Option<Interned<TypeRef>>,
677630
pub is_extern: bool,
678631
pub ast_id: FileAstId<ast::TypeAlias>,

crates/hir_def/src/item_tree/lower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ impl Ctx {
434434
let mut res = Function {
435435
name,
436436
visibility,
437-
generic_params: GenericParamsId::EMPTY,
437+
generic_params: Interned::new(GenericParams::default()),
438438
abi,
439439
params,
440440
ret_type: Interned::new(ret_type),
@@ -682,7 +682,7 @@ impl Ctx {
682682
&mut self,
683683
owner: GenericsOwner<'_>,
684684
node: &impl ast::GenericParamsOwner,
685-
) -> GenericParamsId {
685+
) -> Interned<GenericParams> {
686686
// Generics are part of item headers and may contain inner items we need to collect.
687687
if let Some(params) = node.generic_param_list() {
688688
self.collect_inner_items(params.syntax());
@@ -698,7 +698,7 @@ impl Ctx {
698698
&mut self,
699699
owner: GenericsOwner<'_>,
700700
node: &impl ast::GenericParamsOwner,
701-
) -> GenericParamsId {
701+
) -> Interned<GenericParams> {
702702
let mut sm = &mut Default::default();
703703
let mut generics = GenericParams::default();
704704
match owner {
@@ -740,7 +740,7 @@ impl Ctx {
740740
}
741741

742742
generics.shrink_to_fit();
743-
self.data().generics.alloc(generics)
743+
Interned::new(generics)
744744
}
745745

746746
fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<TypeBound> {

crates/hir_def/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod dyn_map;
2727
pub mod keys;
2828

2929
pub mod item_tree;
30+
pub mod intern;
3031

3132
pub mod adt;
3233
pub mod data;
@@ -49,7 +50,6 @@ pub mod import_map;
4950

5051
#[cfg(test)]
5152
mod test_db;
52-
mod intern;
5353

5454
use std::{
5555
hash::{Hash, Hasher},

crates/hir_def/src/resolver.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::{
1414
db::DefDatabase,
1515
expr::{ExprId, LabelId, PatId},
1616
generics::GenericParams,
17+
intern::Interned,
1718
item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
1819
nameres::DefMap,
1920
path::{ModPath, PathKind},
@@ -50,7 +51,7 @@ enum Scope {
5051
/// All the items and imported names of a module
5152
ModuleScope(ModuleItemMap),
5253
/// Brings the generic parameters of an item into scope
53-
GenericParams { def: GenericDefId, params: Arc<GenericParams> },
54+
GenericParams { def: GenericDefId, params: Interned<GenericParams> },
5455
/// Brings `Self` in `impl` block into scope
5556
ImplDefScope(ImplId),
5657
/// Brings `Self` in enum, struct and union definitions into scope

0 commit comments

Comments
 (0)