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