1 //! Implementation of the Chalk `Interner` trait, which allows customizing the
2 //! representation of the various objects Chalk deals with (types, goals etc.).
4 use crate::{chalk_db, tls, GenericArg};
5 use base_db::salsa::InternId;
6 use chalk_ir::{Goal, GoalData};
8 intern::{impl_internable, InternStorage, Internable, Interned},
12 use smallvec::SmallVec;
13 use std::{fmt, sync::Arc};
15 #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
18 #[derive(PartialEq, Eq, Hash)]
19 pub struct InternedWrapper<T>(T);
21 impl<T: fmt::Debug> fmt::Debug for InternedWrapper<T> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 fmt::Debug::fmt(&self.0, f)
27 impl<T> std::ops::Deref for InternedWrapper<T> {
30 fn deref(&self) -> &Self::Target {
36 InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>,
37 InternedWrapper<SmallVec<[GenericArg; 2]>>,
38 InternedWrapper<chalk_ir::TyData<Interner>>,
39 InternedWrapper<chalk_ir::LifetimeData<Interner>>,
40 InternedWrapper<chalk_ir::ConstData<Interner>>,
41 InternedWrapper<ConstScalar>,
42 InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
43 InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
44 InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
45 InternedWrapper<Vec<chalk_ir::Variance>>,
48 impl chalk_ir::interner::Interner for Interner {
49 type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
50 type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
51 type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
52 type InternedConcreteConst = ConstScalar;
53 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
54 type InternedGoal = Arc<GoalData<Self>>;
55 type InternedGoals = Vec<Goal<Self>>;
56 type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
57 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
58 type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
59 type InternedQuantifiedWhereClauses =
60 Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
61 type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
62 type InternedCanonicalVarKinds =
63 Interned<InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Self>>>>;
64 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
65 type InternedVariances = Interned<InternedWrapper<Vec<chalk_ir::Variance>>>;
66 type DefId = InternId;
67 type InternedAdtId = hir_def::AdtId;
68 type Identifier = TypeAliasId;
72 type_kind_id: chalk_db::AdtId,
73 fmt: &mut fmt::Formatter<'_>,
74 ) -> Option<fmt::Result> {
75 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
79 type_kind_id: chalk_db::TraitId,
80 fmt: &mut fmt::Formatter<'_>,
81 ) -> Option<fmt::Result> {
82 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
85 fn debug_assoc_type_id(
86 id: chalk_db::AssocTypeId,
87 fmt: &mut fmt::Formatter<'_>,
88 ) -> Option<fmt::Result> {
89 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
93 alias: &chalk_ir::AliasTy<Interner>,
94 fmt: &mut fmt::Formatter<'_>,
95 ) -> Option<fmt::Result> {
98 chalk_ir::AliasTy::Projection(projection_ty) => {
99 Interner::debug_projection_ty(projection_ty, fmt)
101 chalk_ir::AliasTy::Opaque(opaque_ty) => Some(opaque_ty.fmt(fmt)),
105 fn debug_projection_ty(
106 proj: &chalk_ir::ProjectionTy<Interner>,
107 fmt: &mut fmt::Formatter<'_>,
108 ) -> Option<fmt::Result> {
109 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
113 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
114 fmt: &mut fmt::Formatter<'_>,
115 ) -> Option<fmt::Result> {
116 Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
119 fn debug_opaque_ty_id(
120 opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
121 fmt: &mut fmt::Formatter<'_>,
122 ) -> Option<fmt::Result> {
123 Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
126 fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
127 Some(write!(fmt, "{:?}", ty.data(Interner)))
131 lifetime: &chalk_ir::Lifetime<Interner>,
132 fmt: &mut fmt::Formatter<'_>,
133 ) -> Option<fmt::Result> {
134 Some(write!(fmt, "{:?}", lifetime.data(Interner)))
137 fn debug_generic_arg(
138 parameter: &GenericArg,
139 fmt: &mut fmt::Formatter<'_>,
140 ) -> Option<fmt::Result> {
141 Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
144 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
145 let goal_data = goal.data(Interner);
146 Some(write!(fmt, "{:?}", goal_data))
150 goals: &chalk_ir::Goals<Interner>,
151 fmt: &mut fmt::Formatter<'_>,
152 ) -> Option<fmt::Result> {
153 Some(write!(fmt, "{:?}", goals.debug(Interner)))
156 fn debug_program_clause_implication(
157 pci: &chalk_ir::ProgramClauseImplication<Interner>,
158 fmt: &mut fmt::Formatter<'_>,
159 ) -> Option<fmt::Result> {
160 Some(write!(fmt, "{:?}", pci.debug(Interner)))
163 fn debug_substitution(
164 substitution: &chalk_ir::Substitution<Interner>,
165 fmt: &mut fmt::Formatter<'_>,
166 ) -> Option<fmt::Result> {
167 Some(write!(fmt, "{:?}", substitution.debug(Interner)))
170 fn debug_separator_trait_ref(
171 separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Interner>,
172 fmt: &mut fmt::Formatter<'_>,
173 ) -> Option<fmt::Result> {
174 Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
178 fn_def_id: chalk_ir::FnDefId<Self>,
179 fmt: &mut fmt::Formatter<'_>,
180 ) -> Option<fmt::Result> {
181 tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
184 constant: &chalk_ir::Const<Self>,
185 fmt: &mut fmt::Formatter<'_>,
186 ) -> Option<fmt::Result> {
187 Some(write!(fmt, "{:?}", constant.data(Interner)))
189 fn debug_variable_kinds(
190 variable_kinds: &chalk_ir::VariableKinds<Self>,
191 fmt: &mut fmt::Formatter<'_>,
192 ) -> Option<fmt::Result> {
193 Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
195 fn debug_variable_kinds_with_angles(
196 variable_kinds: &chalk_ir::VariableKinds<Self>,
197 fmt: &mut fmt::Formatter<'_>,
198 ) -> Option<fmt::Result> {
199 Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
201 fn debug_canonical_var_kinds(
202 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
203 fmt: &mut fmt::Formatter<'_>,
204 ) -> Option<fmt::Result> {
205 Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
207 fn debug_program_clause(
208 clause: &chalk_ir::ProgramClause<Self>,
209 fmt: &mut fmt::Formatter<'_>,
210 ) -> Option<fmt::Result> {
211 Some(write!(fmt, "{:?}", clause.data(Interner)))
213 fn debug_program_clauses(
214 clauses: &chalk_ir::ProgramClauses<Self>,
215 fmt: &mut fmt::Formatter<'_>,
216 ) -> Option<fmt::Result> {
217 Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
219 fn debug_quantified_where_clauses(
220 clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
221 fmt: &mut fmt::Formatter<'_>,
222 ) -> Option<fmt::Result> {
223 Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
226 fn intern_ty(self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
227 let flags = kind.compute_flags(self);
228 Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
231 fn ty_data<'a>(self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
235 fn intern_lifetime(self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
236 Interned::new(InternedWrapper(lifetime))
239 fn lifetime_data<'a>(
241 lifetime: &'a Self::InternedLifetime,
242 ) -> &'a chalk_ir::LifetimeData<Self> {
246 fn intern_const(self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
247 Interned::new(InternedWrapper(constant))
250 fn const_data<'a>(self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
256 _ty: &Self::InternedType,
257 c1: &Self::InternedConcreteConst,
258 c2: &Self::InternedConcreteConst,
260 (c1 == &ConstScalar::Unknown) || (c2 == &ConstScalar::Unknown) || (c1 == c2)
263 fn intern_generic_arg(
265 parameter: chalk_ir::GenericArgData<Self>,
266 ) -> Self::InternedGenericArg {
270 fn generic_arg_data<'a>(
272 parameter: &'a Self::InternedGenericArg,
273 ) -> &'a chalk_ir::GenericArgData<Self> {
277 fn intern_goal(self, goal: GoalData<Self>) -> Self::InternedGoal {
283 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
284 ) -> Result<Self::InternedGoals, E> {
285 data.into_iter().collect()
288 fn goal_data<'a>(self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
292 fn goals_data<'a>(self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
296 fn intern_substitution<E>(
298 data: impl IntoIterator<Item = Result<GenericArg, E>>,
299 ) -> Result<Self::InternedSubstitution, E> {
300 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
303 fn substitution_data<'a>(
305 substitution: &'a Self::InternedSubstitution,
306 ) -> &'a [GenericArg] {
307 &substitution.as_ref().0
310 fn intern_program_clause(
312 data: chalk_ir::ProgramClauseData<Self>,
313 ) -> Self::InternedProgramClause {
317 fn program_clause_data<'a>(
319 clause: &'a Self::InternedProgramClause,
320 ) -> &'a chalk_ir::ProgramClauseData<Self> {
324 fn intern_program_clauses<E>(
326 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
327 ) -> Result<Self::InternedProgramClauses, E> {
328 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
331 fn program_clauses_data<'a>(
333 clauses: &'a Self::InternedProgramClauses,
334 ) -> &'a [chalk_ir::ProgramClause<Self>] {
338 fn intern_quantified_where_clauses<E>(
340 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
341 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
342 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
345 fn quantified_where_clauses_data<'a>(
347 clauses: &'a Self::InternedQuantifiedWhereClauses,
348 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
352 fn intern_generic_arg_kinds<E>(
354 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
355 ) -> Result<Self::InternedVariableKinds, E> {
356 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
359 fn variable_kinds_data<'a>(
361 parameter_kinds: &'a Self::InternedVariableKinds,
362 ) -> &'a [chalk_ir::VariableKind<Self>] {
363 ¶meter_kinds.as_ref().0
366 fn intern_canonical_var_kinds<E>(
368 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
369 ) -> Result<Self::InternedCanonicalVarKinds, E> {
370 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
373 fn canonical_var_kinds_data<'a>(
375 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
376 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
380 fn intern_constraints<E>(
382 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
383 ) -> Result<Self::InternedConstraints, E> {
384 data.into_iter().collect()
387 fn constraints_data<'a>(
389 constraints: &'a Self::InternedConstraints,
390 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
394 _fn_def_id: chalk_ir::ClosureId<Self>,
395 _fmt: &mut fmt::Formatter<'_>,
396 ) -> Option<fmt::Result> {
399 fn debug_constraints(
400 _clauses: &chalk_ir::Constraints<Self>,
401 _fmt: &mut fmt::Formatter<'_>,
402 ) -> Option<fmt::Result> {
406 fn intern_variances<E>(
408 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
409 ) -> Result<Self::InternedVariances, E> {
410 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
413 fn variances_data<'a>(
415 variances: &'a Self::InternedVariances,
416 ) -> &'a [chalk_ir::Variance] {
421 impl chalk_ir::interner::HasInterner for Interner {
422 type Interner = Self;
426 macro_rules! has_interner {
428 impl HasInterner for $t {
429 type Interner = crate::Interner;