diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-25 14:51:17 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-25 14:51:17 +0000 |
commit | ecd1204804a2a3c8b9b98e4b9d18feef06ab51c7 (patch) | |
tree | d051e9bb71631cca33a1b4c23bf3f2576d1c0f56 /crates | |
parent | be00d74c7b61fb82bdade482e95035a21f9dd736 (diff) | |
parent | 1455663ea15ecbfbe87b4b5be6919aa35dd0b260 (diff) |
Merge #2403
2403: Fixme for union fields r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
27 files changed, 190 insertions, 98 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 | ||
321 | impl Struct { | 321 | impl 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 | ||
370 | impl Union { | 370 | impl 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 { | |||
51 | impl HasSource for Struct { | 51 | impl 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 | } |
57 | impl HasSource for Union { | 57 | impl 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 | } |
63 | impl HasSource for Enum { | 63 | impl 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 | ||
3 | use hir_def::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; | 3 | use hir_def::{AstItemDef, LocationCtx, ModuleId}; |
4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
5 | use ra_syntax::{ | 5 | use 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 | ||
23 | impl FromSource for Struct { | 22 | impl 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 | } |
30 | impl FromSource for Union { | 29 | impl 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 | } |
37 | impl FromSource for Enum { | 36 | impl 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/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 1d6df2b7a..994a6d7e9 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -263,6 +263,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
263 | .clone() | 263 | .clone() |
264 | .subst(&a_ty.parameters) | 264 | .subst(&a_ty.parameters) |
265 | }), | 265 | }), |
266 | // FIXME: | ||
267 | TypeCtor::Adt(Adt::Union(_)) => None, | ||
266 | _ => None, | 268 | _ => None, |
267 | }, | 269 | }, |
268 | _ => None, | 270 | _ => None, |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 27cfe00c1..eb51d31bd 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -560,7 +560,8 @@ 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::UnionId(it) => (it.resolver(db), db.union_data(it).variant_data.clone()), | ||
564 | VariantId::EnumVariantId(it) => ( | 565 | VariantId::EnumVariantId(it) => ( |
565 | it.parent.resolver(db), | 566 | it.parent.resolver(db), |
566 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), | 567 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), |
@@ -818,7 +819,7 @@ impl CallableDef { | |||
818 | pub fn krate(self, db: &impl HirDatabase) -> CrateId { | 819 | pub fn krate(self, db: &impl HirDatabase) -> CrateId { |
819 | match self { | 820 | match self { |
820 | CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, | 821 | CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, |
821 | CallableDef::StructId(s) => s.0.module(db).krate, | 822 | CallableDef::StructId(s) => s.module(db).krate, |
822 | CallableDef::EnumVariantId(e) => e.parent.module(db).krate, | 823 | CallableDef::EnumVariantId(e) => e.parent.module(db).krate, |
823 | } | 824 | } |
824 | } | 825 | } |
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index c9f30923e..0091bfbc3 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 | ||
13 | use crate::{ | 13 | use 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 | ||
51 | impl StructData { | 51 | impl 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 | ||
61 | impl EnumData { | 73 | impl EnumData { |
@@ -137,7 +149,12 @@ 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()), |
153 | VariantId::UnionId(it) => it.source(db).map(|it| { | ||
154 | it.record_field_def_list() | ||
155 | .map(ast::StructKind::Record) | ||
156 | .unwrap_or(ast::StructKind::Unit) | ||
157 | }), | ||
141 | }; | 158 | }; |
142 | let mut trace = Trace::new_for_map(); | 159 | let mut trace = Trace::new_for_map(); |
143 | lower_struct(&mut trace, &src.value); | 160 | 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..a88a78b38 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)] |
144 | pub struct StructOrUnionId(salsa::InternId); | 144 | pub struct StructId(salsa::InternId); |
145 | impl_intern_key!(StructOrUnionId); | 145 | impl_intern_key!(StructId); |
146 | impl AstItemDef<ast::StructDef> for StructOrUnionId { | 146 | impl 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)] |
156 | pub struct StructId(pub StructOrUnionId); | 156 | pub struct UnionId(salsa::InternId); |
157 | impl From<StructId> for StructOrUnionId { | 157 | impl_intern_key!(UnionId); |
158 | fn from(id: StructId) -> StructOrUnionId { | 158 | impl 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)] | ||
164 | pub struct UnionId(pub StructOrUnionId); | ||
165 | impl From<UnionId> for StructOrUnionId { | ||
166 | fn from(id: UnionId) -> StructOrUnionId { | ||
167 | id.0 | ||
168 | } | 164 | } |
169 | } | 165 | } |
170 | 166 | ||
@@ -435,6 +431,7 @@ impl_froms!( | |||
435 | pub enum VariantId { | 431 | pub enum VariantId { |
436 | EnumVariantId(EnumVariantId), | 432 | EnumVariantId(EnumVariantId), |
437 | StructId(StructId), | 433 | StructId(StructId), |
434 | UnionId(UnionId), | ||
438 | } | 435 | } |
439 | impl_froms!(VariantId: EnumVariantId, StructId); | 436 | impl_froms!(VariantId: EnumVariantId, StructId); |
440 | 437 | ||
@@ -485,8 +482,8 @@ impl HasModule for ConstLoc { | |||
485 | impl HasModule for AdtId { | 482 | impl HasModule for AdtId { |
486 | fn module(&self, db: &impl db::DefDatabase) -> ModuleId { | 483 | fn module(&self, db: &impl db::DefDatabase) -> ModuleId { |
487 | match self { | 484 | match self { |
488 | AdtId::StructId(it) => it.0.module(db), | 485 | AdtId::StructId(it) => it.module(db), |
489 | AdtId::UnionId(it) => it.0.module(db), | 486 | AdtId::UnionId(it) => it.module(db), |
490 | AdtId::EnumId(it) => it.module(db), | 487 | AdtId::EnumId(it) => it.module(db), |
491 | } | 488 | } |
492 | } | 489 | } |
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 | ||
31 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 31 | pub(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 { | |||
176 | pub(super) enum DefKind { | 176 | pub(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 | ||
22 | impl ShortLabel for ast::UnionDef { | ||
23 | fn short_label(&self) -> Option<String> { | ||
24 | short_label_from_node(self, "union ") | ||
25 | } | ||
26 | } | ||
27 | |||
22 | impl ShortLabel for ast::EnumDef { | 28 | impl 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 85f7eeb00..370990e21 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -1,13 +1,13 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | mod consts; | 3 | mod consts; |
4 | mod nominal; | 4 | mod adt; |
5 | mod traits; | 5 | mod traits; |
6 | mod use_item; | 6 | mod use_item; |
7 | 7 | ||
8 | pub(crate) use self::{ | 8 | pub(crate) use self::{ |
9 | adt::{enum_variant_list, record_field_def_list}, | ||
9 | expressions::{match_arm_list, record_field_list}, | 10 | expressions::{match_arm_list, record_field_list}, |
10 | nominal::{enum_variant_list, record_field_def_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 | }; |
@@ -247,7 +247,7 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
247 | // a: i32, | 247 | // a: i32, |
248 | // b: f32, | 248 | // b: f32, |
249 | // } | 249 | // } |
250 | nominal::struct_def(p, m, T![struct]); | 250 | adt::struct_def(p, m); |
251 | } | 251 | } |
252 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { | 252 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { |
253 | // test union_items | 253 | // test union_items |
@@ -256,9 +256,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
256 | // a: i32, | 256 | // a: i32, |
257 | // b: f32, | 257 | // b: f32, |
258 | // } | 258 | // } |
259 | nominal::struct_def(p, m, T![union]); | 259 | adt::union_def(p, m); |
260 | } | 260 | } |
261 | T![enum] => nominal::enum_def(p, m), | 261 | T![enum] => adt::enum_def(p, m), |
262 | T![use] => use_item::use_item(p, m), | 262 | T![use] => use_item::use_item(p, m), |
263 | T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), | 263 | T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), |
264 | T![static] => consts::static_def(p, m), | 264 | T![static] => consts::static_def(p, m), |
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/adt.rs index 9d8fb8486..c777bc9d0 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/adt.rs | |||
@@ -2,10 +2,19 @@ | |||
2 | 2 | ||
3 | use super::*; | 3 | use super::*; |
4 | 4 | ||
5 | pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | 5 | pub(super) fn struct_def(p: &mut Parser, m: Marker) { |
6 | assert!(p.at(T![struct]) || p.at_contextual_kw("union")); | 6 | assert!(p.at(T![struct])); |
7 | p.bump_remap(kind); | 7 | p.bump(T![struct]); |
8 | struct_or_union(p, m, T![struct], STRUCT_DEF); | ||
9 | } | ||
10 | |||
11 | pub(super) fn union_def(p: &mut Parser, m: Marker) { | ||
12 | assert!(p.at_contextual_kw("union")); | ||
13 | p.bump_remap(T![union]); | ||
14 | struct_or_union(p, m, T![union], UNION_DEF); | ||
15 | } | ||
8 | 16 | ||
17 | fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { | ||
9 | name_r(p, ITEM_RECOVERY_SET); | 18 | name_r(p, ITEM_RECOVERY_SET); |
10 | type_params::opt_type_param_list(p); | 19 | type_params::opt_type_param_list(p); |
11 | match p.current() { | 20 | match p.current() { |
@@ -22,11 +31,11 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | |||
22 | } | 31 | } |
23 | } | 32 | } |
24 | } | 33 | } |
25 | T![;] if kind == T![struct] => { | 34 | T![;] if kw == T![struct] => { |
26 | p.bump(T![;]); | 35 | p.bump(T![;]); |
27 | } | 36 | } |
28 | T!['{'] => record_field_def_list(p), | 37 | T!['{'] => record_field_def_list(p), |
29 | T!['('] if kind == T![struct] => { | 38 | T!['('] if kw == T![struct] => { |
30 | tuple_field_def_list(p); | 39 | tuple_field_def_list(p); |
31 | // test tuple_struct_where | 40 | // test tuple_struct_where |
32 | // struct Test<T>(T) where T: Clone; | 41 | // struct Test<T>(T) where T: Clone; |
@@ -34,14 +43,14 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | |||
34 | type_params::opt_where_clause(p); | 43 | type_params::opt_where_clause(p); |
35 | p.expect(T![;]); | 44 | p.expect(T![;]); |
36 | } | 45 | } |
37 | _ if kind == T![struct] => { | 46 | _ if kw == T![struct] => { |
38 | p.error("expected `;`, `{`, or `(`"); | 47 | p.error("expected `;`, `{`, or `(`"); |
39 | } | 48 | } |
40 | _ => { | 49 | _ => { |
41 | p.error("expected `{`"); | 50 | p.error("expected `{`"); |
42 | } | 51 | } |
43 | } | 52 | } |
44 | m.complete(p, STRUCT_DEF); | 53 | m.complete(p, def); |
45 | } | 54 | } |
46 | 55 | ||
47 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { | 56 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 96b5bce88..fe0fcdb33 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -122,6 +122,7 @@ pub enum SyntaxKind { | |||
122 | R_DOLLAR, | 122 | R_DOLLAR, |
123 | SOURCE_FILE, | 123 | SOURCE_FILE, |
124 | STRUCT_DEF, | 124 | STRUCT_DEF, |
125 | UNION_DEF, | ||
125 | ENUM_DEF, | 126 | ENUM_DEF, |
126 | FN_DEF, | 127 | FN_DEF, |
127 | RET_TYPE, | 128 | RET_TYPE, |
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 | ||
198 | impl ast::StructDef { | 198 | impl 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 de506d7cd..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)] |
1857 | pub enum ModuleItem { | 1857 | pub 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 | } |
1876 | impl From<UnionDef> for ModuleItem { | ||
1877 | fn from(node: UnionDef) -> ModuleItem { | ||
1878 | ModuleItem::UnionDef(node) | ||
1879 | } | ||
1880 | } | ||
1875 | impl From<EnumDef> for ModuleItem { | 1881 | impl 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 { | |||
1925 | impl AstNode for ModuleItem { | 1931 | impl 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 {} | |||
2038 | pub enum NominalDef { | 2046 | pub enum NominalDef { |
2039 | StructDef(StructDef), | 2047 | StructDef(StructDef), |
2040 | EnumDef(EnumDef), | 2048 | EnumDef(EnumDef), |
2049 | UnionDef(UnionDef), | ||
2041 | } | 2050 | } |
2042 | impl From<StructDef> for NominalDef { | 2051 | impl 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 | } |
2061 | impl From<UnionDef> for NominalDef { | ||
2062 | fn from(node: UnionDef) -> NominalDef { | ||
2063 | NominalDef::UnionDef(node) | ||
2064 | } | ||
2065 | } | ||
2052 | impl AstNode for NominalDef { | 2066 | impl 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 | } |
@@ -3789,6 +3805,38 @@ impl AstNode for TypeRef { | |||
3789 | } | 3805 | } |
3790 | impl TypeRef {} | 3806 | impl TypeRef {} |
3791 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3807 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3808 | pub struct UnionDef { | ||
3809 | pub(crate) syntax: SyntaxNode, | ||
3810 | } | ||
3811 | impl AstNode for UnionDef { | ||
3812 | fn can_cast(kind: SyntaxKind) -> bool { | ||
3813 | match kind { | ||
3814 | UNION_DEF => true, | ||
3815 | _ => false, | ||
3816 | } | ||
3817 | } | ||
3818 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
3819 | if Self::can_cast(syntax.kind()) { | ||
3820 | Some(Self { syntax }) | ||
3821 | } else { | ||
3822 | None | ||
3823 | } | ||
3824 | } | ||
3825 | fn syntax(&self) -> &SyntaxNode { | ||
3826 | &self.syntax | ||
3827 | } | ||
3828 | } | ||
3829 | impl ast::VisibilityOwner for UnionDef {} | ||
3830 | impl ast::NameOwner for UnionDef {} | ||
3831 | impl ast::TypeParamsOwner for UnionDef {} | ||
3832 | impl ast::AttrsOwner for UnionDef {} | ||
3833 | impl ast::DocCommentsOwner for UnionDef {} | ||
3834 | impl UnionDef { | ||
3835 | pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> { | ||
3836 | AstChildren::new(&self.syntax).next() | ||
3837 | } | ||
3838 | } | ||
3839 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
3792 | pub struct UseItem { | 3840 | pub struct UseItem { |
3793 | pub(crate) syntax: SyntaxNode, | 3841 | pub(crate) syntax: SyntaxNode, |
3794 | } | 3842 | } |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 88d1dc109..d1be40abe 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -126,6 +126,7 @@ Grammar( | |||
126 | "SOURCE_FILE", | 126 | "SOURCE_FILE", |
127 | 127 | ||
128 | "STRUCT_DEF", | 128 | "STRUCT_DEF", |
129 | "UNION_DEF", | ||
129 | "ENUM_DEF", | 130 | "ENUM_DEF", |
130 | "FN_DEF", | 131 | "FN_DEF", |
131 | "RET_TYPE", | 132 | "RET_TYPE", |
@@ -285,6 +286,16 @@ Grammar( | |||
285 | "DocCommentsOwner" | 286 | "DocCommentsOwner" |
286 | ] | 287 | ] |
287 | ), | 288 | ), |
289 | "UnionDef": ( | ||
290 | traits: [ | ||
291 | "VisibilityOwner", | ||
292 | "NameOwner", | ||
293 | "TypeParamsOwner", | ||
294 | "AttrsOwner", | ||
295 | "DocCommentsOwner" | ||
296 | ], | ||
297 | options: ["RecordFieldDefList"], | ||
298 | ), | ||
288 | "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), | 299 | "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), |
289 | "RecordFieldDef": ( | 300 | "RecordFieldDef": ( |
290 | traits: [ | 301 | traits: [ |
@@ -388,7 +399,7 @@ Grammar( | |||
388 | ]), | 399 | ]), |
389 | 400 | ||
390 | "NominalDef": ( | 401 | "NominalDef": ( |
391 | enum: ["StructDef", "EnumDef"], | 402 | enum: ["StructDef", "EnumDef", "UnionDef"], |
392 | traits: [ | 403 | traits: [ |
393 | "NameOwner", | 404 | "NameOwner", |
394 | "TypeParamsOwner", | 405 | "TypeParamsOwner", |
@@ -396,9 +407,9 @@ Grammar( | |||
396 | ], | 407 | ], |
397 | ), | 408 | ), |
398 | "ModuleItem": ( | 409 | "ModuleItem": ( |
399 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", | 410 | enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", |
400 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], | 411 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], |
401 | traits: ["AttrsOwner"] | 412 | traits: ["AttrsOwner"], |
402 | ), | 413 | ), |
403 | "ImplItem": ( | 414 | "ImplItem": ( |
404 | enum: ["FnDef", "TypeAliasDef", "ConstDef"], | 415 | enum: ["FnDef", "TypeAliasDef", "ConstDef"], |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt index f9ace02ee..9d7982684 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 51) | 1 | SOURCE_FILE@[0; 51) |
2 | STRUCT_DEF@[0; 12) | 2 | UNION_DEF@[0; 12) |
3 | UNION_KW@[0; 5) "union" | 3 | UNION_KW@[0; 5) "union" |
4 | WHITESPACE@[5; 6) " " | 4 | WHITESPACE@[5; 6) " " |
5 | NAME@[6; 9) | 5 | NAME@[6; 9) |
@@ -9,7 +9,7 @@ SOURCE_FILE@[0; 51) | |||
9 | L_CURLY@[10; 11) "{" | 9 | L_CURLY@[10; 11) "{" |
10 | R_CURLY@[11; 12) "}" | 10 | R_CURLY@[11; 12) "}" |
11 | WHITESPACE@[12; 13) "\n" | 11 | WHITESPACE@[12; 13) "\n" |
12 | STRUCT_DEF@[13; 50) | 12 | UNION_DEF@[13; 50) |
13 | UNION_KW@[13; 18) "union" | 13 | UNION_KW@[13; 18) "union" |
14 | WHITESPACE@[18; 19) " " | 14 | WHITESPACE@[18; 19) " " |
15 | NAME@[19; 22) | 15 | NAME@[19; 22) |
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt index 3260cc589..90538b90d 100644 --- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt +++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt | |||
@@ -1592,7 +1592,7 @@ SOURCE_FILE@[0; 3813) | |||
1592 | BLOCK@[2845; 2906) | 1592 | BLOCK@[2845; 2906) |
1593 | L_CURLY@[2845; 2846) "{" | 1593 | L_CURLY@[2845; 2846) "{" |
1594 | WHITESPACE@[2846; 2851) "\n " | 1594 | WHITESPACE@[2846; 2851) "\n " |
1595 | STRUCT_DEF@[2851; 2904) | 1595 | UNION_DEF@[2851; 2904) |
1596 | UNION_KW@[2851; 2856) "union" | 1596 | UNION_KW@[2851; 2856) "union" |
1597 | WHITESPACE@[2856; 2857) " " | 1597 | WHITESPACE@[2856; 2857) " " |
1598 | NAME@[2857; 2862) | 1598 | NAME@[2857; 2862) |