hir_ty/next_solver/
binder.rs1use 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}