aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-11-24 21:45:26 +0000
committerGitHub <[email protected]>2019-11-24 21:45:26 +0000
commitf7f9757b6b144385ab8ce57b15764473b1f57331 (patch)
treedfcb584a03bd4e049291a05912508690cd8f9247 /crates/ra_hir_def/src/lib.rs
parent6a5dea778b16a35d765a3a98f2ac303c5cc3df25 (diff)
parentd06904e90cdc1603ffcb714e70dab83905221f72 (diff)
Merge #2396
2396: Switch to variant-granularity field type inference r=flodiebold a=matklad r? @flodiebold Previously, we had a `ty` query for each field. This PR switcthes to a query per struct, which returns an `ArenaMap` with `Ty`s. I don't know which approach is better. What is bugging me about the original approach is that, if we do all queries on the "leaf" defs, in practice we get a ton of queries which repeatedly reach into the parent definition to compute module, resolver, etc. This *seems* wasteful (but I don't think this is really what causes any perf problems for us). At the same time, I've been looking at Kotlin, and they seem to use the general pattern of analyzing the *parent* definition, and storing info about children into a `BindingContext`. I don't really which way is preferable. I think I want to try this approach, where query granularity generally mirrors the data granularity. The primary motivation for me here is probably just hope that we can avoid adding a ton of helpers to a `StructField`, and maybe in general avoid the need to switch to a global `StructField`, using `LocalStructFieldId` most of the time internally. For external API (ie, for `ra_ide_api`), I think we should continue with fine-grained `StructField::ty` approach, which internally fetches the table for the whole struct and indexes into it. In terms of actual memory savings, the results are as follows: ``` This PR: 142kb FieldTypesQuery (deps) 38kb FieldTypesQuery Status Quo: 208kb TypeForFieldQuery (deps) 18kb TypeForFieldQuery ``` Note how the table itself occupies more than twice as much space! I don't have an explanation for this: a plausible hypothesis is that single-field structs are very common and for them the table is a pessimisation. THere's noticiable wallclock time difference. Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/lib.rs')
-rw-r--r--crates/ra_hir_def/src/lib.rs13
1 files changed, 7 insertions, 6 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 5bc9ffc0d..8e8c2d749 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -192,12 +192,6 @@ pub struct LocalEnumVariantId(RawId);
192impl_arena_id!(LocalEnumVariantId); 192impl_arena_id!(LocalEnumVariantId);
193 193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
195pub enum VariantId {
196 EnumVariantId(EnumVariantId),
197 StructId(StructId),
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
201pub struct StructFieldId { 195pub struct StructFieldId {
202 pub parent: VariantId, 196 pub parent: VariantId,
203 pub local_id: LocalStructFieldId, 197 pub local_id: LocalStructFieldId,
@@ -437,6 +431,13 @@ impl_froms!(
437 ImplId 431 ImplId
438); 432);
439 433
434#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
435pub enum VariantId {
436 EnumVariantId(EnumVariantId),
437 StructId(StructId),
438}
439impl_froms!(VariantId: EnumVariantId, StructId);
440
440trait Intern { 441trait Intern {
441 type ID; 442 type ID;
442 fn intern(self, db: &impl db::DefDatabase) -> Self::ID; 443 fn intern(self, db: &impl db::DefDatabase) -> Self::ID;