aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-25 14:30:50 +0000
committerAleksey Kladov <[email protected]>2019-11-25 14:50:49 +0000
commit5fd68b592938b6a4c074146c1b22ea0f6908fe26 (patch)
tree3403f802366b9ddf9c9e1c1ff59af3d81e476ad1
parente1c0bdaf75f8d88a5c28b3e44def17d91d4f46b3 (diff)
Fix hir for ast::UnionDef
-rw-r--r--crates/ra_assists/src/assists/add_new.rs4
-rw-r--r--crates/ra_hir/src/code_model.rs6
-rw-r--r--crates/ra_hir/src/code_model/src.rs8
-rw-r--r--crates/ra_hir/src/from_source.rs13
-rw-r--r--crates/ra_hir/src/ty.rs2
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs2
-rw-r--r--crates/ra_hir/src/ty/lower.rs4
-rw-r--r--crates/ra_hir_def/src/adt.rs18
-rw-r--r--crates/ra_hir_def/src/attr.rs4
-rw-r--r--crates/ra_hir_def/src/db.rs12
-rw-r--r--crates/ra_hir_def/src/docs.rs4
-rw-r--r--crates/ra_hir_def/src/generics.rs6
-rw-r--r--crates/ra_hir_def/src/lib.rs32
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs12
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs13
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs7
-rw-r--r--crates/ra_ide_api/src/display/short_label.rs6
-rw-r--r--crates/ra_ide_api/src/impls.rs4
-rw-r--r--crates/ra_parser/src/grammar/items.rs2
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs11
-rw-r--r--crates/ra_syntax/src/ast/generated.rs28
-rw-r--r--crates/ra_syntax/src/grammar.ron9
22 files changed, 121 insertions, 86 deletions
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs
index ee8bff346..8f68bd5fb 100644
--- a/crates/ra_assists/src/assists/add_new.rs
+++ b/crates/ra_assists/src/assists/add_new.rs
@@ -35,8 +35,8 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
35 let strukt = ctx.find_node_at_offset::<ast::StructDef>()?; 35 let strukt = ctx.find_node_at_offset::<ast::StructDef>()?;
36 36
37 // We want to only apply this to non-union structs with named fields 37 // We want to only apply this to non-union structs with named fields
38 let field_list = match (strukt.kind(), strukt.is_union()) { 38 let field_list = match strukt.kind() {
39 (StructKind::Record(named), false) => named, 39 StructKind::Record(named) => named,
40 _ => return None, 40 _ => return None,
41 }; 41 };
42 42
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 534f1f8e9..ae730beb5 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -320,7 +320,7 @@ pub struct Struct {
320 320
321impl Struct { 321impl Struct {
322 pub fn module(self, db: &impl DefDatabase) -> Module { 322 pub fn module(self, db: &impl DefDatabase) -> Module {
323 Module { id: self.id.0.module(db) } 323 Module { id: self.id.module(db) }
324 } 324 }
325 325
326 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 326 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -369,11 +369,11 @@ pub struct Union {
369 369
370impl Union { 370impl Union {
371 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 371 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
372 db.struct_data(self.id.into()).name.clone() 372 db.union_data(self.id).name.clone()
373 } 373 }
374 374
375 pub fn module(self, db: &impl DefDatabase) -> Module { 375 pub fn module(self, db: &impl DefDatabase) -> Module {
376 Module { id: self.id.0.module(db) } 376 Module { id: self.id.module(db) }
377 } 377 }
378 378
379 pub fn ty(self, db: &impl HirDatabase) -> Ty { 379 pub fn ty(self, db: &impl HirDatabase) -> Ty {
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index a4e317c20..076d86f2b 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -51,13 +51,13 @@ impl HasSource for StructField {
51impl HasSource for Struct { 51impl HasSource for Struct {
52 type Ast = ast::StructDef; 52 type Ast = ast::StructDef;
53 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { 53 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
54 self.id.0.source(db) 54 self.id.source(db)
55 } 55 }
56} 56}
57impl HasSource for Union { 57impl HasSource for Union {
58 type Ast = ast::StructDef; 58 type Ast = ast::UnionDef;
59 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { 59 fn source(self, db: &impl DefDatabase) -> Source<ast::UnionDef> {
60 self.id.0.source(db) 60 self.id.source(db)
61 } 61 }
62} 62}
63impl HasSource for Enum { 63impl HasSource for Enum {
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 1e7c22774..95db7161b 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; 3use hir_def::{AstItemDef, LocationCtx, ModuleId};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, NameOwner}, 6 ast::{self, AstNode, NameOwner},
@@ -19,19 +19,18 @@ pub trait FromSource: Sized {
19 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; 19 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>;
20} 20}
21 21
22// FIXIME: these two impls are wrong, `ast::StructDef` might produce either a struct or a union
23impl FromSource for Struct { 22impl FromSource for Struct {
24 type Ast = ast::StructDef; 23 type Ast = ast::StructDef;
25 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 24 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
26 let id: StructOrUnionId = from_source(db, src)?; 25 let id = from_source(db, src)?;
27 Some(Struct { id: StructId(id) }) 26 Some(Struct { id })
28 } 27 }
29} 28}
30impl FromSource for Union { 29impl FromSource for Union {
31 type Ast = ast::StructDef; 30 type Ast = ast::UnionDef;
32 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 31 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
33 let id: StructOrUnionId = from_source(db, src)?; 32 let id = from_source(db, src)?;
34 Some(Union { id: UnionId(id) }) 33 Some(Union { id })
35 } 34 }
36} 35}
37impl FromSource for Enum { 36impl FromSource for Enum {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 8c045aaef..3cbcbd1d0 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -858,7 +858,7 @@ impl HirDisplay for ApplicationTy {
858 let name = match def { 858 let name = match def {
859 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), 859 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
860 CallableDef::StructId(s) => { 860 CallableDef::StructId(s) => {
861 f.db.struct_data(s.0).name.clone().unwrap_or_else(Name::missing) 861 f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing)
862 } 862 }
863 CallableDef::EnumVariantId(e) => { 863 CallableDef::EnumVariantId(e) => {
864 let enum_data = f.db.enum_data(e.parent); 864 let enum_data = f.db.enum_data(e.parent);
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 4b53bba73..bb9a2e427 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir/src/ty/infer/coerce.rs
@@ -246,7 +246,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2),
247 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
248 let field_tys = self.db.field_types(struct1.id.into()); 248 let field_tys = self.db.field_types(struct1.id.into());
249 let struct_data = self.db.struct_data(struct1.id.0); 249 let struct_data = self.db.struct_data(struct1.id);
250 250
251 let mut fields = struct_data.variant_data.fields().iter(); 251 let mut fields = struct_data.variant_data.fields().iter();
252 let (last_field_id, _data) = fields.next_back()?; 252 let (last_field_id, _data) = fields.next_back()?;
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 27cfe00c1..89bc4b9ae 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -560,7 +560,7 @@ pub(crate) fn field_types_query(
560 variant_id: VariantId, 560 variant_id: VariantId,
561) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { 561) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
562 let (resolver, var_data) = match variant_id { 562 let (resolver, var_data) = match variant_id {
563 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), 563 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()),
564 VariantId::EnumVariantId(it) => ( 564 VariantId::EnumVariantId(it) => (
565 it.parent.resolver(db), 565 it.parent.resolver(db),
566 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), 566 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(),
@@ -818,7 +818,7 @@ impl CallableDef {
818 pub fn krate(self, db: &impl HirDatabase) -> CrateId { 818 pub fn krate(self, db: &impl HirDatabase) -> CrateId {
819 match self { 819 match self {
820 CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, 820 CallableDef::FunctionId(f) => f.lookup(db).module(db).krate,
821 CallableDef::StructId(s) => s.0.module(db).krate, 821 CallableDef::StructId(s) => s.module(db).krate,
822 CallableDef::EnumVariantId(e) => e.parent.module(db).krate, 822 CallableDef::EnumVariantId(e) => e.parent.module(db).krate,
823 } 823 }
824 } 824 }
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index c9f30923e..71014826e 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -12,7 +12,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
12 12
13use crate::{ 13use crate::{
14 db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, 14 db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource,
15 LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId, 15 LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId,
16}; 16};
17 17
18/// Note that we use `StructData` for unions as well! 18/// Note that we use `StructData` for unions as well!
@@ -49,13 +49,25 @@ pub struct StructFieldData {
49} 49}
50 50
51impl StructData { 51impl StructData {
52 pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc<StructData> { 52 pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> {
53 let src = id.source(db); 53 let src = id.source(db);
54 let name = src.value.name().map(|n| n.as_name()); 54 let name = src.value.name().map(|n| n.as_name());
55 let variant_data = VariantData::new(src.value.kind()); 55 let variant_data = VariantData::new(src.value.kind());
56 let variant_data = Arc::new(variant_data); 56 let variant_data = Arc::new(variant_data);
57 Arc::new(StructData { name, variant_data }) 57 Arc::new(StructData { name, variant_data })
58 } 58 }
59 pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> {
60 let src = id.source(db);
61 let name = src.value.name().map(|n| n.as_name());
62 let variant_data = VariantData::new(
63 src.value
64 .record_field_def_list()
65 .map(ast::StructKind::Record)
66 .unwrap_or(ast::StructKind::Unit),
67 );
68 let variant_data = Arc::new(variant_data);
69 Arc::new(StructData { name, variant_data })
70 }
59} 71}
60 72
61impl EnumData { 73impl EnumData {
@@ -137,7 +149,7 @@ impl HasChildSource for VariantId {
137 let src = it.parent.child_source(db); 149 let src = it.parent.child_source(db);
138 src.map(|map| map[it.local_id].kind()) 150 src.map(|map| map[it.local_id].kind())
139 } 151 }
140 VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()), 152 VariantId::StructId(it) => it.source(db).map(|it| it.kind()),
141 }; 153 };
142 let mut trace = Trace::new_for_map(); 154 let mut trace = Trace::new_for_map();
143 lower_struct(&mut trace, &src.value); 155 lower_struct(&mut trace, &src.value);
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 53456fc08..298608e27 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -54,9 +54,9 @@ impl Attrs {
54 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 54 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
55 } 55 }
56 AttrDefId::AdtId(it) => match it { 56 AttrDefId::AdtId(it) => match it {
57 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), 57 AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
58 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 58 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
59 AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), 59 AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
60 }, 60 },
61 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 61 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
62 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), 62 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 32adb11bd..ef5611ffc 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -18,8 +18,8 @@ use crate::{
18 CrateDefMap, 18 CrateDefMap,
19 }, 19 },
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId,
21 ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, 21 ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc,
22 TypeAliasLoc, 22 UnionId,
23}; 23};
24 24
25#[salsa::query_group(InternDatabaseStorage)] 25#[salsa::query_group(InternDatabaseStorage)]
@@ -27,7 +27,9 @@ pub trait InternDatabase: SourceDatabase {
27 #[salsa::interned] 27 #[salsa::interned]
28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId; 28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
29 #[salsa::interned] 29 #[salsa::interned]
30 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> StructOrUnionId; 30 fn intern_struct(&self, loc: ItemLoc<ast::StructDef>) -> StructId;
31 #[salsa::interned]
32 fn intern_union(&self, loc: ItemLoc<ast::UnionDef>) -> UnionId;
31 #[salsa::interned] 33 #[salsa::interned]
32 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId; 34 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId;
33 #[salsa::interned] 35 #[salsa::interned]
@@ -57,7 +59,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
57 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 59 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
58 60
59 #[salsa::invoke(StructData::struct_data_query)] 61 #[salsa::invoke(StructData::struct_data_query)]
60 fn struct_data(&self, id: StructOrUnionId) -> Arc<StructData>; 62 fn struct_data(&self, id: StructId) -> Arc<StructData>;
63 #[salsa::invoke(StructData::union_data_query)]
64 fn union_data(&self, id: UnionId) -> Arc<StructData>;
61 65
62 #[salsa::invoke(EnumData::enum_data_query)] 66 #[salsa::invoke(EnumData::enum_data_query)]
63 fn enum_data(&self, e: EnumId) -> Arc<EnumData>; 67 fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index 90a8627bc..4749b642f 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -47,9 +47,9 @@ impl Documentation {
47 } 47 }
48 } 48 }
49 AttrDefId::AdtId(it) => match it { 49 AttrDefId::AdtId(it) => match it {
50 AdtId::StructId(it) => docs_from_ast(&it.0.source(db).value), 50 AdtId::StructId(it) => docs_from_ast(&it.source(db).value),
51 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), 51 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value),
52 AdtId::UnionId(it) => docs_from_ast(&it.0.source(db).value), 52 AdtId::UnionId(it) => docs_from_ast(&it.source(db).value),
53 }, 53 },
54 AttrDefId::EnumVariantId(it) => { 54 AttrDefId::EnumVariantId(it) => {
55 let src = it.parent.child_source(db); 55 let src = it.parent.child_source(db);
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 015fe772e..3f94e40e4 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -60,10 +60,8 @@ impl GenericParams {
60 // FIXME: add `: Sized` bound for everything except for `Self` in traits 60 // FIXME: add `: Sized` bound for everything except for `Self` in traits
61 match def { 61 match def {
62 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), 62 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start),
63 GenericDefId::AdtId(AdtId::StructId(it)) => { 63 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start),
64 generics.fill(&it.0.source(db).value, start) 64 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start),
65 }
66 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start),
67 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), 65 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start),
68 GenericDefId::TraitId(it) => { 66 GenericDefId::TraitId(it) => {
69 // traits get the Self type as an implicit first type parameter 67 // traits get the Self type as an implicit first type parameter
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 8e8c2d749..5f11be114 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -141,30 +141,26 @@ impl Lookup for FunctionId {
141} 141}
142 142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
144pub struct StructOrUnionId(salsa::InternId); 144pub struct StructId(salsa::InternId);
145impl_intern_key!(StructOrUnionId); 145impl_intern_key!(StructId);
146impl AstItemDef<ast::StructDef> for StructOrUnionId { 146impl AstItemDef<ast::StructDef> for StructId {
147 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { 147 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
148 db.intern_struct_or_union(loc) 148 db.intern_struct(loc)
149 } 149 }
150 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { 150 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
151 db.lookup_intern_struct_or_union(self) 151 db.lookup_intern_struct(self)
152 } 152 }
153} 153}
154 154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct StructId(pub StructOrUnionId); 156pub struct UnionId(salsa::InternId);
157impl From<StructId> for StructOrUnionId { 157impl_intern_key!(UnionId);
158 fn from(id: StructId) -> StructOrUnionId { 158impl AstItemDef<ast::UnionDef> for UnionId {
159 id.0 159 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::UnionDef>) -> Self {
160 db.intern_union(loc)
160 } 161 }
161} 162 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::UnionDef> {
162 163 db.lookup_intern_union(self)
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
164pub struct UnionId(pub StructOrUnionId);
165impl From<UnionId> for StructOrUnionId {
166 fn from(id: UnionId) -> StructOrUnionId {
167 id.0
168 } 164 }
169} 165}
170 166
@@ -485,8 +481,8 @@ impl HasModule for ConstLoc {
485impl HasModule for AdtId { 481impl HasModule for AdtId {
486 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
487 match self { 483 match self {
488 AdtId::StructId(it) => it.0.module(db), 484 AdtId::StructId(it) => it.module(db),
489 AdtId::UnionId(it) => it.0.module(db), 485 AdtId::UnionId(it) => it.module(db),
490 AdtId::EnumId(it) => it.module(db), 486 AdtId::EnumId(it) => it.module(db),
491 } 487 }
492 } 488 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 41becf8df..4ff6f72cf 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -25,7 +25,7 @@ use crate::{
25 per_ns::PerNs, 25 per_ns::PerNs,
26 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, 26 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId,
27 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, 27 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId,
28 StructOrUnionId, TraitId, TypeAliasLoc, UnionId, 28 TraitId, TypeAliasLoc, UnionId,
29}; 29};
30 30
31pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 31pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -698,14 +698,12 @@ where
698 PerNs::values(def.into()) 698 PerNs::values(def.into())
699 } 699 }
700 raw::DefKind::Struct(ast_id) => { 700 raw::DefKind::Struct(ast_id) => {
701 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); 701 let id = StructId::from_ast_id(ctx, ast_id).into();
702 let s = StructId(id).into(); 702 PerNs::both(id, id)
703 PerNs::both(s, s)
704 } 703 }
705 raw::DefKind::Union(ast_id) => { 704 raw::DefKind::Union(ast_id) => {
706 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); 705 let id = UnionId::from_ast_id(ctx, ast_id).into();
707 let u = UnionId(id).into(); 706 PerNs::both(id, id)
708 PerNs::both(u, u)
709 } 707 }
710 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), 708 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
711 raw::DefKind::Const(ast_id) => { 709 raw::DefKind::Const(ast_id) => {
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 401af031c..6eb106094 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -176,7 +176,7 @@ pub(super) struct DefData {
176pub(super) enum DefKind { 176pub(super) enum DefKind {
177 Function(FileAstId<ast::FnDef>), 177 Function(FileAstId<ast::FnDef>),
178 Struct(FileAstId<ast::StructDef>), 178 Struct(FileAstId<ast::StructDef>),
179 Union(FileAstId<ast::StructDef>), 179 Union(FileAstId<ast::UnionDef>),
180 Enum(FileAstId<ast::EnumDef>), 180 Enum(FileAstId<ast::EnumDef>),
181 Const(FileAstId<ast::ConstDef>), 181 Const(FileAstId<ast::ConstDef>),
182 Static(FileAstId<ast::StaticDef>), 182 Static(FileAstId<ast::StaticDef>),
@@ -246,11 +246,12 @@ impl RawItemsCollector {
246 ast::ModuleItem::StructDef(it) => { 246 ast::ModuleItem::StructDef(it) => {
247 let id = self.source_ast_id_map.ast_id(&it); 247 let id = self.source_ast_id_map.ast_id(&it);
248 let name = it.name(); 248 let name = it.name();
249 if it.is_union() { 249 (DefKind::Struct(id), name)
250 (DefKind::Union(id), name) 250 }
251 } else { 251 ast::ModuleItem::UnionDef(it) => {
252 (DefKind::Struct(id), name) 252 let id = self.source_ast_id_map.ast_id(&it);
253 } 253 let name = it.name();
254 (DefKind::Union(id), name)
254 } 255 }
255 ast::ModuleItem::EnumDef(it) => { 256 ast::ModuleItem::EnumDef(it) => {
256 (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name()) 257 (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name())
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index f502f1cb3..87fcd617c 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -82,6 +82,12 @@ fn crate_def_map_smoke_test() {
82 82
83 //- /foo/bar.rs 83 //- /foo/bar.rs
84 pub struct Baz; 84 pub struct Baz;
85
86 union U {
87 to_be: bool,
88 not_to_be: u8,
89 }
90
85 enum E { V } 91 enum E { V }
86 ", 92 ",
87 ); 93 );
@@ -99,6 +105,7 @@ fn crate_def_map_smoke_test() {
99 â‹®crate::foo::bar 105 â‹®crate::foo::bar
100 â‹®Baz: t v 106 â‹®Baz: t v
101 â‹®E: t 107 â‹®E: t
108 â‹®U: t v
102 "###) 109 "###)
103} 110}
104 111
diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide_api/src/display/short_label.rs
index 5d2bce3d2..9ffc9b980 100644
--- a/crates/ra_ide_api/src/display/short_label.rs
+++ b/crates/ra_ide_api/src/display/short_label.rs
@@ -19,6 +19,12 @@ impl ShortLabel for ast::StructDef {
19 } 19 }
20} 20}
21 21
22impl ShortLabel for ast::UnionDef {
23 fn short_label(&self) -> Option<String> {
24 short_label_from_node(self, "union ")
25 }
26}
27
22impl ShortLabel for ast::EnumDef { 28impl ShortLabel for ast::EnumDef {
23 fn short_label(&self) -> Option<String> { 29 fn short_label(&self) -> Option<String> {
24 short_label_from_node(self, "enum ") 30 short_label_from_node(self, "enum ")
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs
index 3e3012559..2b3100fc3 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide_api/src/impls.rs
@@ -49,6 +49,10 @@ fn impls_for_def(
49 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; 49 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() };
50 hir::Enum::from_source(db, src)?.ty(db) 50 hir::Enum::from_source(db, src)?.ty(db)
51 } 51 }
52 ast::NominalDef::UnionDef(def) => {
53 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() };
54 hir::Union::from_source(db, src)?.ty(db)
55 }
52 }; 56 };
53 57
54 let krate = module.krate(); 58 let krate = module.krate();
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 630e6ce64..370990e21 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -6,8 +6,8 @@ mod traits;
6mod use_item; 6mod use_item;
7 7
8pub(crate) use self::{ 8pub(crate) use self::{
9 expressions::{match_arm_list, record_field_list},
10 adt::{enum_variant_list, record_field_def_list}, 9 adt::{enum_variant_list, record_field_def_list},
10 expressions::{match_arm_list, record_field_list},
11 traits::{impl_item_list, trait_item_list}, 11 traits::{impl_item_list, trait_item_list},
12 use_item::use_tree_list, 12 use_item::use_tree_list,
13}; 13};
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 513ed7920..a8f625176 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -196,17 +196,6 @@ impl StructKind {
196} 196}
197 197
198impl ast::StructDef { 198impl ast::StructDef {
199 pub fn is_union(&self) -> bool {
200 for child in self.syntax().children_with_tokens() {
201 match child.kind() {
202 T![struct] => return false,
203 T![union] => return true,
204 _ => (),
205 }
206 }
207 false
208 }
209
210 pub fn kind(&self) -> StructKind { 199 pub fn kind(&self) -> StructKind {
211 StructKind::from_node(self) 200 StructKind::from_node(self)
212 } 201 }
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 1a03ae56c..c06076e3d 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1856,6 +1856,7 @@ impl Module {
1856#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1856#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1857pub enum ModuleItem { 1857pub enum ModuleItem {
1858 StructDef(StructDef), 1858 StructDef(StructDef),
1859 UnionDef(UnionDef),
1859 EnumDef(EnumDef), 1860 EnumDef(EnumDef),
1860 FnDef(FnDef), 1861 FnDef(FnDef),
1861 TraitDef(TraitDef), 1862 TraitDef(TraitDef),
@@ -1872,6 +1873,11 @@ impl From<StructDef> for ModuleItem {
1872 ModuleItem::StructDef(node) 1873 ModuleItem::StructDef(node)
1873 } 1874 }
1874} 1875}
1876impl From<UnionDef> for ModuleItem {
1877 fn from(node: UnionDef) -> ModuleItem {
1878 ModuleItem::UnionDef(node)
1879 }
1880}
1875impl From<EnumDef> for ModuleItem { 1881impl From<EnumDef> for ModuleItem {
1876 fn from(node: EnumDef) -> ModuleItem { 1882 fn from(node: EnumDef) -> ModuleItem {
1877 ModuleItem::EnumDef(node) 1883 ModuleItem::EnumDef(node)
@@ -1925,14 +1931,15 @@ impl From<Module> for ModuleItem {
1925impl AstNode for ModuleItem { 1931impl AstNode for ModuleItem {
1926 fn can_cast(kind: SyntaxKind) -> bool { 1932 fn can_cast(kind: SyntaxKind) -> bool {
1927 match kind { 1933 match kind {
1928 STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM 1934 STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF
1929 | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, 1935 | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
1930 _ => false, 1936 _ => false,
1931 } 1937 }
1932 } 1938 }
1933 fn cast(syntax: SyntaxNode) -> Option<Self> { 1939 fn cast(syntax: SyntaxNode) -> Option<Self> {
1934 let res = match syntax.kind() { 1940 let res = match syntax.kind() {
1935 STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }), 1941 STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }),
1942 UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }),
1936 ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }), 1943 ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }),
1937 FN_DEF => ModuleItem::FnDef(FnDef { syntax }), 1944 FN_DEF => ModuleItem::FnDef(FnDef { syntax }),
1938 TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }), 1945 TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }),
@@ -1950,6 +1957,7 @@ impl AstNode for ModuleItem {
1950 fn syntax(&self) -> &SyntaxNode { 1957 fn syntax(&self) -> &SyntaxNode {
1951 match self { 1958 match self {
1952 ModuleItem::StructDef(it) => &it.syntax, 1959 ModuleItem::StructDef(it) => &it.syntax,
1960 ModuleItem::UnionDef(it) => &it.syntax,
1953 ModuleItem::EnumDef(it) => &it.syntax, 1961 ModuleItem::EnumDef(it) => &it.syntax,
1954 ModuleItem::FnDef(it) => &it.syntax, 1962 ModuleItem::FnDef(it) => &it.syntax,
1955 ModuleItem::TraitDef(it) => &it.syntax, 1963 ModuleItem::TraitDef(it) => &it.syntax,
@@ -2038,6 +2046,7 @@ impl NeverType {}
2038pub enum NominalDef { 2046pub enum NominalDef {
2039 StructDef(StructDef), 2047 StructDef(StructDef),
2040 EnumDef(EnumDef), 2048 EnumDef(EnumDef),
2049 UnionDef(UnionDef),
2041} 2050}
2042impl From<StructDef> for NominalDef { 2051impl From<StructDef> for NominalDef {
2043 fn from(node: StructDef) -> NominalDef { 2052 fn from(node: StructDef) -> NominalDef {
@@ -2049,10 +2058,15 @@ impl From<EnumDef> for NominalDef {
2049 NominalDef::EnumDef(node) 2058 NominalDef::EnumDef(node)
2050 } 2059 }
2051} 2060}
2061impl From<UnionDef> for NominalDef {
2062 fn from(node: UnionDef) -> NominalDef {
2063 NominalDef::UnionDef(node)
2064 }
2065}
2052impl AstNode for NominalDef { 2066impl AstNode for NominalDef {
2053 fn can_cast(kind: SyntaxKind) -> bool { 2067 fn can_cast(kind: SyntaxKind) -> bool {
2054 match kind { 2068 match kind {
2055 STRUCT_DEF | ENUM_DEF => true, 2069 STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
2056 _ => false, 2070 _ => false,
2057 } 2071 }
2058 } 2072 }
@@ -2060,6 +2074,7 @@ impl AstNode for NominalDef {
2060 let res = match syntax.kind() { 2074 let res = match syntax.kind() {
2061 STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }), 2075 STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }),
2062 ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }), 2076 ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }),
2077 UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }),
2063 _ => return None, 2078 _ => return None,
2064 }; 2079 };
2065 Some(res) 2080 Some(res)
@@ -2068,6 +2083,7 @@ impl AstNode for NominalDef {
2068 match self { 2083 match self {
2069 NominalDef::StructDef(it) => &it.syntax, 2084 NominalDef::StructDef(it) => &it.syntax,
2070 NominalDef::EnumDef(it) => &it.syntax, 2085 NominalDef::EnumDef(it) => &it.syntax,
2086 NominalDef::UnionDef(it) => &it.syntax,
2071 } 2087 }
2072 } 2088 }
2073} 2089}
@@ -3815,7 +3831,11 @@ impl ast::NameOwner for UnionDef {}
3815impl ast::TypeParamsOwner for UnionDef {} 3831impl ast::TypeParamsOwner for UnionDef {}
3816impl ast::AttrsOwner for UnionDef {} 3832impl ast::AttrsOwner for UnionDef {}
3817impl ast::DocCommentsOwner for UnionDef {} 3833impl ast::DocCommentsOwner for UnionDef {}
3818impl UnionDef {} 3834impl UnionDef {
3835 pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
3836 AstChildren::new(&self.syntax).next()
3837 }
3838}
3819#[derive(Debug, Clone, PartialEq, Eq, Hash)] 3839#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3820pub struct UseItem { 3840pub struct UseItem {
3821 pub(crate) syntax: SyntaxNode, 3841 pub(crate) syntax: SyntaxNode,
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index c16bed891..d1be40abe 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -293,7 +293,8 @@ Grammar(
293 "TypeParamsOwner", 293 "TypeParamsOwner",
294 "AttrsOwner", 294 "AttrsOwner",
295 "DocCommentsOwner" 295 "DocCommentsOwner"
296 ] 296 ],
297 options: ["RecordFieldDefList"],
297 ), 298 ),
298 "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), 299 "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]),
299 "RecordFieldDef": ( 300 "RecordFieldDef": (
@@ -398,7 +399,7 @@ Grammar(
398 ]), 399 ]),
399 400
400 "NominalDef": ( 401 "NominalDef": (
401 enum: ["StructDef", "EnumDef"], 402 enum: ["StructDef", "EnumDef", "UnionDef"],
402 traits: [ 403 traits: [
403 "NameOwner", 404 "NameOwner",
404 "TypeParamsOwner", 405 "TypeParamsOwner",
@@ -406,9 +407,9 @@ Grammar(
406 ], 407 ],
407 ), 408 ),
408 "ModuleItem": ( 409 "ModuleItem": (
409 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", 410 enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
410 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], 411 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
411 traits: ["AttrsOwner"] 412 traits: ["AttrsOwner"],
412 ), 413 ),
413 "ImplItem": ( 414 "ImplItem": (
414 enum: ["FnDef", "TypeAliasDef", "ConstDef"], 415 enum: ["FnDef", "TypeAliasDef", "ConstDef"],