1use crate::fold::TypeFoldable;
4use crate::*;
5use std::fmt::Debug;
6use std::sync::Arc;
7
8pub trait Zipper<I: Interner> {
25 fn zip_tys(&mut self, variance: Variance, a: &Ty<I>, b: &Ty<I>) -> Fallible<()>;
27
28 fn zip_lifetimes(
30 &mut self,
31 variance: Variance,
32 a: &Lifetime<I>,
33 b: &Lifetime<I>,
34 ) -> Fallible<()>;
35
36 fn zip_consts(&mut self, variance: Variance, a: &Const<I>, b: &Const<I>) -> Fallible<()>;
38
39 fn zip_binders<T>(
41 &mut self,
42 variance: Variance,
43 a: &Binders<T>,
44 b: &Binders<T>,
45 ) -> Fallible<()>
46 where
47 T: Clone + HasInterner<Interner = I> + Zip<I> + TypeFoldable<I>;
48
49 fn zip_substs(
51 &mut self,
52 ambient: Variance,
53 variances: Option<Variances<I>>,
54 a: &[GenericArg<I>],
55 b: &[GenericArg<I>],
56 ) -> Fallible<()>
57 where
58 Self: Sized,
59 {
60 for (i, (a, b)) in a.iter().zip(b.iter()).enumerate() {
61 let variance = variances
62 .as_ref()
63 .map(|v| v.as_slice(self.interner())[i])
64 .unwrap_or(Variance::Invariant);
65 Zip::zip_with(self, ambient.xform(variance), a, b)?;
66 }
67 Ok(())
68 }
69
70 fn interner(&self) -> I;
72
73 fn unification_database(&self) -> &dyn UnificationDatabase<I>;
75}
76
77impl<'f, Z, I> Zipper<I> for &'f mut Z
78where
79 I: Interner,
80 Z: Zipper<I>,
81{
82 fn zip_tys(&mut self, variance: Variance, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> {
83 (**self).zip_tys(variance, a, b)
84 }
85
86 fn zip_lifetimes(
87 &mut self,
88 variance: Variance,
89 a: &Lifetime<I>,
90 b: &Lifetime<I>,
91 ) -> Fallible<()> {
92 (**self).zip_lifetimes(variance, a, b)
93 }
94
95 fn zip_consts(&mut self, variance: Variance, a: &Const<I>, b: &Const<I>) -> Fallible<()> {
96 (**self).zip_consts(variance, a, b)
97 }
98
99 fn zip_binders<T>(&mut self, variance: Variance, a: &Binders<T>, b: &Binders<T>) -> Fallible<()>
100 where
101 T: Clone + HasInterner<Interner = I> + Zip<I> + TypeFoldable<I>,
102 {
103 (**self).zip_binders(variance, a, b)
104 }
105
106 fn interner(&self) -> I {
107 Z::interner(*self)
108 }
109
110 fn unification_database(&self) -> &dyn UnificationDatabase<I> {
111 (**self).unification_database()
112 }
113}
114
115pub trait Zip<I>: Debug
123where
124 I: Interner,
125{
126 fn zip_with<Z: Zipper<I>>(
128 zipper: &mut Z,
129 variance: Variance,
130 a: &Self,
131 b: &Self,
132 ) -> Fallible<()>;
133}
134
135impl<'a, T: ?Sized + Zip<I>, I: Interner> Zip<I> for &'a T {
136 fn zip_with<Z: Zipper<I>>(
137 zipper: &mut Z,
138 variance: Variance,
139 a: &Self,
140 b: &Self,
141 ) -> Fallible<()> {
142 <T as Zip<I>>::zip_with(zipper, variance, a, b)
143 }
144}
145
146impl<I: Interner> Zip<I> for () {
147 fn zip_with<Z: Zipper<I>>(_: &mut Z, _: Variance, _: &Self, _: &Self) -> Fallible<()> {
148 Ok(())
149 }
150}
151
152impl<T: Zip<I>, I: Interner> Zip<I> for Vec<T> {
153 fn zip_with<Z: Zipper<I>>(
154 zipper: &mut Z,
155 variance: Variance,
156 a: &Self,
157 b: &Self,
158 ) -> Fallible<()> {
159 <[T] as Zip<I>>::zip_with(zipper, variance, a, b)
160 }
161}
162
163impl<T: Zip<I>, I: Interner> Zip<I> for [T] {
164 fn zip_with<Z: Zipper<I>>(
165 zipper: &mut Z,
166 variance: Variance,
167 a: &Self,
168 b: &Self,
169 ) -> Fallible<()> {
170 if a.len() != b.len() {
171 return Err(NoSolution);
172 }
173
174 for (a_elem, b_elem) in a.iter().zip(b) {
175 Zip::zip_with(zipper, variance, a_elem, b_elem)?;
176 }
177
178 Ok(())
179 }
180}
181
182impl<T: Zip<I>, I: Interner> Zip<I> for Arc<T> {
183 fn zip_with<Z: Zipper<I>>(
184 zipper: &mut Z,
185 variance: Variance,
186 a: &Self,
187 b: &Self,
188 ) -> Fallible<()> {
189 <T as Zip<I>>::zip_with(zipper, variance, a, b)
190 }
191}
192
193impl<T: Zip<I>, I: Interner> Zip<I> for Box<T> {
194 fn zip_with<Z: Zipper<I>>(
195 zipper: &mut Z,
196 variance: Variance,
197 a: &Self,
198 b: &Self,
199 ) -> Fallible<()> {
200 <T as Zip<I>>::zip_with(zipper, variance, a, b)
201 }
202}
203
204impl<T: Zip<I>, U: Zip<I>, I: Interner> Zip<I> for (T, U) {
205 fn zip_with<Z: Zipper<I>>(
206 zipper: &mut Z,
207 variance: Variance,
208 a: &Self,
209 b: &Self,
210 ) -> Fallible<()> {
211 Zip::zip_with(zipper, variance, &a.0, &b.0)?;
212 Zip::zip_with(zipper, variance, &a.1, &b.1)?;
213 Ok(())
214 }
215}
216
217impl<I: Interner> Zip<I> for Ty<I> {
218 fn zip_with<Z: Zipper<I>>(
219 zipper: &mut Z,
220 variance: Variance,
221 a: &Self,
222 b: &Self,
223 ) -> Fallible<()> {
224 zipper.zip_tys(variance, a, b)
225 }
226}
227
228impl<I: Interner> Zip<I> for Lifetime<I> {
229 fn zip_with<Z: Zipper<I>>(
230 zipper: &mut Z,
231 variance: Variance,
232 a: &Self,
233 b: &Self,
234 ) -> Fallible<()> {
235 zipper.zip_lifetimes(variance, a, b)
236 }
237}
238
239impl<I: Interner> Zip<I> for Const<I> {
240 fn zip_with<Z: Zipper<I>>(
241 zipper: &mut Z,
242 variance: Variance,
243 a: &Self,
244 b: &Self,
245 ) -> Fallible<()> {
246 zipper.zip_consts(variance, a, b)
247 }
248}
249impl<I: Interner, T> Zip<I> for Binders<T>
250where
251 T: Clone + HasInterner<Interner = I> + Zip<I> + TypeFoldable<I>,
252{
253 fn zip_with<Z: Zipper<I>>(
254 zipper: &mut Z,
255 variance: Variance,
256 a: &Self,
257 b: &Self,
258 ) -> Fallible<()> {
259 zipper.zip_binders(variance, a, b)
260 }
261}
262
263macro_rules! eq_zip {
266 ($I:ident => $t:ty) => {
267 impl<$I: Interner> Zip<$I> for $t {
268 fn zip_with<Z: Zipper<$I>>(
269 _zipper: &mut Z,
270 _variance: Variance,
271 a: &Self,
272 b: &Self,
273 ) -> Fallible<()> {
274 if a != b {
275 return Err(NoSolution);
276 }
277 Ok(())
278 }
279 }
280 };
281}
282
283eq_zip!(I => AdtId<I>);
284eq_zip!(I => TraitId<I>);
285eq_zip!(I => AssocTypeId<I>);
286eq_zip!(I => OpaqueTyId<I>);
287eq_zip!(I => CoroutineId<I>);
288eq_zip!(I => ForeignDefId<I>);
289eq_zip!(I => FnDefId<I>);
290eq_zip!(I => ClosureId<I>);
291eq_zip!(I => QuantifierKind);
292eq_zip!(I => PhantomData<I>);
293eq_zip!(I => PlaceholderIndex);
294eq_zip!(I => ClausePriority);
295eq_zip!(I => Mutability);
296eq_zip!(I => Scalar);
297
298impl<T: HasInterner<Interner = I> + Zip<I>, I: Interner> Zip<I> for InEnvironment<T> {
299 fn zip_with<Z: Zipper<I>>(
300 zipper: &mut Z,
301 variance: Variance,
302 a: &Self,
303 b: &Self,
304 ) -> Fallible<()> {
305 Zip::zip_with(zipper, variance, &a.environment, &b.environment)?;
306 Zip::zip_with(zipper, variance, &a.goal, &b.goal)?;
307 Ok(())
308 }
309}
310
311impl<I: Interner> Zip<I> for Environment<I> {
312 fn zip_with<Z: Zipper<I>>(
313 zipper: &mut Z,
314 variance: Variance,
315 a: &Self,
316 b: &Self,
317 ) -> Fallible<()> {
318 let interner = zipper.interner();
319 assert_eq!(a.clauses.len(interner), b.clauses.len(interner)); Zip::zip_with(
321 zipper,
322 variance,
323 a.clauses.as_slice(interner),
324 b.clauses.as_slice(interner),
325 )?;
326 Ok(())
327 }
328}
329
330impl<I: Interner> Zip<I> for Goals<I> {
331 fn zip_with<Z: Zipper<I>>(
332 zipper: &mut Z,
333 variance: Variance,
334 a: &Self,
335 b: &Self,
336 ) -> Fallible<()> {
337 let interner = zipper.interner();
338 Zip::zip_with(zipper, variance, a.as_slice(interner), b.as_slice(interner))?;
339 Ok(())
340 }
341}
342
343impl<I: Interner> Zip<I> for ProgramClauses<I> {
344 fn zip_with<Z: Zipper<I>>(
345 zipper: &mut Z,
346 variance: Variance,
347 a: &Self,
348 b: &Self,
349 ) -> Fallible<()> {
350 let interner = zipper.interner();
351 Zip::zip_with(zipper, variance, a.as_slice(interner), b.as_slice(interner))?;
352 Ok(())
353 }
354}
355
356impl<I: Interner> Zip<I> for Constraints<I> {
357 fn zip_with<Z: Zipper<I>>(
358 zipper: &mut Z,
359 variance: Variance,
360 a: &Self,
361 b: &Self,
362 ) -> Fallible<()> {
363 let interner = zipper.interner();
364 Zip::zip_with(zipper, variance, a.as_slice(interner), b.as_slice(interner))?;
365 Ok(())
366 }
367}
368
369impl<I: Interner> Zip<I> for QuantifiedWhereClauses<I> {
370 fn zip_with<Z: Zipper<I>>(
371 zipper: &mut Z,
372 variance: Variance,
373 a: &Self,
374 b: &Self,
375 ) -> Fallible<()> {
376 let interner = zipper.interner();
377 Zip::zip_with(zipper, variance, a.as_slice(interner), b.as_slice(interner))?;
378 Ok(())
379 }
380}
381
382impl<I: Interner> Zip<I> for Goal<I> {
386 fn zip_with<Z: Zipper<I>>(
387 zipper: &mut Z,
388 variance: Variance,
389 a: &Self,
390 b: &Self,
391 ) -> Fallible<()> {
392 let interner = zipper.interner();
393 Zip::zip_with(zipper, variance, a.data(interner), b.data(interner))
394 }
395}
396
397impl<I: Interner> Zip<I> for VariableKind<I> {
399 fn zip_with<Z: Zipper<I>>(
400 zipper: &mut Z,
401 variance: Variance,
402 a: &Self,
403 b: &Self,
404 ) -> Fallible<()> {
405 match (a, b) {
406 (VariableKind::Ty(a), VariableKind::Ty(b)) if a == b => Ok(()),
407 (VariableKind::Lifetime, VariableKind::Lifetime) => Ok(()),
408 (VariableKind::Const(ty_a), VariableKind::Const(ty_b)) => {
409 Zip::zip_with(zipper, variance, ty_a, ty_b)
410 }
411 (VariableKind::Ty(_), _)
412 | (VariableKind::Lifetime, _)
413 | (VariableKind::Const(_), _) => panic!("zipping things of mixed kind"),
414 }
415 }
416}
417
418impl<I: Interner> Zip<I> for GenericArg<I> {
419 fn zip_with<Z: Zipper<I>>(
420 zipper: &mut Z,
421 variance: Variance,
422 a: &Self,
423 b: &Self,
424 ) -> Fallible<()> {
425 let interner = zipper.interner();
426 Zip::zip_with(zipper, variance, a.data(interner), b.data(interner))
427 }
428}
429
430impl<I: Interner> Zip<I> for ProgramClause<I> {
431 fn zip_with<Z: Zipper<I>>(
432 zipper: &mut Z,
433 variance: Variance,
434 a: &Self,
435 b: &Self,
436 ) -> Fallible<()> {
437 let interner = zipper.interner();
438 Zip::zip_with(zipper, variance, a.data(interner), b.data(interner))
439 }
440}
441
442impl<I: Interner> Zip<I> for TraitRef<I> {
443 fn zip_with<Z: Zipper<I>>(
444 zipper: &mut Z,
445 variance: Variance,
446 a: &Self,
447 b: &Self,
448 ) -> Fallible<()> {
449 let interner = zipper.interner();
450 Zip::zip_with(zipper, variance, &a.trait_id, &b.trait_id)?;
451 zipper.zip_substs(
452 variance,
453 None,
454 a.substitution.as_slice(interner),
455 b.substitution.as_slice(interner),
456 )
457 }
458}
459
460impl<I: Interner> Zip<I> for ProjectionTy<I> {
461 fn zip_with<Z: Zipper<I>>(
462 zipper: &mut Z,
463 variance: Variance,
464 a: &Self,
465 b: &Self,
466 ) -> Fallible<()> {
467 let interner = zipper.interner();
468 Zip::zip_with(zipper, variance, &a.associated_ty_id, &b.associated_ty_id)?;
469 zipper.zip_substs(
470 variance,
471 None,
472 a.substitution.as_slice(interner),
473 b.substitution.as_slice(interner),
474 )
475 }
476}
477
478impl<I: Interner> Zip<I> for OpaqueTy<I> {
479 fn zip_with<Z: Zipper<I>>(
480 zipper: &mut Z,
481 variance: Variance,
482 a: &Self,
483 b: &Self,
484 ) -> Fallible<()> {
485 let interner = zipper.interner();
486 Zip::zip_with(zipper, variance, &a.opaque_ty_id, &b.opaque_ty_id)?;
487 zipper.zip_substs(
488 variance,
489 None,
490 a.substitution.as_slice(interner),
491 b.substitution.as_slice(interner),
492 )
493 }
494}
495
496impl<I: Interner> Zip<I> for DynTy<I> {
497 fn zip_with<Z: Zipper<I>>(
498 zipper: &mut Z,
499 variance: Variance,
500 a: &Self,
501 b: &Self,
502 ) -> Fallible<()> {
503 Zip::zip_with(
504 zipper,
505 variance.xform(Variance::Invariant),
506 &a.bounds,
507 &b.bounds,
508 )?;
509 Zip::zip_with(
510 zipper,
511 variance.xform(Variance::Contravariant),
512 &a.lifetime,
513 &b.lifetime,
514 )?;
515 Ok(())
516 }
517}
518
519impl<I: Interner> Zip<I> for FnSubst<I> {
520 fn zip_with<Z: Zipper<I>>(
521 zipper: &mut Z,
522 variance: Variance,
523 a: &Self,
524 b: &Self,
525 ) -> Fallible<()> {
526 let interner = zipper.interner();
527 Zip::zip_with(
529 zipper,
530 variance.xform(Variance::Contravariant),
531 &a.0.as_slice(interner)[..a.0.len(interner) - 1],
532 &b.0.as_slice(interner)[..b.0.len(interner) - 1],
533 )?;
534 Zip::zip_with(
536 zipper,
537 variance,
538 a.0.iter(interner).last().unwrap(),
539 b.0.iter(interner).last().unwrap(),
540 )?;
541 Ok(())
542 }
543}