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, Debug)]
19 pub struct InternedWrapper<T>(T);
21 impl<T> std::ops::Deref for InternedWrapper<T> {
24 fn deref(&self) -> &Self::Target {
30 InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>,
31 InternedWrapper<SmallVec<[GenericArg; 2]>>,
32 InternedWrapper<chalk_ir::TyData<Interner>>,
33 InternedWrapper<chalk_ir::LifetimeData<Interner>>,
34 InternedWrapper<chalk_ir::ConstData<Interner>>,
35 InternedWrapper<ConstScalar>,
36 InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
37 InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
38 InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
39 InternedWrapper<Vec<chalk_ir::Variance>>,
42 impl chalk_ir::interner::Interner for Interner {
43 type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
44 type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
45 type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
46 type InternedConcreteConst = ConstScalar;
47 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
48 type InternedGoal = Arc<GoalData<Self>>;
49 type InternedGoals = Vec<Goal<Self>>;
50 type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
51 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
52 type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
53 type InternedQuantifiedWhereClauses =
54 Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
55 type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
56 type InternedCanonicalVarKinds =
57 Interned<InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Self>>>>;
58 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
59 type InternedVariances = Interned<InternedWrapper<Vec<chalk_ir::Variance>>>;
60 type DefId = InternId;
61 type InternedAdtId = hir_def::AdtId;
62 type Identifier = TypeAliasId;
66 type_kind_id: chalk_db::AdtId,
67 fmt: &mut fmt::Formatter<'_>,
68 ) -> Option<fmt::Result> {
69 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
73 type_kind_id: chalk_db::TraitId,
74 fmt: &mut fmt::Formatter<'_>,
75 ) -> Option<fmt::Result> {
76 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
79 fn debug_assoc_type_id(
80 id: chalk_db::AssocTypeId,
81 fmt: &mut fmt::Formatter<'_>,
82 ) -> Option<fmt::Result> {
83 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
87 alias: &chalk_ir::AliasTy<Interner>,
88 fmt: &mut fmt::Formatter<'_>,
89 ) -> Option<fmt::Result> {
90 tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
93 fn debug_projection_ty(
94 proj: &chalk_ir::ProjectionTy<Interner>,
95 fmt: &mut fmt::Formatter<'_>,
96 ) -> Option<fmt::Result> {
97 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
101 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
102 fmt: &mut fmt::Formatter<'_>,
103 ) -> Option<fmt::Result> {
104 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt)))
107 fn debug_opaque_ty_id(
108 opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
109 fmt: &mut fmt::Formatter<'_>,
110 ) -> Option<fmt::Result> {
111 tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt)))
114 fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
115 tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
119 lifetime: &chalk_ir::Lifetime<Interner>,
120 fmt: &mut fmt::Formatter<'_>,
121 ) -> Option<fmt::Result> {
122 tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt)))
125 fn debug_generic_arg(
126 parameter: &GenericArg,
127 fmt: &mut fmt::Formatter<'_>,
128 ) -> Option<fmt::Result> {
129 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
132 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
133 tls::with_current_program(|prog| Some(prog?.debug_goal(goal, fmt)))
137 goals: &chalk_ir::Goals<Interner>,
138 fmt: &mut fmt::Formatter<'_>,
139 ) -> Option<fmt::Result> {
140 tls::with_current_program(|prog| Some(prog?.debug_goals(goals, fmt)))
143 fn debug_program_clause_implication(
144 pci: &chalk_ir::ProgramClauseImplication<Interner>,
145 fmt: &mut fmt::Formatter<'_>,
146 ) -> Option<fmt::Result> {
147 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
150 fn debug_substitution(
151 substitution: &chalk_ir::Substitution<Interner>,
152 fmt: &mut fmt::Formatter<'_>,
153 ) -> Option<fmt::Result> {
154 tls::with_current_program(|prog| Some(prog?.debug_substitution(substitution, fmt)))
157 fn debug_separator_trait_ref(
158 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
159 fmt: &mut fmt::Formatter<'_>,
160 ) -> Option<fmt::Result> {
161 tls::with_current_program(|prog| {
162 Some(prog?.debug_separator_trait_ref(separator_trait_ref, fmt))
167 fn_def_id: chalk_ir::FnDefId<Self>,
168 fmt: &mut fmt::Formatter<'_>,
169 ) -> Option<fmt::Result> {
170 tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
173 constant: &chalk_ir::Const<Self>,
174 fmt: &mut fmt::Formatter<'_>,
175 ) -> Option<fmt::Result> {
176 tls::with_current_program(|prog| Some(prog?.debug_const(constant, fmt)))
178 fn debug_variable_kinds(
179 variable_kinds: &chalk_ir::VariableKinds<Self>,
180 fmt: &mut fmt::Formatter<'_>,
181 ) -> Option<fmt::Result> {
182 tls::with_current_program(|prog| Some(prog?.debug_variable_kinds(variable_kinds, fmt)))
184 fn debug_variable_kinds_with_angles(
185 variable_kinds: &chalk_ir::VariableKinds<Self>,
186 fmt: &mut fmt::Formatter<'_>,
187 ) -> Option<fmt::Result> {
188 tls::with_current_program(|prog| {
189 Some(prog?.debug_variable_kinds_with_angles(variable_kinds, fmt))
192 fn debug_canonical_var_kinds(
193 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
194 fmt: &mut fmt::Formatter<'_>,
195 ) -> Option<fmt::Result> {
196 tls::with_current_program(|prog| {
197 Some(prog?.debug_canonical_var_kinds(canonical_var_kinds, fmt))
200 fn debug_program_clause(
201 clause: &chalk_ir::ProgramClause<Self>,
202 fmt: &mut fmt::Formatter<'_>,
203 ) -> Option<fmt::Result> {
204 tls::with_current_program(|prog| Some(prog?.debug_program_clause(clause, fmt)))
206 fn debug_program_clauses(
207 clauses: &chalk_ir::ProgramClauses<Self>,
208 fmt: &mut fmt::Formatter<'_>,
209 ) -> Option<fmt::Result> {
210 tls::with_current_program(|prog| Some(prog?.debug_program_clauses(clauses, fmt)))
212 fn debug_quantified_where_clauses(
213 clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
214 fmt: &mut fmt::Formatter<'_>,
215 ) -> Option<fmt::Result> {
216 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
219 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
220 let flags = kind.compute_flags(self);
221 Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
224 fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
228 fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
229 Interned::new(InternedWrapper(lifetime))
232 fn lifetime_data<'a>(
234 lifetime: &'a Self::InternedLifetime,
235 ) -> &'a chalk_ir::LifetimeData<Self> {
239 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
240 Interned::new(InternedWrapper(constant))
243 fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
249 _ty: &Self::InternedType,
250 c1: &Self::InternedConcreteConst,
251 c2: &Self::InternedConcreteConst,
254 (&ConstScalar::Usize(a), &ConstScalar::Usize(b)) => a == b,
255 // we were previously assuming this to be true, I'm not whether true or false on
256 // unknown values is safer.
261 fn intern_generic_arg(
263 parameter: chalk_ir::GenericArgData<Self>,
264 ) -> Self::InternedGenericArg {
268 fn generic_arg_data<'a>(
270 parameter: &'a Self::InternedGenericArg,
271 ) -> &'a chalk_ir::GenericArgData<Self> {
275 fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
281 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
282 ) -> Result<Self::InternedGoals, E> {
283 data.into_iter().collect()
286 fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
290 fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
294 fn intern_substitution<E>(
296 data: impl IntoIterator<Item = Result<GenericArg, E>>,
297 ) -> Result<Self::InternedSubstitution, E> {
298 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
301 fn substitution_data<'a>(
303 substitution: &'a Self::InternedSubstitution,
304 ) -> &'a [GenericArg] {
305 &substitution.as_ref().0
308 fn intern_program_clause(
310 data: chalk_ir::ProgramClauseData<Self>,
311 ) -> Self::InternedProgramClause {
315 fn program_clause_data<'a>(
317 clause: &'a Self::InternedProgramClause,
318 ) -> &'a chalk_ir::ProgramClauseData<Self> {
322 fn intern_program_clauses<E>(
324 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
325 ) -> Result<Self::InternedProgramClauses, E> {
326 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
329 fn program_clauses_data<'a>(
331 clauses: &'a Self::InternedProgramClauses,
332 ) -> &'a [chalk_ir::ProgramClause<Self>] {
336 fn intern_quantified_where_clauses<E>(
338 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
339 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
340 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
343 fn quantified_where_clauses_data<'a>(
345 clauses: &'a Self::InternedQuantifiedWhereClauses,
346 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
350 fn intern_generic_arg_kinds<E>(
352 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
353 ) -> Result<Self::InternedVariableKinds, E> {
354 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
357 fn variable_kinds_data<'a>(
359 parameter_kinds: &'a Self::InternedVariableKinds,
360 ) -> &'a [chalk_ir::VariableKind<Self>] {
361 ¶meter_kinds.as_ref().0
364 fn intern_canonical_var_kinds<E>(
366 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
367 ) -> Result<Self::InternedCanonicalVarKinds, E> {
368 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
371 fn canonical_var_kinds_data<'a>(
373 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
374 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
378 fn intern_constraints<E>(
380 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
381 ) -> Result<Self::InternedConstraints, E> {
382 data.into_iter().collect()
385 fn constraints_data<'a>(
387 constraints: &'a Self::InternedConstraints,
388 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
392 _fn_def_id: chalk_ir::ClosureId<Self>,
393 _fmt: &mut fmt::Formatter<'_>,
394 ) -> Option<fmt::Result> {
397 fn debug_constraints(
398 _clauses: &chalk_ir::Constraints<Self>,
399 _fmt: &mut fmt::Formatter<'_>,
400 ) -> Option<fmt::Result> {
404 fn intern_variances<E>(
406 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
407 ) -> Result<Self::InternedVariances, E> {
408 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
411 fn variances_data<'a>(
413 variances: &'a Self::InternedVariances,
414 ) -> &'a [chalk_ir::Variance] {
419 impl chalk_ir::interner::HasInterner for Interner {
420 type Interner = Self;
424 macro_rules! has_interner {
426 impl HasInterner for $t {
427 type Interner = crate::Interner;