Skip to main content

hir_ty/next_solver/
binder.rs

1use hir_def::TraitId;
2use macros::{TypeFoldable, TypeVisitable};
3use salsa::Update;
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, Update)]
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)]
72pub struct StoredPolyFnSig {
73    bound_vars: StoredBoundVarKinds,
74    inputs_and_output: StoredTys,
75    fn_sig_kind: FnSigKind<'static>,
76}
77
78impl StoredPolyFnSig {
79    #[inline]
80    pub fn new(sig: PolyFnSig<'_>) -> Self {
81        let bound_vars = sig.bound_vars().store();
82        let sig = sig.skip_binder();
83        Self {
84            bound_vars,
85            inputs_and_output: sig.inputs_and_output.store(),
86            fn_sig_kind: FnSigKind::new(
87                sig.fn_sig_kind.abi(),
88                sig.fn_sig_kind.safety(),
89                sig.fn_sig_kind.c_variadic(),
90            ),
91        }
92    }
93
94    #[inline]
95    pub fn get(&self) -> PolyFnSig<'_> {
96        Binder::bind_with_vars(
97            FnSig {
98                inputs_and_output: self.inputs_and_output.as_ref(),
99                fn_sig_kind: self.fn_sig_kind,
100            },
101            self.bound_vars.as_ref(),
102        )
103    }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Update)]
107pub struct StoredTraitRef {
108    #[type_visitable(ignore)]
109    def_id: TraitId,
110    args: StoredGenericArgs,
111}
112
113impl StoredTraitRef {
114    #[inline]
115    pub fn new(trait_ref: TraitRef<'_>) -> Self {
116        Self { def_id: trait_ref.def_id.0, args: trait_ref.args.store() }
117    }
118
119    #[inline]
120    pub fn get<'db>(&'db self, interner: DbInterner<'db>) -> TraitRef<'db> {
121        TraitRef::new_from_args(interner, self.def_id.into(), self.args.as_ref())
122    }
123}