Skip to main content

hir_ty/next_solver/
binder.rs

1use hir_def::TraitId;
2use macros::{TypeFoldable, TypeVisitable};
3use salsa::SalsaValue;
4
5use crate::next_solver::{
6    Binder, Clauses, DbInterner, EarlyBinder, FnSig, FnSigKind, GenericArg, PolyFnSig,
7    StoredBoundVarKinds, StoredClauses, StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys,
8    TraitRef, Ty,
9};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SalsaValue)]
12pub struct StoredEarlyBinder<T>(T);
13
14impl<T> StoredEarlyBinder<T> {
15    #[inline]
16    pub fn bind(value: T) -> Self {
17        Self(value)
18    }
19
20    #[inline]
21    pub fn skip_binder(self) -> T {
22        self.0
23    }
24
25    #[inline]
26    pub fn as_ref(&self) -> StoredEarlyBinder<&T> {
27        StoredEarlyBinder(&self.0)
28    }
29
30    #[inline]
31    pub fn get_with<'db, 'a, R>(&'a self, f: impl FnOnce(&'a T) -> R) -> EarlyBinder<'db, R> {
32        EarlyBinder::bind(f(&self.0))
33    }
34}
35
36impl StoredEarlyBinder<StoredTy> {
37    #[inline]
38    pub fn get<'db>(&self) -> EarlyBinder<'db, Ty<'db>> {
39        self.get_with(|it| it.as_ref())
40    }
41}
42
43impl StoredEarlyBinder<StoredGenericArg> {
44    #[inline]
45    pub fn get<'db>(&self) -> EarlyBinder<'db, GenericArg<'db>> {
46        self.get_with(|it| it.as_ref())
47    }
48}
49
50impl StoredEarlyBinder<StoredClauses> {
51    #[inline]
52    pub fn get<'db>(&self) -> EarlyBinder<'db, Clauses<'db>> {
53        self.get_with(|it| it.as_ref())
54    }
55}
56
57impl StoredEarlyBinder<StoredPolyFnSig> {
58    #[inline]
59    pub fn get<'db>(&'db self) -> EarlyBinder<'db, PolyFnSig<'db>> {
60        self.get_with(|it| it.get())
61    }
62}
63
64impl StoredEarlyBinder<StoredTraitRef> {
65    #[inline]
66    pub fn get<'db>(&'db self, interner: DbInterner<'db>) -> EarlyBinder<'db, TraitRef<'db>> {
67        self.get_with(|it| it.get(interner))
68    }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash, SalsaValue)]
72pub struct StoredPolyFnSig {
73    bound_vars: StoredBoundVarKinds,
74    sig: StoredFnSig,
75}
76
77impl StoredPolyFnSig {
78    #[inline]
79    pub fn new(sig: PolyFnSig<'_>) -> Self {
80        let bound_vars = sig.bound_vars().store();
81        Self { bound_vars, sig: StoredFnSig::new(sig.skip_binder()) }
82    }
83
84    #[inline]
85    pub fn get(&self) -> PolyFnSig<'_> {
86        Binder::bind_with_vars(self.sig.get(), self.bound_vars.as_ref())
87    }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
91pub struct StoredFnSig {
92    inputs_and_output: StoredTys,
93    #[type_visitable(ignore)]
94    fn_sig_kind: FnSigKind<'static>,
95}
96
97impl StoredFnSig {
98    #[inline]
99    pub fn new(sig: FnSig<'_>) -> Self {
100        Self {
101            inputs_and_output: sig.inputs_and_output.store(),
102            fn_sig_kind: FnSigKind::new(
103                sig.fn_sig_kind.abi(),
104                sig.fn_sig_kind.safety(),
105                sig.fn_sig_kind.c_variadic(),
106            ),
107        }
108    }
109
110    #[inline]
111    pub fn get(&self) -> FnSig<'_> {
112        FnSig { inputs_and_output: self.inputs_and_output.as_ref(), fn_sig_kind: self.fn_sig_kind }
113    }
114}
115
116#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, SalsaValue)]
117pub struct StoredTraitRef {
118    #[type_visitable(ignore)]
119    def_id: TraitId,
120    args: StoredGenericArgs,
121}
122
123impl StoredTraitRef {
124    #[inline]
125    pub fn new(trait_ref: TraitRef<'_>) -> Self {
126        Self { def_id: trait_ref.def_id.0, args: trait_ref.args.store() }
127    }
128
129    #[inline]
130    pub fn get<'db>(&'db self, interner: DbInterner<'db>) -> TraitRef<'db> {
131        TraitRef::new_from_args(interner, self.def_id.into(), self.args.as_ref())
132    }
133}