]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/traits/chalk.rs
Auto merge of #101212 - eholk:dyn-star, r=compiler-errors
[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                 write!(fmt, "(")?;
164                 for (idx, substitution) in substs.interned().iter().enumerate() {
165                     if idx == *len && *len != 1 {
166                         // Don't add a trailing comma if the tuple has more than one element
167                         write!(fmt, "{:?}", substitution)?;
168                     } else {
169                         write!(fmt, "{:?},", substitution)?;
170                     }
171                 }
172                 write!(fmt, ")")
173             })()),
174             _ => None,
175         }
176     }
177
178     fn debug_alias(
179         alias_ty: &chalk_ir::AliasTy<Self>,
180         fmt: &mut fmt::Formatter<'_>,
181     ) -> Option<fmt::Result> {
182         match alias_ty {
183             chalk_ir::AliasTy::Projection(projection_ty) => {
184                 Self::debug_projection_ty(projection_ty, fmt)
185             }
186             chalk_ir::AliasTy::Opaque(opaque_ty) => Self::debug_opaque_ty(opaque_ty, fmt),
187         }
188     }
189
190     fn debug_projection_ty(
191         projection_ty: &chalk_ir::ProjectionTy<Self>,
192         fmt: &mut fmt::Formatter<'_>,
193     ) -> Option<fmt::Result> {
194         Some(write!(
195             fmt,
196             "projection: {:?} {:?}",
197             projection_ty.associated_ty_id, projection_ty.substitution,
198         ))
199     }
200
201     fn debug_opaque_ty(
202         opaque_ty: &chalk_ir::OpaqueTy<Self>,
203         fmt: &mut fmt::Formatter<'_>,
204     ) -> Option<fmt::Result> {
205         Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
206     }
207
208     fn intern_ty(self, ty: chalk_ir::TyKind<Self>) -> Self::InternedType {
209         let flags = ty.compute_flags(self);
210         Box::new(chalk_ir::TyData { kind: ty, flags: flags })
211     }
212
213     fn ty_data<'a>(self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
214         ty
215     }
216
217     fn intern_lifetime(self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
218         Box::new(lifetime)
219     }
220
221     fn lifetime_data<'a>(
222         self,
223         lifetime: &'a Self::InternedLifetime,
224     ) -> &'a chalk_ir::LifetimeData<Self> {
225         &lifetime
226     }
227
228     fn intern_const(self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
229         Box::new(constant)
230     }
231
232     fn const_data<'a>(self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
233         &constant
234     }
235
236     fn const_eq(
237         self,
238         _ty: &Self::InternedType,
239         c1: &Self::InternedConcreteConst,
240         c2: &Self::InternedConcreteConst,
241     ) -> bool {
242         c1 == c2
243     }
244
245     fn intern_generic_arg(self, data: chalk_ir::GenericArgData<Self>) -> Self::InternedGenericArg {
246         Box::new(data)
247     }
248
249     fn generic_arg_data<'a>(
250         self,
251         data: &'a Self::InternedGenericArg,
252     ) -> &'a chalk_ir::GenericArgData<Self> {
253         &data
254     }
255
256     fn intern_goal(self, goal: chalk_ir::GoalData<Self>) -> Self::InternedGoal {
257         Box::new(goal)
258     }
259
260     fn goal_data<'a>(self, goal: &'a Self::InternedGoal) -> &'a chalk_ir::GoalData<Self> {
261         &goal
262     }
263
264     fn intern_goals<E>(
265         self,
266         data: impl IntoIterator<Item = Result<chalk_ir::Goal<Self>, E>>,
267     ) -> Result<Self::InternedGoals, E> {
268         data.into_iter().collect::<Result<Vec<_>, _>>()
269     }
270
271     fn goals_data<'a>(self, goals: &'a Self::InternedGoals) -> &'a [chalk_ir::Goal<Self>] {
272         goals
273     }
274
275     fn intern_substitution<E>(
276         self,
277         data: impl IntoIterator<Item = Result<chalk_ir::GenericArg<Self>, E>>,
278     ) -> Result<Self::InternedSubstitution, E> {
279         data.into_iter().collect::<Result<Vec<_>, _>>()
280     }
281
282     fn substitution_data<'a>(
283         self,
284         substitution: &'a Self::InternedSubstitution,
285     ) -> &'a [chalk_ir::GenericArg<Self>] {
286         substitution
287     }
288
289     fn intern_program_clause(
290         self,
291         data: chalk_ir::ProgramClauseData<Self>,
292     ) -> Self::InternedProgramClause {
293         Box::new(data)
294     }
295
296     fn program_clause_data<'a>(
297         self,
298         clause: &'a Self::InternedProgramClause,
299     ) -> &'a chalk_ir::ProgramClauseData<Self> {
300         &clause
301     }
302
303     fn intern_program_clauses<E>(
304         self,
305         data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
306     ) -> Result<Self::InternedProgramClauses, E> {
307         data.into_iter().collect::<Result<Vec<_>, _>>()
308     }
309
310     fn program_clauses_data<'a>(
311         self,
312         clauses: &'a Self::InternedProgramClauses,
313     ) -> &'a [chalk_ir::ProgramClause<Self>] {
314         clauses
315     }
316
317     fn intern_quantified_where_clauses<E>(
318         self,
319         data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
320     ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
321         data.into_iter().collect::<Result<Vec<_>, _>>()
322     }
323
324     fn quantified_where_clauses_data<'a>(
325         self,
326         clauses: &'a Self::InternedQuantifiedWhereClauses,
327     ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
328         clauses
329     }
330
331     fn intern_generic_arg_kinds<E>(
332         self,
333         data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
334     ) -> Result<Self::InternedVariableKinds, E> {
335         data.into_iter().collect::<Result<Vec<_>, _>>()
336     }
337
338     fn variable_kinds_data<'a>(
339         self,
340         parameter_kinds: &'a Self::InternedVariableKinds,
341     ) -> &'a [chalk_ir::VariableKind<Self>] {
342         parameter_kinds
343     }
344
345     fn intern_canonical_var_kinds<E>(
346         self,
347         data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
348     ) -> Result<Self::InternedCanonicalVarKinds, E> {
349         data.into_iter().collect::<Result<Vec<_>, _>>()
350     }
351
352     fn canonical_var_kinds_data<'a>(
353         self,
354         canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
355     ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
356         canonical_var_kinds
357     }
358
359     fn intern_constraints<E>(
360         self,
361         data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
362     ) -> Result<Self::InternedConstraints, E> {
363         data.into_iter().collect::<Result<Vec<_>, _>>()
364     }
365
366     fn constraints_data<'a>(
367         self,
368         constraints: &'a Self::InternedConstraints,
369     ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
370         constraints
371     }
372
373     fn intern_variances<E>(
374         self,
375         data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
376     ) -> Result<Self::InternedVariances, E> {
377         data.into_iter().collect::<Result<Vec<_>, _>>()
378     }
379
380     fn variances_data<'a>(
381         self,
382         variances: &'a Self::InternedVariances,
383     ) -> &'a [chalk_ir::Variance] {
384         variances
385     }
386 }
387
388 impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
389     type Interner = Self;
390 }
391
392 /// A chalk environment and goal.
393 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)]
394 pub struct ChalkEnvironmentAndGoal<'tcx> {
395     pub environment: &'tcx ty::List<ty::Predicate<'tcx>>,
396     pub goal: ty::Predicate<'tcx>,
397 }
398
399 impl<'tcx> fmt::Display for ChalkEnvironmentAndGoal<'tcx> {
400     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401         write!(f, "environment: {:?}, goal: {}", self.environment, self.goal)
402     }
403 }