1use std::fmt::Debug;
2use std::hash::Hash;
3use std::marker::PhantomData;
4use std::ops::{ControlFlow, Deref};
5
6use derive_where::derive_where;
7#[cfg(feature = "nightly")]
8use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
9use tracing::instrument;
10
11use crate::data_structures::SsoHashSet;
12use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
13use crate::inherent::*;
14use crate::lift::Lift;
15use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
16use crate::{self as ty, Interner};
17
18#[derive_where(Clone; I: Interner, T: Clone)]
28#[derive_where(Copy; I: Interner, T: Copy)]
29#[derive_where(Hash; I: Interner, T: Hash)]
30#[derive_where(PartialEq; I: Interner, T: PartialEq)]
31#[derive_where(Eq; I: Interner, T: Eq)]
32#[derive_where(Debug; I: Interner, T: Debug)]
33#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
34pub struct Binder<I: Interner, T> {
35 value: T,
36 bound_vars: I::BoundVarKinds,
37}
38
39impl<I: Interner, U: Interner, T> Lift<U> for Binder<I, T>
42where
43 T: Lift<U>,
44 I::BoundVarKinds: Lift<U, Lifted = U::BoundVarKinds>,
45{
46 type Lifted = Binder<U, T::Lifted>;
47
48 fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
49 Some(Binder {
50 value: self.value.lift_to_interner(cx)?,
51 bound_vars: self.bound_vars.lift_to_interner(cx)?,
52 })
53 }
54}
55
56#[cfg(feature = "nightly")]
57macro_rules! impl_binder_encode_decode {
58 ($($t:ty),+ $(,)?) => {
59 $(
60 impl<I: Interner, E: crate::TyEncoder<I = I>> rustc_serialize::Encodable<E> for ty::Binder<I, $t>
61 where
62 $t: rustc_serialize::Encodable<E>,
63 I::BoundVarKinds: rustc_serialize::Encodable<E>,
64 {
65 fn encode(&self, e: &mut E) {
66 self.bound_vars().encode(e);
67 self.as_ref().skip_binder().encode(e);
68 }
69 }
70 impl<I: Interner, D: crate::TyDecoder<I = I>> rustc_serialize::Decodable<D> for ty::Binder<I, $t>
71 where
72 $t: TypeVisitable<I> + rustc_serialize::Decodable<D>,
73 I::BoundVarKinds: rustc_serialize::Decodable<D>,
74 {
75 fn decode(decoder: &mut D) -> Self {
76 let bound_vars = rustc_serialize::Decodable::decode(decoder);
77 ty::Binder::bind_with_vars(rustc_serialize::Decodable::decode(decoder), bound_vars)
78 }
79 }
80 )*
81 }
82}
83
84#[cfg(feature = "nightly")]
85impl_binder_encode_decode! {
86 ty::FnSig<I>,
87 ty::FnSigTys<I>,
88 ty::TraitPredicate<I>,
89 ty::ExistentialPredicate<I>,
90 ty::TraitRef<I>,
91 ty::ExistentialTraitRef<I>,
92 ty::HostEffectPredicate<I>,
93}
94
95impl<I: Interner, T> Binder<I, T>
96where
97 T: TypeVisitable<I>,
98{
99 #[track_caller]
104 pub fn dummy(value: T) -> Binder<I, T> {
105 assert!(
106 !value.has_escaping_bound_vars(),
107 "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
108 );
109 Binder { value, bound_vars: Default::default() }
110 }
111
112 pub fn bind_with_vars(value: T, bound_vars: I::BoundVarKinds) -> Binder<I, T> {
113 if cfg!(debug_assertions) {
114 let mut validator = ValidateBoundVars::new(bound_vars);
115 value.visit_with(&mut validator);
116 }
117 Binder { value, bound_vars }
118 }
119}
120
121impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Binder<I, T> {
122 fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
123 folder.try_fold_binder(self)
124 }
125}
126
127impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Binder<I, T> {
128 fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
129 visitor.visit_binder(self)
130 }
131}
132
133impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
134 fn try_super_fold_with<F: FallibleTypeFolder<I>>(
135 self,
136 folder: &mut F,
137 ) -> Result<Self, F::Error> {
138 self.try_map_bound(|ty| ty.try_fold_with(folder))
139 }
140}
141
142impl<I: Interner, T: TypeVisitable<I>> TypeSuperVisitable<I> for Binder<I, T> {
143 fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
144 self.as_ref().skip_binder().visit_with(visitor)
145 }
146}
147
148impl<I: Interner, T> Binder<I, T> {
149 pub fn skip_binder(self) -> T {
166 self.value
167 }
168
169 pub fn bound_vars(&self) -> I::BoundVarKinds {
170 self.bound_vars
171 }
172
173 pub fn as_ref(&self) -> Binder<I, &T> {
174 Binder { value: &self.value, bound_vars: self.bound_vars }
175 }
176
177 pub fn as_deref(&self) -> Binder<I, &T::Target>
178 where
179 T: Deref,
180 {
181 Binder { value: &self.value, bound_vars: self.bound_vars }
182 }
183
184 pub fn map_bound_ref<F, U: TypeVisitable<I>>(&self, f: F) -> Binder<I, U>
185 where
186 F: FnOnce(&T) -> U,
187 {
188 self.as_ref().map_bound(f)
189 }
190
191 pub fn map_bound<F, U: TypeVisitable<I>>(self, f: F) -> Binder<I, U>
192 where
193 F: FnOnce(T) -> U,
194 {
195 let Binder { value, bound_vars } = self;
196 let value = f(value);
197 if cfg!(debug_assertions) {
198 let mut validator = ValidateBoundVars::new(bound_vars);
199 value.visit_with(&mut validator);
200 }
201 Binder { value, bound_vars }
202 }
203
204 pub fn try_map_bound<F, U: TypeVisitable<I>, E>(self, f: F) -> Result<Binder<I, U>, E>
205 where
206 F: FnOnce(T) -> Result<U, E>,
207 {
208 let Binder { value, bound_vars } = self;
209 let value = f(value)?;
210 if cfg!(debug_assertions) {
211 let mut validator = ValidateBoundVars::new(bound_vars);
212 value.visit_with(&mut validator);
213 }
214 Ok(Binder { value, bound_vars })
215 }
216
217 pub fn rebind<U>(&self, value: U) -> Binder<I, U>
227 where
228 U: TypeVisitable<I>,
229 {
230 Binder::bind_with_vars(value, self.bound_vars)
231 }
232
233 pub fn no_bound_vars(self) -> Option<T>
244 where
245 T: TypeVisitable<I>,
246 {
247 if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
249 }
250}
251
252impl<I: Interner, T> Binder<I, Option<T>> {
253 pub fn transpose(self) -> Option<Binder<I, T>> {
254 let Binder { value, bound_vars } = self;
255 value.map(|value| Binder { value, bound_vars })
256 }
257}
258
259impl<I: Interner, T: IntoIterator> Binder<I, T> {
260 pub fn iter(self) -> impl Iterator<Item = Binder<I, T::Item>> {
261 let Binder { value, bound_vars } = self;
262 value.into_iter().map(move |value| Binder { value, bound_vars })
263 }
264}
265
266pub struct ValidateBoundVars<I: Interner> {
267 bound_vars: I::BoundVarKinds,
268 binder_index: ty::DebruijnIndex,
269 visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>,
272}
273
274impl<I: Interner> ValidateBoundVars<I> {
275 pub fn new(bound_vars: I::BoundVarKinds) -> Self {
276 ValidateBoundVars {
277 bound_vars,
278 binder_index: ty::INNERMOST,
279 visited: SsoHashSet::default(),
280 }
281 }
282}
283
284impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
285 type Result = ControlFlow<()>;
286
287 fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
288 self.binder_index.shift_in(1);
289 let result = t.super_visit_with(self);
290 self.binder_index.shift_out(1);
291 result
292 }
293
294 fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
295 if t.outer_exclusive_binder() < self.binder_index
296 || !self.visited.insert((self.binder_index, t))
297 {
298 return ControlFlow::Break(());
299 }
300 match t.kind() {
301 ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
302 let idx = bound_ty.var().as_usize();
303 if self.bound_vars.len() <= idx {
304 panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
305 }
306 bound_ty.assert_eq(self.bound_vars.get(idx).unwrap());
307 }
308 _ => {}
309 };
310
311 t.super_visit_with(self)
312 }
313
314 fn visit_region(&mut self, r: I::Region) -> Self::Result {
315 match r.kind() {
316 ty::ReBound(index, br) if index == self.binder_index => {
317 let idx = br.var().as_usize();
318 if self.bound_vars.len() <= idx {
319 panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
320 }
321 br.assert_eq(self.bound_vars.get(idx).unwrap());
322 }
323
324 _ => (),
325 };
326
327 ControlFlow::Continue(())
328 }
329}
330
331#[derive_where(Clone; I: Interner, T: Clone)]
338#[derive_where(Copy; I: Interner, T: Copy)]
339#[derive_where(PartialEq; I: Interner, T: PartialEq)]
340#[derive_where(Eq; I: Interner, T: Eq)]
341#[derive_where(Ord; I: Interner, T: Ord)]
342#[derive_where(PartialOrd; I: Interner, T: Ord)]
343#[derive_where(Hash; I: Interner, T: Hash)]
344#[derive_where(Debug; I: Interner, T: Debug)]
345#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
346pub struct EarlyBinder<I: Interner, T> {
347 value: T,
348 #[derive_where(skip(Debug))]
349 _tcx: PhantomData<I>,
350}
351
352#[cfg(feature = "nightly")]
354impl<I: Interner, T> !TypeFoldable<I> for ty::EarlyBinder<I, T> {}
355
356#[cfg(feature = "nightly")]
358impl<I: Interner, T> !TypeVisitable<I> for ty::EarlyBinder<I, T> {}
359
360impl<I: Interner, T> EarlyBinder<I, T> {
361 pub fn bind(value: T) -> EarlyBinder<I, T> {
362 EarlyBinder { value, _tcx: PhantomData }
363 }
364
365 pub fn as_ref(&self) -> EarlyBinder<I, &T> {
366 EarlyBinder { value: &self.value, _tcx: PhantomData }
367 }
368
369 pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<I, U>
370 where
371 F: FnOnce(&T) -> U,
372 {
373 self.as_ref().map_bound(f)
374 }
375
376 pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<I, U>
377 where
378 F: FnOnce(T) -> U,
379 {
380 let value = f(self.value);
381 EarlyBinder { value, _tcx: PhantomData }
382 }
383
384 pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<I, U>, E>
385 where
386 F: FnOnce(T) -> Result<U, E>,
387 {
388 let value = f(self.value)?;
389 Ok(EarlyBinder { value, _tcx: PhantomData })
390 }
391
392 pub fn rebind<U>(&self, value: U) -> EarlyBinder<I, U> {
393 EarlyBinder { value, _tcx: PhantomData }
394 }
395
396 pub fn skip_binder(self) -> T {
408 self.value
409 }
410}
411
412impl<I: Interner, T> EarlyBinder<I, Option<T>> {
413 pub fn transpose(self) -> Option<EarlyBinder<I, T>> {
414 self.value.map(|value| EarlyBinder { value, _tcx: PhantomData })
415 }
416}
417
418impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
419where
420 Iter::Item: TypeFoldable<I>,
421{
422 pub fn iter_instantiated<A>(self, cx: I, args: A) -> IterInstantiated<I, Iter, A>
423 where
424 A: SliceLike<Item = I::GenericArg>,
425 {
426 IterInstantiated { it: self.value.into_iter(), cx, args }
427 }
428
429 pub fn iter_identity(self) -> Iter::IntoIter {
432 self.value.into_iter()
433 }
434}
435
436pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> {
437 it: Iter::IntoIter,
438 cx: I,
439 args: A,
440}
441
442impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A>
443where
444 Iter::Item: TypeFoldable<I>,
445 A: SliceLike<Item = I::GenericArg>,
446{
447 type Item = Iter::Item;
448
449 fn next(&mut self) -> Option<Self::Item> {
450 Some(
451 EarlyBinder { value: self.it.next()?, _tcx: PhantomData }
452 .instantiate(self.cx, self.args),
453 )
454 }
455
456 fn size_hint(&self) -> (usize, Option<usize>) {
457 self.it.size_hint()
458 }
459}
460
461impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A>
462where
463 Iter::IntoIter: DoubleEndedIterator,
464 Iter::Item: TypeFoldable<I>,
465 A: SliceLike<Item = I::GenericArg>,
466{
467 fn next_back(&mut self) -> Option<Self::Item> {
468 Some(
469 EarlyBinder { value: self.it.next_back()?, _tcx: PhantomData }
470 .instantiate(self.cx, self.args),
471 )
472 }
473}
474
475impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A>
476where
477 Iter::IntoIter: ExactSizeIterator,
478 Iter::Item: TypeFoldable<I>,
479 A: SliceLike<Item = I::GenericArg>,
480{
481}
482
483impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
484where
485 Iter::Item: Deref,
486 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
487{
488 pub fn iter_instantiated_copied(
489 self,
490 cx: I,
491 args: &'s [I::GenericArg],
492 ) -> IterInstantiatedCopied<'s, I, Iter> {
493 IterInstantiatedCopied { it: self.value.into_iter(), cx, args }
494 }
495
496 pub fn iter_identity_copied(self) -> IterIdentityCopied<Iter> {
499 IterIdentityCopied { it: self.value.into_iter() }
500 }
501}
502
503pub struct IterInstantiatedCopied<'a, I: Interner, Iter: IntoIterator> {
504 it: Iter::IntoIter,
505 cx: I,
506 args: &'a [I::GenericArg],
507}
508
509impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiatedCopied<'_, I, Iter>
510where
511 Iter::Item: Deref,
512 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
513{
514 type Item = <Iter::Item as Deref>::Target;
515
516 fn next(&mut self) -> Option<Self::Item> {
517 self.it.next().map(|value| {
518 EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args)
519 })
520 }
521
522 fn size_hint(&self) -> (usize, Option<usize>) {
523 self.it.size_hint()
524 }
525}
526
527impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, I, Iter>
528where
529 Iter::IntoIter: DoubleEndedIterator,
530 Iter::Item: Deref,
531 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
532{
533 fn next_back(&mut self) -> Option<Self::Item> {
534 self.it.next_back().map(|value| {
535 EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args)
536 })
537 }
538}
539
540impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiatedCopied<'_, I, Iter>
541where
542 Iter::IntoIter: ExactSizeIterator,
543 Iter::Item: Deref,
544 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
545{
546}
547
548pub struct IterIdentityCopied<Iter: IntoIterator> {
549 it: Iter::IntoIter,
550}
551
552impl<Iter: IntoIterator> Iterator for IterIdentityCopied<Iter>
553where
554 Iter::Item: Deref,
555 <Iter::Item as Deref>::Target: Copy,
556{
557 type Item = <Iter::Item as Deref>::Target;
558
559 fn next(&mut self) -> Option<Self::Item> {
560 self.it.next().map(|i| *i)
561 }
562
563 fn size_hint(&self) -> (usize, Option<usize>) {
564 self.it.size_hint()
565 }
566}
567
568impl<Iter: IntoIterator> DoubleEndedIterator for IterIdentityCopied<Iter>
569where
570 Iter::IntoIter: DoubleEndedIterator,
571 Iter::Item: Deref,
572 <Iter::Item as Deref>::Target: Copy,
573{
574 fn next_back(&mut self) -> Option<Self::Item> {
575 self.it.next_back().map(|i| *i)
576 }
577}
578
579impl<Iter: IntoIterator> ExactSizeIterator for IterIdentityCopied<Iter>
580where
581 Iter::IntoIter: ExactSizeIterator,
582 Iter::Item: Deref,
583 <Iter::Item as Deref>::Target: Copy,
584{
585}
586pub struct EarlyBinderIter<I, T> {
587 t: T,
588 _tcx: PhantomData<I>,
589}
590
591impl<I: Interner, T: IntoIterator> EarlyBinder<I, T> {
592 pub fn transpose_iter(self) -> EarlyBinderIter<I, T::IntoIter> {
593 EarlyBinderIter { t: self.value.into_iter(), _tcx: PhantomData }
594 }
595}
596
597impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
598 type Item = EarlyBinder<I, T::Item>;
599
600 fn next(&mut self) -> Option<Self::Item> {
601 self.t.next().map(|value| EarlyBinder { value, _tcx: PhantomData })
602 }
603
604 fn size_hint(&self) -> (usize, Option<usize>) {
605 self.t.size_hint()
606 }
607}
608
609impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
610 pub fn instantiate<A>(self, cx: I, args: A) -> T
611 where
612 A: SliceLike<Item = I::GenericArg>,
613 {
614 let mut folder = ArgFolder { cx, args: args.as_slice(), binders_passed: 0 };
615 self.value.fold_with(&mut folder)
616 }
617
618 pub fn instantiate_identity(self) -> T {
627 self.value
628 }
629
630 pub fn no_bound_vars(self) -> Option<T> {
632 if !self.value.has_param() { Some(self.value) } else { None }
633 }
634}
635
636struct ArgFolder<'a, I: Interner> {
640 cx: I,
641 args: &'a [I::GenericArg],
642
643 binders_passed: u32,
645}
646
647impl<'a, I: Interner> TypeFolder<I> for ArgFolder<'a, I> {
648 #[inline]
649 fn cx(&self) -> I {
650 self.cx
651 }
652
653 fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
654 self.binders_passed += 1;
655 let t = t.super_fold_with(self);
656 self.binders_passed -= 1;
657 t
658 }
659
660 fn fold_region(&mut self, r: I::Region) -> I::Region {
661 match r.kind() {
667 ty::ReEarlyParam(data) => {
668 let rk = self.args.get(data.index() as usize).map(|k| k.kind());
669 match rk {
670 Some(ty::GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
671 Some(other) => self.region_param_expected(data, r, other),
672 None => self.region_param_out_of_range(data, r),
673 }
674 }
675 ty::ReBound(..)
676 | ty::ReLateParam(_)
677 | ty::ReStatic
678 | ty::RePlaceholder(_)
679 | ty::ReErased
680 | ty::ReError(_) => r,
681 ty::ReVar(_) => panic!("unexpected region: {r:?}"),
682 }
683 }
684
685 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
686 if !t.has_param() {
687 return t;
688 }
689
690 match t.kind() {
691 ty::Param(p) => self.ty_for_param(p, t),
692 _ => t.super_fold_with(self),
693 }
694 }
695
696 fn fold_const(&mut self, c: I::Const) -> I::Const {
697 if let ty::ConstKind::Param(p) = c.kind() {
698 self.const_for_param(p, c)
699 } else {
700 c.super_fold_with(self)
701 }
702 }
703}
704
705impl<'a, I: Interner> ArgFolder<'a, I> {
706 fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty {
707 let opt_ty = self.args.get(p.index() as usize).map(|k| k.kind());
709 let ty = match opt_ty {
710 Some(ty::GenericArgKind::Type(ty)) => ty,
711 Some(kind) => self.type_param_expected(p, source_ty, kind),
712 None => self.type_param_out_of_range(p, source_ty),
713 };
714
715 self.shift_vars_through_binders(ty)
716 }
717
718 #[cold]
719 #[inline(never)]
720 fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind<I>) -> ! {
721 panic!(
722 "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}",
723 p,
724 ty,
725 p.index(),
726 kind,
727 self.args,
728 )
729 }
730
731 #[cold]
732 #[inline(never)]
733 fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! {
734 panic!(
735 "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}",
736 p,
737 ty,
738 p.index(),
739 self.args,
740 )
741 }
742
743 fn const_for_param(&self, p: I::ParamConst, source_ct: I::Const) -> I::Const {
744 let opt_ct = self.args.get(p.index() as usize).map(|k| k.kind());
746 let ct = match opt_ct {
747 Some(ty::GenericArgKind::Const(ct)) => ct,
748 Some(kind) => self.const_param_expected(p, source_ct, kind),
749 None => self.const_param_out_of_range(p, source_ct),
750 };
751
752 self.shift_vars_through_binders(ct)
753 }
754
755 #[cold]
756 #[inline(never)]
757 fn const_param_expected(
758 &self,
759 p: I::ParamConst,
760 ct: I::Const,
761 kind: ty::GenericArgKind<I>,
762 ) -> ! {
763 panic!(
764 "expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
765 p,
766 ct,
767 p.index(),
768 kind,
769 self.args,
770 )
771 }
772
773 #[cold]
774 #[inline(never)]
775 fn const_param_out_of_range(&self, p: I::ParamConst, ct: I::Const) -> ! {
776 panic!(
777 "const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
778 p,
779 ct,
780 p.index(),
781 self.args,
782 )
783 }
784
785 #[cold]
786 #[inline(never)]
787 fn region_param_expected(
788 &self,
789 ebr: I::EarlyParamRegion,
790 r: I::Region,
791 kind: ty::GenericArgKind<I>,
792 ) -> ! {
793 panic!(
794 "expected region for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
795 ebr,
796 r,
797 ebr.index(),
798 kind,
799 self.args,
800 )
801 }
802
803 #[cold]
804 #[inline(never)]
805 fn region_param_out_of_range(&self, ebr: I::EarlyParamRegion, r: I::Region) -> ! {
806 panic!(
807 "region parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
808 ebr,
809 r,
810 ebr.index(),
811 self.args,
812 )
813 }
814
815 #[instrument(level = "trace", skip(self), fields(binders_passed = self.binders_passed), ret)]
858 fn shift_vars_through_binders<T: TypeFoldable<I>>(&self, val: T) -> T {
859 if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
860 val
861 } else {
862 ty::fold::shift_vars(self.cx, val, self.binders_passed)
863 }
864 }
865
866 fn shift_region_through_binders(&self, region: I::Region) -> I::Region {
867 if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
868 region
869 } else {
870 ty::fold::shift_region(self.cx, region, self.binders_passed)
871 }
872 }
873}