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