hir_ty/next_solver/
def_id.rs

1//! Definition of `SolverDefId`
2
3use hir_def::{
4    AdtId, AttrDefId, CallableDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
5    GeneralConstId, GenericDefId, HasModule, ImplId, ModuleId, StaticId, StructId, TraitId,
6    TypeAliasId, UnionId, db::DefDatabase,
7};
8use rustc_type_ir::inherent;
9use stdx::impl_from;
10
11use crate::db::{InternedClosureId, InternedCoroutineId, InternedOpaqueTyId};
12
13use super::DbInterner;
14
15#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
16pub enum Ctor {
17    Struct(StructId),
18    Enum(EnumVariantId),
19}
20
21#[derive(PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
22pub enum SolverDefId {
23    AdtId(AdtId),
24    ConstId(ConstId),
25    FunctionId(FunctionId),
26    ImplId(ImplId),
27    StaticId(StaticId),
28    TraitId(TraitId),
29    TypeAliasId(TypeAliasId),
30    InternedClosureId(InternedClosureId),
31    InternedCoroutineId(InternedCoroutineId),
32    InternedOpaqueTyId(InternedOpaqueTyId),
33    EnumVariantId(EnumVariantId),
34    // FIXME(next-solver): Do we need the separation of `Ctor`? It duplicates some variants.
35    Ctor(Ctor),
36}
37
38impl std::fmt::Debug for SolverDefId {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        let interner = DbInterner::conjure();
41        let db = interner.db;
42        match *self {
43            SolverDefId::AdtId(AdtId::StructId(id)) => {
44                f.debug_tuple("AdtId").field(&db.struct_signature(id).name.as_str()).finish()
45            }
46            SolverDefId::AdtId(AdtId::EnumId(id)) => {
47                f.debug_tuple("AdtId").field(&db.enum_signature(id).name.as_str()).finish()
48            }
49            SolverDefId::AdtId(AdtId::UnionId(id)) => {
50                f.debug_tuple("AdtId").field(&db.union_signature(id).name.as_str()).finish()
51            }
52            SolverDefId::ConstId(id) => f
53                .debug_tuple("ConstId")
54                .field(&db.const_signature(id).name.as_ref().map_or("_", |name| name.as_str()))
55                .finish(),
56            SolverDefId::FunctionId(id) => {
57                f.debug_tuple("FunctionId").field(&db.function_signature(id).name.as_str()).finish()
58            }
59            SolverDefId::ImplId(id) => f.debug_tuple("ImplId").field(&id).finish(),
60            SolverDefId::StaticId(id) => {
61                f.debug_tuple("StaticId").field(&db.static_signature(id).name.as_str()).finish()
62            }
63            SolverDefId::TraitId(id) => {
64                f.debug_tuple("TraitId").field(&db.trait_signature(id).name.as_str()).finish()
65            }
66            SolverDefId::TypeAliasId(id) => f
67                .debug_tuple("TypeAliasId")
68                .field(&db.type_alias_signature(id).name.as_str())
69                .finish(),
70            SolverDefId::InternedClosureId(id) => {
71                f.debug_tuple("InternedClosureId").field(&id).finish()
72            }
73            SolverDefId::InternedCoroutineId(id) => {
74                f.debug_tuple("InternedCoroutineId").field(&id).finish()
75            }
76            SolverDefId::InternedOpaqueTyId(id) => {
77                f.debug_tuple("InternedOpaqueTyId").field(&id).finish()
78            }
79            SolverDefId::EnumVariantId(id) => {
80                let parent_enum = id.loc(db).parent;
81                f.debug_tuple("EnumVariantId")
82                    .field(&format_args!(
83                        "\"{}::{}\"",
84                        db.enum_signature(parent_enum).name.as_str(),
85                        parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str()
86                    ))
87                    .finish()
88            }
89            SolverDefId::Ctor(Ctor::Struct(id)) => {
90                f.debug_tuple("Ctor").field(&db.struct_signature(id).name.as_str()).finish()
91            }
92            SolverDefId::Ctor(Ctor::Enum(id)) => {
93                let parent_enum = id.loc(db).parent;
94                f.debug_tuple("Ctor")
95                    .field(&format_args!(
96                        "\"{}::{}\"",
97                        db.enum_signature(parent_enum).name.as_str(),
98                        parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str()
99                    ))
100                    .finish()
101            }
102        }
103    }
104}
105
106impl_from!(
107    AdtId(StructId, EnumId, UnionId),
108    ConstId,
109    FunctionId,
110    ImplId,
111    StaticId,
112    TraitId,
113    TypeAliasId,
114    InternedClosureId,
115    InternedCoroutineId,
116    InternedOpaqueTyId,
117    EnumVariantId,
118    Ctor
119    for SolverDefId
120);
121
122impl From<GenericDefId> for SolverDefId {
123    fn from(value: GenericDefId) -> Self {
124        match value {
125            GenericDefId::AdtId(adt_id) => SolverDefId::AdtId(adt_id),
126            GenericDefId::ConstId(const_id) => SolverDefId::ConstId(const_id),
127            GenericDefId::FunctionId(function_id) => SolverDefId::FunctionId(function_id),
128            GenericDefId::ImplId(impl_id) => SolverDefId::ImplId(impl_id),
129            GenericDefId::StaticId(static_id) => SolverDefId::StaticId(static_id),
130            GenericDefId::TraitId(trait_id) => SolverDefId::TraitId(trait_id),
131            GenericDefId::TypeAliasId(type_alias_id) => SolverDefId::TypeAliasId(type_alias_id),
132        }
133    }
134}
135
136impl From<GeneralConstId> for SolverDefId {
137    #[inline]
138    fn from(value: GeneralConstId) -> Self {
139        match value {
140            GeneralConstId::ConstId(const_id) => SolverDefId::ConstId(const_id),
141            GeneralConstId::StaticId(static_id) => SolverDefId::StaticId(static_id),
142        }
143    }
144}
145
146impl From<DefWithBodyId> for SolverDefId {
147    #[inline]
148    fn from(value: DefWithBodyId) -> Self {
149        match value {
150            DefWithBodyId::FunctionId(id) => id.into(),
151            DefWithBodyId::StaticId(id) => id.into(),
152            DefWithBodyId::ConstId(id) => id.into(),
153            DefWithBodyId::VariantId(id) => id.into(),
154        }
155    }
156}
157
158impl TryFrom<SolverDefId> for AttrDefId {
159    type Error = ();
160    #[inline]
161    fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
162        match value {
163            SolverDefId::AdtId(it) => Ok(it.into()),
164            SolverDefId::ConstId(it) => Ok(it.into()),
165            SolverDefId::FunctionId(it) => Ok(it.into()),
166            SolverDefId::ImplId(it) => Ok(it.into()),
167            SolverDefId::StaticId(it) => Ok(it.into()),
168            SolverDefId::TraitId(it) => Ok(it.into()),
169            SolverDefId::TypeAliasId(it) => Ok(it.into()),
170            SolverDefId::EnumVariantId(it) => Ok(it.into()),
171            SolverDefId::Ctor(Ctor::Struct(it)) => Ok(it.into()),
172            SolverDefId::Ctor(Ctor::Enum(it)) => Ok(it.into()),
173            SolverDefId::InternedClosureId(_)
174            | SolverDefId::InternedCoroutineId(_)
175            | SolverDefId::InternedOpaqueTyId(_) => Err(()),
176        }
177    }
178}
179
180impl TryFrom<SolverDefId> for DefWithBodyId {
181    type Error = ();
182
183    #[inline]
184    fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
185        let id = match value {
186            SolverDefId::ConstId(id) => id.into(),
187            SolverDefId::FunctionId(id) => id.into(),
188            SolverDefId::StaticId(id) => id.into(),
189            SolverDefId::EnumVariantId(id) | SolverDefId::Ctor(Ctor::Enum(id)) => id.into(),
190            SolverDefId::InternedOpaqueTyId(_)
191            | SolverDefId::TraitId(_)
192            | SolverDefId::TypeAliasId(_)
193            | SolverDefId::ImplId(_)
194            | SolverDefId::InternedClosureId(_)
195            | SolverDefId::InternedCoroutineId(_)
196            | SolverDefId::Ctor(Ctor::Struct(_))
197            | SolverDefId::AdtId(_) => return Err(()),
198        };
199        Ok(id)
200    }
201}
202
203impl TryFrom<SolverDefId> for GenericDefId {
204    type Error = ();
205
206    fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
207        Ok(match value {
208            SolverDefId::AdtId(adt_id) => GenericDefId::AdtId(adt_id),
209            SolverDefId::ConstId(const_id) => GenericDefId::ConstId(const_id),
210            SolverDefId::FunctionId(function_id) => GenericDefId::FunctionId(function_id),
211            SolverDefId::ImplId(impl_id) => GenericDefId::ImplId(impl_id),
212            SolverDefId::StaticId(static_id) => GenericDefId::StaticId(static_id),
213            SolverDefId::TraitId(trait_id) => GenericDefId::TraitId(trait_id),
214            SolverDefId::TypeAliasId(type_alias_id) => GenericDefId::TypeAliasId(type_alias_id),
215            SolverDefId::InternedClosureId(_)
216            | SolverDefId::InternedCoroutineId(_)
217            | SolverDefId::InternedOpaqueTyId(_)
218            | SolverDefId::EnumVariantId(_)
219            | SolverDefId::Ctor(_) => return Err(()),
220        })
221    }
222}
223
224impl SolverDefId {
225    #[inline]
226    #[track_caller]
227    pub fn expect_opaque_ty(self) -> InternedOpaqueTyId {
228        match self {
229            SolverDefId::InternedOpaqueTyId(it) => it,
230            _ => panic!("expected opaque type, found {self:?}"),
231        }
232    }
233
234    #[inline]
235    #[track_caller]
236    pub fn expect_type_alias(self) -> TypeAliasId {
237        match self {
238            SolverDefId::TypeAliasId(it) => it,
239            _ => panic!("expected type alias, found {self:?}"),
240        }
241    }
242}
243
244impl HasModule for SolverDefId {
245    fn module(&self, db: &dyn DefDatabase) -> ModuleId {
246        match *self {
247            SolverDefId::AdtId(id) => id.module(db),
248            SolverDefId::ConstId(id) => id.module(db),
249            SolverDefId::FunctionId(id) => id.module(db),
250            SolverDefId::ImplId(id) => id.module(db),
251            SolverDefId::StaticId(id) => id.module(db),
252            SolverDefId::TraitId(id) => id.module(db),
253            SolverDefId::TypeAliasId(id) => id.module(db),
254            SolverDefId::InternedClosureId(id) => id.loc(db).0.module(db),
255            SolverDefId::InternedCoroutineId(id) => id.loc(db).0.module(db),
256            SolverDefId::InternedOpaqueTyId(id) => match id.loc(db) {
257                crate::ImplTraitId::ReturnTypeImplTrait(owner, _) => owner.module(db),
258                crate::ImplTraitId::TypeAliasImplTrait(owner, _) => owner.module(db),
259            },
260            SolverDefId::Ctor(Ctor::Enum(id)) | SolverDefId::EnumVariantId(id) => id.module(db),
261            SolverDefId::Ctor(Ctor::Struct(id)) => id.module(db),
262        }
263    }
264}
265
266impl<'db> inherent::DefId<DbInterner<'db>> for SolverDefId {
267    fn as_local(self) -> Option<SolverDefId> {
268        Some(self)
269    }
270    fn is_local(self) -> bool {
271        true
272    }
273}
274
275macro_rules! declare_id_wrapper {
276    ($name:ident, $wraps:ident) => {
277        #[derive(Clone, Copy, PartialEq, Eq, Hash)]
278        pub struct $name(pub $wraps);
279
280        impl std::fmt::Debug for $name {
281            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282                std::fmt::Debug::fmt(&SolverDefId::from(self.0), f)
283            }
284        }
285
286        impl From<$name> for $wraps {
287            #[inline]
288            fn from(value: $name) -> $wraps {
289                value.0
290            }
291        }
292
293        impl From<$wraps> for $name {
294            #[inline]
295            fn from(value: $wraps) -> $name {
296                Self(value)
297            }
298        }
299
300        impl From<$name> for SolverDefId {
301            #[inline]
302            fn from(value: $name) -> SolverDefId {
303                value.0.into()
304            }
305        }
306
307        impl TryFrom<SolverDefId> for $name {
308            type Error = ();
309
310            #[inline]
311            fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
312                match value {
313                    SolverDefId::$wraps(it) => Ok(Self(it)),
314                    _ => Err(()),
315                }
316            }
317        }
318
319        impl<'db> inherent::DefId<DbInterner<'db>> for $name {
320            fn as_local(self) -> Option<SolverDefId> {
321                Some(self.into())
322            }
323            fn is_local(self) -> bool {
324                true
325            }
326        }
327    };
328}
329
330declare_id_wrapper!(TraitIdWrapper, TraitId);
331declare_id_wrapper!(TypeAliasIdWrapper, TypeAliasId);
332declare_id_wrapper!(ClosureIdWrapper, InternedClosureId);
333declare_id_wrapper!(CoroutineIdWrapper, InternedCoroutineId);
334declare_id_wrapper!(AdtIdWrapper, AdtId);
335declare_id_wrapper!(ImplIdWrapper, ImplId);
336
337#[derive(Clone, Copy, PartialEq, Eq, Hash)]
338pub struct GeneralConstIdWrapper(pub GeneralConstId);
339
340impl std::fmt::Debug for GeneralConstIdWrapper {
341    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
342        std::fmt::Debug::fmt(&self.0, f)
343    }
344}
345impl From<GeneralConstIdWrapper> for GeneralConstId {
346    #[inline]
347    fn from(value: GeneralConstIdWrapper) -> GeneralConstId {
348        value.0
349    }
350}
351impl From<GeneralConstId> for GeneralConstIdWrapper {
352    #[inline]
353    fn from(value: GeneralConstId) -> GeneralConstIdWrapper {
354        Self(value)
355    }
356}
357impl From<GeneralConstIdWrapper> for SolverDefId {
358    #[inline]
359    fn from(value: GeneralConstIdWrapper) -> SolverDefId {
360        match value.0 {
361            GeneralConstId::ConstId(id) => SolverDefId::ConstId(id),
362            GeneralConstId::StaticId(id) => SolverDefId::StaticId(id),
363        }
364    }
365}
366impl TryFrom<SolverDefId> for GeneralConstIdWrapper {
367    type Error = ();
368    #[inline]
369    fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
370        match value {
371            SolverDefId::ConstId(it) => Ok(Self(it.into())),
372            SolverDefId::StaticId(it) => Ok(Self(it.into())),
373            _ => Err(()),
374        }
375    }
376}
377impl<'db> inherent::DefId<DbInterner<'db>> for GeneralConstIdWrapper {
378    fn as_local(self) -> Option<SolverDefId> {
379        Some(self.into())
380    }
381    fn is_local(self) -> bool {
382        true
383    }
384}
385
386#[derive(Clone, Copy, PartialEq, Eq, Hash)]
387pub struct CallableIdWrapper(pub CallableDefId);
388
389impl std::fmt::Debug for CallableIdWrapper {
390    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
391        std::fmt::Debug::fmt(&self.0, f)
392    }
393}
394impl From<CallableIdWrapper> for CallableDefId {
395    #[inline]
396    fn from(value: CallableIdWrapper) -> CallableDefId {
397        value.0
398    }
399}
400impl From<CallableDefId> for CallableIdWrapper {
401    #[inline]
402    fn from(value: CallableDefId) -> CallableIdWrapper {
403        Self(value)
404    }
405}
406impl From<CallableIdWrapper> for SolverDefId {
407    #[inline]
408    fn from(value: CallableIdWrapper) -> SolverDefId {
409        match value.0 {
410            CallableDefId::FunctionId(it) => it.into(),
411            CallableDefId::StructId(it) => Ctor::Struct(it).into(),
412            CallableDefId::EnumVariantId(it) => Ctor::Enum(it).into(),
413        }
414    }
415}
416impl TryFrom<SolverDefId> for CallableIdWrapper {
417    type Error = ();
418    #[inline]
419    fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
420        match value {
421            SolverDefId::FunctionId(it) => Ok(Self(it.into())),
422            SolverDefId::Ctor(Ctor::Struct(it)) => Ok(Self(it.into())),
423            SolverDefId::Ctor(Ctor::Enum(it)) => Ok(Self(it.into())),
424            _ => Err(()),
425        }
426    }
427}
428impl<'db> inherent::DefId<DbInterner<'db>> for CallableIdWrapper {
429    fn as_local(self) -> Option<SolverDefId> {
430        Some(self.into())
431    }
432    fn is_local(self) -> bool {
433        true
434    }
435}