]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/interner.rs
Add lowering of array lengths in types
[rust.git] / crates / hir_ty / src / interner.rs
1 //! Implementation of the Chalk `Interner` trait, which allows customizing the
2 //! representation of the various objects Chalk deals with (types, goals etc.).
3
4 use crate::{chalk_db, tls, GenericArg};
5 use base_db::salsa::InternId;
6 use chalk_ir::{Goal, GoalData};
7 use hir_def::{
8     intern::{impl_internable, InternStorage, Internable, Interned},
9     type_ref::ConstScalar,
10     TypeAliasId,
11 };
12 use smallvec::SmallVec;
13 use std::{fmt, sync::Arc};
14
15 #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
16 pub struct Interner;
17
18 #[derive(PartialEq, Eq, Hash, Debug)]
19 pub struct InternedWrapper<T>(T);
20
21 impl<T> std::ops::Deref for InternedWrapper<T> {
22     type Target = T;
23
24     fn deref(&self) -> &Self::Target {
25         &self.0
26     }
27 }
28
29 impl_internable!(
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>>,
40 );
41
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;
63     type FnAbi = ();
64
65     fn debug_adt_id(
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)))
70     }
71
72     fn debug_trait_id(
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)))
77     }
78
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)))
84     }
85
86     fn debug_alias(
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)))
91     }
92
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)))
98     }
99
100     fn debug_opaque_ty(
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)))
105     }
106
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)))
112     }
113
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)))
116     }
117
118     fn debug_lifetime(
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)))
123     }
124
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)))
130     }
131
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)))
134     }
135
136     fn debug_goals(
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)))
141     }
142
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)))
148     }
149
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)))
155     }
156
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))
163         })
164     }
165
166     fn debug_fn_def_id(
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)))
171     }
172     fn debug_const(
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)))
177     }
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)))
183     }
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))
190         })
191     }
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))
198         })
199     }
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)))
205     }
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)))
211     }
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)))
217     }
218
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 }))
222     }
223
224     fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
225         &ty.0
226     }
227
228     fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
229         Interned::new(InternedWrapper(lifetime))
230     }
231
232     fn lifetime_data<'a>(
233         &self,
234         lifetime: &'a Self::InternedLifetime,
235     ) -> &'a chalk_ir::LifetimeData<Self> {
236         &lifetime.0
237     }
238
239     fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
240         Interned::new(InternedWrapper(constant))
241     }
242
243     fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
244         &constant.0
245     }
246
247     fn const_eq(
248         &self,
249         _ty: &Self::InternedType,
250         c1: &Self::InternedConcreteConst,
251         c2: &Self::InternedConcreteConst,
252     ) -> bool {
253         match (c1, c2) {
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.
257             (_, _) => true,
258         }
259     }
260
261     fn intern_generic_arg(
262         &self,
263         parameter: chalk_ir::GenericArgData<Self>,
264     ) -> Self::InternedGenericArg {
265         parameter
266     }
267
268     fn generic_arg_data<'a>(
269         &self,
270         parameter: &'a Self::InternedGenericArg,
271     ) -> &'a chalk_ir::GenericArgData<Self> {
272         parameter
273     }
274
275     fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
276         Arc::new(goal)
277     }
278
279     fn intern_goals<E>(
280         &self,
281         data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
282     ) -> Result<Self::InternedGoals, E> {
283         data.into_iter().collect()
284     }
285
286     fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
287         goal
288     }
289
290     fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
291         goals
292     }
293
294     fn intern_substitution<E>(
295         &self,
296         data: impl IntoIterator<Item = Result<GenericArg, E>>,
297     ) -> Result<Self::InternedSubstitution, E> {
298         Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
299     }
300
301     fn substitution_data<'a>(
302         &self,
303         substitution: &'a Self::InternedSubstitution,
304     ) -> &'a [GenericArg] {
305         &substitution.as_ref().0
306     }
307
308     fn intern_program_clause(
309         &self,
310         data: chalk_ir::ProgramClauseData<Self>,
311     ) -> Self::InternedProgramClause {
312         data
313     }
314
315     fn program_clause_data<'a>(
316         &self,
317         clause: &'a Self::InternedProgramClause,
318     ) -> &'a chalk_ir::ProgramClauseData<Self> {
319         clause
320     }
321
322     fn intern_program_clauses<E>(
323         &self,
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<_, _>>()?)))
327     }
328
329     fn program_clauses_data<'a>(
330         &self,
331         clauses: &'a Self::InternedProgramClauses,
332     ) -> &'a [chalk_ir::ProgramClause<Self>] {
333         &clauses
334     }
335
336     fn intern_quantified_where_clauses<E>(
337         &self,
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<_, _>>()?)))
341     }
342
343     fn quantified_where_clauses_data<'a>(
344         &self,
345         clauses: &'a Self::InternedQuantifiedWhereClauses,
346     ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
347         clauses
348     }
349
350     fn intern_generic_arg_kinds<E>(
351         &self,
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<_, _>>()?)))
355     }
356
357     fn variable_kinds_data<'a>(
358         &self,
359         parameter_kinds: &'a Self::InternedVariableKinds,
360     ) -> &'a [chalk_ir::VariableKind<Self>] {
361         &parameter_kinds.as_ref().0
362     }
363
364     fn intern_canonical_var_kinds<E>(
365         &self,
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<_, _>>()?)))
369     }
370
371     fn canonical_var_kinds_data<'a>(
372         &self,
373         canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
374     ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
375         &canonical_var_kinds
376     }
377
378     fn intern_constraints<E>(
379         &self,
380         data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
381     ) -> Result<Self::InternedConstraints, E> {
382         data.into_iter().collect()
383     }
384
385     fn constraints_data<'a>(
386         &self,
387         constraints: &'a Self::InternedConstraints,
388     ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
389         constraints
390     }
391     fn debug_closure_id(
392         _fn_def_id: chalk_ir::ClosureId<Self>,
393         _fmt: &mut fmt::Formatter<'_>,
394     ) -> Option<fmt::Result> {
395         None
396     }
397     fn debug_constraints(
398         _clauses: &chalk_ir::Constraints<Self>,
399         _fmt: &mut fmt::Formatter<'_>,
400     ) -> Option<fmt::Result> {
401         None
402     }
403
404     fn intern_variances<E>(
405         &self,
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<_, _>>()?)))
409     }
410
411     fn variances_data<'a>(
412         &self,
413         variances: &'a Self::InternedVariances,
414     ) -> &'a [chalk_ir::Variance] {
415         &variances
416     }
417 }
418
419 impl chalk_ir::interner::HasInterner for Interner {
420     type Interner = Self;
421 }
422
423 #[macro_export]
424 macro_rules! has_interner {
425     ($t:ty) => {
426         impl HasInterner for $t {
427             type Interner = crate::Interner;
428         }
429     };
430 }