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::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
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: rustc_serialize::Encoder> 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: rustc_serialize::Decoder> 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 let _ = 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 fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
127 folder.fold_binder(self)
128 }
129}
130
131impl<I: Interner, T: TypeFoldable<I>> TypeVisitable<I> for Binder<I, T> {
132 fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
133 visitor.visit_binder(self)
134 }
135}
136
137impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
138 fn try_super_fold_with<F: FallibleTypeFolder<I>>(
139 self,
140 folder: &mut F,
141 ) -> Result<Self, F::Error> {
142 self.try_map_bound(|t| t.try_fold_with(folder))
143 }
144
145 fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
146 self.map_bound(|t| t.fold_with(folder))
147 }
148}
149
150impl<I: Interner, T: TypeFoldable<I>> TypeSuperVisitable<I> for Binder<I, T> {
151 fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
152 self.as_ref().skip_binder().visit_with(visitor)
153 }
154}
155
156impl<I: Interner, T> Binder<I, T> {
157 pub fn skip_binder(self) -> T {
174 self.value
175 }
176
177 pub fn bound_vars(&self) -> I::BoundVarKinds {
178 self.bound_vars
179 }
180
181 pub fn as_ref(&self) -> Binder<I, &T> {
182 Binder { value: &self.value, bound_vars: self.bound_vars }
183 }
184
185 pub fn as_deref(&self) -> Binder<I, &T::Target>
186 where
187 T: Deref,
188 {
189 Binder { value: &self.value, bound_vars: self.bound_vars }
190 }
191
192 pub fn map_bound_ref<F, U: TypeVisitable<I>>(&self, f: F) -> Binder<I, U>
193 where
194 F: FnOnce(&T) -> U,
195 {
196 self.as_ref().map_bound(f)
197 }
198
199 pub fn map_bound<F, U: TypeVisitable<I>>(self, f: F) -> Binder<I, U>
200 where
201 F: FnOnce(T) -> U,
202 {
203 let Binder { value, bound_vars } = self;
204 let value = f(value);
205 if cfg!(debug_assertions) {
206 let mut validator = ValidateBoundVars::new(bound_vars);
207 let _ = value.visit_with(&mut validator);
208 }
209 Binder { value, bound_vars }
210 }
211
212 pub fn try_map_bound<F, U: TypeVisitable<I>, E>(self, f: F) -> Result<Binder<I, U>, E>
213 where
214 F: FnOnce(T) -> Result<U, E>,
215 {
216 let Binder { value, bound_vars } = self;
217 let value = f(value)?;
218 if cfg!(debug_assertions) {
219 let mut validator = ValidateBoundVars::new(bound_vars);
220 let _ = value.visit_with(&mut validator);
221 }
222 Ok(Binder { value, bound_vars })
223 }
224
225 pub fn rebind<U>(&self, value: U) -> Binder<I, U>
235 where
236 U: TypeVisitable<I>,
237 {
238 Binder::bind_with_vars(value, self.bound_vars)
239 }
240
241 pub fn no_bound_vars(self) -> Option<T>
252 where
253 T: TypeVisitable<I>,
254 {
255 if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
257 }
258}
259
260impl<I: Interner, T> Binder<I, Option<T>> {
261 pub fn transpose(self) -> Option<Binder<I, T>> {
262 let Binder { value, bound_vars } = self;
263 value.map(|value| Binder { value, bound_vars })
264 }
265}
266
267impl<I: Interner, T: IntoIterator> Binder<I, T> {
268 pub fn iter(self) -> impl Iterator<Item = Binder<I, T::Item>> {
269 let Binder { value, bound_vars } = self;
270 value.into_iter().map(move |value| Binder { value, bound_vars })
271 }
272}
273
274pub struct ValidateBoundVars<I: Interner> {
275 bound_vars: I::BoundVarKinds,
276 binder_index: ty::DebruijnIndex,
277 visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>,
280}
281
282impl<I: Interner> ValidateBoundVars<I> {
283 pub fn new(bound_vars: I::BoundVarKinds) -> Self {
284 ValidateBoundVars {
285 bound_vars,
286 binder_index: ty::INNERMOST,
287 visited: SsoHashSet::default(),
288 }
289 }
290}
291
292impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
293 type Result = ControlFlow<()>;
294
295 fn visit_binder<T: TypeFoldable<I>>(&mut self, t: &Binder<I, T>) -> Self::Result {
296 self.binder_index.shift_in(1);
297 let result = t.super_visit_with(self);
298 self.binder_index.shift_out(1);
299 result
300 }
301
302 fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
303 if t.outer_exclusive_binder() < self.binder_index
304 || !self.visited.insert((self.binder_index, t))
305 {
306 return ControlFlow::Break(());
307 }
308 match t.kind() {
309 ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
310 let idx = bound_ty.var().as_usize();
311 if self.bound_vars.len() <= idx {
312 panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
313 }
314 bound_ty.assert_eq(self.bound_vars.get(idx).unwrap());
315 }
316 _ => {}
317 };
318
319 t.super_visit_with(self)
320 }
321
322 fn visit_region(&mut self, r: I::Region) -> Self::Result {
323 match r.kind() {
324 ty::ReBound(index, br) if index == self.binder_index => {
325 let idx = br.var().as_usize();
326 if self.bound_vars.len() <= idx {
327 panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
328 }
329 br.assert_eq(self.bound_vars.get(idx).unwrap());
330 }
331
332 _ => (),
333 };
334
335 ControlFlow::Continue(())
336 }
337}
338
339#[derive_where(Clone; I: Interner, T: Clone)]
346#[derive_where(Copy; I: Interner, T: Copy)]
347#[derive_where(PartialEq; I: Interner, T: PartialEq)]
348#[derive_where(Eq; I: Interner, T: Eq)]
349#[derive_where(Ord; I: Interner, T: Ord)]
350#[derive_where(PartialOrd; I: Interner, T: Ord)]
351#[derive_where(Hash; I: Interner, T: Hash)]
352#[derive_where(Debug; I: Interner, T: Debug)]
353#[cfg_attr(
354 feature = "nightly",
355 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
356)]
357pub struct EarlyBinder<I: Interner, T> {
358 value: T,
359 #[derive_where(skip(Debug))]
360 _tcx: PhantomData<I>,
361}
362
363#[cfg(feature = "nightly")]
365impl<I: Interner, T> !TypeFoldable<I> for ty::EarlyBinder<I, T> {}
366
367#[cfg(feature = "nightly")]
369impl<I: Interner, T> !TypeVisitable<I> for ty::EarlyBinder<I, T> {}
370
371impl<I: Interner, T> EarlyBinder<I, T> {
372 pub fn bind(value: T) -> EarlyBinder<I, T> {
373 EarlyBinder { value, _tcx: PhantomData }
374 }
375
376 pub fn as_ref(&self) -> EarlyBinder<I, &T> {
377 EarlyBinder { value: &self.value, _tcx: PhantomData }
378 }
379
380 pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<I, U>
381 where
382 F: FnOnce(&T) -> U,
383 {
384 self.as_ref().map_bound(f)
385 }
386
387 pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<I, U>
388 where
389 F: FnOnce(T) -> U,
390 {
391 let value = f(self.value);
392 EarlyBinder { value, _tcx: PhantomData }
393 }
394
395 pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<I, U>, E>
396 where
397 F: FnOnce(T) -> Result<U, E>,
398 {
399 let value = f(self.value)?;
400 Ok(EarlyBinder { value, _tcx: PhantomData })
401 }
402
403 pub fn rebind<U>(&self, value: U) -> EarlyBinder<I, U> {
404 EarlyBinder { value, _tcx: PhantomData }
405 }
406
407 pub fn skip_binder(self) -> T {
419 self.value
420 }
421}
422
423impl<I: Interner, T> EarlyBinder<I, Option<T>> {
424 pub fn transpose(self) -> Option<EarlyBinder<I, T>> {
425 self.value.map(|value| EarlyBinder { value, _tcx: PhantomData })
426 }
427}
428
429impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
430where
431 Iter::Item: TypeFoldable<I>,
432{
433 pub fn iter_instantiated<A>(self, cx: I, args: A) -> IterInstantiated<I, Iter, A>
434 where
435 A: SliceLike<Item = I::GenericArg>,
436 {
437 IterInstantiated { it: self.value.into_iter(), cx, args }
438 }
439
440 pub fn iter_identity(self) -> Iter::IntoIter {
443 self.value.into_iter()
444 }
445}
446
447pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> {
448 it: Iter::IntoIter,
449 cx: I,
450 args: A,
451}
452
453impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A>
454where
455 Iter::Item: TypeFoldable<I>,
456 A: SliceLike<Item = I::GenericArg>,
457{
458 type Item = Iter::Item;
459
460 fn next(&mut self) -> Option<Self::Item> {
461 Some(
462 EarlyBinder { value: self.it.next()?, _tcx: PhantomData }
463 .instantiate(self.cx, self.args),
464 )
465 }
466
467 fn size_hint(&self) -> (usize, Option<usize>) {
468 self.it.size_hint()
469 }
470}
471
472impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A>
473where
474 Iter::IntoIter: DoubleEndedIterator,
475 Iter::Item: TypeFoldable<I>,
476 A: SliceLike<Item = I::GenericArg>,
477{
478 fn next_back(&mut self) -> Option<Self::Item> {
479 Some(
480 EarlyBinder { value: self.it.next_back()?, _tcx: PhantomData }
481 .instantiate(self.cx, self.args),
482 )
483 }
484}
485
486impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A>
487where
488 Iter::IntoIter: ExactSizeIterator,
489 Iter::Item: TypeFoldable<I>,
490 A: SliceLike<Item = I::GenericArg>,
491{
492}
493
494impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
495where
496 Iter::Item: Deref,
497 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
498{
499 pub fn iter_instantiated_copied(
500 self,
501 cx: I,
502 args: &'s [I::GenericArg],
503 ) -> IterInstantiatedCopied<'s, I, Iter> {
504 IterInstantiatedCopied { it: self.value.into_iter(), cx, args }
505 }
506
507 pub fn iter_identity_copied(self) -> IterIdentityCopied<Iter> {
510 IterIdentityCopied { it: self.value.into_iter() }
511 }
512}
513
514pub struct IterInstantiatedCopied<'a, I: Interner, Iter: IntoIterator> {
515 it: Iter::IntoIter,
516 cx: I,
517 args: &'a [I::GenericArg],
518}
519
520impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiatedCopied<'_, I, Iter>
521where
522 Iter::Item: Deref,
523 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
524{
525 type Item = <Iter::Item as Deref>::Target;
526
527 fn next(&mut self) -> Option<Self::Item> {
528 self.it.next().map(|value| {
529 EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args)
530 })
531 }
532
533 fn size_hint(&self) -> (usize, Option<usize>) {
534 self.it.size_hint()
535 }
536}
537
538impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, I, Iter>
539where
540 Iter::IntoIter: DoubleEndedIterator,
541 Iter::Item: Deref,
542 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
543{
544 fn next_back(&mut self) -> Option<Self::Item> {
545 self.it.next_back().map(|value| {
546 EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.cx, self.args)
547 })
548 }
549}
550
551impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiatedCopied<'_, I, Iter>
552where
553 Iter::IntoIter: ExactSizeIterator,
554 Iter::Item: Deref,
555 <Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
556{
557}
558
559pub struct IterIdentityCopied<Iter: IntoIterator> {
560 it: Iter::IntoIter,
561}
562
563impl<Iter: IntoIterator> Iterator for IterIdentityCopied<Iter>
564where
565 Iter::Item: Deref,
566 <Iter::Item as Deref>::Target: Copy,
567{
568 type Item = <Iter::Item as Deref>::Target;
569
570 fn next(&mut self) -> Option<Self::Item> {
571 self.it.next().map(|i| *i)
572 }
573
574 fn size_hint(&self) -> (usize, Option<usize>) {
575 self.it.size_hint()
576 }
577}
578
579impl<Iter: IntoIterator> DoubleEndedIterator for IterIdentityCopied<Iter>
580where
581 Iter::IntoIter: DoubleEndedIterator,
582 Iter::Item: Deref,
583 <Iter::Item as Deref>::Target: Copy,
584{
585 fn next_back(&mut self) -> Option<Self::Item> {
586 self.it.next_back().map(|i| *i)
587 }
588}
589
590impl<Iter: IntoIterator> ExactSizeIterator for IterIdentityCopied<Iter>
591where
592 Iter::IntoIter: ExactSizeIterator,
593 Iter::Item: Deref,
594 <Iter::Item as Deref>::Target: Copy,
595{
596}
597pub struct EarlyBinderIter<I, T> {
598 t: T,
599 _tcx: PhantomData<I>,
600}
601
602impl<I: Interner, T: IntoIterator> EarlyBinder<I, T> {
603 pub fn transpose_iter(self) -> EarlyBinderIter<I, T::IntoIter> {
604 EarlyBinderIter { t: self.value.into_iter(), _tcx: PhantomData }
605 }
606}
607
608impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
609 type Item = EarlyBinder<I, T::Item>;
610
611 fn next(&mut self) -> Option<Self::Item> {
612 self.t.next().map(|value| EarlyBinder { value, _tcx: PhantomData })
613 }
614
615 fn size_hint(&self) -> (usize, Option<usize>) {
616 self.t.size_hint()
617 }
618}
619
620impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
621 pub fn instantiate<A>(self, cx: I, args: A) -> T
622 where
623 A: SliceLike<Item = I::GenericArg>,
624 {
625 let mut folder = ArgFolder { cx, args: args.as_slice(), binders_passed: 0 };
626 self.value.fold_with(&mut folder)
627 }
628
629 pub fn instantiate_identity(self) -> T {
638 self.value
639 }
640
641 pub fn no_bound_vars(self) -> Option<T> {
643 if !self.value.has_param() { Some(self.value) } else { None }
644 }
645}
646
647struct ArgFolder<'a, I: Interner> {
651 cx: I,
652 args: &'a [I::GenericArg],
653
654 binders_passed: u32,
656}
657
658impl<'a, I: Interner> TypeFolder<I> for ArgFolder<'a, I> {
659 #[inline]
660 fn cx(&self) -> I {
661 self.cx
662 }
663
664 fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
665 self.binders_passed += 1;
666 let t = t.super_fold_with(self);
667 self.binders_passed -= 1;
668 t
669 }
670
671 fn fold_region(&mut self, r: I::Region) -> I::Region {
672 match r.kind() {
678 ty::ReEarlyParam(data) => {
679 let rk = self.args.get(data.index() as usize).map(|k| k.kind());
680 match rk {
681 Some(ty::GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
682 Some(other) => self.region_param_expected(data, r, other),
683 None => self.region_param_out_of_range(data, r),
684 }
685 }
686 ty::ReBound(..)
687 | ty::ReLateParam(_)
688 | ty::ReStatic
689 | ty::RePlaceholder(_)
690 | ty::ReErased
691 | ty::ReError(_) => r,
692 ty::ReVar(_) => panic!("unexpected region: {r:?}"),
693 }
694 }
695
696 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
697 if !t.has_param() {
698 return t;
699 }
700
701 match t.kind() {
702 ty::Param(p) => self.ty_for_param(p, t),
703 _ => t.super_fold_with(self),
704 }
705 }
706
707 fn fold_const(&mut self, c: I::Const) -> I::Const {
708 if let ty::ConstKind::Param(p) = c.kind() {
709 self.const_for_param(p, c)
710 } else {
711 c.super_fold_with(self)
712 }
713 }
714}
715
716impl<'a, I: Interner> ArgFolder<'a, I> {
717 fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty {
718 let opt_ty = self.args.get(p.index() as usize).map(|k| k.kind());
720 let ty = match opt_ty {
721 Some(ty::GenericArgKind::Type(ty)) => ty,
722 Some(kind) => self.type_param_expected(p, source_ty, kind),
723 None => self.type_param_out_of_range(p, source_ty),
724 };
725
726 self.shift_vars_through_binders(ty)
727 }
728
729 #[cold]
730 #[inline(never)]
731 fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind<I>) -> ! {
732 panic!(
733 "expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}",
734 p,
735 ty,
736 p.index(),
737 kind,
738 self.args,
739 )
740 }
741
742 #[cold]
743 #[inline(never)]
744 fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! {
745 panic!(
746 "type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}",
747 p,
748 ty,
749 p.index(),
750 self.args,
751 )
752 }
753
754 fn const_for_param(&self, p: I::ParamConst, source_ct: I::Const) -> I::Const {
755 let opt_ct = self.args.get(p.index() as usize).map(|k| k.kind());
757 let ct = match opt_ct {
758 Some(ty::GenericArgKind::Const(ct)) => ct,
759 Some(kind) => self.const_param_expected(p, source_ct, kind),
760 None => self.const_param_out_of_range(p, source_ct),
761 };
762
763 self.shift_vars_through_binders(ct)
764 }
765
766 #[cold]
767 #[inline(never)]
768 fn const_param_expected(
769 &self,
770 p: I::ParamConst,
771 ct: I::Const,
772 kind: ty::GenericArgKind<I>,
773 ) -> ! {
774 panic!(
775 "expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
776 p,
777 ct,
778 p.index(),
779 kind,
780 self.args,
781 )
782 }
783
784 #[cold]
785 #[inline(never)]
786 fn const_param_out_of_range(&self, p: I::ParamConst, ct: I::Const) -> ! {
787 panic!(
788 "const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
789 p,
790 ct,
791 p.index(),
792 self.args,
793 )
794 }
795
796 #[cold]
797 #[inline(never)]
798 fn region_param_expected(
799 &self,
800 ebr: I::EarlyParamRegion,
801 r: I::Region,
802 kind: ty::GenericArgKind<I>,
803 ) -> ! {
804 panic!(
805 "expected region for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
806 ebr,
807 r,
808 ebr.index(),
809 kind,
810 self.args,
811 )
812 }
813
814 #[cold]
815 #[inline(never)]
816 fn region_param_out_of_range(&self, ebr: I::EarlyParamRegion, r: I::Region) -> ! {
817 panic!(
818 "region parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
819 ebr,
820 r,
821 ebr.index(),
822 self.args,
823 )
824 }
825
826 #[instrument(level = "trace", skip(self), fields(binders_passed = self.binders_passed), ret)]
869 fn shift_vars_through_binders<T: TypeFoldable<I>>(&self, val: T) -> T {
870 if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
871 val
872 } else {
873 ty::shift_vars(self.cx, val, self.binders_passed)
874 }
875 }
876
877 fn shift_region_through_binders(&self, region: I::Region) -> I::Region {
878 if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
879 region
880 } else {
881 ty::shift_region(self.cx, region, self.binders_passed)
882 }
883 }
884}