Unnamed repository; edit this file 'description' to name the repository.
Support lifetimes in `impl_from` macro
| -rw-r--r-- | crates/hir-def/src/item_scope.rs | 31 | ||||
| -rw-r--r-- | crates/hir-def/src/lib.rs | 68 | ||||
| -rw-r--r-- | crates/hir-ty/src/db.rs | 17 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 31 | ||||
| -rw-r--r-- | crates/hir-ty/src/next_solver/def_id.rs | 129 | ||||
| -rw-r--r-- | crates/hir/src/from_id.rs | 174 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 106 | ||||
| -rw-r--r-- | crates/ide-db/src/defs.rs | 55 | ||||
| -rw-r--r-- | crates/stdx/src/macros.rs | 82 |
9 files changed, 267 insertions, 426 deletions
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index ac1d2fd2a4..1443d3ea4b 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -12,7 +12,7 @@ use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::SmallVec; use span::Edition; -use stdx::format_to; +use stdx::{format_to, impl_from}; use syntax::ast; use thin_vec::ThinVec; @@ -37,14 +37,7 @@ pub enum ImportOrExternCrate { ExternCrate(ExternCrateId), } -impl From<ImportOrGlob> for ImportOrExternCrate { - fn from(value: ImportOrGlob) -> Self { - match value { - ImportOrGlob::Glob(it) => ImportOrExternCrate::Glob(it), - ImportOrGlob::Import(it) => ImportOrExternCrate::Import(it), - } - } -} +impl_from!(ImportOrGlob { Glob, Import } for ImportOrExternCrate); impl ImportOrExternCrate { pub fn import_or_glob(self) -> Option<ImportOrGlob> { @@ -101,24 +94,8 @@ pub enum ImportOrDef { Def(ModuleDefId), } -impl From<ImportOrExternCrate> for ImportOrDef { - fn from(value: ImportOrExternCrate) -> Self { - match value { - ImportOrExternCrate::Import(it) => ImportOrDef::Import(it), - ImportOrExternCrate::Glob(it) => ImportOrDef::Glob(it), - ImportOrExternCrate::ExternCrate(it) => ImportOrDef::ExternCrate(it), - } - } -} - -impl From<ImportOrGlob> for ImportOrDef { - fn from(value: ImportOrGlob) -> Self { - match value { - ImportOrGlob::Import(it) => ImportOrDef::Import(it), - ImportOrGlob::Glob(it) => ImportOrDef::Glob(it), - } - } -} +impl_from!(ImportOrExternCrate { Import, Glob, ExternCrate } for ImportOrDef); +impl_from!(ImportOrGlob { Import, Glob } for ImportOrDef); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct ImportId { diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 8b93fe5e2f..f2a3c1b091 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -896,15 +896,14 @@ pub enum AssocItemId { // casting them, and somehow making the constructors private, which would be annoying. impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId); -impl From<AssocItemId> for ModuleDefId { - fn from(item: AssocItemId) -> Self { - match item { - AssocItemId::FunctionId(f) => f.into(), - AssocItemId::ConstId(c) => c.into(), - AssocItemId::TypeAliasId(t) => t.into(), - } +impl_from!( + AssocItemId { + FunctionId => FunctionId, + ConstId => ConstId, + TypeAliasId => TypeAliasId, } -} + for ModuleDefId +); #[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum GenericDefId { @@ -1044,15 +1043,14 @@ impl GenericDefId { } } -impl From<AssocItemId> for GenericDefId { - fn from(item: AssocItemId) -> Self { - match item { - AssocItemId::FunctionId(f) => f.into(), - AssocItemId::ConstId(c) => c.into(), - AssocItemId::TypeAliasId(t) => t.into(), - } +impl_from!( + AssocItemId { + FunctionId => FunctionId, + ConstId => ConstId, + TypeAliasId => TypeAliasId, } -} + for GenericDefId +); #[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum CallableDefId { @@ -1062,15 +1060,14 @@ pub enum CallableDefId { } impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId); -impl From<CallableDefId> for ModuleDefId { - fn from(def: CallableDefId) -> ModuleDefId { - match def { - CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f), - CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)), - CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e), - } +impl_from!( + CallableDefId { + FunctionId => FunctionId, + StructId => AdtId, + EnumVariantId => EnumVariantId, } -} + for ModuleDefId +); impl CallableDefId { pub fn krate(self, db: &dyn SourceDatabase) -> Crate { @@ -1114,24 +1111,11 @@ impl_from!( for AttrDefId ); -impl From<AssocItemId> for AttrDefId { - fn from(assoc: AssocItemId) -> Self { - match assoc { - AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it), - AssocItemId::ConstId(it) => AttrDefId::ConstId(it), - AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it), - } - } -} -impl From<VariantId> for AttrDefId { - fn from(vid: VariantId) -> Self { - match vid { - VariantId::EnumVariantId(id) => id.into(), - VariantId::StructId(id) => id.into(), - VariantId::UnionId(id) => id.into(), - } - } -} +impl_from!(AssocItemId { FunctionId, ConstId, TypeAliasId } for AttrDefId); +impl_from!( + VariantId { EnumVariantId => EnumVariantId, StructId => AdtId, UnionId => AdtId } + for AttrDefId +); #[derive( Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa_macros::Supertype, salsa::Update, diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 73b1183cb2..7e66e938a0 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -18,6 +18,7 @@ use hir_def::{ use la_arena::ArenaMap; use salsa::Update; use span::Edition; +use stdx::impl_from; use triomphe::Arc; use crate::{ @@ -488,21 +489,7 @@ pub enum GeneralConstId<'db> { AnonConstId(AnonConstId<'db>), } -impl<'db> From<ConstId> for GeneralConstId<'db> { - fn from(it: ConstId) -> GeneralConstId<'db> { - GeneralConstId::ConstId(it) - } -} -impl<'db> From<StaticId> for GeneralConstId<'db> { - fn from(it: StaticId) -> GeneralConstId<'db> { - GeneralConstId::StaticId(it) - } -} -impl<'db> From<AnonConstId<'db>> for GeneralConstId<'db> { - fn from(it: AnonConstId<'db>) -> GeneralConstId<'db> { - GeneralConstId::AnonConstId(it) - } -} +impl_from!(impl<'db> ConstId, StaticId, AnonConstId<'db> for GeneralConstId<'db>); impl<'db> GeneralConstId<'db> { pub fn generic_def(self, db: &'db dyn HirDatabase) -> Option<GenericDefId> { diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index d217024b56..0ab29db377 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -559,31 +559,12 @@ pub enum InferBodyId<'db> { DefWithBodyId(DefWithBodyId), AnonConstId(AnonConstId<'db>), } -impl<'db> From<DefWithBodyId> for InferBodyId<'db> { - fn from(it: DefWithBodyId) -> InferBodyId<'db> { - InferBodyId::DefWithBodyId(it) - } -} -impl<'db> From<FunctionId> for InferBodyId<'db> { - fn from(it: FunctionId) -> InferBodyId<'db> { - InferBodyId::DefWithBodyId(it.into()) - } -} -impl<'db> From<ConstId> for InferBodyId<'db> { - fn from(it: ConstId) -> InferBodyId<'db> { - InferBodyId::DefWithBodyId(it.into()) - } -} -impl<'db> From<StaticId> for InferBodyId<'db> { - fn from(it: StaticId) -> InferBodyId<'db> { - InferBodyId::DefWithBodyId(it.into()) - } -} -impl<'db> From<AnonConstId<'db>> for InferBodyId<'db> { - fn from(it: AnonConstId<'db>) -> InferBodyId<'db> { - InferBodyId::AnonConstId(it) - } -} +impl_from!( + impl<'db> + DefWithBodyId(FunctionId, ConstId, StaticId), + AnonConstId<'db> + for InferBodyId<'db> +); impl<'db> From<EnumVariantId> for InferBodyId<'db> { fn from(id: EnumVariantId) -> Self { InferBodyId::DefWithBodyId(DefWithBodyId::VariantId(id)) diff --git a/crates/hir-ty/src/next_solver/def_id.rs b/crates/hir-ty/src/next_solver/def_id.rs index 09b999ae5f..f7d831d7fc 100644 --- a/crates/hir-ty/src/next_solver/def_id.rs +++ b/crates/hir-ty/src/next_solver/def_id.rs @@ -122,110 +122,31 @@ impl std::fmt::Debug for SolverDefId<'_> { } } -impl<'db> From<AdtId> for SolverDefId<'db> { - fn from(it: AdtId) -> SolverDefId<'db> { - SolverDefId::AdtId(it) - } -} -impl<'db> From<StructId> for SolverDefId<'db> { - fn from(it: StructId) -> SolverDefId<'db> { - SolverDefId::AdtId(AdtId::StructId(it)) - } -} -impl<'db> From<EnumId> for SolverDefId<'db> { - fn from(it: EnumId) -> SolverDefId<'db> { - SolverDefId::AdtId(AdtId::EnumId(it)) - } -} -impl<'db> From<UnionId> for SolverDefId<'db> { - fn from(it: UnionId) -> SolverDefId<'db> { - SolverDefId::AdtId(AdtId::UnionId(it)) - } -} -impl<'db> From<ConstId> for SolverDefId<'db> { - fn from(it: ConstId) -> SolverDefId<'db> { - SolverDefId::ConstId(it) - } -} -impl<'db> From<FunctionId> for SolverDefId<'db> { - fn from(it: FunctionId) -> SolverDefId<'db> { - SolverDefId::FunctionId(it) - } -} -impl<'db> From<ImplId> for SolverDefId<'db> { - fn from(it: ImplId) -> SolverDefId<'db> { - SolverDefId::ImplId(it) - } -} -impl<'db> From<BuiltinDeriveImplId> for SolverDefId<'db> { - fn from(it: BuiltinDeriveImplId) -> SolverDefId<'db> { - SolverDefId::BuiltinDeriveImplId(it) - } -} -impl<'db> From<StaticId> for SolverDefId<'db> { - fn from(it: StaticId) -> SolverDefId<'db> { - SolverDefId::StaticId(it) - } -} -impl<'db> From<AnonConstId<'db>> for SolverDefId<'db> { - fn from(it: AnonConstId<'db>) -> SolverDefId<'db> { - SolverDefId::AnonConstId(it) - } -} -impl<'db> From<TraitId> for SolverDefId<'db> { - fn from(it: TraitId) -> SolverDefId<'db> { - SolverDefId::TraitId(it) - } -} -impl<'db> From<TypeAliasId> for SolverDefId<'db> { - fn from(it: TypeAliasId) -> SolverDefId<'db> { - SolverDefId::TypeAliasId(it) - } -} -impl<'db> From<InternedClosureId<'db>> for SolverDefId<'db> { - fn from(it: InternedClosureId<'db>) -> SolverDefId<'db> { - SolverDefId::InternedClosureId(it) - } -} -impl<'db> From<InternedCoroutineId<'db>> for SolverDefId<'db> { - fn from(it: InternedCoroutineId<'db>) -> SolverDefId<'db> { - SolverDefId::InternedCoroutineId(it) - } -} -impl<'db> From<InternedCoroutineClosureId<'db>> for SolverDefId<'db> { - fn from(it: InternedCoroutineClosureId<'db>) -> SolverDefId<'db> { - SolverDefId::InternedCoroutineClosureId(it) - } -} -impl<'db> From<InternedOpaqueTyId> for SolverDefId<'db> { - fn from(it: InternedOpaqueTyId) -> SolverDefId<'db> { - SolverDefId::InternedOpaqueTyId(it) - } -} -impl<'db> From<EnumVariantId> for SolverDefId<'db> { - fn from(it: EnumVariantId) -> SolverDefId<'db> { - SolverDefId::EnumVariantId(it) - } -} -impl<'db> From<Ctor> for SolverDefId<'db> { - fn from(it: Ctor) -> SolverDefId<'db> { - SolverDefId::Ctor(it) - } -} - -impl<'db> From<GenericDefId> for SolverDefId<'db> { - fn from(value: GenericDefId) -> Self { - match value { - GenericDefId::AdtId(adt_id) => SolverDefId::AdtId(adt_id), - GenericDefId::ConstId(const_id) => SolverDefId::ConstId(const_id), - GenericDefId::FunctionId(function_id) => SolverDefId::FunctionId(function_id), - GenericDefId::ImplId(impl_id) => SolverDefId::ImplId(impl_id), - GenericDefId::StaticId(static_id) => SolverDefId::StaticId(static_id), - GenericDefId::TraitId(trait_id) => SolverDefId::TraitId(trait_id), - GenericDefId::TypeAliasId(type_alias_id) => SolverDefId::TypeAliasId(type_alias_id), - } - } -} +impl_from!( + impl<'db> + AdtId(StructId, EnumId, UnionId), + ConstId, + FunctionId, + ImplId, + BuiltinDeriveImplId, + StaticId, + AnonConstId<'db>, + TraitId, + TypeAliasId, + InternedClosureId<'db>, + InternedCoroutineId<'db>, + InternedCoroutineClosureId<'db>, + InternedOpaqueTyId, + EnumVariantId, + Ctor + for SolverDefId<'db> +); + +impl_from!( + impl<'db> + GenericDefId { AdtId, ConstId, FunctionId, ImplId, StaticId, TraitId, TypeAliasId } + for SolverDefId<'db> +); impl<'db> From<GeneralConstId<'db>> for SolverDefId<'db> { #[inline] diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index e94279bc45..9b07aa494e 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -7,8 +7,10 @@ use hir_def::{ AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, ModuleDefId, VariantId, hir::{BindingId, LabelId}, + item_scope::ItemInNs as ItemInNsId, }; use hir_ty::next_solver::AnyImplId; +use stdx::impl_from; use crate::{ Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, EnumVariant, ExpressionStoreOwner, @@ -51,54 +53,28 @@ from_id![ (hir_def::ExternBlockId, crate::ExternBlock), ]; -impl From<AdtId> for Adt { - fn from(id: AdtId) -> Self { - match id { - AdtId::StructId(it) => Adt::Struct(it.into()), - AdtId::UnionId(it) => Adt::Union(it.into()), - AdtId::EnumId(it) => Adt::Enum(it.into()), - } - } -} - -impl From<Adt> for AdtId { - fn from(id: Adt) -> Self { - match id { - Adt::Struct(it) => AdtId::StructId(it.id), - Adt::Union(it) => AdtId::UnionId(it.id), - Adt::Enum(it) => AdtId::EnumId(it.id), - } - } -} - -impl From<VariantId> for Variant { - fn from(v: VariantId) -> Self { - match v { - VariantId::EnumVariantId(it) => Variant::EnumVariant(it.into()), - VariantId::StructId(it) => Variant::Struct(it.into()), - VariantId::UnionId(it) => Variant::Union(it.into()), - } +impl_from!(AdtId { StructId => Struct, UnionId => Union, EnumId => Enum } for Adt); +impl_from!(Adt { Struct => StructId, Union => UnionId, Enum => EnumId } for AdtId); +impl_from!( + VariantId { EnumVariantId => EnumVariant, StructId => Struct, UnionId => Union } + for Variant +); +impl_from!( + GenericParamId { + TypeParamId => TypeParam, + ConstParamId => ConstParam, + LifetimeParamId => LifetimeParam, } -} -impl From<GenericParamId> for GenericParam { - fn from(id: GenericParamId) -> Self { - match id { - GenericParamId::TypeParamId(it) => GenericParam::TypeParam(it.into()), - GenericParamId::ConstParamId(it) => GenericParam::ConstParam(it.into()), - GenericParamId::LifetimeParamId(it) => GenericParam::LifetimeParam(it.into()), - } + for GenericParam +); +impl_from!( + GenericParam { + LifetimeParam => LifetimeParamId, + ConstParam => ConstParamId, + TypeParam => TypeParamId, } -} - -impl From<GenericParam> for GenericParamId { - fn from(id: GenericParam) -> Self { - match id { - GenericParam::LifetimeParam(it) => GenericParamId::LifetimeParamId(it.id), - GenericParam::ConstParam(it) => GenericParamId::ConstParamId(it.id), - GenericParam::TypeParam(it) => GenericParamId::TypeParamId(it.id), - } - } -} + for GenericParamId +); impl From<EnumVariantId> for EnumVariant { fn from(id: EnumVariantId) -> Self { @@ -112,22 +88,21 @@ impl From<EnumVariant> for EnumVariantId { } } -impl From<ModuleDefId> for ModuleDef { - fn from(id: ModuleDefId) -> Self { - match id { - ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), - ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), - ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), - ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()), - ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), - ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), - ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), - ModuleDefId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()), - ModuleDefId::BuiltinType(it) => ModuleDef::BuiltinType(it.into()), - ModuleDefId::MacroId(it) => ModuleDef::Macro(it.into()), - } +impl_from!( + ModuleDefId { + ModuleId => Module, + FunctionId => Function, + AdtId => Adt, + EnumVariantId => EnumVariant, + ConstId => Const, + StaticId => Static, + TraitId => Trait, + TypeAliasId => TypeAlias, + BuiltinType => BuiltinType, + MacroId => Macro, } -} + for ModuleDef +); impl TryFrom<ModuleDef> for ModuleDefId { type Error = (); @@ -165,26 +140,19 @@ impl TryFrom<DefWithBody> for DefWithBodyId { } } -impl From<DefWithBodyId> for DefWithBody { - fn from(def: DefWithBodyId) -> Self { - match def { - DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()), - DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()), - DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()), - DefWithBodyId::VariantId(it) => DefWithBody::EnumVariant(it.into()), - } +impl_from!( + DefWithBodyId { + FunctionId => Function, + StaticId => Static, + ConstId => Const, + VariantId => EnumVariant, } -} - -impl From<AssocItemId> for AssocItem { - fn from(def: AssocItemId) -> Self { - match def { - AssocItemId::FunctionId(it) => AssocItem::Function(it.into()), - AssocItemId::TypeAliasId(it) => AssocItem::TypeAlias(it.into()), - AssocItemId::ConstId(it) => AssocItem::Const(it.into()), - } - } -} + for DefWithBody +); +impl_from!( + AssocItemId { FunctionId => Function, TypeAliasId => TypeAlias, ConstId => Const } + for AssocItem +); impl TryFrom<GenericDef> for GenericDefId { type Error = (); @@ -194,19 +162,18 @@ impl TryFrom<GenericDef> for GenericDefId { } } -impl From<GenericDefId> for GenericDef { - fn from(def: GenericDefId) -> Self { - match def { - GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), - GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), - GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), - GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), - GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), - GenericDefId::ConstId(it) => GenericDef::Const(it.into()), - GenericDefId::StaticId(it) => GenericDef::Static(it.into()), - } +impl_from!( + GenericDefId { + FunctionId => Function, + AdtId => Adt, + TraitId => Trait, + TypeAliasId => TypeAlias, + ImplId => Impl, + ConstId => Const, + StaticId => Static, } -} + for GenericDef +); impl From<Adt> for GenericDefId { fn from(id: Adt) -> Self { @@ -218,15 +185,10 @@ impl From<Adt> for GenericDefId { } } -impl From<Variant> for VariantId { - fn from(def: Variant) -> Self { - match def { - Variant::Struct(it) => VariantId::StructId(it.id), - Variant::EnumVariant(it) => VariantId::EnumVariantId(it.into()), - Variant::Union(it) => VariantId::UnionId(it.id), - } - } -} +impl_from!( + Variant { Struct => StructId, EnumVariant => EnumVariantId, Union => UnionId } + for VariantId +); impl From<Field> for FieldId { fn from(def: Field) -> Self { @@ -266,15 +228,7 @@ impl From<(ExpressionStoreOwnerId, LabelId)> for Label { } } -impl From<hir_def::item_scope::ItemInNs> for ItemInNs { - fn from(it: hir_def::item_scope::ItemInNs) -> Self { - match it { - hir_def::item_scope::ItemInNs::Types(it) => ItemInNs::Types(it.into()), - hir_def::item_scope::ItemInNs::Values(it) => ItemInNs::Values(it.into()), - hir_def::item_scope::ItemInNs::Macros(it) => ItemInNs::Macros(it.into()), - } - } -} +impl_from!(ItemInNsId { Types => Types, Values => Values, Macros => Macros } for ItemInNs); impl TryFrom<ItemInNs> for hir_def::item_scope::ItemInNs { type Error = (); diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index fd00480c0a..9fde9abf66 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -416,15 +416,10 @@ impl_from!( for ModuleDef ); -impl From<Variant> for ModuleDef { - fn from(var: Variant) -> Self { - match var { - Variant::Struct(t) => Adt::from(t).into(), - Variant::Union(t) => Adt::from(t).into(), - Variant::EnumVariant(t) => t.into(), - } - } -} +impl_from!( + Variant { Struct => Adt, Union => Adt, EnumVariant => EnumVariant } + for ModuleDef +); impl ModuleDef { pub fn module(self, db: &dyn HirDatabase) -> Option<Module> { @@ -1923,19 +1918,14 @@ impl From<DefWithBody> for ExpressionStoreOwner { } } -impl From<ExpressionStoreOwnerId> for ExpressionStoreOwner { - fn from(v: ExpressionStoreOwnerId) -> Self { - match v { - ExpressionStoreOwnerId::Signature(generic_def_id) => { - Self::Signature(generic_def_id.into()) - } - ExpressionStoreOwnerId::Body(def_with_body_id) => Self::Body(def_with_body_id.into()), - ExpressionStoreOwnerId::VariantFields(variant_id) => { - Self::VariantFields(variant_id.into()) - } - } +impl_from!( + ExpressionStoreOwnerId { + Signature => Signature, + Body => Body, + VariantFields => VariantFields, } -} + for ExpressionStoreOwner +); impl ExpressionStoreOwner { pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -3478,17 +3468,21 @@ impl From<Macro> for ItemInNs { } } -impl From<ModuleDef> for ItemInNs { - fn from(module_def: ModuleDef) -> Self { - match module_def { - ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::Function(_) => { - ItemInNs::Values(module_def) - } - ModuleDef::Macro(it) => ItemInNs::Macros(it), - _ => ItemInNs::Types(module_def), - } - } -} +impl_from!( + ModuleDef { + Module => Types, + Function => Values, + Adt => Types, + EnumVariant => Types, + Const => Values, + Static => Values, + Trait => Types, + TypeAlias => Types, + BuiltinType => Types, + Macro => Macros, + } + for ItemInNs +); impl ItemInNs { pub fn into_module_def(self) -> ModuleDef { @@ -3831,15 +3825,7 @@ impl HasVisibility for AssocItem { } } -impl From<AssocItem> for ModuleDef { - fn from(assoc: AssocItem) -> Self { - match assoc { - AssocItem::Function(it) => ModuleDef::Function(it), - AssocItem::Const(it) => ModuleDef::Const(it), - AssocItem::TypeAlias(it) => ModuleDef::TypeAlias(it), - } - } -} +impl_from!(AssocItem { Function, Const, TypeAlias } for ModuleDef); #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum GenericDef { @@ -5264,23 +5250,13 @@ enum TypeOwnerId<'db> { NoParams(base_db::Crate), } -impl<'db> From<GenericDefId> for TypeOwnerId<'db> { - fn from(it: GenericDefId) -> TypeOwnerId<'db> { - TypeOwnerId::GenericDefId(it) - } -} - -impl<'db> From<BuiltinDeriveImplId> for TypeOwnerId<'db> { - fn from(it: BuiltinDeriveImplId) -> TypeOwnerId<'db> { - TypeOwnerId::BuiltinDeriveImplId(it) - } -} - -impl<'db> From<AnonConstId<'db>> for TypeOwnerId<'db> { - fn from(it: AnonConstId<'db>) -> TypeOwnerId<'db> { - TypeOwnerId::AnonConstId(it) - } -} +impl_from!( + impl<'db> + GenericDefId, + BuiltinDeriveImplId, + AnonConstId<'db> + for TypeOwnerId<'db> +); impl TypeOwnerId<'_> { fn unify(self, other: Self) -> Option<Self> { @@ -7009,15 +6985,11 @@ impl ScopeDef<'_> { } } -impl From<ItemInNs> for ScopeDef<'_> { - fn from(item: ItemInNs) -> Self { - match item { - ItemInNs::Types(id) => ScopeDef::ModuleDef(id), - ItemInNs::Values(id) => ScopeDef::ModuleDef(id), - ItemInNs::Macros(id) => ScopeDef::ModuleDef(ModuleDef::Macro(id)), - } - } -} +impl_from!( + impl<'db> + ItemInNs { Types => ModuleDef, Values => ModuleDef, Macros => ModuleDef } + for ScopeDef<'db> +); #[derive(Clone, Debug, PartialEq, Eq)] pub struct Adjustment<'db> { diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 52cd664000..c1fd002b34 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -22,7 +22,7 @@ use hir::{ Visibility, }; use span::Edition; -use stdx::format_to; +use stdx::{format_to, impl_from}; use syntax::{ SyntaxKind, SyntaxNode, SyntaxToken, ast::{self, AstNode}, @@ -891,33 +891,26 @@ impl<'db> NameRefClass<'db> { } } -macro_rules! impl_from_definition { - ($($variant:ident: $ty:ty),* $(,)?) => {$( - impl<'db> From<$ty> for Definition<'db> { - fn from(it: $ty) -> Self { - Definition::$variant(it) - } - } - )*}; -} - -impl_from_definition!( - Field: Field, - TupleField: TupleField<'db>, - Module: Module, - Function: Function, - Adt: Adt, - EnumVariant: EnumVariant, - Const: Const, - Static: Static, - Trait: Trait, - TypeAlias: TypeAlias, - BuiltinType: BuiltinType, - Local: Local<'db>, - GenericParam: GenericParam, - Label: Label, - Macro: Macro, - ExternCrateDecl: ExternCrateDecl, +impl_from!( + impl<'db> + Field, + TupleField<'db>, + Module, + Function, + Adt, + EnumVariant, + Const, + Static, + Trait, + TypeAlias, + BuiltinType, + Local<'db>, + GenericParam, + Label, + Macro, + ExternCrateDecl, + InlineAsmOperand + for Definition<'db> ); impl<'db> From<Impl> for Definition<'db> { @@ -926,12 +919,6 @@ impl<'db> From<Impl> for Definition<'db> { } } -impl<'db> From<InlineAsmOperand> for Definition<'db> { - fn from(value: InlineAsmOperand) -> Self { - Definition::InlineAsmOperand(value) - } -} - impl<'db> From<Either<PathResolution<'db>, InlineAsmOperand>> for Definition<'db> { fn from(value: Either<PathResolution<'db>, InlineAsmOperand>) -> Self { value.either(Definition::from, Definition::from) diff --git a/crates/stdx/src/macros.rs b/crates/stdx/src/macros.rs index 880e2da70f..907746888f 100644 --- a/crates/stdx/src/macros.rs +++ b/crates/stdx/src/macros.rs @@ -30,15 +30,93 @@ macro_rules! format_to_acc { }; } -/// Generates `From` impls for `Enum E { Foo(Foo), Bar(Bar) }` enums +/// Generates `From` impls that wrap values in, or map variants between, enums. /// -/// # Example +/// Enum mappings with `Source => Target` rename the variant and convert its payload with `.into()`. +/// +/// # Examples /// /// ```ignore /// impl_from!(Struct, Union, Enum for Adt); +/// impl_from!(impl<'db> Item, InternedItem<'db> for ItemId<'db>); +/// impl_from!(AssocItem { Function, Const, TypeAlias } for Item); +/// impl_from!(AdtId { StructId => Struct, EnumId => Enum } for Adt); /// ``` #[macro_export] macro_rules! impl_from { + ( + impl<$lifetime:lifetime> + $source:ident $(<$source_lifetime:lifetime>)? + { $($source_variant:ident $(=> $target_variant:ident)?),* $(,)? } + for $target:ident<$target_lifetime:lifetime> + ) => { + impl<$lifetime> From<$source$(<$source_lifetime>)?> for $target<$target_lifetime> { + fn from(value: $source$(<$source_lifetime>)?) -> Self { + match value { + $( + $source::$source_variant(value) => $crate::impl_from!( + @map_enum_variant $target, value, $source_variant + $(=> $target_variant)? + ), + )* + } + } + } + }; + ( + $source:ident + { $($source_variant:ident $(=> $target_variant:ident)?),* $(,)? } + for $target:ident + ) => { + impl From<$source> for $target { + fn from(value: $source) -> Self { + match value { + $( + $source::$source_variant(value) => $crate::impl_from!( + @map_enum_variant $target, value, $source_variant + $(=> $target_variant)? + ), + )* + } + } + } + }; + (@map_enum_variant $target:ident, $value:ident, $variant:ident) => { + $target::$variant($value) + }; + ( + @map_enum_variant $target:ident, $value:ident, + $source_variant:ident => $target_variant:ident + ) => { + $target::$target_variant($value.into()) + }; + ( + impl<$lifetime:lifetime> + $( + $variant:ident $(<$variant_lifetime:lifetime>)? + $(($($sub_variant:ident $(<$sub_variant_lifetime:lifetime>)?),*))? + ),* + for $enum:ident<$enum_lifetime:lifetime> + ) => { + $( + impl<$lifetime> From<$variant$(<$variant_lifetime>)?> for $enum<$enum_lifetime> { + fn from(it: $variant$(<$variant_lifetime>)?) -> $enum<$enum_lifetime> { + $enum::$variant(it) + } + } + $($( + impl<$lifetime> From<$sub_variant$(<$sub_variant_lifetime>)?> + for $enum<$enum_lifetime> + { + fn from( + it: $sub_variant$(<$sub_variant_lifetime>)?, + ) -> $enum<$enum_lifetime> { + $enum::$variant($variant::$sub_variant(it)) + } + } + )*)? + )* + }; ($($variant:ident $(($($sub_variant:ident),*))?),* for $enum:ident) => { $( impl From<$variant> for $enum { |