From 5fd68b592938b6a4c074146c1b22ea0f6908fe26 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 17:30:50 +0300 Subject: Fix hir for ast::UnionDef --- crates/ra_assists/src/assists/add_new.rs | 4 ++-- crates/ra_hir/src/code_model.rs | 6 +++--- crates/ra_hir/src/code_model/src.rs | 8 +++---- crates/ra_hir/src/from_source.rs | 13 ++++++----- crates/ra_hir/src/ty.rs | 2 +- crates/ra_hir/src/ty/infer/coerce.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 4 ++-- crates/ra_hir_def/src/adt.rs | 18 +++++++++++++--- crates/ra_hir_def/src/attr.rs | 4 ++-- crates/ra_hir_def/src/db.rs | 12 +++++++---- crates/ra_hir_def/src/docs.rs | 4 ++-- crates/ra_hir_def/src/generics.rs | 6 ++---- crates/ra_hir_def/src/lib.rs | 32 ++++++++++++---------------- crates/ra_hir_def/src/nameres/collector.rs | 12 +++++------ crates/ra_hir_def/src/nameres/raw.rs | 13 +++++------ crates/ra_hir_def/src/nameres/tests.rs | 7 ++++++ crates/ra_ide_api/src/display/short_label.rs | 6 ++++++ crates/ra_ide_api/src/impls.rs | 4 ++++ crates/ra_parser/src/grammar/items.rs | 2 +- crates/ra_syntax/src/ast/extensions.rs | 11 ---------- crates/ra_syntax/src/ast/generated.rs | 28 ++++++++++++++++++++---- crates/ra_syntax/src/grammar.ron | 9 ++++---- 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) -> Option { let strukt = ctx.find_node_at_offset::()?; // We want to only apply this to non-union structs with named fields - let field_list = match (strukt.kind(), strukt.is_union()) { - (StructKind::Record(named), false) => named, + let field_list = match strukt.kind() { + StructKind::Record(named) => named, _ => return None, }; 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 { impl Struct { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.0.module(db) } + Module { id: self.id.module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { @@ -369,11 +369,11 @@ pub struct Union { impl Union { pub fn name(self, db: &impl DefDatabase) -> Option { - db.struct_data(self.id.into()).name.clone() + db.union_data(self.id).name.clone() } pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.0.module(db) } + Module { id: self.id.module(db) } } 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 { impl HasSource for Struct { type Ast = ast::StructDef; fn source(self, db: &impl DefDatabase) -> Source { - self.id.0.source(db) + self.id.source(db) } } impl HasSource for Union { - type Ast = ast::StructDef; - fn source(self, db: &impl DefDatabase) -> Source { - self.id.0.source(db) + type Ast = ast::UnionDef; + fn source(self, db: &impl DefDatabase) -> Source { + self.id.source(db) } } 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 @@ //! FIXME: write short doc here -use hir_def::{AstItemDef, LocationCtx, ModuleId, StructId, StructOrUnionId, UnionId}; +use hir_def::{AstItemDef, LocationCtx, ModuleId}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ ast::{self, AstNode, NameOwner}, @@ -19,19 +19,18 @@ pub trait FromSource: Sized { fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option; } -// FIXIME: these two impls are wrong, `ast::StructDef` might produce either a struct or a union impl FromSource for Struct { type Ast = ast::StructDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id: StructOrUnionId = from_source(db, src)?; - Some(Struct { id: StructId(id) }) + let id = from_source(db, src)?; + Some(Struct { id }) } } impl FromSource for Union { - type Ast = ast::StructDef; + type Ast = ast::UnionDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id: StructOrUnionId = from_source(db, src)?; - Some(Union { id: UnionId(id) }) + let id = from_source(db, src)?; + Some(Union { id }) } } 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 { let name = match def { CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), CallableDef::StructId(s) => { - f.db.struct_data(s.0).name.clone().unwrap_or_else(Name::missing) + f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing) } CallableDef::EnumVariantId(e) => { 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> { ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), ) if struct1 == struct2 => { let field_tys = self.db.field_types(struct1.id.into()); - let struct_data = self.db.struct_data(struct1.id.0); + let struct_data = self.db.struct_data(struct1.id); let mut fields = struct_data.variant_data.fields().iter(); 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( variant_id: VariantId, ) -> Arc> { let (resolver, var_data) = match variant_id { - VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), + VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()), VariantId::EnumVariantId(it) => ( it.parent.resolver(db), db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), @@ -818,7 +818,7 @@ impl CallableDef { pub fn krate(self, db: &impl HirDatabase) -> CrateId { match self { CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, - CallableDef::StructId(s) => s.0.module(db).krate, + CallableDef::StructId(s) => s.module(db).krate, CallableDef::EnumVariantId(e) => e.parent.module(db).krate, } } 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}; use crate::{ db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, - LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId, + LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, }; /// Note that we use `StructData` for unions as well! @@ -49,13 +49,25 @@ pub struct StructFieldData { } impl StructData { - pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc { + pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc { let src = id.source(db); let name = src.value.name().map(|n| n.as_name()); let variant_data = VariantData::new(src.value.kind()); let variant_data = Arc::new(variant_data); Arc::new(StructData { name, variant_data }) } + pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc { + let src = id.source(db); + let name = src.value.name().map(|n| n.as_name()); + let variant_data = VariantData::new( + src.value + .record_field_def_list() + .map(ast::StructKind::Record) + .unwrap_or(ast::StructKind::Unit), + ); + let variant_data = Arc::new(variant_data); + Arc::new(StructData { name, variant_data }) + } } impl EnumData { @@ -137,7 +149,7 @@ impl HasChildSource for VariantId { let src = it.parent.child_source(db); src.map(|map| map[it.local_id].kind()) } - VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()), + VariantId::StructId(it) => it.source(db).map(|it| it.kind()), }; let mut trace = Trace::new_for_map(); 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 { Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), - AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), }, AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 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::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, - TypeAliasLoc, + ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc, + UnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -27,7 +27,9 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; #[salsa::interned] - fn intern_struct_or_union(&self, loc: ItemLoc) -> StructOrUnionId; + fn intern_struct(&self, loc: ItemLoc) -> StructId; + #[salsa::interned] + fn intern_union(&self, loc: ItemLoc) -> UnionId; #[salsa::interned] fn intern_enum(&self, loc: ItemLoc) -> EnumId; #[salsa::interned] @@ -57,7 +59,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase { fn crate_def_map(&self, krate: CrateId) -> Arc; #[salsa::invoke(StructData::struct_data_query)] - fn struct_data(&self, id: StructOrUnionId) -> Arc; + fn struct_data(&self, id: StructId) -> Arc; + #[salsa::invoke(StructData::union_data_query)] + fn union_data(&self, id: UnionId) -> Arc; #[salsa::invoke(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; 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 { } } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => docs_from_ast(&it.0.source(db).value), + AdtId::StructId(it) => docs_from_ast(&it.source(db).value), AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), - AdtId::UnionId(it) => docs_from_ast(&it.0.source(db).value), + AdtId::UnionId(it) => docs_from_ast(&it.source(db).value), }, AttrDefId::EnumVariantId(it) => { 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 { // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), - GenericDefId::AdtId(AdtId::StructId(it)) => { - generics.fill(&it.0.source(db).value, start) - } - GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start), + GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), + GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::TraitId(it) => { // 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 { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StructOrUnionId(salsa::InternId); -impl_intern_key!(StructOrUnionId); -impl AstItemDef for StructOrUnionId { +pub struct StructId(salsa::InternId); +impl_intern_key!(StructId); +impl AstItemDef for StructId { fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_struct_or_union(loc) + db.intern_struct(loc) } fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_struct_or_union(self) + db.lookup_intern_struct(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StructId(pub StructOrUnionId); -impl From for StructOrUnionId { - fn from(id: StructId) -> StructOrUnionId { - id.0 +pub struct UnionId(salsa::InternId); +impl_intern_key!(UnionId); +impl AstItemDef for UnionId { + fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { + db.intern_union(loc) } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct UnionId(pub StructOrUnionId); -impl From for StructOrUnionId { - fn from(id: UnionId) -> StructOrUnionId { - id.0 + fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { + db.lookup_intern_union(self) } } @@ -485,8 +481,8 @@ impl HasModule for ConstLoc { impl HasModule for AdtId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self { - AdtId::StructId(it) => it.0.module(db), - AdtId::UnionId(it) => it.0.module(db), + AdtId::StructId(it) => it.module(db), + AdtId::UnionId(it) => it.module(db), AdtId::EnumId(it) => it.module(db), } } 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::{ per_ns::PerNs, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, - StructOrUnionId, TraitId, TypeAliasLoc, UnionId, + TraitId, TypeAliasLoc, UnionId, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -698,14 +698,12 @@ where PerNs::values(def.into()) } raw::DefKind::Struct(ast_id) => { - let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); - let s = StructId(id).into(); - PerNs::both(s, s) + let id = StructId::from_ast_id(ctx, ast_id).into(); + PerNs::both(id, id) } raw::DefKind::Union(ast_id) => { - let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); - let u = UnionId(id).into(); - PerNs::both(u, u) + let id = UnionId::from_ast_id(ctx, ast_id).into(); + PerNs::both(id, id) } raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), 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 { pub(super) enum DefKind { Function(FileAstId), Struct(FileAstId), - Union(FileAstId), + Union(FileAstId), Enum(FileAstId), Const(FileAstId), Static(FileAstId), @@ -246,11 +246,12 @@ impl RawItemsCollector { ast::ModuleItem::StructDef(it) => { let id = self.source_ast_id_map.ast_id(&it); let name = it.name(); - if it.is_union() { - (DefKind::Union(id), name) - } else { - (DefKind::Struct(id), name) - } + (DefKind::Struct(id), name) + } + ast::ModuleItem::UnionDef(it) => { + let id = self.source_ast_id_map.ast_id(&it); + let name = it.name(); + (DefKind::Union(id), name) } ast::ModuleItem::EnumDef(it) => { (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() { //- /foo/bar.rs pub struct Baz; + + union U { + to_be: bool, + not_to_be: u8, + } + enum E { V } ", ); @@ -99,6 +105,7 @@ fn crate_def_map_smoke_test() { ⋮crate::foo::bar ⋮Baz: t v ⋮E: t + ⋮U: t v "###) } 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 { } } +impl ShortLabel for ast::UnionDef { + fn short_label(&self) -> Option { + short_label_from_node(self, "union ") + } +} + impl ShortLabel for ast::EnumDef { fn short_label(&self) -> Option { 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( let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; hir::Enum::from_source(db, src)?.ty(db) } + ast::NominalDef::UnionDef(def) => { + let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; + hir::Union::from_source(db, src)?.ty(db) + } }; 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; mod use_item; pub(crate) use self::{ - expressions::{match_arm_list, record_field_list}, adt::{enum_variant_list, record_field_def_list}, + expressions::{match_arm_list, record_field_list}, traits::{impl_item_list, trait_item_list}, use_item::use_tree_list, }; 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 { } impl ast::StructDef { - pub fn is_union(&self) -> bool { - for child in self.syntax().children_with_tokens() { - match child.kind() { - T![struct] => return false, - T![union] => return true, - _ => (), - } - } - false - } - pub fn kind(&self) -> StructKind { StructKind::from_node(self) } 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 { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ModuleItem { StructDef(StructDef), + UnionDef(UnionDef), EnumDef(EnumDef), FnDef(FnDef), TraitDef(TraitDef), @@ -1872,6 +1873,11 @@ impl From for ModuleItem { ModuleItem::StructDef(node) } } +impl From for ModuleItem { + fn from(node: UnionDef) -> ModuleItem { + ModuleItem::UnionDef(node) + } +} impl From for ModuleItem { fn from(node: EnumDef) -> ModuleItem { ModuleItem::EnumDef(node) @@ -1925,14 +1931,15 @@ impl From for ModuleItem { impl AstNode for ModuleItem { fn can_cast(kind: SyntaxKind) -> bool { match kind { - STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM - | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, + STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF + | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, _ => false, } } fn cast(syntax: SyntaxNode) -> Option { let res = match syntax.kind() { STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }), + UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }), ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }), FN_DEF => ModuleItem::FnDef(FnDef { syntax }), TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }), @@ -1950,6 +1957,7 @@ impl AstNode for ModuleItem { fn syntax(&self) -> &SyntaxNode { match self { ModuleItem::StructDef(it) => &it.syntax, + ModuleItem::UnionDef(it) => &it.syntax, ModuleItem::EnumDef(it) => &it.syntax, ModuleItem::FnDef(it) => &it.syntax, ModuleItem::TraitDef(it) => &it.syntax, @@ -2038,6 +2046,7 @@ impl NeverType {} pub enum NominalDef { StructDef(StructDef), EnumDef(EnumDef), + UnionDef(UnionDef), } impl From for NominalDef { fn from(node: StructDef) -> NominalDef { @@ -2049,10 +2058,15 @@ impl From for NominalDef { NominalDef::EnumDef(node) } } +impl From for NominalDef { + fn from(node: UnionDef) -> NominalDef { + NominalDef::UnionDef(node) + } +} impl AstNode for NominalDef { fn can_cast(kind: SyntaxKind) -> bool { match kind { - STRUCT_DEF | ENUM_DEF => true, + STRUCT_DEF | ENUM_DEF | UNION_DEF => true, _ => false, } } @@ -2060,6 +2074,7 @@ impl AstNode for NominalDef { let res = match syntax.kind() { STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }), ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }), + UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }), _ => return None, }; Some(res) @@ -2068,6 +2083,7 @@ impl AstNode for NominalDef { match self { NominalDef::StructDef(it) => &it.syntax, NominalDef::EnumDef(it) => &it.syntax, + NominalDef::UnionDef(it) => &it.syntax, } } } @@ -3815,7 +3831,11 @@ impl ast::NameOwner for UnionDef {} impl ast::TypeParamsOwner for UnionDef {} impl ast::AttrsOwner for UnionDef {} impl ast::DocCommentsOwner for UnionDef {} -impl UnionDef {} +impl UnionDef { + pub fn record_field_def_list(&self) -> Option { + AstChildren::new(&self.syntax).next() + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UseItem { 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( "TypeParamsOwner", "AttrsOwner", "DocCommentsOwner" - ] + ], + options: ["RecordFieldDefList"], ), "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), "RecordFieldDef": ( @@ -398,7 +399,7 @@ Grammar( ]), "NominalDef": ( - enum: ["StructDef", "EnumDef"], + enum: ["StructDef", "EnumDef", "UnionDef"], traits: [ "NameOwner", "TypeParamsOwner", @@ -406,9 +407,9 @@ Grammar( ], ), "ModuleItem": ( - enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", + enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], - traits: ["AttrsOwner"] + traits: ["AttrsOwner"], ), "ImplItem": ( enum: ["FnDef", "TypeAliasDef", "ConstDef"], -- cgit v1.2.3