Skip to main content

hir/
from_id.rs

1//! Utility module for converting between hir_def ids and code_model wrappers.
2//!
3//! It's unclear if we need this long-term, but it's definitely useful while we
4//! are splitting the hir.
5
6use hir_def::{
7    AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId,
8    FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, ModuleDefId, VariantId,
9    hir::{BindingId, LabelId},
10    item_scope::ItemInNs as ItemInNsId,
11};
12use hir_ty::next_solver::AnyImplId;
13use stdx::impl_from;
14
15use crate::{
16    Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, EnumVariant, ExpressionStoreOwner,
17    Field, Function, GenericDef, GenericParam, Impl, ItemInNs, Label, Local, ModuleDef, Variant,
18};
19
20macro_rules! from_id {
21    ($(($id:path, $ty:path)),* $(,)?) => {$(
22        impl From<$id> for $ty {
23            fn from(id: $id) -> $ty {
24                $ty { id }
25            }
26        }
27        impl From<$ty> for $id {
28            fn from(ty: $ty) -> $id {
29                ty.id
30            }
31        }
32    )*}
33}
34
35from_id![
36    (base_db::Crate, crate::Crate),
37    (hir_def::ModuleId, crate::Module),
38    (hir_def::StructId, crate::Struct),
39    (hir_def::UnionId, crate::Union),
40    (hir_def::EnumId, crate::Enum),
41    (hir_def::TypeAliasId, crate::TypeAlias),
42    (hir_def::TraitId, crate::Trait),
43    (hir_def::StaticId, crate::Static),
44    (hir_def::ConstId, crate::Const),
45    (crate::AnyFunctionId, crate::Function),
46    (hir_ty::next_solver::AnyImplId, crate::Impl),
47    (hir_def::TypeOrConstParamId, crate::TypeOrConstParam),
48    (hir_def::TypeParamId, crate::TypeParam),
49    (hir_def::ConstParamId, crate::ConstParam),
50    (hir_def::LifetimeParamId, crate::LifetimeParam),
51    (hir_def::MacroId, crate::Macro),
52    (hir_def::ExternCrateId, crate::ExternCrateDecl),
53    (hir_def::ExternBlockId, crate::ExternBlock),
54];
55
56impl_from!(AdtId { StructId => Struct, UnionId => Union, EnumId => Enum } for Adt);
57impl_from!(Adt { Struct => StructId, Union => UnionId, Enum => EnumId } for AdtId);
58impl_from!(
59    VariantId { EnumVariantId => EnumVariant, StructId => Struct, UnionId => Union }
60    for Variant
61);
62impl_from!(
63    GenericParamId {
64        TypeParamId => TypeParam,
65        ConstParamId => ConstParam,
66        LifetimeParamId => LifetimeParam,
67    }
68    for GenericParam
69);
70impl_from!(
71    GenericParam {
72        LifetimeParam => LifetimeParamId,
73        ConstParam => ConstParamId,
74        TypeParam => TypeParamId,
75    }
76    for GenericParamId
77);
78
79impl From<EnumVariantId> for EnumVariant {
80    fn from(id: EnumVariantId) -> Self {
81        EnumVariant { id }
82    }
83}
84
85impl From<EnumVariant> for EnumVariantId {
86    fn from(def: EnumVariant) -> Self {
87        def.id
88    }
89}
90
91impl_from!(
92    ModuleDefId {
93        ModuleId => Module,
94        FunctionId => Function,
95        AdtId => Adt,
96        EnumVariantId => EnumVariant,
97        ConstId => Const,
98        StaticId => Static,
99        TraitId => Trait,
100        TypeAliasId => TypeAlias,
101        BuiltinType => BuiltinType,
102        MacroId => Macro,
103    }
104    for ModuleDef
105);
106
107impl TryFrom<ModuleDef> for ModuleDefId {
108    type Error = ();
109    fn try_from(id: ModuleDef) -> Result<Self, Self::Error> {
110        Ok(match id {
111            ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()),
112            ModuleDef::Function(it) => match it.id {
113                AnyFunctionId::FunctionId(it) => it.into(),
114                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()),
115            },
116            ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()),
117            ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()),
118            ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()),
119            ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()),
120            ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()),
121            ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()),
122            ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it.into()),
123            ModuleDef::Macro(it) => ModuleDefId::MacroId(it.into()),
124        })
125    }
126}
127
128impl TryFrom<DefWithBody> for DefWithBodyId {
129    type Error = ();
130    fn try_from(def: DefWithBody) -> Result<Self, ()> {
131        Ok(match def {
132            DefWithBody::Function(it) => match it.id {
133                AnyFunctionId::FunctionId(it) => it.into(),
134                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()),
135            },
136            DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id),
137            DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
138            DefWithBody::EnumVariant(it) => DefWithBodyId::VariantId(it.into()),
139        })
140    }
141}
142
143impl_from!(
144    DefWithBodyId {
145        FunctionId => Function,
146        StaticId => Static,
147        ConstId => Const,
148        VariantId => EnumVariant,
149    }
150    for DefWithBody
151);
152impl_from!(
153    AssocItemId { FunctionId => Function, TypeAliasId => TypeAlias, ConstId => Const }
154    for AssocItem
155);
156
157impl TryFrom<GenericDef> for GenericDefId {
158    type Error = ();
159
160    fn try_from(def: GenericDef) -> Result<Self, Self::Error> {
161        def.id().ok_or(())
162    }
163}
164
165impl_from!(
166    GenericDefId {
167        FunctionId => Function,
168        AdtId => Adt,
169        TraitId => Trait,
170        TypeAliasId => TypeAlias,
171        ImplId => Impl,
172        ConstId => Const,
173        StaticId => Static,
174    }
175    for GenericDef
176);
177
178impl From<Adt> for GenericDefId {
179    fn from(id: Adt) -> Self {
180        match id {
181            Adt::Struct(it) => it.id.into(),
182            Adt::Union(it) => it.id.into(),
183            Adt::Enum(it) => it.id.into(),
184        }
185    }
186}
187
188impl_from!(
189    Variant { Struct => StructId, EnumVariant => EnumVariantId, Union => UnionId }
190    for VariantId
191);
192
193impl From<Field> for FieldId {
194    fn from(def: Field) -> Self {
195        FieldId { parent: def.parent.into(), local_id: def.id }
196    }
197}
198
199impl From<FieldId> for Field {
200    fn from(def: FieldId) -> Self {
201        Field { parent: def.parent.into(), id: def.local_id }
202    }
203}
204
205impl TryFrom<AssocItem> for GenericDefId {
206    type Error = ();
207    fn try_from(item: AssocItem) -> Result<Self, Self::Error> {
208        Ok(match item {
209            AssocItem::Function(f) => match f.id {
210                AnyFunctionId::FunctionId(it) => it.into(),
211                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()),
212            },
213            AssocItem::Const(c) => c.id.into(),
214            AssocItem::TypeAlias(t) => t.id.into(),
215        })
216    }
217}
218
219impl<'db> From<(DefWithBodyId, BindingId)> for Local<'db> {
220    fn from((parent, binding_id): (DefWithBodyId, BindingId)) -> Self {
221        Local { parent: parent.into(), parent_infer: parent.into(), binding_id }
222    }
223}
224
225impl From<(ExpressionStoreOwnerId, LabelId)> for Label {
226    fn from((parent, label_id): (ExpressionStoreOwnerId, LabelId)) -> Self {
227        Label { parent, label_id }
228    }
229}
230
231impl_from!(ItemInNsId { Types => Types, Values => Values, Macros => Macros } for ItemInNs);
232
233impl TryFrom<ItemInNs> for hir_def::item_scope::ItemInNs {
234    type Error = ();
235    fn try_from(it: ItemInNs) -> Result<Self, Self::Error> {
236        Ok(match it {
237            ItemInNs::Types(it) => Self::Types(it.try_into()?),
238            ItemInNs::Values(it) => Self::Values(it.try_into()?),
239            ItemInNs::Macros(it) => Self::Macros(it.into()),
240        })
241    }
242}
243
244impl From<hir_def::builtin_type::BuiltinType> for BuiltinType {
245    fn from(inner: hir_def::builtin_type::BuiltinType) -> Self {
246        Self { inner }
247    }
248}
249
250impl From<BuiltinType> for hir_def::builtin_type::BuiltinType {
251    fn from(it: BuiltinType) -> Self {
252        it.inner
253    }
254}
255
256impl From<hir_def::ImplId> for crate::Impl {
257    fn from(value: hir_def::ImplId) -> Self {
258        crate::Impl { id: AnyImplId::ImplId(value) }
259    }
260}
261
262impl From<BuiltinDeriveImplId> for crate::Impl {
263    fn from(value: BuiltinDeriveImplId) -> Self {
264        crate::Impl { id: AnyImplId::BuiltinDeriveImplId(value) }
265    }
266}
267
268impl From<hir_def::FunctionId> for crate::Function {
269    fn from(value: hir_def::FunctionId) -> Self {
270        crate::Function { id: AnyFunctionId::FunctionId(value) }
271    }
272}
273
274impl TryFrom<ExpressionStoreOwner> for ExpressionStoreOwnerId {
275    type Error = ();
276
277    fn try_from(v: ExpressionStoreOwner) -> Result<Self, Self::Error> {
278        match v {
279            ExpressionStoreOwner::Signature(generic_def_id) => {
280                Ok(Self::Signature(generic_def_id.try_into()?))
281            }
282            ExpressionStoreOwner::Body(def_with_body_id) => {
283                Ok(Self::Body(def_with_body_id.try_into()?))
284            }
285            ExpressionStoreOwner::VariantFields(variant_id) => {
286                Ok(Self::VariantFields(variant_id.into()))
287            }
288        }
289    }
290}
291
292impl TryFrom<Function> for FunctionId {
293    type Error = ();
294
295    fn try_from(v: Function) -> Result<Self, Self::Error> {
296        match v.id {
297            AnyFunctionId::FunctionId(id) => Ok(id),
298            _ => Err(()),
299        }
300    }
301}
302
303impl TryFrom<Impl> for ImplId {
304    type Error = ();
305
306    fn try_from(v: Impl) -> Result<Self, Self::Error> {
307        match v.id {
308            AnyImplId::ImplId(id) => Ok(id),
309            _ => Err(()),
310        }
311    }
312}