chalk_ir/
interner.rs

1//! Encapsulates the concrete representation of core types such as types and goals.
2use crate::AliasTy;
3use crate::AssocTypeId;
4use crate::CanonicalVarKind;
5use crate::CanonicalVarKinds;
6use crate::ClosureId;
7use crate::Constraint;
8use crate::Constraints;
9use crate::CoroutineId;
10use crate::FnDefId;
11use crate::ForeignDefId;
12use crate::GenericArg;
13use crate::GenericArgData;
14use crate::Goal;
15use crate::GoalData;
16use crate::Goals;
17use crate::InEnvironment;
18use crate::Lifetime;
19use crate::LifetimeData;
20use crate::OpaqueTy;
21use crate::OpaqueTyId;
22use crate::ProgramClause;
23use crate::ProgramClauseData;
24use crate::ProgramClauseImplication;
25use crate::ProgramClauses;
26use crate::ProjectionTy;
27use crate::QuantifiedWhereClause;
28use crate::QuantifiedWhereClauses;
29use crate::SeparatorTraitRef;
30use crate::Substitution;
31use crate::TraitId;
32use crate::Ty;
33use crate::TyData;
34use crate::VariableKind;
35use crate::VariableKinds;
36use crate::Variance;
37use crate::Variances;
38use crate::{AdtId, TyKind};
39use crate::{Const, ConstData};
40use std::fmt::{self, Debug};
41use std::hash::Hash;
42use std::marker::PhantomData;
43use std::sync::Arc;
44
45/// A "interner" encapsulates the concrete representation of
46/// certain "core types" from chalk-ir. All the types in chalk-ir are
47/// parameterized by a `I: Interner`, and so (e.g.) if they want to
48/// store a type, they don't store a `Ty<I>` instance directly, but
49/// rather prefer a `Ty<I>`. You can think of `I::Type` as the
50/// interned representation (and, indeed, it may well be an interned
51/// pointer, e.g. in rustc).
52///
53/// Type families allow chalk to be embedded in different contexts
54/// where the concrete representation of core types varies. They also
55/// allow us to write generic code that reasons about multiple
56/// distinct sets of types by using distinct generic type parameters
57/// (e.g., `SourceI` and `TargetI`) -- even if those type parameters
58/// wind up being mapped to the same underlying type families in the
59/// end.
60pub trait Interner: Debug + Copy + Eq + Hash + Sized {
61    /// "Interned" representation of types.  In normal user code,
62    /// `Self::InternedType` is not referenced. Instead, we refer to
63    /// `Ty<Self>`, which wraps this type.
64    ///
65    /// An `InternedType` must be something that can be created from a
66    /// `TyKind` (by the [`intern_ty`][Self::intern_ty] method) and then later
67    /// converted back (by the [`ty_data`][Self::ty_data] method). The interned form
68    /// must also introduce indirection, either via a `Box`, `&`, or
69    /// other pointer type.
70    type InternedType: Debug + Clone + Eq + Hash;
71
72    /// "Interned" representation of lifetimes.  In normal user code,
73    /// `Self::InternedLifetime` is not referenced. Instead, we refer to
74    /// `Lifetime<Self>`, which wraps this type.
75    ///
76    /// An `InternedLifetime` must be something that can be created
77    /// from a `LifetimeData` (by the [`intern_lifetime`][Self::intern_lifetime] method) and
78    /// then later converted back (by the [`lifetime_data`][Self::lifetime_data] method).
79    type InternedLifetime: Debug + Clone + Eq + Hash;
80
81    /// "Interned" representation of const expressions. In normal user code,
82    /// `Self::InternedConst` is not referenced. Instead, we refer to
83    /// `Const<Self>`, which wraps this type.
84    ///
85    /// An `InternedConst` must be something that can be created
86    /// from a `ConstData` (by the [`intern_const`][Self::intern_const] method) and
87    /// then later converted back (by the [`const_data`][Self::const_data] method).
88    type InternedConst: Debug + Clone + Eq + Hash;
89
90    /// "Interned" representation of an evaluated const value.
91    /// `Self::InternedConcreteConst` is not referenced. Instead,
92    /// we refer to `ConcreteConst<Self>`, which wraps this type.
93    ///
94    /// `InternedConcreteConst` instances are not created by chalk,
95    /// it can only make a query asking about equality of two
96    /// evaluated consts.
97    type InternedConcreteConst: Debug + Clone + Eq + Hash;
98
99    /// "Interned" representation of a "generic parameter", which can
100    /// be either a type or a lifetime.  In normal user code,
101    /// `Self::InternedGenericArg` is not referenced. Instead, we refer to
102    /// `GenericArg<Self>`, which wraps this type.
103    ///
104    /// An `InternedType` is created by `intern_generic_arg` and can be
105    /// converted back to its underlying data via `generic_arg_data`.
106    type InternedGenericArg: Debug + Clone + Eq + Hash;
107
108    /// "Interned" representation of a "goal".  In normal user code,
109    /// `Self::InternedGoal` is not referenced. Instead, we refer to
110    /// `Goal<Self>`, which wraps this type.
111    ///
112    /// An `InternedGoal` is created by `intern_goal` and can be
113    /// converted back to its underlying data via `goal_data`.
114    type InternedGoal: Debug + Clone + Eq + Hash;
115
116    /// "Interned" representation of a list of goals.  In normal user code,
117    /// `Self::InternedGoals` is not referenced. Instead, we refer to
118    /// `Goals<Self>`, which wraps this type.
119    ///
120    /// An `InternedGoals` is created by `intern_goals` and can be
121    /// converted back to its underlying data via `goals_data`.
122    type InternedGoals: Debug + Clone + Eq + Hash;
123
124    /// "Interned" representation of a "substitution".  In normal user code,
125    /// `Self::InternedSubstitution` is not referenced. Instead, we refer to
126    /// `Substitution<Self>`, which wraps this type.
127    ///
128    /// An `InternedSubstitution` is created by `intern_substitution` and can be
129    /// converted back to its underlying data via `substitution_data`.
130    type InternedSubstitution: Debug + Clone + Eq + Hash;
131
132    /// "Interned" representation of a list of program clauses.  In normal user code,
133    /// `Self::InternedProgramClauses` is not referenced. Instead, we refer to
134    /// `ProgramClauses<Self>`, which wraps this type.
135    ///
136    /// An `InternedProgramClauses` is created by `intern_program_clauses` and can be
137    /// converted back to its underlying data via `program_clauses_data`.
138    type InternedProgramClauses: Debug + Clone + Eq + Hash;
139
140    /// "Interned" representation of a "program clause".  In normal user code,
141    /// `Self::InternedProgramClause` is not referenced. Instead, we refer to
142    /// `ProgramClause<Self>`, which wraps this type.
143    ///
144    /// An `InternedProgramClause` is created by `intern_program_clause` and can be
145    /// converted back to its underlying data via `program_clause_data`.
146    type InternedProgramClause: Debug + Clone + Eq + Hash;
147
148    /// "Interned" representation of a list of quantified where clauses.
149    /// In normal user code, `Self::InternedQuantifiedWhereClauses` is not referenced.
150    /// Instead, we refer to `QuantifiedWhereClauses<Self>`, which wraps this type.
151    ///
152    /// An `InternedQuantifiedWhereClauses` is created by `intern_quantified_where_clauses`
153    /// and can be converted back to its underlying data via `quantified_where_clauses_data`.
154    type InternedQuantifiedWhereClauses: Debug + Clone + Eq + Hash;
155
156    /// "Interned" representation of a list of variable kinds.
157    /// In normal user code, `Self::InternedVariableKinds` is not referenced.
158    /// Instead, we refer to `VariableKinds<Self>`, which wraps this type.
159    ///
160    /// An `InternedVariableKinds` is created by `intern_generic_arg_kinds`
161    /// and can be converted back to its underlying data via `variable_kinds_data`.
162    type InternedVariableKinds: Debug + Clone + Eq + Hash;
163
164    /// "Interned" representation of a list of variable kinds with universe index.
165    /// In normal user code, `Self::InternedCanonicalVarKinds` is not referenced.
166    /// Instead, we refer to `CanonicalVarKinds<Self>`, which wraps this type.
167    ///
168    /// An `InternedCanonicalVarKinds` is created by
169    /// `intern_canonical_var_kinds` and can be converted back
170    /// to its underlying data via `canonical_var_kinds_data`.
171    type InternedCanonicalVarKinds: Debug + Clone + Eq + Hash;
172
173    /// "Interned" representation of a list of region constraints.
174    /// In normal user code, `Self::InternedConstraints` is not referenced.
175    /// Instead, we refer to `Constraints<Self>`, which wraps this type.
176    ///
177    /// An `InternedConstraints` is created by `intern_constraints`
178    /// and can be converted back to its underlying data via `constraints_data`.
179    type InternedConstraints: Debug + Clone + Eq + Hash;
180
181    /// "Interned" representation of a list of `chalk_ir::Variance`.
182    /// In normal user code, `Self::InternedVariances` is not referenced.
183    /// Instead, we refer to `Variances<Self>`, which wraps this type.
184    ///
185    /// An `InternedVariances` is created by
186    /// `intern_variances` and can be converted back
187    /// to its underlying data via `variances_data`.
188    type InternedVariances: Debug + Clone + Eq + Hash;
189
190    /// The core "id" type used for trait-ids and the like.
191    type DefId: Debug + Copy + Eq + Hash;
192
193    /// The ID type for ADTs
194    type InternedAdtId: Debug + Copy + Eq + Hash;
195
196    /// Representation of identifiers.
197    type Identifier: Debug + Clone + Eq + Hash;
198
199    /// Representation of function ABI (e.g. calling convention).
200    type FnAbi: Debug + Copy + Eq + Hash;
201
202    /// Prints the debug representation of a type-kind-id.
203    /// Returns `None` to fallback to the default debug output.
204    #[allow(unused_variables)]
205    fn debug_adt_id(adt_id: AdtId<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
206        None
207    }
208
209    /// Prints the debug representation of a type-kind-id.
210    /// Returns `None` to fallback to the default debug output (e.g.,
211    /// if no info about current program is available from TLS).
212    #[allow(unused_variables)]
213    fn debug_trait_id(
214        trait_id: TraitId<Self>,
215        fmt: &mut fmt::Formatter<'_>,
216    ) -> Option<fmt::Result> {
217        None
218    }
219
220    /// Prints the debug representation of a type-kind-id.
221    /// Returns `None` to fallback to the default debug output.
222    #[allow(unused_variables)]
223    fn debug_assoc_type_id(
224        type_id: AssocTypeId<Self>,
225        fmt: &mut fmt::Formatter<'_>,
226    ) -> Option<fmt::Result> {
227        None
228    }
229
230    /// Prints the debug representation of an opaque type.
231    /// Returns `None` to fallback to the default debug output.
232    #[allow(unused_variables)]
233    fn debug_opaque_ty_id(
234        opaque_ty_id: OpaqueTyId<Self>,
235        fmt: &mut fmt::Formatter<'_>,
236    ) -> Option<fmt::Result> {
237        None
238    }
239
240    /// Prints the debug representation of a function-def-id.
241    /// Returns `None` to fallback to the default debug output.
242    #[allow(unused_variables)]
243    fn debug_fn_def_id(
244        fn_def_id: FnDefId<Self>,
245        fmt: &mut fmt::Formatter<'_>,
246    ) -> Option<fmt::Result> {
247        None
248    }
249
250    /// Prints the debug representation of a closure id.
251    /// Returns `None` to fallback to the default debug output.
252    #[allow(unused_variables)]
253    fn debug_closure_id(
254        fn_def_id: ClosureId<Self>,
255        fmt: &mut fmt::Formatter<'_>,
256    ) -> Option<fmt::Result> {
257        None
258    }
259
260    /// Prints the debug representation of a foreign-def-id.
261    /// Returns `None` to fallback to the default debug output.
262    #[allow(unused_variables)]
263    fn debug_foreign_def_id(
264        foreign_def_id: ForeignDefId<Self>,
265        fmt: &mut fmt::Formatter<'_>,
266    ) -> Option<fmt::Result> {
267        None
268    }
269
270    /// Prints the debug representation of an alias.
271    /// Returns `None` to fallback to the default debug output.
272    #[allow(unused_variables)]
273    fn debug_coroutine_id(
274        coroutine_id: CoroutineId<Self>,
275        fmt: &mut fmt::Formatter<'_>,
276    ) -> Option<fmt::Result> {
277        None
278    }
279
280    /// Prints the debug representation of an alias. To get good
281    /// results, this requires inspecting TLS, and is difficult to
282    /// code without reference to a specific interner (and hence
283    /// fully known types).
284    ///
285    /// Returns `None` to fallback to the default debug output (e.g.,
286    /// if no info about current program is available from TLS).
287    #[allow(unused_variables)]
288    fn debug_alias(alias: &AliasTy<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
289        None
290    }
291
292    /// Prints the debug representation of a ProjectionTy.
293    /// Returns `None` to fallback to the default debug output.
294    #[allow(unused_variables)]
295    fn debug_projection_ty(
296        projection_ty: &ProjectionTy<Self>,
297        fmt: &mut fmt::Formatter<'_>,
298    ) -> Option<fmt::Result> {
299        None
300    }
301
302    /// Prints the debug representation of an OpaqueTy.
303    /// Returns `None` to fallback to the default debug output.
304    #[allow(unused_variables)]
305    fn debug_opaque_ty(
306        opaque_ty: &OpaqueTy<Self>,
307        fmt: &mut fmt::Formatter<'_>,
308    ) -> Option<fmt::Result> {
309        None
310    }
311
312    /// Prints the debug representation of a type.
313    /// Returns `None` to fallback to the default debug output.
314    #[allow(unused_variables)]
315    fn debug_ty(ty: &Ty<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
316        None
317    }
318
319    /// Prints the debug representation of a lifetime.
320    /// Returns `None` to fallback to the default debug output.
321    #[allow(unused_variables)]
322    fn debug_lifetime(
323        lifetime: &Lifetime<Self>,
324        fmt: &mut fmt::Formatter<'_>,
325    ) -> Option<fmt::Result> {
326        None
327    }
328
329    /// Prints the debug representation of a const.
330    /// Returns `None` to fallback to the default debug output.
331    #[allow(unused_variables)]
332    fn debug_const(constant: &Const<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
333        None
334    }
335
336    /// Prints the debug representation of an parameter.
337    /// Returns `None` to fallback to the default debug output.
338    #[allow(unused_variables)]
339    fn debug_generic_arg(
340        generic_arg: &GenericArg<Self>,
341        fmt: &mut fmt::Formatter<'_>,
342    ) -> Option<fmt::Result> {
343        None
344    }
345
346    /// Prints the debug representation of a parameter kinds list.
347    /// Returns `None` to fallback to the default debug output.
348    #[allow(unused_variables)]
349    fn debug_variable_kinds(
350        variable_kinds: &VariableKinds<Self>,
351        fmt: &mut fmt::Formatter<'_>,
352    ) -> Option<fmt::Result> {
353        None
354    }
355
356    /// Prints the debug representation of a parameter kinds list, with angle brackets.
357    /// Returns `None` to fallback to the default debug output.
358    #[allow(unused_variables)]
359    fn debug_variable_kinds_with_angles(
360        variable_kinds: &VariableKinds<Self>,
361        fmt: &mut fmt::Formatter<'_>,
362    ) -> Option<fmt::Result> {
363        None
364    }
365
366    /// Prints the debug representation of an parameter kinds list with universe index.
367    /// Returns `None` to fallback to the default debug output.
368    #[allow(unused_variables)]
369    fn debug_canonical_var_kinds(
370        canonical_var_kinds: &CanonicalVarKinds<Self>,
371        fmt: &mut fmt::Formatter<'_>,
372    ) -> Option<fmt::Result> {
373        None
374    }
375
376    /// Prints the debug representation of an goal.
377    /// Returns `None` to fallback to the default debug output.
378    #[allow(unused_variables)]
379    fn debug_goal(goal: &Goal<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
380        None
381    }
382
383    /// Prints the debug representation of a list of goals.
384    /// Returns `None` to fallback to the default debug output.
385    #[allow(unused_variables)]
386    fn debug_goals(goals: &Goals<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
387        None
388    }
389
390    /// Prints the debug representation of a ProgramClauseImplication.
391    /// Returns `None` to fallback to the default debug output.
392    #[allow(unused_variables)]
393    fn debug_program_clause_implication(
394        pci: &ProgramClauseImplication<Self>,
395        fmt: &mut fmt::Formatter<'_>,
396    ) -> Option<fmt::Result> {
397        None
398    }
399
400    /// Prints the debug representation of a ProgramClause.
401    /// Returns `None` to fallback to the default debug output.
402    #[allow(unused_variables)]
403    fn debug_program_clause(
404        clause: &ProgramClause<Self>,
405        fmt: &mut fmt::Formatter<'_>,
406    ) -> Option<fmt::Result> {
407        None
408    }
409
410    /// Prints the debug representation of a ProgramClauses.
411    /// Returns `None` to fallback to the default debug output.
412    #[allow(unused_variables)]
413    fn debug_program_clauses(
414        clauses: &ProgramClauses<Self>,
415        fmt: &mut fmt::Formatter<'_>,
416    ) -> Option<fmt::Result> {
417        None
418    }
419
420    /// Prints the debug representation of a Substitution.
421    /// Returns `None` to fallback to the default debug output.
422    #[allow(unused_variables)]
423    fn debug_substitution(
424        substitution: &Substitution<Self>,
425        fmt: &mut fmt::Formatter<'_>,
426    ) -> Option<fmt::Result> {
427        None
428    }
429
430    /// Prints the debug representation of a SeparatorTraitRef.
431    /// Returns `None` to fallback to the default debug output.
432    #[allow(unused_variables)]
433    fn debug_separator_trait_ref(
434        separator_trait_ref: &SeparatorTraitRef<'_, Self>,
435        fmt: &mut fmt::Formatter<'_>,
436    ) -> Option<fmt::Result> {
437        None
438    }
439
440    /// Prints the debug representation of a QuantifiedWhereClauses.
441    /// Returns `None` to fallback to the default debug output.
442    #[allow(unused_variables)]
443    fn debug_quantified_where_clauses(
444        clauses: &QuantifiedWhereClauses<Self>,
445        fmt: &mut fmt::Formatter<'_>,
446    ) -> Option<fmt::Result> {
447        None
448    }
449
450    /// Prints the debug representation of a Constraints.
451    /// Returns `None` to fallback to the default debug output.
452    #[allow(unused_variables)]
453    fn debug_constraints(
454        clauses: &Constraints<Self>,
455        fmt: &mut fmt::Formatter<'_>,
456    ) -> Option<fmt::Result> {
457        None
458    }
459
460    /// Prints the debug representation of a Variances.
461    /// Returns `None` to fallback to the default debug output.
462    #[allow(unused_variables)]
463    fn debug_variances(
464        variances: &Variances<Self>,
465        fmt: &mut fmt::Formatter<'_>,
466    ) -> Option<fmt::Result> {
467        None
468    }
469
470    /// Create an "interned" type from `ty`. This is not normally
471    /// invoked directly; instead, you invoke `TyKind::intern` (which
472    /// will ultimately call this method).
473    fn intern_ty(self, kind: TyKind<Self>) -> Self::InternedType;
474
475    /// Lookup the `TyKind` from an interned type.
476    fn ty_data(self, ty: &Self::InternedType) -> &TyData<Self>;
477
478    /// Create an "interned" lifetime from `lifetime`. This is not
479    /// normally invoked directly; instead, you invoke
480    /// `LifetimeData::intern` (which will ultimately call this
481    /// method).
482    fn intern_lifetime(self, lifetime: LifetimeData<Self>) -> Self::InternedLifetime;
483
484    /// Lookup the `LifetimeData` that was interned to create a `InternedLifetime`.
485    fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &LifetimeData<Self>;
486
487    /// Create an "interned" const from `const`. This is not
488    /// normally invoked directly; instead, you invoke
489    /// `ConstData::intern` (which will ultimately call this
490    /// method).
491    fn intern_const(self, constant: ConstData<Self>) -> Self::InternedConst;
492
493    /// Lookup the `ConstData` that was interned to create a `InternedConst`.
494    fn const_data(self, constant: &Self::InternedConst) -> &ConstData<Self>;
495
496    /// Determine whether two concrete const values are equal.
497    fn const_eq(
498        self,
499        ty: &Self::InternedType,
500        c1: &Self::InternedConcreteConst,
501        c2: &Self::InternedConcreteConst,
502    ) -> bool;
503
504    /// Create an "interned" parameter from `data`. This is not
505    /// normally invoked directly; instead, you invoke
506    /// `GenericArgData::intern` (which will ultimately call this
507    /// method).
508    fn intern_generic_arg(self, data: GenericArgData<Self>) -> Self::InternedGenericArg;
509
510    /// Lookup the `LifetimeData` that was interned to create a `InternedLifetime`.
511    fn generic_arg_data(self, lifetime: &Self::InternedGenericArg) -> &GenericArgData<Self>;
512
513    /// Create an "interned" goal from `data`. This is not
514    /// normally invoked directly; instead, you invoke
515    /// `GoalData::intern` (which will ultimately call this
516    /// method).
517    fn intern_goal(self, data: GoalData<Self>) -> Self::InternedGoal;
518
519    /// Lookup the `GoalData` that was interned to create a `InternedGoal`.
520    fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self>;
521
522    /// Create an "interned" goals from `data`. This is not
523    /// normally invoked directly; instead, you invoke
524    /// `GoalsData::intern` (which will ultimately call this
525    /// method).
526    fn intern_goals<E>(
527        self,
528        data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
529    ) -> Result<Self::InternedGoals, E>;
530
531    /// Lookup the `GoalsData` that was interned to create a `InternedGoals`.
532    fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal<Self>];
533
534    /// Create an "interned" substitution from `data`. This is not
535    /// normally invoked directly; instead, you invoke
536    /// `SubstitutionData::intern` (which will ultimately call this
537    /// method).
538    fn intern_substitution<E>(
539        self,
540        data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
541    ) -> Result<Self::InternedSubstitution, E>;
542
543    /// Lookup the `SubstitutionData` that was interned to create a `InternedSubstitution`.
544    fn substitution_data(self, substitution: &Self::InternedSubstitution) -> &[GenericArg<Self>];
545
546    /// Create an "interned" program clause from `data`. This is not
547    /// normally invoked directly; instead, you invoke
548    /// `ProgramClauseData::intern` (which will ultimately call this
549    /// method).
550    fn intern_program_clause(self, data: ProgramClauseData<Self>) -> Self::InternedProgramClause;
551
552    /// Lookup the `ProgramClauseData` that was interned to create a `ProgramClause`.
553    fn program_clause_data(self, clause: &Self::InternedProgramClause) -> &ProgramClauseData<Self>;
554
555    /// Create an "interned" program clauses from `data`. This is not
556    /// normally invoked directly; instead, you invoke
557    /// `ProgramClauses::from_iter` (which will ultimately call this
558    /// method).
559    fn intern_program_clauses<E>(
560        self,
561        data: impl IntoIterator<Item = Result<ProgramClause<Self>, E>>,
562    ) -> Result<Self::InternedProgramClauses, E>;
563
564    /// Lookup the `ProgramClauseData` that was interned to create a `ProgramClause`.
565    fn program_clauses_data(self, clauses: &Self::InternedProgramClauses)
566        -> &[ProgramClause<Self>];
567
568    /// Create an "interned" quantified where clauses from `data`. This is not
569    /// normally invoked directly; instead, you invoke
570    /// `QuantifiedWhereClauses::from_iter` (which will ultimately call this
571    /// method).
572    fn intern_quantified_where_clauses<E>(
573        self,
574        data: impl IntoIterator<Item = Result<QuantifiedWhereClause<Self>, E>>,
575    ) -> Result<Self::InternedQuantifiedWhereClauses, E>;
576
577    /// Lookup the slice of `QuantifiedWhereClause` that was interned to
578    /// create a `QuantifiedWhereClauses`.
579    fn quantified_where_clauses_data(
580        self,
581        clauses: &Self::InternedQuantifiedWhereClauses,
582    ) -> &[QuantifiedWhereClause<Self>];
583
584    /// Create an "interned" parameter kinds from `data`. This is not
585    /// normally invoked directly; instead, you invoke
586    /// `VariableKinds::from_iter` (which will ultimately call this
587    /// method).
588    fn intern_generic_arg_kinds<E>(
589        self,
590        data: impl IntoIterator<Item = Result<VariableKind<Self>, E>>,
591    ) -> Result<Self::InternedVariableKinds, E>;
592
593    /// Lookup the slice of `VariableKinds` that was interned to
594    /// create a `VariableKinds`.
595    fn variable_kinds_data(
596        self,
597        variable_kinds: &Self::InternedVariableKinds,
598    ) -> &[VariableKind<Self>];
599
600    /// Create "interned" variable kinds with universe index from `data`. This is not
601    /// normally invoked directly; instead, you invoke
602    /// `CanonicalVarKinds::from_iter` (which will ultimately call this
603    /// method).
604    fn intern_canonical_var_kinds<E>(
605        self,
606        data: impl IntoIterator<Item = Result<CanonicalVarKind<Self>, E>>,
607    ) -> Result<Self::InternedCanonicalVarKinds, E>;
608
609    /// Lookup the slice of `CanonicalVariableKind` that was interned to
610    /// create a `CanonicalVariableKinds`.
611    fn canonical_var_kinds_data(
612        self,
613        canonical_var_kinds: &Self::InternedCanonicalVarKinds,
614    ) -> &[CanonicalVarKind<Self>];
615
616    /// Create "interned" constraints from `data`. This is not
617    /// normally invoked dirctly; instead, you invoke
618    /// `Constraints::from_iter` (which will ultimately call this
619    /// method).
620    fn intern_constraints<E>(
621        self,
622        data: impl IntoIterator<Item = Result<InEnvironment<Constraint<Self>>, E>>,
623    ) -> Result<Self::InternedConstraints, E>;
624
625    /// Lookup the slice of `Constraint` that was interned to
626    /// create a `Constraints`.
627    fn constraints_data(
628        self,
629        constraints: &Self::InternedConstraints,
630    ) -> &[InEnvironment<Constraint<Self>>];
631
632    /// Create "interned" variances from `data`. This is not
633    /// normally invoked directly; instead, you invoke
634    /// `Variances::from` (which will ultimately call this
635    /// method).
636    fn intern_variances<E>(
637        self,
638        data: impl IntoIterator<Item = Result<Variance, E>>,
639    ) -> Result<Self::InternedVariances, E>;
640
641    /// Lookup the slice of `Variance` that was interned to
642    /// create a `Variances`.
643    fn variances_data(self, variances: &Self::InternedVariances) -> &[Variance];
644}
645
646/// Implemented by types that have an associated interner (which
647/// are virtually all of the types in chalk-ir, for example).
648/// This lets us map from a type like `Ty<I>` to the parameter `I`.
649///
650/// It's particularly useful for writing `TypeFoldable` impls for generic types like
651/// `Binder<T>`, since it allows us to figure out the interner of `T`.
652pub trait HasInterner {
653    /// The interner associated with the type.
654    type Interner: Interner;
655}
656
657impl<T: HasInterner> HasInterner for [T] {
658    type Interner = T::Interner;
659}
660
661impl<T: HasInterner> HasInterner for Vec<T> {
662    type Interner = T::Interner;
663}
664
665impl<T: HasInterner + ?Sized> HasInterner for Box<T> {
666    type Interner = T::Interner;
667}
668
669impl<T: HasInterner + ?Sized> HasInterner for Arc<T> {
670    type Interner = T::Interner;
671}
672
673impl<T: HasInterner + ?Sized> HasInterner for &T {
674    type Interner = T::Interner;
675}
676
677impl<I: Interner> HasInterner for PhantomData<I> {
678    type Interner = I;
679}
680
681impl<A, B, I> HasInterner for (A, B)
682where
683    A: HasInterner<Interner = I>,
684    B: HasInterner<Interner = I>,
685    I: Interner,
686{
687    type Interner = I;
688}
689
690impl<A, B, C, I> HasInterner for (A, B, C)
691where
692    A: HasInterner<Interner = I>,
693    B: HasInterner<Interner = I>,
694    C: HasInterner<Interner = I>,
695    I: Interner,
696{
697    type Interner = I;
698}
699
700impl<'a, T: HasInterner> HasInterner for std::slice::Iter<'a, T> {
701    type Interner = T::Interner;
702}