Fix hir for ast::UnionDef

This commit is contained in:
Aleksey Kladov 2019-11-25 17:30:50 +03:00
parent e1c0bdaf75
commit 5fd68b5929
22 changed files with 121 additions and 86 deletions

View file

@ -35,8 +35,8 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
let strukt = ctx.find_node_at_offset::<ast::StructDef>()?; let strukt = ctx.find_node_at_offset::<ast::StructDef>()?;
// We want to only apply this to non-union structs with named fields // We want to only apply this to non-union structs with named fields
let field_list = match (strukt.kind(), strukt.is_union()) { let field_list = match strukt.kind() {
(StructKind::Record(named), false) => named, StructKind::Record(named) => named,
_ => return None, _ => return None,
}; };

View file

@ -320,7 +320,7 @@ pub struct Struct {
impl Struct { impl Struct {
pub fn module(self, db: &impl DefDatabase) -> Module { 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<Crate> { pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@ -369,11 +369,11 @@ pub struct Union {
impl Union { impl Union {
pub fn name(self, db: &impl DefDatabase) -> Option<Name> { pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.struct_data(self.id.into()).name.clone() db.union_data(self.id).name.clone()
} }
pub fn module(self, db: &impl DefDatabase) -> Module { 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 { pub fn ty(self, db: &impl HirDatabase) -> Ty {

View file

@ -51,13 +51,13 @@ impl HasSource for StructField {
impl HasSource for Struct { impl HasSource for Struct {
type Ast = ast::StructDef; type Ast = ast::StructDef;
fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
self.id.0.source(db) self.id.source(db)
} }
} }
impl HasSource for Union { impl HasSource for Union {
type Ast = ast::StructDef; type Ast = ast::UnionDef;
fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { fn source(self, db: &impl DefDatabase) -> Source<ast::UnionDef> {
self.id.0.source(db) self.id.source(db)
} }
} }
impl HasSource for Enum { impl HasSource for Enum {

View file

@ -1,6 +1,6 @@
//! FIXME: write short doc here //! 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 hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
use ra_syntax::{ use ra_syntax::{
ast::{self, AstNode, NameOwner}, ast::{self, AstNode, NameOwner},
@ -19,19 +19,18 @@ pub trait FromSource: Sized {
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>;
} }
// FIXIME: these two impls are wrong, `ast::StructDef` might produce either a struct or a union
impl FromSource for Struct { impl FromSource for Struct {
type Ast = ast::StructDef; type Ast = ast::StructDef;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
let id: StructOrUnionId = from_source(db, src)?; let id = from_source(db, src)?;
Some(Struct { id: StructId(id) }) Some(Struct { id })
} }
} }
impl FromSource for Union { impl FromSource for Union {
type Ast = ast::StructDef; type Ast = ast::UnionDef;
fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
let id: StructOrUnionId = from_source(db, src)?; let id = from_source(db, src)?;
Some(Union { id: UnionId(id) }) Some(Union { id })
} }
} }
impl FromSource for Enum { impl FromSource for Enum {

View file

@ -858,7 +858,7 @@ impl HirDisplay for ApplicationTy {
let name = match def { let name = match def {
CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
CallableDef::StructId(s) => { 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) => { CallableDef::EnumVariantId(e) => {
let enum_data = f.db.enum_data(e.parent); let enum_data = f.db.enum_data(e.parent);

View file

@ -246,7 +246,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2),
) if struct1 == struct2 => { ) if struct1 == struct2 => {
let field_tys = self.db.field_types(struct1.id.into()); 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 mut fields = struct_data.variant_data.fields().iter();
let (last_field_id, _data) = fields.next_back()?; let (last_field_id, _data) = fields.next_back()?;

View file

@ -560,7 +560,7 @@ pub(crate) fn field_types_query(
variant_id: VariantId, variant_id: VariantId,
) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
let (resolver, var_data) = match variant_id { 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) => ( VariantId::EnumVariantId(it) => (
it.parent.resolver(db), it.parent.resolver(db),
db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), 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 { pub fn krate(self, db: &impl HirDatabase) -> CrateId {
match self { match self {
CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, 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, CallableDef::EnumVariantId(e) => e.parent.module(db).krate,
} }
} }

View file

@ -12,7 +12,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
use crate::{ use crate::{
db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, 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! /// Note that we use `StructData` for unions as well!
@ -49,13 +49,25 @@ pub struct StructFieldData {
} }
impl StructData { impl StructData {
pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc<StructData> { pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> {
let src = id.source(db); let src = id.source(db);
let name = src.value.name().map(|n| n.as_name()); let name = src.value.name().map(|n| n.as_name());
let variant_data = VariantData::new(src.value.kind()); let variant_data = VariantData::new(src.value.kind());
let variant_data = Arc::new(variant_data); let variant_data = Arc::new(variant_data);
Arc::new(StructData { name, variant_data }) Arc::new(StructData { name, variant_data })
} }
pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> {
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 { impl EnumData {
@ -137,7 +149,7 @@ impl HasChildSource for VariantId {
let src = it.parent.child_source(db); let src = it.parent.child_source(db);
src.map(|map| map[it.local_id].kind()) 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(); let mut trace = Trace::new_for_map();
lower_struct(&mut trace, &src.value); lower_struct(&mut trace, &src.value);

View file

@ -54,9 +54,9 @@ impl Attrs {
Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
} }
AttrDefId::AdtId(it) => match it { 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::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::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),

View file

@ -18,8 +18,8 @@ use crate::{
CrateDefMap, CrateDefMap,
}, },
AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId,
ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc,
TypeAliasLoc, UnionId,
}; };
#[salsa::query_group(InternDatabaseStorage)] #[salsa::query_group(InternDatabaseStorage)]
@ -27,7 +27,9 @@ pub trait InternDatabase: SourceDatabase {
#[salsa::interned] #[salsa::interned]
fn intern_function(&self, loc: FunctionLoc) -> FunctionId; fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
#[salsa::interned] #[salsa::interned]
fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> StructOrUnionId; fn intern_struct(&self, loc: ItemLoc<ast::StructDef>) -> StructId;
#[salsa::interned]
fn intern_union(&self, loc: ItemLoc<ast::UnionDef>) -> UnionId;
#[salsa::interned] #[salsa::interned]
fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId; fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId;
#[salsa::interned] #[salsa::interned]
@ -57,7 +59,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
#[salsa::invoke(StructData::struct_data_query)] #[salsa::invoke(StructData::struct_data_query)]
fn struct_data(&self, id: StructOrUnionId) -> Arc<StructData>; fn struct_data(&self, id: StructId) -> Arc<StructData>;
#[salsa::invoke(StructData::union_data_query)]
fn union_data(&self, id: UnionId) -> Arc<StructData>;
#[salsa::invoke(EnumData::enum_data_query)] #[salsa::invoke(EnumData::enum_data_query)]
fn enum_data(&self, e: EnumId) -> Arc<EnumData>; fn enum_data(&self, e: EnumId) -> Arc<EnumData>;

View file

@ -47,9 +47,9 @@ impl Documentation {
} }
} }
AttrDefId::AdtId(it) => match it { 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::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) => { AttrDefId::EnumVariantId(it) => {
let src = it.parent.child_source(db); let src = it.parent.child_source(db);

View file

@ -60,10 +60,8 @@ impl GenericParams {
// FIXME: add `: Sized` bound for everything except for `Self` in traits // FIXME: add `: Sized` bound for everything except for `Self` in traits
match def { match def {
GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start),
GenericDefId::AdtId(AdtId::StructId(it)) => { GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start),
generics.fill(&it.0.source(db).value, start) GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start),
}
GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.0.source(db).value, start),
GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start),
GenericDefId::TraitId(it) => { GenericDefId::TraitId(it) => {
// traits get the Self type as an implicit first type parameter // traits get the Self type as an implicit first type parameter

View file

@ -141,30 +141,26 @@ impl Lookup for FunctionId {
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StructOrUnionId(salsa::InternId); pub struct StructId(salsa::InternId);
impl_intern_key!(StructOrUnionId); impl_intern_key!(StructId);
impl AstItemDef<ast::StructDef> for StructOrUnionId { impl AstItemDef<ast::StructDef> for StructId {
fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
db.intern_struct_or_union(loc) db.intern_struct(loc)
} }
fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
db.lookup_intern_struct_or_union(self) db.lookup_intern_struct(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StructId(pub StructOrUnionId); pub struct UnionId(salsa::InternId);
impl From<StructId> for StructOrUnionId { impl_intern_key!(UnionId);
fn from(id: StructId) -> StructOrUnionId { impl AstItemDef<ast::UnionDef> for UnionId {
id.0 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::UnionDef>) -> Self {
db.intern_union(loc)
} }
} fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::UnionDef> {
db.lookup_intern_union(self)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UnionId(pub StructOrUnionId);
impl From<UnionId> for StructOrUnionId {
fn from(id: UnionId) -> StructOrUnionId {
id.0
} }
} }
@ -485,8 +481,8 @@ impl HasModule for ConstLoc {
impl HasModule for AdtId { impl HasModule for AdtId {
fn module(&self, db: &impl db::DefDatabase) -> ModuleId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
match self { match self {
AdtId::StructId(it) => it.0.module(db), AdtId::StructId(it) => it.module(db),
AdtId::UnionId(it) => it.0.module(db), AdtId::UnionId(it) => it.module(db),
AdtId::EnumId(it) => it.module(db), AdtId::EnumId(it) => it.module(db),
} }
} }

View file

@ -25,7 +25,7 @@ use crate::{
per_ns::PerNs, per_ns::PerNs,
AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId,
Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, 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 { pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@ -698,14 +698,12 @@ where
PerNs::values(def.into()) PerNs::values(def.into())
} }
raw::DefKind::Struct(ast_id) => { raw::DefKind::Struct(ast_id) => {
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); let id = StructId::from_ast_id(ctx, ast_id).into();
let s = StructId(id).into(); PerNs::both(id, id)
PerNs::both(s, s)
} }
raw::DefKind::Union(ast_id) => { raw::DefKind::Union(ast_id) => {
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); let id = UnionId::from_ast_id(ctx, ast_id).into();
let u = UnionId(id).into(); PerNs::both(id, id)
PerNs::both(u, u)
} }
raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
raw::DefKind::Const(ast_id) => { raw::DefKind::Const(ast_id) => {

View file

@ -176,7 +176,7 @@ pub(super) struct DefData {
pub(super) enum DefKind { pub(super) enum DefKind {
Function(FileAstId<ast::FnDef>), Function(FileAstId<ast::FnDef>),
Struct(FileAstId<ast::StructDef>), Struct(FileAstId<ast::StructDef>),
Union(FileAstId<ast::StructDef>), Union(FileAstId<ast::UnionDef>),
Enum(FileAstId<ast::EnumDef>), Enum(FileAstId<ast::EnumDef>),
Const(FileAstId<ast::ConstDef>), Const(FileAstId<ast::ConstDef>),
Static(FileAstId<ast::StaticDef>), Static(FileAstId<ast::StaticDef>),
@ -246,11 +246,12 @@ impl RawItemsCollector {
ast::ModuleItem::StructDef(it) => { ast::ModuleItem::StructDef(it) => {
let id = self.source_ast_id_map.ast_id(&it); let id = self.source_ast_id_map.ast_id(&it);
let name = it.name(); 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) => { ast::ModuleItem::EnumDef(it) => {
(DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name()) (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name())

View file

@ -82,6 +82,12 @@ fn crate_def_map_smoke_test() {
//- /foo/bar.rs //- /foo/bar.rs
pub struct Baz; pub struct Baz;
union U {
to_be: bool,
not_to_be: u8,
}
enum E { V } enum E { V }
", ",
); );
@ -99,6 +105,7 @@ fn crate_def_map_smoke_test() {
crate::foo::bar crate::foo::bar
Baz: t v Baz: t v
E: t E: t
U: t v
"###) "###)
} }

View file

@ -19,6 +19,12 @@ impl ShortLabel for ast::StructDef {
} }
} }
impl ShortLabel for ast::UnionDef {
fn short_label(&self) -> Option<String> {
short_label_from_node(self, "union ")
}
}
impl ShortLabel for ast::EnumDef { impl ShortLabel for ast::EnumDef {
fn short_label(&self) -> Option<String> { fn short_label(&self) -> Option<String> {
short_label_from_node(self, "enum ") short_label_from_node(self, "enum ")

View file

@ -49,6 +49,10 @@ fn impls_for_def(
let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; let src = hir::Source { file_id: position.file_id.into(), value: def.clone() };
hir::Enum::from_source(db, src)?.ty(db) 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(); let krate = module.krate();

View file

@ -6,8 +6,8 @@ mod traits;
mod use_item; mod use_item;
pub(crate) use self::{ pub(crate) use self::{
expressions::{match_arm_list, record_field_list},
adt::{enum_variant_list, record_field_def_list}, adt::{enum_variant_list, record_field_def_list},
expressions::{match_arm_list, record_field_list},
traits::{impl_item_list, trait_item_list}, traits::{impl_item_list, trait_item_list},
use_item::use_tree_list, use_item::use_tree_list,
}; };

View file

@ -196,17 +196,6 @@ impl StructKind {
} }
impl ast::StructDef { 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 { pub fn kind(&self) -> StructKind {
StructKind::from_node(self) StructKind::from_node(self)
} }

View file

@ -1856,6 +1856,7 @@ impl Module {
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ModuleItem { pub enum ModuleItem {
StructDef(StructDef), StructDef(StructDef),
UnionDef(UnionDef),
EnumDef(EnumDef), EnumDef(EnumDef),
FnDef(FnDef), FnDef(FnDef),
TraitDef(TraitDef), TraitDef(TraitDef),
@ -1872,6 +1873,11 @@ impl From<StructDef> for ModuleItem {
ModuleItem::StructDef(node) ModuleItem::StructDef(node)
} }
} }
impl From<UnionDef> for ModuleItem {
fn from(node: UnionDef) -> ModuleItem {
ModuleItem::UnionDef(node)
}
}
impl From<EnumDef> for ModuleItem { impl From<EnumDef> for ModuleItem {
fn from(node: EnumDef) -> ModuleItem { fn from(node: EnumDef) -> ModuleItem {
ModuleItem::EnumDef(node) ModuleItem::EnumDef(node)
@ -1925,14 +1931,15 @@ impl From<Module> for ModuleItem {
impl AstNode for ModuleItem { impl AstNode for ModuleItem {
fn can_cast(kind: SyntaxKind) -> bool { fn can_cast(kind: SyntaxKind) -> bool {
match kind { match kind {
STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF
| EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true, | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
_ => false, _ => false,
} }
} }
fn cast(syntax: SyntaxNode) -> Option<Self> { fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() { let res = match syntax.kind() {
STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }), STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }),
UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }),
ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }), ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }),
FN_DEF => ModuleItem::FnDef(FnDef { syntax }), FN_DEF => ModuleItem::FnDef(FnDef { syntax }),
TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }), TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }),
@ -1950,6 +1957,7 @@ impl AstNode for ModuleItem {
fn syntax(&self) -> &SyntaxNode { fn syntax(&self) -> &SyntaxNode {
match self { match self {
ModuleItem::StructDef(it) => &it.syntax, ModuleItem::StructDef(it) => &it.syntax,
ModuleItem::UnionDef(it) => &it.syntax,
ModuleItem::EnumDef(it) => &it.syntax, ModuleItem::EnumDef(it) => &it.syntax,
ModuleItem::FnDef(it) => &it.syntax, ModuleItem::FnDef(it) => &it.syntax,
ModuleItem::TraitDef(it) => &it.syntax, ModuleItem::TraitDef(it) => &it.syntax,
@ -2038,6 +2046,7 @@ impl NeverType {}
pub enum NominalDef { pub enum NominalDef {
StructDef(StructDef), StructDef(StructDef),
EnumDef(EnumDef), EnumDef(EnumDef),
UnionDef(UnionDef),
} }
impl From<StructDef> for NominalDef { impl From<StructDef> for NominalDef {
fn from(node: StructDef) -> NominalDef { fn from(node: StructDef) -> NominalDef {
@ -2049,10 +2058,15 @@ impl From<EnumDef> for NominalDef {
NominalDef::EnumDef(node) NominalDef::EnumDef(node)
} }
} }
impl From<UnionDef> for NominalDef {
fn from(node: UnionDef) -> NominalDef {
NominalDef::UnionDef(node)
}
}
impl AstNode for NominalDef { impl AstNode for NominalDef {
fn can_cast(kind: SyntaxKind) -> bool { fn can_cast(kind: SyntaxKind) -> bool {
match kind { match kind {
STRUCT_DEF | ENUM_DEF => true, STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
_ => false, _ => false,
} }
} }
@ -2060,6 +2074,7 @@ impl AstNode for NominalDef {
let res = match syntax.kind() { let res = match syntax.kind() {
STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }), STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }),
ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }), ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }),
UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }),
_ => return None, _ => return None,
}; };
Some(res) Some(res)
@ -2068,6 +2083,7 @@ impl AstNode for NominalDef {
match self { match self {
NominalDef::StructDef(it) => &it.syntax, NominalDef::StructDef(it) => &it.syntax,
NominalDef::EnumDef(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::TypeParamsOwner for UnionDef {}
impl ast::AttrsOwner for UnionDef {} impl ast::AttrsOwner for UnionDef {}
impl ast::DocCommentsOwner for UnionDef {} impl ast::DocCommentsOwner for UnionDef {}
impl UnionDef {} impl UnionDef {
pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
AstChildren::new(&self.syntax).next()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UseItem { pub struct UseItem {
pub(crate) syntax: SyntaxNode, pub(crate) syntax: SyntaxNode,

View file

@ -293,7 +293,8 @@ Grammar(
"TypeParamsOwner", "TypeParamsOwner",
"AttrsOwner", "AttrsOwner",
"DocCommentsOwner" "DocCommentsOwner"
] ],
options: ["RecordFieldDefList"],
), ),
"RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]),
"RecordFieldDef": ( "RecordFieldDef": (
@ -398,7 +399,7 @@ Grammar(
]), ]),
"NominalDef": ( "NominalDef": (
enum: ["StructDef", "EnumDef"], enum: ["StructDef", "EnumDef", "UnionDef"],
traits: [ traits: [
"NameOwner", "NameOwner",
"TypeParamsOwner", "TypeParamsOwner",
@ -406,9 +407,9 @@ Grammar(
], ],
), ),
"ModuleItem": ( "ModuleItem": (
enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
"UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
traits: ["AttrsOwner"] traits: ["AttrsOwner"],
), ),
"ImplItem": ( "ImplItem": (
enum: ["FnDef", "TypeAliasDef", "ConstDef"], enum: ["FnDef", "TypeAliasDef", "ConstDef"],