Unnamed repository; edit this file 'description' to name the repository.
Support lifetimes in `impl_from` macro
Lukas Wirth 3 weeks ago
parent 4e40ef9 · commit 42e538e
-rw-r--r--crates/hir-def/src/item_scope.rs31
-rw-r--r--crates/hir-def/src/lib.rs68
-rw-r--r--crates/hir-ty/src/db.rs17
-rw-r--r--crates/hir-ty/src/lib.rs31
-rw-r--r--crates/hir-ty/src/next_solver/def_id.rs129
-rw-r--r--crates/hir/src/from_id.rs174
-rw-r--r--crates/hir/src/lib.rs106
-rw-r--r--crates/ide-db/src/defs.rs55
-rw-r--r--crates/stdx/src/macros.rs82
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 {