]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/traits/chalk.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / compiler / rustc_middle / src / traits / chalk.rs
1 //! Types required for Chalk-related queries
2 //!
3 //! The primary purpose of this file is defining an implementation for the
4 //! `chalk_ir::interner::Interner` trait. The primary purpose of this trait, as
5 //! its name suggest, is to provide an abstraction boundary for creating
6 //! interned Chalk types.
7
8 use rustc_middle::ty::{self, AdtDef, TyCtxt};
9
10 use rustc_hir::def_id::DefId;
11 use rustc_target::spec::abi::Abi;
12
13 use std::cmp::Ordering;
14 use std::fmt;
15 use std::hash::{Hash, Hasher};
16
17 #[derive(Copy, Clone)]
18 pub struct RustInterner<'tcx> {
19     pub tcx: TyCtxt<'tcx>,
20 }
21
22 /// We don't ever actually need this. It's only required for derives.
23 impl<'tcx> Hash for RustInterner<'tcx> {
24     fn hash<H: Hasher>(&self, _state: &mut H) {}
25 }
26
27 /// We don't ever actually need this. It's only required for derives.
28 impl<'tcx> Ord for RustInterner<'tcx> {
29     fn cmp(&self, _other: &Self) -> Ordering {
30         Ordering::Equal
31     }
32 }
33
34 /// We don't ever actually need this. It's only required for derives.
35 impl<'tcx> PartialOrd for RustInterner<'tcx> {
36     fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
37         None
38     }
39 }
40
41 /// We don't ever actually need this. It's only required for derives.
42 impl<'tcx> PartialEq for RustInterner<'tcx> {
43     fn eq(&self, _other: &Self) -> bool {
44         false
45     }
46 }
47
48 /// We don't ever actually need this. It's only required for derives.
49 impl<'tcx> Eq for RustInterner<'tcx> {}
50
51 impl fmt::Debug for RustInterner<'_> {
52     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53         write!(f, "RustInterner")
54     }
55 }
56
57 // Right now, there is no interning at all. I was running into problems with
58 // adding interning in `ty/context.rs` for Chalk types with
59 // `parallel-compiler = true`. -jackh726
60 impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
61     type InternedType = Box<chalk_ir::TyData<Self>>;
62     type InternedLifetime = Box<chalk_ir::LifetimeData<Self>>;
63     type InternedConst = Box<chalk_ir::ConstData<Self>>;
64     type InternedConcreteConst = ty::ValTree<'tcx>;
65     type InternedGenericArg = Box<chalk_ir::GenericArgData<Self>>;
66     type InternedGoal = Box<chalk_ir::GoalData<Self>>;
67     type InternedGoals = Vec<chalk_ir::Goal<Self>>;
68     type InternedSubstitution = Vec<chalk_ir::GenericArg<Self>>;
69     type InternedProgramClause = Box<chalk_ir::ProgramClauseData<Self>>;
70     type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>;
71     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
72     type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
73     type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
74     type InternedVariances = Vec<chalk_ir::Variance>;
75     type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
76     type DefId = DefId;
77     type InternedAdtId = AdtDef<'tcx>;
78     type Identifier = ();
79     type FnAbi = Abi;
80
81     fn debug_program_clause_implication(
82         pci: &chalk_ir::ProgramClauseImplication<Self>,
83         fmt: &mut fmt::Formatter<'_>,
84     ) -> Option<fmt::Result> {
85         let mut write = || {
86             write!(fmt, "{:?}", pci.consequence)?;
87
88             let conditions = pci.conditions.interned();
89             let constraints = pci.constraints.interned();
90
91             let conds = conditions.len();
92             let consts = constraints.len();
93             if conds == 0 && consts == 0 {
94                 return Ok(());
95             }
96
97             write!(fmt, " :- ")?;
98
99             if conds != 0 {
100                 for cond in &conditions[..conds - 1] {
101                     write!(fmt, "{:?}, ", cond)?;
102                 }
103                 write!(fmt, "{:?}", conditions[conds - 1])?;
104             }
105
106             if conds != 0 && consts != 0 {
107                 write!(fmt, " ; ")?;
108             }
109
110             if consts != 0 {
111                 for constraint in &constraints[..consts - 1] {
112                     write!(fmt, "{:?}, ", constraint)?;
113                 }
114                 write!(fmt, "{:?}", constraints[consts - 1])?;
115             }
116
117             Ok(())
118         };
119         Some(write())
120     }
121
122     fn debug_substitution(
123         substitution: &chalk_ir::Substitution<Self>,
124         fmt: &mut fmt::Formatter<'_>,
125     ) -> Option<fmt::Result> {
126         Some(write!(fmt, "{:?}", substitution.interned()))
127     }
128
129     fn debug_separator_trait_ref(
130         separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Self>,
131         fmt: &mut fmt::Formatter<'_>,
132     ) -> Option<fmt::Result> {
133         let substitution = &separator_trait_ref.trait_ref.substitution;
134         let parameters = substitution.interned();
135         Some(write!(
136             fmt,
137             "{:?}{}{:?}{:?}",
138             parameters[0],
139             separator_trait_ref.separator,
140             separator_trait_ref.trait_ref.trait_id,
141             chalk_ir::debug::Angle(&parameters[1..])
142         ))
143     }
144
145     fn debug_quantified_where_clauses(
146         clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
147         fmt: &mut fmt::Formatter<'_>,
148     ) -> Option<fmt::Result> {
149         Some(write!(fmt, "{:?}", clauses.interned()))
150     }
151
152     fn debug_ty(ty: &chalk_ir::Ty<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
153         match &ty.interned().kind {
154             chalk_ir::TyKind::Ref(chalk_ir::Mutability::Not, lifetime, ty) => {
155                 Some(write!(fmt, "(&{:?} {:?})", lifetime, ty))
156             }
157             chalk_ir::TyKind::Ref(chalk_ir::Mutability::Mut, lifetime, ty) => {
158                 Some(write!(fmt, "(&{:?} mut {:?})", lifetime, ty))
159             }
160             chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)),
161             chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)),
162             chalk_ir::TyKind::Tuple(len, substs) => Some(
163                 try {
164                     write!(fmt, "(")?;
165                     for (idx, substitution) in substs.interned().iter().enumerate() {
166                         if idx == *len && *len != 1 {
167                             // Don't add a trailing comma if the tuple has more than one element
168                             write!(fmt, "{:?}", substitution)?;
169                         } else {
170                             write!(fmt, "{:?},", substitution)?;
171                         }
172                     }
173                     write!(fmt, ")")?;
174                 },
175             ),
176             _ => None,
177         }
178     }
179
180     fn debug_alias(
181         alias_ty: &chalk_ir::AliasTy<Self>,
182         fmt: &mut fmt::Formatter<'_>,
183     ) -> Option<fmt::Result> {
184         match alias_ty {
185             chalk_ir::AliasTy::Projection(projection_ty) => {
186                 Self::debug_projection_ty(projection_ty, fmt)
187             }
188             chalk_ir::AliasTy::Opaque(opaque_ty) => Self::debug_opaque_ty(opaque_ty, fmt),
189         }
190     }
191
192     fn debug_projection_ty(
193         projection_ty: &chalk_ir::ProjectionTy<Self>,
194         fmt: &mut fmt::Formatter<'_>,
195     ) -> Option<fmt::Result> {
196         Some(write!(
197             fmt,
198             "projection: {:?} {:?}",
199             projection_ty.associated_ty_id, projection_ty.substitution,
200         ))
201     }
202
203     fn debug_opaque_ty(
204         opaque_ty: &chalk_ir::OpaqueTy<Self>,
205         fmt: &mut fmt::Formatter<'_>,
206     ) -> Option<fmt::Result> {
207         Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
208     }
209
210     fn intern_ty(self, ty: chalk_ir::TyKind<Self>) -> Self::InternedType {
211         let flags = ty.compute_flags(self);
212         Box::new(chalk_ir::TyData { kind: ty, flags: flags })
213     }
214
215     fn ty_data(self, ty: &Self::InternedType) -> &chalk_ir::TyData<Self> {
216         ty
217     }
218
219     fn intern_lifetime(self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
220         Box::new(lifetime)
221     }
222
223     fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &chalk_ir::LifetimeData<Self> {
224         &lifetime
225     }
226
227     fn intern_const(self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
228         Box::new(constant)
229     }
230
231     fn const_data(self, constant: &Self::InternedConst) -> &chalk_ir::ConstData<Self> {
232         &constant
233     }
234
235     fn const_eq(
236         self,
237         _ty: &Self::InternedType,
238         c1: &Self::InternedConcreteConst,
239         c2: &Self::InternedConcreteConst,
240     ) -> bool {
241         c1 == c2
242     }
243
244     fn intern_generic_arg(self, data: chalk_ir::GenericArgData<Self>) -> Self::InternedGenericArg {
245         Box::new(data)
246     }
247
248     fn generic_arg_data(self, data: &Self::InternedGenericArg) -> &chalk_ir::GenericArgData<Self> {
249         &data
250     }
251
252     fn intern_goal(self, goal: chalk_ir::GoalData<Self>) -> Self::InternedGoal {
253         Box::new(goal)
254     }
255
256     fn goal_data(self, goal: &Self::InternedGoal) -> &chalk_ir::GoalData<Self> {
257         &goal
258     }
259
260     fn intern_goals<E>(
261         self,
262         data: impl IntoIterator<Item = Result<chalk_ir::Goal<Self>, E>>,
263     ) -> Result<Self::InternedGoals, E> {
264         data.into_iter().collect::<Result<Vec<_>, _>>()
265     }
266
267     fn goals_data(self, goals: &Self::InternedGoals) -> &[chalk_ir::Goal<Self>] {
268         goals
269     }
270
271     fn intern_substitution<E>(
272         self,
273         data: impl IntoIterator<Item = Result<chalk_ir::GenericArg<Self>, E>>,
274     ) -> Result<Self::InternedSubstitution, E> {
275         data.into_iter().collect::<Result<Vec<_>, _>>()
276     }
277
278     fn substitution_data(
279         self,
280         substitution: &Self::InternedSubstitution,
281     ) -> &[chalk_ir::GenericArg<Self>] {
282         substitution
283     }
284
285     fn intern_program_clause(
286         self,
287         data: chalk_ir::ProgramClauseData<Self>,
288     ) -> Self::InternedProgramClause {
289         Box::new(data)
290     }
291
292     fn program_clause_data(
293         self,
294         clause: &Self::InternedProgramClause,
295     ) -> &chalk_ir::ProgramClauseData<Self> {
296         &clause
297     }
298
299     fn intern_program_clauses<E>(
300         self,
301         data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
302     ) -> Result<Self::InternedProgramClauses, E> {
303         data.into_iter().collect::<Result<Vec<_>, _>>()
304     }
305
306     fn program_clauses_data(
307         self,
308         clauses: &Self::InternedProgramClauses,
309     ) -> &[chalk_ir::ProgramClause<Self>] {
310         clauses
311     }
312
313     fn intern_quantified_where_clauses<E>(
314         self,
315         data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
316     ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
317         data.into_iter().collect::<Result<Vec<_>, _>>()
318     }
319
320     fn quantified_where_clauses_data(
321         self,
322         clauses: &Self::InternedQuantifiedWhereClauses,
323     ) -> &[chalk_ir::QuantifiedWhereClause<Self>] {
324         clauses
325     }
326
327     fn intern_generic_arg_kinds<E>(
328         self,
329         data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
330     ) -> Result<Self::InternedVariableKinds, E> {
331         data.into_iter().collect::<Result<Vec<_>, _>>()
332     }
333
334     fn variable_kinds_data(
335         self,
336         parameter_kinds: &Self::InternedVariableKinds,
337     ) -> &[chalk_ir::VariableKind<Self>] {
338         parameter_kinds
339     }
340
341     fn intern_canonical_var_kinds<E>(
342         self,
343         data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
344     ) -> Result<Self::InternedCanonicalVarKinds, E> {
345         data.into_iter().collect::<Result<Vec<_>, _>>()
346     }
347
348     fn canonical_var_kinds_data(
349         self,
350         canonical_var_kinds: &Self::InternedCanonicalVarKinds,
351     ) -> &[chalk_ir::CanonicalVarKind<Self>] {
352         canonical_var_kinds
353     }
354
355     fn intern_constraints<E>(
356         self,
357         data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
358     ) -> Result<Self::InternedConstraints, E> {
359         data.into_iter().collect::<Result<Vec<_>, _>>()
360     }
361
362     fn constraints_data(
363         self,
364         constraints: &Self::InternedConstraints,
365     ) -> &[chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
366         constraints
367     }
368
369     fn intern_variances<E>(
370         self,
371         data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
372     ) -> Result<Self::InternedVariances, E> {
373         data.into_iter().collect::<Result<Vec<_>, _>>()
374     }
375
376     fn variances_data(self, variances: &Self::InternedVariances) -> &[chalk_ir::Variance] {
377         variances
378     }
379 }
380
381 impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
382     type Interner = Self;
383 }
384
385 /// A chalk environment and goal.
386 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)]
387 pub struct ChalkEnvironmentAndGoal<'tcx> {
388     pub environment: &'tcx ty::List<ty::Predicate<'tcx>>,
389     pub goal: ty::Predicate<'tcx>,
390 }
391
392 impl<'tcx> fmt::Display for ChalkEnvironmentAndGoal<'tcx> {
393     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
394         write!(f, "environment: {:?}, goal: {}", self.environment, self.goal)
395     }
396 }