1use crate::{
5 AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData, ConstScalar, FnAbi,
6 FnDefId, GenericArg, GenericArgData, Goal, GoalData, InEnvironment, Lifetime, LifetimeData,
7 OpaqueTy, OpaqueTyId, ProgramClause, ProjectionTy, QuantifiedWhereClause,
8 QuantifiedWhereClauses, Substitution, Ty, TyKind, VariableKind, chalk_db, tls,
9};
10use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variance};
11use hir_def::TypeAliasId;
12use intern::{Interned, impl_internable};
13use smallvec::SmallVec;
14use std::fmt;
15use triomphe::Arc;
16
17type TyData = chalk_ir::TyData<Interner>;
18type VariableKinds = chalk_ir::VariableKinds<Interner>;
19type Goals = chalk_ir::Goals<Interner>;
20type ProgramClauseData = chalk_ir::ProgramClauseData<Interner>;
21type Constraint = chalk_ir::Constraint<Interner>;
22type Constraints = chalk_ir::Constraints<Interner>;
23type ProgramClauses = chalk_ir::ProgramClauses<Interner>;
24
25#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
26pub struct Interner;
27
28#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
29pub struct InternedWrapper<T>(pub(crate) T);
30
31impl<T: fmt::Debug> fmt::Debug for InternedWrapper<T> {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 fmt::Debug::fmt(&self.0, f)
34 }
35}
36
37#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
38pub struct InternedWrapperNoDebug<T>(pub(crate) T);
39
40impl<T> std::ops::Deref for InternedWrapper<T> {
41 type Target = T;
42
43 fn deref(&self) -> &Self::Target {
44 &self.0
45 }
46}
47
48impl_internable!(
49 InternedWrapper<Vec<VariableKind>>,
50 InternedWrapper<SmallVec<[GenericArg; 2]>>,
51 InternedWrapper<TyData>,
52 InternedWrapper<LifetimeData>,
53 InternedWrapper<ConstData>,
54 InternedWrapper<ConstScalar>,
55 InternedWrapper<Vec<CanonicalVarKind>>,
56 InternedWrapper<Box<[ProgramClause]>>,
57 InternedWrapper<Vec<QuantifiedWhereClause>>,
58 InternedWrapper<SmallVec<[Variance; 16]>>,
59);
60
61impl chalk_ir::interner::Interner for Interner {
62 type InternedType = Interned<InternedWrapper<TyData>>;
63 type InternedLifetime = Interned<InternedWrapper<LifetimeData>>;
64 type InternedConst = Interned<InternedWrapper<ConstData>>;
65 type InternedConcreteConst = ConstScalar;
66 type InternedGenericArg = GenericArgData;
67 type InternedGoal = Arc<GoalData>;
71 type InternedGoals = Vec<Goal>;
72 type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
73 type InternedProgramClauses = Interned<InternedWrapper<Box<[ProgramClause]>>>;
74 type InternedProgramClause = ProgramClauseData;
75 type InternedQuantifiedWhereClauses = Interned<InternedWrapper<Vec<QuantifiedWhereClause>>>;
76 type InternedVariableKinds = Interned<InternedWrapper<Vec<VariableKind>>>;
77 type InternedCanonicalVarKinds = Interned<InternedWrapper<Vec<CanonicalVarKind>>>;
78 type InternedConstraints = Vec<InEnvironment<Constraint>>;
79 type InternedVariances = SmallVec<[Variance; 16]>;
80 type DefId = salsa::Id;
81 type InternedAdtId = hir_def::AdtId;
82 type Identifier = TypeAliasId;
83 type FnAbi = FnAbi;
84
85 fn debug_adt_id(
86 type_kind_id: chalk_db::AdtId,
87 fmt: &mut fmt::Formatter<'_>,
88 ) -> Option<fmt::Result> {
89 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
90 }
91
92 fn debug_trait_id(
93 type_kind_id: chalk_db::TraitId,
94 fmt: &mut fmt::Formatter<'_>,
95 ) -> Option<fmt::Result> {
96 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
97 }
98
99 fn debug_assoc_type_id(
100 id: chalk_db::AssocTypeId,
101 fmt: &mut fmt::Formatter<'_>,
102 ) -> Option<fmt::Result> {
103 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
104 }
105
106 fn debug_opaque_ty_id(
107 opaque_ty_id: OpaqueTyId,
108 fmt: &mut fmt::Formatter<'_>,
109 ) -> Option<fmt::Result> {
110 Some(write!(fmt, "OpaqueTy#{:?}", opaque_ty_id.0))
111 }
112
113 fn debug_fn_def_id(fn_def_id: FnDefId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
114 tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
115 }
116
117 fn debug_closure_id(
118 _fn_def_id: ClosureId,
119 _fmt: &mut fmt::Formatter<'_>,
120 ) -> Option<fmt::Result> {
121 None
122 }
123
124 fn debug_alias(alias: &AliasTy, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
125 use std::fmt::Debug;
126 match alias {
127 AliasTy::Projection(projection_ty) => Interner::debug_projection_ty(projection_ty, fmt),
128 AliasTy::Opaque(opaque_ty) => Some(opaque_ty.fmt(fmt)),
129 }
130 }
131
132 fn debug_projection_ty(
133 proj: &ProjectionTy,
134 fmt: &mut fmt::Formatter<'_>,
135 ) -> Option<fmt::Result> {
136 tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
137 .or_else(|| Some(fmt.write_str("ProjectionTy")))
138 }
139
140 fn debug_opaque_ty(opaque_ty: &OpaqueTy, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
141 Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
142 }
143
144 fn debug_ty(ty: &Ty, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
145 Some(write!(fmt, "{:?}", ty.data(Interner)))
146 }
147
148 fn debug_lifetime(lifetime: &Lifetime, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
149 Some(write!(fmt, "{:?}", lifetime.data(Interner)))
150 }
151
152 fn debug_const(constant: &Const, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
153 Some(write!(fmt, "{:?}", constant.data(Interner)))
154 }
155
156 fn debug_generic_arg(
157 parameter: &GenericArg,
158 fmt: &mut fmt::Formatter<'_>,
159 ) -> Option<fmt::Result> {
160 Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
161 }
162
163 fn debug_variable_kinds(
164 variable_kinds: &VariableKinds,
165 fmt: &mut fmt::Formatter<'_>,
166 ) -> Option<fmt::Result> {
167 Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
168 }
169
170 fn debug_variable_kinds_with_angles(
171 variable_kinds: &VariableKinds,
172 fmt: &mut fmt::Formatter<'_>,
173 ) -> Option<fmt::Result> {
174 Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
175 }
176
177 fn debug_canonical_var_kinds(
178 canonical_var_kinds: &CanonicalVarKinds,
179 fmt: &mut fmt::Formatter<'_>,
180 ) -> Option<fmt::Result> {
181 Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
182 }
183 fn debug_goal(goal: &Goal, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
184 let goal_data = goal.data(Interner);
185 Some(write!(fmt, "{goal_data:?}"))
186 }
187 fn debug_goals(goals: &Goals, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
188 Some(write!(fmt, "{:?}", goals.debug(Interner)))
189 }
190 fn debug_program_clause_implication(
191 pci: &ProgramClauseImplication<Self>,
192 fmt: &mut fmt::Formatter<'_>,
193 ) -> Option<fmt::Result> {
194 Some(write!(fmt, "{:?}", pci.debug(Interner)))
195 }
196 fn debug_program_clause(
197 clause: &ProgramClause,
198 fmt: &mut fmt::Formatter<'_>,
199 ) -> Option<fmt::Result> {
200 Some(write!(fmt, "{:?}", clause.data(Interner)))
201 }
202 fn debug_program_clauses(
203 clauses: &ProgramClauses,
204 fmt: &mut fmt::Formatter<'_>,
205 ) -> Option<fmt::Result> {
206 Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
207 }
208 fn debug_substitution(
209 substitution: &Substitution,
210 fmt: &mut fmt::Formatter<'_>,
211 ) -> Option<fmt::Result> {
212 Some(write!(fmt, "{:?}", substitution.debug(Interner)))
213 }
214 fn debug_separator_trait_ref(
215 separator_trait_ref: &SeparatorTraitRef<'_, Interner>,
216 fmt: &mut fmt::Formatter<'_>,
217 ) -> Option<fmt::Result> {
218 Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
219 }
220
221 fn debug_quantified_where_clauses(
222 clauses: &QuantifiedWhereClauses,
223 fmt: &mut fmt::Formatter<'_>,
224 ) -> Option<fmt::Result> {
225 Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
226 }
227
228 fn debug_constraints(
229 _clauses: &Constraints,
230 _fmt: &mut fmt::Formatter<'_>,
231 ) -> Option<fmt::Result> {
232 None
233 }
234
235 fn intern_ty(self, kind: TyKind) -> Self::InternedType {
236 let flags = kind.compute_flags(self);
237 Interned::new(InternedWrapper(TyData { kind, flags }))
238 }
239
240 fn ty_data(self, ty: &Self::InternedType) -> &TyData {
241 &ty.0
242 }
243
244 fn intern_lifetime(self, lifetime: LifetimeData) -> Self::InternedLifetime {
245 Interned::new(InternedWrapper(lifetime))
246 }
247
248 fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &LifetimeData {
249 &lifetime.0
250 }
251
252 fn intern_const(self, constant: ConstData) -> Self::InternedConst {
253 Interned::new(InternedWrapper(constant))
254 }
255
256 fn const_data(self, constant: &Self::InternedConst) -> &ConstData {
257 &constant.0
258 }
259
260 fn const_eq(
261 self,
262 _ty: &Self::InternedType,
263 c1: &Self::InternedConcreteConst,
264 c2: &Self::InternedConcreteConst,
265 ) -> bool {
266 !matches!(c1, ConstScalar::Bytes(..)) || !matches!(c2, ConstScalar::Bytes(..)) || (c1 == c2)
267 }
268
269 fn intern_generic_arg(self, parameter: GenericArgData) -> Self::InternedGenericArg {
270 parameter
271 }
272
273 fn generic_arg_data(self, parameter: &Self::InternedGenericArg) -> &GenericArgData {
274 parameter
275 }
276
277 fn intern_goal(self, goal: GoalData) -> Self::InternedGoal {
278 Arc::new(goal)
279 }
280
281 fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData {
282 goal
283 }
284
285 fn intern_goals<E>(
286 self,
287 data: impl IntoIterator<Item = Result<Goal, E>>,
288 ) -> Result<Self::InternedGoals, E> {
289 data.into_iter().collect()
293 }
294
295 fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal] {
296 goals
297 }
298
299 fn intern_substitution<E>(
300 self,
301 data: impl IntoIterator<Item = Result<GenericArg, E>>,
302 ) -> Result<Self::InternedSubstitution, E> {
303 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
304 }
305
306 fn substitution_data(self, substitution: &Self::InternedSubstitution) -> &[GenericArg] {
307 &substitution.as_ref().0
308 }
309
310 fn intern_program_clause(self, data: ProgramClauseData) -> Self::InternedProgramClause {
311 data
312 }
313
314 fn program_clause_data(self, clause: &Self::InternedProgramClause) -> &ProgramClauseData {
315 clause
316 }
317
318 fn intern_program_clauses<E>(
319 self,
320 data: impl IntoIterator<Item = Result<ProgramClause, E>>,
321 ) -> Result<Self::InternedProgramClauses, E> {
322 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
323 }
324
325 fn program_clauses_data(self, clauses: &Self::InternedProgramClauses) -> &[ProgramClause] {
326 clauses
327 }
328
329 fn intern_quantified_where_clauses<E>(
330 self,
331 data: impl IntoIterator<Item = Result<QuantifiedWhereClause, E>>,
332 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
333 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
334 }
335
336 fn quantified_where_clauses_data(
337 self,
338 clauses: &Self::InternedQuantifiedWhereClauses,
339 ) -> &[QuantifiedWhereClause] {
340 clauses
341 }
342
343 fn intern_generic_arg_kinds<E>(
344 self,
345 data: impl IntoIterator<Item = Result<VariableKind, E>>,
346 ) -> Result<Self::InternedVariableKinds, E> {
347 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
348 }
349
350 fn variable_kinds_data(self, parameter_kinds: &Self::InternedVariableKinds) -> &[VariableKind] {
351 ¶meter_kinds.as_ref().0
352 }
353
354 fn intern_canonical_var_kinds<E>(
355 self,
356 data: impl IntoIterator<Item = Result<CanonicalVarKind, E>>,
357 ) -> Result<Self::InternedCanonicalVarKinds, E> {
358 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
359 }
360
361 fn canonical_var_kinds_data(
362 self,
363 canonical_var_kinds: &Self::InternedCanonicalVarKinds,
364 ) -> &[CanonicalVarKind] {
365 canonical_var_kinds
366 }
367 fn intern_constraints<E>(
368 self,
369 data: impl IntoIterator<Item = Result<InEnvironment<Constraint>, E>>,
370 ) -> Result<Self::InternedConstraints, E> {
371 data.into_iter().collect()
372 }
373 fn constraints_data(
374 self,
375 constraints: &Self::InternedConstraints,
376 ) -> &[InEnvironment<Constraint>] {
377 constraints
378 }
379
380 fn intern_variances<E>(
381 self,
382 data: impl IntoIterator<Item = Result<Variance, E>>,
383 ) -> Result<Self::InternedVariances, E> {
384 data.into_iter().collect::<Result<_, _>>()
385 }
386
387 fn variances_data(self, variances: &Self::InternedVariances) -> &[Variance] {
388 variances
389 }
390}
391
392impl chalk_ir::interner::HasInterner for Interner {
393 type Interner = Self;
394}
395
396#[macro_export]
397macro_rules! has_interner {
398 ($t:ty) => {
399 impl HasInterner for $t {
400 type Interner = $crate::Interner;
401 }
402 };
403}