]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/interner.rs
Merge #8427
[rust.git] / crates / hir_ty / src / interner.rs
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         &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
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 }