aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-25 09:51:17 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-25 09:51:17 +0000
commitae97cd59ff086e7efb6409f14c2f8ae8861596e4 (patch)
treeb9dcccf99c868b6b2abf75e08fc56f42869b9ce5
parentc4a351b736632f0c01d9c51ce1cd3b4b4c6194d9 (diff)
parent87288d802c3cad7ec50c508276b89a8c454f336c (diff)
Merge #637
637: pack enum variants into arena r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_hir/src/adt.rs75
-rw-r--r--crates/ra_hir/src/code_model_api.rs26
-rw-r--r--crates/ra_hir/src/db.rs7
-rw-r--r--crates/ra_hir/src/mock.rs1
-rw-r--r--crates/ra_hir/src/nameres.rs9
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs10
-rw-r--r--crates/ra_ide_api/src/db.rs1
7 files changed, 55 insertions, 74 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index e0f515642..dc936e826 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -3,6 +3,7 @@
3 3
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use ra_arena::{RawId, Arena, impl_arena_id};
6use ra_syntax::{ 7use ra_syntax::{
7 TreeArc, 8 TreeArc,
8 ast::{self, NameOwner, StructFlavor} 9 ast::{self, NameOwner, StructFlavor}
@@ -12,7 +13,6 @@ use crate::{
12 Name, AsName, Struct, Enum, EnumVariant, Crate, 13 Name, AsName, Struct, Enum, EnumVariant, Crate,
13 HirDatabase, HirFileId, 14 HirDatabase, HirFileId,
14 type_ref::TypeRef, 15 type_ref::TypeRef,
15 ids::LocationCtx,
16}; 16};
17 17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -66,43 +66,47 @@ fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant>
66} 66}
67 67
68impl EnumVariant { 68impl EnumVariant {
69 pub fn source_impl(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { 69 pub(crate) fn source_impl(
70 &self,
71 db: &impl HirDatabase,
72 ) -> (HirFileId, TreeArc<ast::EnumVariant>) {
70 let (file_id, enum_def) = self.parent.source(db); 73 let (file_id, enum_def) = self.parent.source(db);
71 let var = variants(&*enum_def) 74 let var = variants(&*enum_def)
72 .nth(self.idx as usize) 75 .zip(db.enum_data(self.parent).variants.iter())
76 .find(|(_syntax, (id, _))| *id == self.id)
73 .unwrap() 77 .unwrap()
78 .0
74 .to_owned(); 79 .to_owned();
75 (file_id, var) 80 (file_id, var)
76 } 81 }
77} 82}
78 83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub(crate) struct EnumVariantId(RawId);
86impl_arena_id!(EnumVariantId);
87
79#[derive(Debug, Clone, PartialEq, Eq)] 88#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct EnumData { 89pub struct EnumData {
81 pub(crate) name: Option<Name>, 90 pub(crate) name: Option<Name>,
82 pub(crate) variants: Vec<(Name, EnumVariant)>, 91 pub(crate) variants: Arena<EnumVariantId, EnumVariantData>,
83} 92}
84 93
85impl EnumData { 94impl EnumData {
86 fn new(enum_def: &ast::EnumDef, variants: Vec<(Name, EnumVariant)>) -> Self {
87 let name = enum_def.name().map(|n| n.as_name());
88 EnumData { name, variants }
89 }
90
91 pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> { 95 pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
92 let (_file_id, enum_def) = e.source(db); 96 let (_file_id, enum_def) = e.source(db);
93 let variants = variants(&*enum_def) 97 let mut res = EnumData {
94 .enumerate() 98 name: enum_def.name().map(|n| n.as_name()),
95 .filter_map(|(idx, variant_def)| { 99 variants: Arena::default(),
96 let name = variant_def.name()?.as_name(); 100 };
97 let var = EnumVariant { 101 for var in variants(&*enum_def) {
98 parent: e, 102 let data = EnumVariantData {
99 idx: idx as u32, 103 name: var.name().map(|it| it.as_name()),
100 }; 104 variant_data: Arc::new(VariantData::new(var.flavor())),
101 Some((name, var)) 105 };
102 }) 106 res.variants.alloc(data);
103 .collect(); 107 }
104 108
105 Arc::new(EnumData::new(&*enum_def, variants)) 109 Arc::new(res)
106 } 110 }
107} 111}
108 112
@@ -110,33 +114,6 @@ impl EnumData {
110pub struct EnumVariantData { 114pub struct EnumVariantData {
111 pub(crate) name: Option<Name>, 115 pub(crate) name: Option<Name>,
112 pub(crate) variant_data: Arc<VariantData>, 116 pub(crate) variant_data: Arc<VariantData>,
113 pub(crate) parent_enum: Enum,
114}
115
116impl EnumVariantData {
117 fn new(variant_def: &ast::EnumVariant, parent_enum: Enum) -> EnumVariantData {
118 let name = variant_def.name().map(|n| n.as_name());
119 let variant_data = VariantData::new(variant_def.flavor());
120 let variant_data = Arc::new(variant_data);
121 EnumVariantData {
122 name,
123 variant_data,
124 parent_enum,
125 }
126 }
127
128 pub(crate) fn enum_variant_data_query(
129 db: &impl HirDatabase,
130 var: EnumVariant,
131 ) -> Arc<EnumVariantData> {
132 let (file_id, variant_def) = var.source(db);
133 let enum_def = variant_def.parent_enum();
134 let ctx = LocationCtx::new(db, var.module(db), file_id);
135 let e = Enum {
136 id: ctx.to_def(enum_def),
137 };
138 Arc::new(EnumVariantData::new(&*variant_def, e))
139 }
140} 117}
141 118
142/// A single field of an enum variant or struct 119/// A single field of an enum variant or struct
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 4fc47aba5..249a4aba9 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -11,7 +11,7 @@ use crate::{
11 db::HirDatabase, 11 db::HirDatabase,
12 expr::BodySyntaxMapping, 12 expr::BodySyntaxMapping,
13 ty::{InferenceResult, VariantDef}, 13 ty::{InferenceResult, VariantDef},
14 adt::VariantData, 14 adt::{VariantData, EnumVariantId},
15 generics::GenericParams, 15 generics::GenericParams,
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
@@ -252,8 +252,20 @@ impl Enum {
252 db.enum_data(*self).name.clone() 252 db.enum_data(*self).name.clone()
253 } 253 }
254 254
255 pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> { 255 pub fn variants(&self, db: &impl HirDatabase) -> Vec<EnumVariant> {
256 db.enum_data(*self).variants.clone() 256 db.enum_data(*self)
257 .variants
258 .iter()
259 .map(|(id, _)| EnumVariant { parent: *self, id })
260 .collect()
261 }
262
263 pub fn variant(&self, db: &impl HirDatabase, name: &Name) -> Option<EnumVariant> {
264 db.enum_data(*self)
265 .variants
266 .iter()
267 .find(|(_id, data)| data.name.as_ref() == Some(name))
268 .map(|(id, _)| EnumVariant { parent: *self, id })
257 } 269 }
258 270
259 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 271 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
@@ -270,7 +282,7 @@ impl Docs for Enum {
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 282#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
271pub struct EnumVariant { 283pub struct EnumVariant {
272 pub(crate) parent: Enum, 284 pub(crate) parent: Enum,
273 pub(crate) idx: u32, 285 pub(crate) id: EnumVariantId,
274} 286}
275 287
276impl EnumVariant { 288impl EnumVariant {
@@ -285,11 +297,13 @@ impl EnumVariant {
285 } 297 }
286 298
287 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 299 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
288 db.enum_variant_data(*self).name.clone() 300 db.enum_data(self.parent).variants[self.id].name.clone()
289 } 301 }
290 302
291 pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { 303 pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
292 db.enum_variant_data(*self).variant_data.clone() 304 db.enum_data(self.parent).variants[self.id]
305 .variant_data
306 .clone()
293 } 307 }
294 308
295 pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { 309 pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 5304f5d31..5a29e54d6 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -8,12 +8,12 @@ use crate::{
8 SourceFileItems, SourceItemId, Crate, Module, HirInterner, 8 SourceFileItems, SourceItemId, Crate, Module, HirInterner,
9 query_definitions, 9 query_definitions,
10 Function, FnSignature, FnScopes, 10 Function, FnSignature, FnScopes,
11 Struct, Enum, EnumVariant, 11 Struct, Enum,
12 macros::MacroExpansion, 12 macros::MacroExpansion,
13 module_tree::ModuleTree, 13 module_tree::ModuleTree,
14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, 14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, VariantDef}, 15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, VariantDef},
16 adt::{StructData, EnumData, EnumVariantData}, 16 adt::{StructData, EnumData},
17 impl_block::ModuleImplBlocks, 17 impl_block::ModuleImplBlocks,
18 generics::{GenericParams, GenericDef}, 18 generics::{GenericParams, GenericDef},
19}; 19};
@@ -35,9 +35,6 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
35 #[salsa::invoke(crate::adt::EnumData::enum_data_query)] 35 #[salsa::invoke(crate::adt::EnumData::enum_data_query)]
36 fn enum_data(&self, e: Enum) -> Arc<EnumData>; 36 fn enum_data(&self, e: Enum) -> Arc<EnumData>;
37 37
38 #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)]
39 fn enum_variant_data(&self, var: EnumVariant) -> Arc<EnumVariantData>;
40
41 #[salsa::invoke(crate::ty::infer)] 38 #[salsa::invoke(crate::ty::infer)]
42 fn infer(&self, func: Function) -> Arc<InferenceResult>; 39 fn infer(&self, func: Function) -> Arc<InferenceResult>;
43 40
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 361366f6a..1a83a5c87 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -231,7 +231,6 @@ salsa::database_storage! {
231 fn type_for_field() for db::TypeForFieldQuery; 231 fn type_for_field() for db::TypeForFieldQuery;
232 fn struct_data() for db::StructDataQuery; 232 fn struct_data() for db::StructDataQuery;
233 fn enum_data() for db::EnumDataQuery; 233 fn enum_data() for db::EnumDataQuery;
234 fn enum_variant_data() for db::EnumVariantDataQuery;
235 fn impls_in_module() for db::ImplsInModuleQuery; 234 fn impls_in_module() for db::ImplsInModuleQuery;
236 fn impls_in_crate() for db::ImplsInCrateQuery; 235 fn impls_in_crate() for db::ImplsInCrateQuery;
237 fn body_hir() for db::BodyHirQuery; 236 fn body_hir() for db::BodyHirQuery;
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 639726b5e..028c1882f 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -397,13 +397,8 @@ impl ItemMap {
397 ModuleDef::Enum(e) => { 397 ModuleDef::Enum(e) => {
398 // enum variant 398 // enum variant
399 tested_by!(item_map_enum_importing); 399 tested_by!(item_map_enum_importing);
400 let matching_variant = e 400 match e.variant(db, &segment.name) {
401 .variants(db) 401 Some(variant) => PerNs::both(variant.into(), (*e).into()),
402 .into_iter()
403 .find(|(n, _variant)| n == &segment.name);
404
405 match matching_variant {
406 Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()),
407 None => PerNs::none(), 402 None => PerNs::none(),
408 } 403 }
409 } 404 }
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index e72586e2e..e3f1d42f8 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -27,18 +27,18 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
27 } 27 }
28 } 28 }
29 hir::ModuleDef::Enum(e) => { 29 hir::ModuleDef::Enum(e) => {
30 e.variants(ctx.db) 30 e.variants(ctx.db).into_iter().for_each(|variant| {
31 .into_iter() 31 if let Some(name) = variant.name(ctx.db) {
32 .for_each(|(variant_name, variant)| {
33 CompletionItem::new( 32 CompletionItem::new(
34 CompletionKind::Reference, 33 CompletionKind::Reference,
35 ctx.source_range(), 34 ctx.source_range(),
36 variant_name.to_string(), 35 name.to_string(),
37 ) 36 )
38 .kind(CompletionItemKind::EnumVariant) 37 .kind(CompletionItemKind::EnumVariant)
39 .set_documentation(variant.docs(ctx.db)) 38 .set_documentation(variant.docs(ctx.db))
40 .add_to(acc) 39 .add_to(acc)
41 }); 40 }
41 });
42 } 42 }
43 _ => return, 43 _ => return,
44 }; 44 };
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index bff6b7237..11305613c 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -104,7 +104,6 @@ salsa::database_storage! {
104 fn type_for_field() for hir::db::TypeForFieldQuery; 104 fn type_for_field() for hir::db::TypeForFieldQuery;
105 fn struct_data() for hir::db::StructDataQuery; 105 fn struct_data() for hir::db::StructDataQuery;
106 fn enum_data() for hir::db::EnumDataQuery; 106 fn enum_data() for hir::db::EnumDataQuery;
107 fn enum_variant_data() for hir::db::EnumVariantDataQuery;
108 fn impls_in_module() for hir::db::ImplsInModuleQuery; 107 fn impls_in_module() for hir::db::ImplsInModuleQuery;
109 fn impls_in_crate() for hir::db::ImplsInCrateQuery; 108 fn impls_in_crate() for hir::db::ImplsInCrateQuery;
110 fn body_hir() for hir::db::BodyHirQuery; 109 fn body_hir() for hir::db::BodyHirQuery;