mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Fix hir for ast::UnionDef
This commit is contained in:
parent
e1c0bdaf75
commit
5fd68b5929
22 changed files with 121 additions and 86 deletions
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()?;
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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::Struct(id), name)
|
||||||
(DefKind::Union(id), name)
|
}
|
||||||
} else {
|
ast::ModuleItem::UnionDef(it) => {
|
||||||
(DefKind::Struct(id), name)
|
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())
|
||||||
|
|
|
@ -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
|
||||||
"###)
|
"###)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 ")
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue