aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/interner.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/interner.rs')
-rw-r--r--crates/hir_ty/src/interner.rs423
1 files changed, 423 insertions, 0 deletions
diff --git a/crates/hir_ty/src/interner.rs b/crates/hir_ty/src/interner.rs
new file mode 100644
index 000000000..a1656115d
--- /dev/null
+++ b/crates/hir_ty/src/interner.rs
@@ -0,0 +1,423 @@
1//! Implementation of the Chalk `Interner` trait, which allows customizing the
2//! representation of the various objects Chalk deals with (types, goals etc.).
3
4use crate::{chalk_db, tls, GenericArg};
5use base_db::salsa::InternId;
6use chalk_ir::{Goal, GoalData};
7use hir_def::{
8 intern::{impl_internable, InternStorage, Internable, Interned},
9 TypeAliasId,
10};
11use smallvec::SmallVec;
12use std::{fmt, sync::Arc};
13
14#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
15pub struct Interner;
16
17#[derive(PartialEq, Eq, Hash, Debug)]
18pub struct InternedWrapper<T>(T);
19
20impl<T> std::ops::Deref for InternedWrapper<T> {
21 type Target = T;
22
23 fn deref(&self) -> &Self::Target {
24 &self.0
25 }
26}
27
28impl_internable!(
29 InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>,
30 InternedWrapper<SmallVec<[GenericArg; 2]>>,
31 InternedWrapper<chalk_ir::TyData<Interner>>,
32 InternedWrapper<chalk_ir::LifetimeData<Interner>>,
33 InternedWrapper<chalk_ir::ConstData<Interner>>,
34 InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
35 InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
36 InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
37 InternedWrapper<Vec<chalk_ir::Variance>>,
38);
39
40impl chalk_ir::interner::Interner for Interner {
41 type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
42 type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
43 type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
44 type InternedConcreteConst = ();
45 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
46 type InternedGoal = Arc<GoalData<Self>>;
47 type InternedGoals = Vec<Goal<Self>>;
48 type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
49 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
50 type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
51 type InternedQuantifiedWhereClauses =
52 Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
53 type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
54 type InternedCanonicalVarKinds =
55 Interned<InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Self>>>>;
56 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
57 type InternedVariances = Interned<InternedWrapper<Vec<chalk_ir::Variance>>>;
58 type DefId = InternId;
59 type InternedAdtId = hir_def::AdtId;
60 type Identifier = TypeAliasId;
61 type FnAbi = ();
62
63 fn debug_adt_id(
64 type_kind_id: chalk_db::AdtId,
65 fmt: &mut fmt::Formatter<'_>,
66 ) -> Option<fmt::Result> {
67 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
68 }
69
70 fn debug_trait_id(
71 type_kind_id: chalk_db::TraitId,
72 fmt: &mut fmt::Formatter<'_>,
73 ) -> Option<fmt::Result> {
74 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
75 }
76
77 fn debug_assoc_type_id(
78 id: chalk_db::AssocTypeId,
79 fmt: &mut fmt::Formatter<'_>,
80 ) -> Option<fmt::Result> {
81 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
82 }
83
84 fn debug_alias(
85 alias: &chalk_ir::AliasTy<Interner>,
86 fmt: &mut fmt::Formatter<'_>,
87 ) -> Option<fmt::Result> {
88 tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
89 }
90
91 fn debug_projection_ty(
92 proj: &chalk_ir::ProjectionTy<Interner>,
93 fmt: &mut fmt::Formatter<'_>,
94 ) -> Option<fmt::Result> {
95 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
96 }
97
98 fn debug_opaque_ty(
99 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
100 fmt: &mut fmt::Formatter<'_>,
101 ) -> Option<fmt::Result> {
102 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt)))
103 }
104
105 fn debug_opaque_ty_id(
106 opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
107 fmt: &mut fmt::Formatter<'_>,
108 ) -> Option<fmt::Result> {
109 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt)))
110 }
111
112 fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
113 tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
114 }
115
116 fn debug_lifetime(
117 lifetime: &chalk_ir::Lifetime<Interner>,
118 fmt: &mut fmt::Formatter<'_>,
119 ) -> Option<fmt::Result> {
120 tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt)))
121 }
122
123 fn debug_generic_arg(
124 parameter: &GenericArg,
125 fmt: &mut fmt::Formatter<'_>,
126 ) -> Option<fmt::Result> {
127 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
128 }
129
130 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
131 tls::with_current_program(|prog| Some(prog?.debug_goal(goal, fmt)))
132 }
133
134 fn debug_goals(
135 goals: &chalk_ir::Goals<Interner>,
136 fmt: &mut fmt::Formatter<'_>,
137 ) -> Option<fmt::Result> {
138 tls::with_current_program(|prog| Some(prog?.debug_goals(goals, fmt)))
139 }
140
141 fn debug_program_clause_implication(
142 pci: &chalk_ir::ProgramClauseImplication<Interner>,
143 fmt: &mut fmt::Formatter<'_>,
144 ) -> Option<fmt::Result> {
145 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
146 }
147
148 fn debug_substitution(
149 substitution: &chalk_ir::Substitution<Interner>,
150 fmt: &mut fmt::Formatter<'_>,
151 ) -> Option<fmt::Result> {
152 tls::with_current_program(|prog| Some(prog?.debug_substitution(substitution, fmt)))
153 }
154
155 fn debug_separator_trait_ref(
156 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
157 fmt: &mut fmt::Formatter<'_>,
158 ) -> Option<fmt::Result> {
159 tls::with_current_program(|prog| {
160 Some(prog?.debug_separator_trait_ref(separator_trait_ref, fmt))
161 })
162 }
163
164 fn debug_fn_def_id(
165 fn_def_id: chalk_ir::FnDefId<Self>,
166 fmt: &mut fmt::Formatter<'_>,
167 ) -> Option<fmt::Result> {
168 tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
169 }
170 fn debug_const(
171 constant: &chalk_ir::Const<Self>,
172 fmt: &mut fmt::Formatter<'_>,
173 ) -> Option<fmt::Result> {
174 tls::with_current_program(|prog| Some(prog?.debug_const(constant, fmt)))
175 }
176 fn debug_variable_kinds(
177 variable_kinds: &chalk_ir::VariableKinds<Self>,
178 fmt: &mut fmt::Formatter<'_>,
179 ) -> Option<fmt::Result> {
180 tls::with_current_program(|prog| Some(prog?.debug_variable_kinds(variable_kinds, fmt)))
181 }
182 fn debug_variable_kinds_with_angles(
183 variable_kinds: &chalk_ir::VariableKinds<Self>,
184 fmt: &mut fmt::Formatter<'_>,
185 ) -> Option<fmt::Result> {
186 tls::with_current_program(|prog| {
187 Some(prog?.debug_variable_kinds_with_angles(variable_kinds, fmt))
188 })
189 }
190 fn debug_canonical_var_kinds(
191 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
192 fmt: &mut fmt::Formatter<'_>,
193 ) -> Option<fmt::Result> {
194 tls::with_current_program(|prog| {
195 Some(prog?.debug_canonical_var_kinds(canonical_var_kinds, fmt))
196 })
197 }
198 fn debug_program_clause(
199 clause: &chalk_ir::ProgramClause<Self>,
200 fmt: &mut fmt::Formatter<'_>,
201 ) -> Option<fmt::Result> {
202 tls::with_current_program(|prog| Some(prog?.debug_program_clause(clause, fmt)))
203 }
204 fn debug_program_clauses(
205 clauses: &chalk_ir::ProgramClauses<Self>,
206 fmt: &mut fmt::Formatter<'_>,
207 ) -> Option<fmt::Result> {
208 tls::with_current_program(|prog| Some(prog?.debug_program_clauses(clauses, fmt)))
209 }
210 fn debug_quantified_where_clauses(
211 clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
212 fmt: &mut fmt::Formatter<'_>,
213 ) -> Option<fmt::Result> {
214 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
215 }
216
217 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
218 let flags = kind.compute_flags(self);
219 Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
220 }
221
222 fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
223 &ty.0
224 }
225
226 fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
227 Interned::new(InternedWrapper(lifetime))
228 }
229
230 fn lifetime_data<'a>(
231 &self,
232 lifetime: &'a Self::InternedLifetime,
233 ) -> &'a chalk_ir::LifetimeData<Self> {
234 &lifetime.0
235 }
236
237 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
238 Interned::new(InternedWrapper(constant))
239 }
240
241 fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
242 &constant.0
243 }
244
245 fn const_eq(
246 &self,
247 _ty: &Self::InternedType,
248 _c1: &Self::InternedConcreteConst,
249 _c2: &Self::InternedConcreteConst,
250 ) -> bool {
251 true
252 }
253
254 fn intern_generic_arg(
255 &self,
256 parameter: chalk_ir::GenericArgData<Self>,
257 ) -> Self::InternedGenericArg {
258 parameter
259 }
260
261 fn generic_arg_data<'a>(
262 &self,
263 parameter: &'a Self::InternedGenericArg,
264 ) -> &'a chalk_ir::GenericArgData<Self> {
265 parameter
266 }
267
268 fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
269 Arc::new(goal)
270 }
271
272 fn intern_goals<E>(
273 &self,
274 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
275 ) -> Result<Self::InternedGoals, E> {
276 data.into_iter().collect()
277 }
278
279 fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
280 goal
281 }
282
283 fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
284 goals
285 }
286
287 fn intern_substitution<E>(
288 &self,
289 data: impl IntoIterator<Item = Result<GenericArg, E>>,
290 ) -> Result<Self::InternedSubstitution, E> {
291 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
292 }
293
294 fn substitution_data<'a>(
295 &self,
296 substitution: &'a Self::InternedSubstitution,
297 ) -> &'a [GenericArg] {
298 &substitution.as_ref().0
299 }
300
301 fn intern_program_clause(
302 &self,
303 data: chalk_ir::ProgramClauseData<Self>,
304 ) -> Self::InternedProgramClause {
305 data
306 }
307
308 fn program_clause_data<'a>(
309 &self,
310 clause: &'a Self::InternedProgramClause,
311 ) -> &'a chalk_ir::ProgramClauseData<Self> {
312 clause
313 }
314
315 fn intern_program_clauses<E>(
316 &self,
317 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
318 ) -> Result<Self::InternedProgramClauses, E> {
319 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
320 }
321
322 fn program_clauses_data<'a>(
323 &self,
324 clauses: &'a Self::InternedProgramClauses,
325 ) -> &'a [chalk_ir::ProgramClause<Self>] {
326 &clauses
327 }
328
329 fn intern_quantified_where_clauses<E>(
330 &self,
331 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
332 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
333 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
334 }
335
336 fn quantified_where_clauses_data<'a>(
337 &self,
338 clauses: &'a Self::InternedQuantifiedWhereClauses,
339 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
340 clauses
341 }
342
343 fn intern_generic_arg_kinds<E>(
344 &self,
345 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
346 ) -> Result<Self::InternedVariableKinds, E> {
347 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
348 }
349
350 fn variable_kinds_data<'a>(
351 &self,
352 parameter_kinds: &'a Self::InternedVariableKinds,
353 ) -> &'a [chalk_ir::VariableKind<Self>] {
354 &parameter_kinds.as_ref().0
355 }
356
357 fn intern_canonical_var_kinds<E>(
358 &self,
359 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
360 ) -> Result<Self::InternedCanonicalVarKinds, E> {
361 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
362 }
363
364 fn canonical_var_kinds_data<'a>(
365 &self,
366 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
367 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
368 &canonical_var_kinds
369 }
370
371 fn intern_constraints<E>(
372 &self,
373 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
374 ) -> Result<Self::InternedConstraints, E> {
375 data.into_iter().collect()
376 }
377
378 fn constraints_data<'a>(
379 &self,
380 constraints: &'a Self::InternedConstraints,
381 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
382 constraints
383 }
384 fn debug_closure_id(
385 _fn_def_id: chalk_ir::ClosureId<Self>,
386 _fmt: &mut fmt::Formatter<'_>,
387 ) -> Option<fmt::Result> {
388 None
389 }
390 fn debug_constraints(
391 _clauses: &chalk_ir::Constraints<Self>,
392 _fmt: &mut fmt::Formatter<'_>,
393 ) -> Option<fmt::Result> {
394 None
395 }
396
397 fn intern_variances<E>(
398 &self,
399 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
400 ) -> Result<Self::InternedVariances, E> {
401 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
402 }
403
404 fn variances_data<'a>(
405 &self,
406 variances: &'a Self::InternedVariances,
407 ) -> &'a [chalk_ir::Variance] {
408 &variances
409 }
410}
411
412impl chalk_ir::interner::HasInterner for Interner {
413 type Interner = Self;
414}
415
416#[macro_export]
417macro_rules! has_interner {
418 ($t:ty) => {
419 impl HasInterner for $t {
420 type Interner = crate::Interner;
421 }
422 };
423}