]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-ir-0.14.0/src/fold/subst.rs
2 use crate::fold
::shift
::Shift
;
4 pub struct Subst
<'s
, 'i
, I
: Interner
> {
5 /// Values to substitute. A reference to a free variable with
6 /// index `i` will be mapped to `parameters[i]` -- if `i >
7 /// parameters.len()`, then we will leave the variable untouched.
8 parameters
: &'s
[GenericArg
<I
>],
12 impl<I
: Interner
> Subst
<'_
, '_
, I
> {
13 pub fn apply
<T
: Fold
<I
, I
>>(
15 parameters
: &[GenericArg
<I
>],
24 DebruijnIndex
::INNERMOST
,
30 impl<'i
, I
: Interner
> Folder
<'i
, I
> for Subst
<'_
, 'i
, I
> {
31 fn as_dyn(&mut self) -> &mut dyn Folder
<'i
, I
> {
35 /// We are eliminating one binder, but binders outside of that get preserved.
37 /// So e.g. consider this:
40 /// for<A, B> { for<C> { [A, C] } }
41 /// // ^ the binder we are substituing with `[u32]`
44 /// Here, `A` would be `^1.0` and `C` would be `^0.0`. We will replace `^0.0` with the
45 /// 0th index from the list (`u32`). We will convert `^1.0` (A) to `^0.0` -- i.e., shift
46 /// it **out** of one level of binder (the `for<C>` binder we are eliminating).
48 /// This gives us as a result:
51 /// for<A, B> { [A, u32] }
52 /// ^ represented as `^0.0`
57 outer_binder
: DebruijnIndex
,
58 ) -> Fallible
<Ty
<I
>> {
59 if let Some(index
) = bound_var
.index_if_innermost() {
60 match self.parameters
[index
].data(self.interner()) {
61 GenericArgData
::Ty(t
) => Ok(t
.shifted_in_from(self.interner(), outer_binder
)),
62 _
=> panic
!("mismatched kinds in substitution"),
67 .expect("cannot fail because this is not the innermost")
68 .shifted_in_from(outer_binder
)
69 .to_ty(self.interner()))
73 /// see `fold_free_var_ty`
74 fn fold_free_var_lifetime(
77 outer_binder
: DebruijnIndex
,
78 ) -> Fallible
<Lifetime
<I
>> {
79 if let Some(index
) = bound_var
.index_if_innermost() {
80 match self.parameters
[index
].data(self.interner()) {
81 GenericArgData
::Lifetime(l
) => Ok(l
.shifted_in_from(self.interner(), outer_binder
)),
82 _
=> panic
!("mismatched kinds in substitution"),
88 .shifted_in_from(outer_binder
)
89 .to_lifetime(self.interner()))
93 /// see `fold_free_var_ty`
94 fn fold_free_var_const(
98 outer_binder
: DebruijnIndex
,
99 ) -> Fallible
<Const
<I
>> {
100 if let Some(index
) = bound_var
.index_if_innermost() {
101 match self.parameters
[index
].data(self.interner()) {
102 GenericArgData
::Const(c
) => Ok(c
.shifted_in_from(self.interner(), outer_binder
)),
103 _
=> panic
!("mismatched kinds in substitution"),
109 .shifted_in_from(outer_binder
)
110 .to_const(self.interner(), ty
.clone()))
114 fn interner(&self) -> &'i I
{
118 fn target_interner(&self) -> &'i I
{