diff options
Diffstat (limited to 'crates/hir_ty/src/interner.rs')
-rw-r--r-- | crates/hir_ty/src/interner.rs | 423 |
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 | |||
4 | use crate::{chalk_db, tls, GenericArg}; | ||
5 | use base_db::salsa::InternId; | ||
6 | use chalk_ir::{Goal, GoalData}; | ||
7 | use hir_def::{ | ||
8 | intern::{impl_internable, InternStorage, Internable, Interned}, | ||
9 | TypeAliasId, | ||
10 | }; | ||
11 | use smallvec::SmallVec; | ||
12 | use std::{fmt, sync::Arc}; | ||
13 | |||
14 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] | ||
15 | pub struct Interner; | ||
16 | |||
17 | #[derive(PartialEq, Eq, Hash, Debug)] | ||
18 | pub struct InternedWrapper<T>(T); | ||
19 | |||
20 | impl<T> std::ops::Deref for InternedWrapper<T> { | ||
21 | type Target = T; | ||
22 | |||
23 | fn deref(&self) -> &Self::Target { | ||
24 | &self.0 | ||
25 | } | ||
26 | } | ||
27 | |||
28 | impl_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 | |||
40 | impl 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 | ¶meter_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 | |||
412 | impl chalk_ir::interner::HasInterner for Interner { | ||
413 | type Interner = Self; | ||
414 | } | ||
415 | |||
416 | #[macro_export] | ||
417 | macro_rules! has_interner { | ||
418 | ($t:ty) => { | ||
419 | impl HasInterner for $t { | ||
420 | type Interner = crate::Interner; | ||
421 | } | ||
422 | }; | ||
423 | } | ||