summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-ir-0.80.0/src/interner.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chalk-ir-0.80.0/src/interner.rs')
-rw-r--r--vendor/chalk-ir-0.80.0/src/interner.rs702
1 files changed, 702 insertions, 0 deletions
diff --git a/vendor/chalk-ir-0.80.0/src/interner.rs b/vendor/chalk-ir-0.80.0/src/interner.rs
new file mode 100644
index 000000000..8a3f88cc4
--- /dev/null
+++ b/vendor/chalk-ir-0.80.0/src/interner.rs
@@ -0,0 +1,702 @@
+//! Encapsulates the concrete representation of core types such as types and goals.
+use crate::AliasTy;
+use crate::AssocTypeId;
+use crate::CanonicalVarKind;
+use crate::CanonicalVarKinds;
+use crate::ClosureId;
+use crate::Constraint;
+use crate::Constraints;
+use crate::FnDefId;
+use crate::ForeignDefId;
+use crate::GeneratorId;
+use crate::GenericArg;
+use crate::GenericArgData;
+use crate::Goal;
+use crate::GoalData;
+use crate::Goals;
+use crate::InEnvironment;
+use crate::Lifetime;
+use crate::LifetimeData;
+use crate::OpaqueTy;
+use crate::OpaqueTyId;
+use crate::ProgramClause;
+use crate::ProgramClauseData;
+use crate::ProgramClauseImplication;
+use crate::ProgramClauses;
+use crate::ProjectionTy;
+use crate::QuantifiedWhereClause;
+use crate::QuantifiedWhereClauses;
+use crate::SeparatorTraitRef;
+use crate::Substitution;
+use crate::TraitId;
+use crate::Ty;
+use crate::TyData;
+use crate::VariableKind;
+use crate::VariableKinds;
+use crate::Variance;
+use crate::Variances;
+use crate::{AdtId, TyKind};
+use crate::{Const, ConstData};
+use std::fmt::{self, Debug};
+use std::hash::Hash;
+use std::marker::PhantomData;
+use std::sync::Arc;
+
+/// A "interner" encapsulates the concrete representation of
+/// certain "core types" from chalk-ir. All the types in chalk-ir are
+/// parameterized by a `I: Interner`, and so (e.g.) if they want to
+/// store a type, they don't store a `Ty<I>` instance directly, but
+/// rather prefer a `Ty<I>`. You can think of `I::Type` as the
+/// interned representation (and, indeed, it may well be an interned
+/// pointer, e.g. in rustc).
+///
+/// Type families allow chalk to be embedded in different contexts
+/// where the concrete representation of core types varies. They also
+/// allow us to write generic code that reasons about multiple
+/// distinct sets of types by using distinct generic type parameters
+/// (e.g., `SourceI` and `TargetI`) -- even if those type parameters
+/// wind up being mapped to the same underlying type families in the
+/// end.
+pub trait Interner: Debug + Copy + Eq + Hash + Sized {
+ /// "Interned" representation of types. In normal user code,
+ /// `Self::InternedType` is not referenced. Instead, we refer to
+ /// `Ty<Self>`, which wraps this type.
+ ///
+ /// An `InternedType` must be something that can be created from a
+ /// `TyKind` (by the [`intern_ty`][Self::intern_ty] method) and then later
+ /// converted back (by the [`ty_data`][Self::ty_data] method). The interned form
+ /// must also introduce indirection, either via a `Box`, `&`, or
+ /// other pointer type.
+ type InternedType: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of lifetimes. In normal user code,
+ /// `Self::InternedLifetime` is not referenced. Instead, we refer to
+ /// `Lifetime<Self>`, which wraps this type.
+ ///
+ /// An `InternedLifetime` must be something that can be created
+ /// from a `LifetimeData` (by the [`intern_lifetime`][Self::intern_lifetime] method) and
+ /// then later converted back (by the [`lifetime_data`][Self::lifetime_data] method).
+ type InternedLifetime: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of const expressions. In normal user code,
+ /// `Self::InternedConst` is not referenced. Instead, we refer to
+ /// `Const<Self>`, which wraps this type.
+ ///
+ /// An `InternedConst` must be something that can be created
+ /// from a `ConstData` (by the [`intern_const`][Self::intern_const] method) and
+ /// then later converted back (by the [`const_data`][Self::const_data] method).
+ type InternedConst: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of an evaluated const value.
+ /// `Self::InternedConcreteConst` is not referenced. Instead,
+ /// we refer to `ConcreteConst<Self>`, which wraps this type.
+ ///
+ /// `InternedConcreteConst` instances are not created by chalk,
+ /// it can only make a query asking about equality of two
+ /// evaluated consts.
+ type InternedConcreteConst: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a "generic parameter", which can
+ /// be either a type or a lifetime. In normal user code,
+ /// `Self::InternedGenericArg` is not referenced. Instead, we refer to
+ /// `GenericArg<Self>`, which wraps this type.
+ ///
+ /// An `InternedType` is created by `intern_generic_arg` and can be
+ /// converted back to its underlying data via `generic_arg_data`.
+ type InternedGenericArg: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a "goal". In normal user code,
+ /// `Self::InternedGoal` is not referenced. Instead, we refer to
+ /// `Goal<Self>`, which wraps this type.
+ ///
+ /// An `InternedGoal` is created by `intern_goal` and can be
+ /// converted back to its underlying data via `goal_data`.
+ type InternedGoal: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of goals. In normal user code,
+ /// `Self::InternedGoals` is not referenced. Instead, we refer to
+ /// `Goals<Self>`, which wraps this type.
+ ///
+ /// An `InternedGoals` is created by `intern_goals` and can be
+ /// converted back to its underlying data via `goals_data`.
+ type InternedGoals: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a "substitution". In normal user code,
+ /// `Self::InternedSubstitution` is not referenced. Instead, we refer to
+ /// `Substitution<Self>`, which wraps this type.
+ ///
+ /// An `InternedSubstitution` is created by `intern_substitution` and can be
+ /// converted back to its underlying data via `substitution_data`.
+ type InternedSubstitution: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of program clauses. In normal user code,
+ /// `Self::InternedProgramClauses` is not referenced. Instead, we refer to
+ /// `ProgramClauses<Self>`, which wraps this type.
+ ///
+ /// An `InternedProgramClauses` is created by `intern_program_clauses` and can be
+ /// converted back to its underlying data via `program_clauses_data`.
+ type InternedProgramClauses: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a "program clause". In normal user code,
+ /// `Self::InternedProgramClause` is not referenced. Instead, we refer to
+ /// `ProgramClause<Self>`, which wraps this type.
+ ///
+ /// An `InternedProgramClause` is created by `intern_program_clause` and can be
+ /// converted back to its underlying data via `program_clause_data`.
+ type InternedProgramClause: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of quantified where clauses.
+ /// In normal user code, `Self::InternedQuantifiedWhereClauses` is not referenced.
+ /// Instead, we refer to `QuantifiedWhereClauses<Self>`, which wraps this type.
+ ///
+ /// An `InternedQuantifiedWhereClauses` is created by `intern_quantified_where_clauses`
+ /// and can be converted back to its underlying data via `quantified_where_clauses_data`.
+ type InternedQuantifiedWhereClauses: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of variable kinds.
+ /// In normal user code, `Self::InternedVariableKinds` is not referenced.
+ /// Instead, we refer to `VariableKinds<Self>`, which wraps this type.
+ ///
+ /// An `InternedVariableKinds` is created by `intern_generic_arg_kinds`
+ /// and can be converted back to its underlying data via `variable_kinds_data`.
+ type InternedVariableKinds: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of variable kinds with universe index.
+ /// In normal user code, `Self::InternedCanonicalVarKinds` is not referenced.
+ /// Instead, we refer to `CanonicalVarKinds<Self>`, which wraps this type.
+ ///
+ /// An `InternedCanonicalVarKinds` is created by
+ /// `intern_canonical_var_kinds` and can be converted back
+ /// to its underlying data via `canonical_var_kinds_data`.
+ type InternedCanonicalVarKinds: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of region constraints.
+ /// In normal user code, `Self::InternedConstraints` is not referenced.
+ /// Instead, we refer to `Constraints<Self>`, which wraps this type.
+ ///
+ /// An `InternedConstraints` is created by `intern_constraints`
+ /// and can be converted back to its underlying data via `constraints_data`.
+ type InternedConstraints: Debug + Clone + Eq + Hash;
+
+ /// "Interned" representation of a list of `chalk_ir::Variance`.
+ /// In normal user code, `Self::InternedVariances` is not referenced.
+ /// Instead, we refer to `Variances<Self>`, which wraps this type.
+ ///
+ /// An `InternedVariances` is created by
+ /// `intern_variances` and can be converted back
+ /// to its underlying data via `variances_data`.
+ type InternedVariances: Debug + Clone + Eq + Hash;
+
+ /// The core "id" type used for trait-ids and the like.
+ type DefId: Debug + Copy + Eq + Hash;
+
+ /// The ID type for ADTs
+ type InternedAdtId: Debug + Copy + Eq + Hash;
+
+ /// Representation of identifiers.
+ type Identifier: Debug + Clone + Eq + Hash;
+
+ /// Representation of function ABI (e.g. calling convention).
+ type FnAbi: Debug + Copy + Eq + Hash;
+
+ /// Prints the debug representation of a type-kind-id.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_adt_id(adt_id: AdtId<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a type-kind-id.
+ /// Returns `None` to fallback to the default debug output (e.g.,
+ /// if no info about current program is available from TLS).
+ #[allow(unused_variables)]
+ fn debug_trait_id(
+ trait_id: TraitId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a type-kind-id.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_assoc_type_id(
+ type_id: AssocTypeId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an opaque type.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_opaque_ty_id(
+ opaque_ty_id: OpaqueTyId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a function-def-id.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_fn_def_id(
+ fn_def_id: FnDefId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a closure id.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_closure_id(
+ fn_def_id: ClosureId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a foreign-def-id.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_foreign_def_id(
+ foreign_def_id: ForeignDefId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an alias.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_generator_id(
+ generator_id: GeneratorId<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an alias. To get good
+ /// results, this requires inspecting TLS, and is difficult to
+ /// code without reference to a specific interner (and hence
+ /// fully known types).
+ ///
+ /// Returns `None` to fallback to the default debug output (e.g.,
+ /// if no info about current program is available from TLS).
+ #[allow(unused_variables)]
+ fn debug_alias(alias: &AliasTy<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a ProjectionTy.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_projection_ty(
+ projection_ty: &ProjectionTy<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an OpaqueTy.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_opaque_ty(
+ opaque_ty: &OpaqueTy<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a type.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_ty(ty: &Ty<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a lifetime.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_lifetime(
+ lifetime: &Lifetime<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a const.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_const(constant: &Const<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an parameter.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_generic_arg(
+ generic_arg: &GenericArg<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a parameter kinds list.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_variable_kinds(
+ variable_kinds: &VariableKinds<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a parameter kinds list, with angle brackets.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_variable_kinds_with_angles(
+ variable_kinds: &VariableKinds<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an parameter kinds list with universe index.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_canonical_var_kinds(
+ canonical_var_kinds: &CanonicalVarKinds<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of an goal.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_goal(goal: &Goal<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a list of goals.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_goals(goals: &Goals<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a ProgramClauseImplication.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_program_clause_implication(
+ pci: &ProgramClauseImplication<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a ProgramClause.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_program_clause(
+ clause: &ProgramClause<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a ProgramClauses.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_program_clauses(
+ clauses: &ProgramClauses<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a Substitution.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_substitution(
+ substitution: &Substitution<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a SeparatorTraitRef.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_separator_trait_ref(
+ separator_trait_ref: &SeparatorTraitRef<'_, Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a QuantifiedWhereClauses.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_quantified_where_clauses(
+ clauses: &QuantifiedWhereClauses<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a Constraints.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_constraints(
+ clauses: &Constraints<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Prints the debug representation of a Variances.
+ /// Returns `None` to fallback to the default debug output.
+ #[allow(unused_variables)]
+ fn debug_variances(
+ variances: &Variances<Self>,
+ fmt: &mut fmt::Formatter<'_>,
+ ) -> Option<fmt::Result> {
+ None
+ }
+
+ /// Create an "interned" type from `ty`. This is not normally
+ /// invoked directly; instead, you invoke `TyKind::intern` (which
+ /// will ultimately call this method).
+ fn intern_ty(self, kind: TyKind<Self>) -> Self::InternedType;
+
+ /// Lookup the `TyKind` from an interned type.
+ fn ty_data(self, ty: &Self::InternedType) -> &TyData<Self>;
+
+ /// Create an "interned" lifetime from `lifetime`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `LifetimeData::intern` (which will ultimately call this
+ /// method).
+ fn intern_lifetime(self, lifetime: LifetimeData<Self>) -> Self::InternedLifetime;
+
+ /// Lookup the `LifetimeData` that was interned to create a `InternedLifetime`.
+ fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &LifetimeData<Self>;
+
+ /// Create an "interned" const from `const`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `ConstData::intern` (which will ultimately call this
+ /// method).
+ fn intern_const(self, constant: ConstData<Self>) -> Self::InternedConst;
+
+ /// Lookup the `ConstData` that was interned to create a `InternedConst`.
+ fn const_data(self, constant: &Self::InternedConst) -> &ConstData<Self>;
+
+ /// Determine whether two concrete const values are equal.
+ fn const_eq(
+ self,
+ ty: &Self::InternedType,
+ c1: &Self::InternedConcreteConst,
+ c2: &Self::InternedConcreteConst,
+ ) -> bool;
+
+ /// Create an "interned" parameter from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `GenericArgData::intern` (which will ultimately call this
+ /// method).
+ fn intern_generic_arg(self, data: GenericArgData<Self>) -> Self::InternedGenericArg;
+
+ /// Lookup the `LifetimeData` that was interned to create a `InternedLifetime`.
+ fn generic_arg_data(self, lifetime: &Self::InternedGenericArg) -> &GenericArgData<Self>;
+
+ /// Create an "interned" goal from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `GoalData::intern` (which will ultimately call this
+ /// method).
+ fn intern_goal(self, data: GoalData<Self>) -> Self::InternedGoal;
+
+ /// Lookup the `GoalData` that was interned to create a `InternedGoal`.
+ fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self>;
+
+ /// Create an "interned" goals from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `GoalsData::intern` (which will ultimately call this
+ /// method).
+ fn intern_goals<E>(
+ self,
+ data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
+ ) -> Result<Self::InternedGoals, E>;
+
+ /// Lookup the `GoalsData` that was interned to create a `InternedGoals`.
+ fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal<Self>];
+
+ /// Create an "interned" substitution from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `SubstitutionData::intern` (which will ultimately call this
+ /// method).
+ fn intern_substitution<E>(
+ self,
+ data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
+ ) -> Result<Self::InternedSubstitution, E>;
+
+ /// Lookup the `SubstitutionData` that was interned to create a `InternedSubstitution`.
+ fn substitution_data(self, substitution: &Self::InternedSubstitution) -> &[GenericArg<Self>];
+
+ /// Create an "interned" program clause from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `ProgramClauseData::intern` (which will ultimately call this
+ /// method).
+ fn intern_program_clause(self, data: ProgramClauseData<Self>) -> Self::InternedProgramClause;
+
+ /// Lookup the `ProgramClauseData` that was interned to create a `ProgramClause`.
+ fn program_clause_data(self, clause: &Self::InternedProgramClause) -> &ProgramClauseData<Self>;
+
+ /// Create an "interned" program clauses from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `ProgramClauses::from_iter` (which will ultimately call this
+ /// method).
+ fn intern_program_clauses<E>(
+ self,
+ data: impl IntoIterator<Item = Result<ProgramClause<Self>, E>>,
+ ) -> Result<Self::InternedProgramClauses, E>;
+
+ /// Lookup the `ProgramClauseData` that was interned to create a `ProgramClause`.
+ fn program_clauses_data(self, clauses: &Self::InternedProgramClauses)
+ -> &[ProgramClause<Self>];
+
+ /// Create an "interned" quantified where clauses from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `QuantifiedWhereClauses::from_iter` (which will ultimately call this
+ /// method).
+ fn intern_quantified_where_clauses<E>(
+ self,
+ data: impl IntoIterator<Item = Result<QuantifiedWhereClause<Self>, E>>,
+ ) -> Result<Self::InternedQuantifiedWhereClauses, E>;
+
+ /// Lookup the slice of `QuantifiedWhereClause` that was interned to
+ /// create a `QuantifiedWhereClauses`.
+ fn quantified_where_clauses_data(
+ self,
+ clauses: &Self::InternedQuantifiedWhereClauses,
+ ) -> &[QuantifiedWhereClause<Self>];
+
+ /// Create an "interned" parameter kinds from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `VariableKinds::from_iter` (which will ultimately call this
+ /// method).
+ fn intern_generic_arg_kinds<E>(
+ self,
+ data: impl IntoIterator<Item = Result<VariableKind<Self>, E>>,
+ ) -> Result<Self::InternedVariableKinds, E>;
+
+ /// Lookup the slice of `VariableKinds` that was interned to
+ /// create a `VariableKinds`.
+ fn variable_kinds_data(
+ self,
+ variable_kinds: &Self::InternedVariableKinds,
+ ) -> &[VariableKind<Self>];
+
+ /// Create "interned" variable kinds with universe index from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `CanonicalVarKinds::from_iter` (which will ultimately call this
+ /// method).
+ fn intern_canonical_var_kinds<E>(
+ self,
+ data: impl IntoIterator<Item = Result<CanonicalVarKind<Self>, E>>,
+ ) -> Result<Self::InternedCanonicalVarKinds, E>;
+
+ /// Lookup the slice of `CanonicalVariableKind` that was interned to
+ /// create a `CanonicalVariableKinds`.
+ fn canonical_var_kinds_data(
+ self,
+ canonical_var_kinds: &Self::InternedCanonicalVarKinds,
+ ) -> &[CanonicalVarKind<Self>];
+
+ /// Create "interned" constraints from `data`. This is not
+ /// normally invoked dirctly; instead, you invoke
+ /// `Constraints::from_iter` (which will ultimately call this
+ /// method).
+ fn intern_constraints<E>(
+ self,
+ data: impl IntoIterator<Item = Result<InEnvironment<Constraint<Self>>, E>>,
+ ) -> Result<Self::InternedConstraints, E>;
+
+ /// Lookup the slice of `Constraint` that was interned to
+ /// create a `Constraints`.
+ fn constraints_data(
+ self,
+ constraints: &Self::InternedConstraints,
+ ) -> &[InEnvironment<Constraint<Self>>];
+
+ /// Create "interned" variances from `data`. This is not
+ /// normally invoked directly; instead, you invoke
+ /// `Variances::from` (which will ultimately call this
+ /// method).
+ fn intern_variances<E>(
+ self,
+ data: impl IntoIterator<Item = Result<Variance, E>>,
+ ) -> Result<Self::InternedVariances, E>;
+
+ /// Lookup the slice of `Variance` that was interned to
+ /// create a `Variances`.
+ fn variances_data(self, variances: &Self::InternedVariances) -> &[Variance];
+}
+
+/// Implemented by types that have an associated interner (which
+/// are virtually all of the types in chalk-ir, for example).
+/// This lets us map from a type like `Ty<I>` to the parameter `I`.
+///
+/// It's particularly useful for writing `Fold` impls for generic types like
+/// `Binder<T>`, since it allows us to figure out the interner of `T`.
+pub trait HasInterner {
+ /// The interner associated with the type.
+ type Interner: Interner;
+}
+
+impl<T: HasInterner> HasInterner for [T] {
+ type Interner = T::Interner;
+}
+
+impl<T: HasInterner> HasInterner for Vec<T> {
+ type Interner = T::Interner;
+}
+
+impl<T: HasInterner> HasInterner for Box<T> {
+ type Interner = T::Interner;
+}
+
+impl<T: HasInterner> HasInterner for Arc<T> {
+ type Interner = T::Interner;
+}
+
+impl<T: HasInterner + ?Sized> HasInterner for &T {
+ type Interner = T::Interner;
+}
+
+impl<I: Interner> HasInterner for PhantomData<I> {
+ type Interner = I;
+}
+
+impl<A, B, I> HasInterner for (A, B)
+where
+ A: HasInterner<Interner = I>,
+ B: HasInterner<Interner = I>,
+ I: Interner,
+{
+ type Interner = I;
+}
+
+impl<A, B, C, I> HasInterner for (A, B, C)
+where
+ A: HasInterner<Interner = I>,
+ B: HasInterner<Interner = I>,
+ C: HasInterner<Interner = I>,
+ I: Interner,
+{
+ type Interner = I;
+}
+
+impl<'a, T: HasInterner> HasInterner for std::slice::Iter<'a, T> {
+ type Interner = T::Interner;
+}