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},
11 use smallvec::SmallVec;
12 use std::{fmt, sync::Arc};
14 #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
17 #[derive(PartialEq, Eq, Hash, Debug)]
18 pub struct InternedWrapper<T>(T);
20 impl<T> std::ops::Deref for InternedWrapper<T> {
23 fn deref(&self) -> &Self::Target {
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>>,
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;
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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)))
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))
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)))
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)))
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)))
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))
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))
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)))
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)))
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)))
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 }))
222 fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
226 fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
227 Interned::new(InternedWrapper(lifetime))
230 fn lifetime_data<'a>(
232 lifetime: &'a Self::InternedLifetime,
233 ) -> &'a chalk_ir::LifetimeData<Self> {
237 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
238 Interned::new(InternedWrapper(constant))
241 fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
247 _ty: &Self::InternedType,
248 _c1: &Self::InternedConcreteConst,
249 _c2: &Self::InternedConcreteConst,
254 fn intern_generic_arg(
256 parameter: chalk_ir::GenericArgData<Self>,
257 ) -> Self::InternedGenericArg {
261 fn generic_arg_data<'a>(
263 parameter: &'a Self::InternedGenericArg,
264 ) -> &'a chalk_ir::GenericArgData<Self> {
268 fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
274 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
275 ) -> Result<Self::InternedGoals, E> {
276 data.into_iter().collect()
279 fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
283 fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
287 fn intern_substitution<E>(
289 data: impl IntoIterator<Item = Result<GenericArg, E>>,
290 ) -> Result<Self::InternedSubstitution, E> {
291 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
294 fn substitution_data<'a>(
296 substitution: &'a Self::InternedSubstitution,
297 ) -> &'a [GenericArg] {
298 &substitution.as_ref().0
301 fn intern_program_clause(
303 data: chalk_ir::ProgramClauseData<Self>,
304 ) -> Self::InternedProgramClause {
308 fn program_clause_data<'a>(
310 clause: &'a Self::InternedProgramClause,
311 ) -> &'a chalk_ir::ProgramClauseData<Self> {
315 fn intern_program_clauses<E>(
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<_, _>>()?)))
322 fn program_clauses_data<'a>(
324 clauses: &'a Self::InternedProgramClauses,
325 ) -> &'a [chalk_ir::ProgramClause<Self>] {
329 fn intern_quantified_where_clauses<E>(
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<_, _>>()?)))
336 fn quantified_where_clauses_data<'a>(
338 clauses: &'a Self::InternedQuantifiedWhereClauses,
339 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
343 fn intern_generic_arg_kinds<E>(
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<_, _>>()?)))
350 fn variable_kinds_data<'a>(
352 parameter_kinds: &'a Self::InternedVariableKinds,
353 ) -> &'a [chalk_ir::VariableKind<Self>] {
354 ¶meter_kinds.as_ref().0
357 fn intern_canonical_var_kinds<E>(
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<_, _>>()?)))
364 fn canonical_var_kinds_data<'a>(
366 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
367 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
371 fn intern_constraints<E>(
373 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
374 ) -> Result<Self::InternedConstraints, E> {
375 data.into_iter().collect()
378 fn constraints_data<'a>(
380 constraints: &'a Self::InternedConstraints,
381 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
385 _fn_def_id: chalk_ir::ClosureId<Self>,
386 _fmt: &mut fmt::Formatter<'_>,
387 ) -> Option<fmt::Result> {
390 fn debug_constraints(
391 _clauses: &chalk_ir::Constraints<Self>,
392 _fmt: &mut fmt::Formatter<'_>,
393 ) -> Option<fmt::Result> {
397 fn intern_variances<E>(
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<_, _>>()?)))
404 fn variances_data<'a>(
406 variances: &'a Self::InternedVariances,
407 ) -> &'a [chalk_ir::Variance] {
412 impl chalk_ir::interner::HasInterner for Interner {
413 type Interner = Self;