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> {
96 tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
99 fn debug_projection_ty(
100 proj: &chalk_ir::ProjectionTy<Interner>,
101 fmt: &mut fmt::Formatter<'_>,
102 ) -> Option<fmt::Result> {
103 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
107 opaque_ty: &chalk_ir::OpaqueTy<Interner>,
108 fmt: &mut fmt::Formatter<'_>,
109 ) -> Option<fmt::Result> {
110 Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
113 fn debug_opaque_ty_id(
114 opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
115 fmt: &mut fmt::Formatter<'_>,
116 ) -> Option<fmt::Result> {
117 Some(fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish())
120 fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
121 Some(write!(fmt, "{:?}", ty.data(&Interner)))
125 lifetime: &chalk_ir::Lifetime<Interner>,
126 fmt: &mut fmt::Formatter<'_>,
127 ) -> Option<fmt::Result> {
128 Some(write!(fmt, "{:?}", lifetime.data(&Interner)))
131 fn debug_generic_arg(
132 parameter: &GenericArg,
133 fmt: &mut fmt::Formatter<'_>,
134 ) -> Option<fmt::Result> {
135 Some(write!(fmt, "{:?}", parameter.data(&Interner).inner_debug()))
138 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
139 let goal_data = goal.data(&Interner);
140 Some(write!(fmt, "{:?}", goal_data))
144 goals: &chalk_ir::Goals<Interner>,
145 fmt: &mut fmt::Formatter<'_>,
146 ) -> Option<fmt::Result> {
147 Some(write!(fmt, "{:?}", goals.debug(&Interner)))
150 fn debug_program_clause_implication(
151 pci: &chalk_ir::ProgramClauseImplication<Interner>,
152 fmt: &mut fmt::Formatter<'_>,
153 ) -> Option<fmt::Result> {
154 Some(write!(fmt, "{:?}", pci.debug(&Interner)))
157 fn debug_substitution(
158 substitution: &chalk_ir::Substitution<Interner>,
159 fmt: &mut fmt::Formatter<'_>,
160 ) -> Option<fmt::Result> {
161 Some(write!(fmt, "{:?}", substitution.debug(&Interner)))
164 fn debug_separator_trait_ref(
165 separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
166 fmt: &mut fmt::Formatter<'_>,
167 ) -> Option<fmt::Result> {
168 Some(write!(fmt, "{:?}", separator_trait_ref.debug(&Interner)))
172 fn_def_id: chalk_ir::FnDefId<Self>,
173 fmt: &mut fmt::Formatter<'_>,
174 ) -> Option<fmt::Result> {
175 tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
178 constant: &chalk_ir::Const<Self>,
179 fmt: &mut fmt::Formatter<'_>,
180 ) -> Option<fmt::Result> {
181 Some(write!(fmt, "{:?}", constant.data(&Interner)))
183 fn debug_variable_kinds(
184 variable_kinds: &chalk_ir::VariableKinds<Self>,
185 fmt: &mut fmt::Formatter<'_>,
186 ) -> Option<fmt::Result> {
187 Some(write!(fmt, "{:?}", variable_kinds.as_slice(&Interner)))
189 fn debug_variable_kinds_with_angles(
190 variable_kinds: &chalk_ir::VariableKinds<Self>,
191 fmt: &mut fmt::Formatter<'_>,
192 ) -> Option<fmt::Result> {
193 Some(write!(fmt, "{:?}", variable_kinds.inner_debug(&Interner)))
195 fn debug_canonical_var_kinds(
196 canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
197 fmt: &mut fmt::Formatter<'_>,
198 ) -> Option<fmt::Result> {
199 Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(&Interner)))
201 fn debug_program_clause(
202 clause: &chalk_ir::ProgramClause<Self>,
203 fmt: &mut fmt::Formatter<'_>,
204 ) -> Option<fmt::Result> {
205 Some(write!(fmt, "{:?}", clause.data(&Interner)))
207 fn debug_program_clauses(
208 clauses: &chalk_ir::ProgramClauses<Self>,
209 fmt: &mut fmt::Formatter<'_>,
210 ) -> Option<fmt::Result> {
211 Some(write!(fmt, "{:?}", clauses.as_slice(&Interner)))
213 fn debug_quantified_where_clauses(
214 clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
215 fmt: &mut fmt::Formatter<'_>,
216 ) -> Option<fmt::Result> {
217 Some(write!(fmt, "{:?}", clauses.as_slice(&Interner)))
220 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
221 let flags = kind.compute_flags(self);
222 Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
225 fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
229 fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
230 Interned::new(InternedWrapper(lifetime))
233 fn lifetime_data<'a>(
235 lifetime: &'a Self::InternedLifetime,
236 ) -> &'a chalk_ir::LifetimeData<Self> {
240 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
241 Interned::new(InternedWrapper(constant))
244 fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
250 _ty: &Self::InternedType,
251 c1: &Self::InternedConcreteConst,
252 c2: &Self::InternedConcreteConst,
255 (&ConstScalar::Usize(a), &ConstScalar::Usize(b)) => a == b,
256 // we were previously assuming this to be true, I'm not whether true or false on
257 // unknown values is safer.
262 fn intern_generic_arg(
264 parameter: chalk_ir::GenericArgData<Self>,
265 ) -> Self::InternedGenericArg {
269 fn generic_arg_data<'a>(
271 parameter: &'a Self::InternedGenericArg,
272 ) -> &'a chalk_ir::GenericArgData<Self> {
276 fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
282 data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
283 ) -> Result<Self::InternedGoals, E> {
284 data.into_iter().collect()
287 fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
291 fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
295 fn intern_substitution<E>(
297 data: impl IntoIterator<Item = Result<GenericArg, E>>,
298 ) -> Result<Self::InternedSubstitution, E> {
299 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
302 fn substitution_data<'a>(
304 substitution: &'a Self::InternedSubstitution,
305 ) -> &'a [GenericArg] {
306 &substitution.as_ref().0
309 fn intern_program_clause(
311 data: chalk_ir::ProgramClauseData<Self>,
312 ) -> Self::InternedProgramClause {
316 fn program_clause_data<'a>(
318 clause: &'a Self::InternedProgramClause,
319 ) -> &'a chalk_ir::ProgramClauseData<Self> {
323 fn intern_program_clauses<E>(
325 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
326 ) -> Result<Self::InternedProgramClauses, E> {
327 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
330 fn program_clauses_data<'a>(
332 clauses: &'a Self::InternedProgramClauses,
333 ) -> &'a [chalk_ir::ProgramClause<Self>] {
337 fn intern_quantified_where_clauses<E>(
339 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
340 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
341 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
344 fn quantified_where_clauses_data<'a>(
346 clauses: &'a Self::InternedQuantifiedWhereClauses,
347 ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
351 fn intern_generic_arg_kinds<E>(
353 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
354 ) -> Result<Self::InternedVariableKinds, E> {
355 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
358 fn variable_kinds_data<'a>(
360 parameter_kinds: &'a Self::InternedVariableKinds,
361 ) -> &'a [chalk_ir::VariableKind<Self>] {
362 ¶meter_kinds.as_ref().0
365 fn intern_canonical_var_kinds<E>(
367 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
368 ) -> Result<Self::InternedCanonicalVarKinds, E> {
369 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
372 fn canonical_var_kinds_data<'a>(
374 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
375 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
379 fn intern_constraints<E>(
381 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
382 ) -> Result<Self::InternedConstraints, E> {
383 data.into_iter().collect()
386 fn constraints_data<'a>(
388 constraints: &'a Self::InternedConstraints,
389 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
393 _fn_def_id: chalk_ir::ClosureId<Self>,
394 _fmt: &mut fmt::Formatter<'_>,
395 ) -> Option<fmt::Result> {
398 fn debug_constraints(
399 _clauses: &chalk_ir::Constraints<Self>,
400 _fmt: &mut fmt::Formatter<'_>,
401 ) -> Option<fmt::Result> {
405 fn intern_variances<E>(
407 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
408 ) -> Result<Self::InternedVariances, E> {
409 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
412 fn variances_data<'a>(
414 variances: &'a Self::InternedVariances,
415 ) -> &'a [chalk_ir::Variance] {
420 impl chalk_ir::interner::HasInterner for Interner {
421 type Interner = Self;
425 macro_rules! has_interner {
427 impl HasInterner for $t {
428 type Interner = crate::Interner;