]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-ir-0.25.0/src/fold/subst.rs
2 use crate::fold
::shift
::Shift
;
4 /// Substitution used during folding
5 pub struct Subst
<'s
, 'i
, I
: Interner
> {
6 /// Values to substitute. A reference to a free variable with
7 /// index `i` will be mapped to `parameters[i]` -- if `i >
8 /// parameters.len()`, then we will leave the variable untouched.
9 parameters
: &'s
[GenericArg
<I
>],
13 impl<I
: Interner
> Subst
<'_
, '_
, I
> {
14 /// Applies the substitution by folding
15 pub fn apply
<T
: Fold
<I
, I
>>(
17 parameters
: &[GenericArg
<I
>],
26 DebruijnIndex
::INNERMOST
,
32 impl<'i
, I
: Interner
> Folder
<'i
, I
> for Subst
<'_
, 'i
, I
> {
33 fn as_dyn(&mut self) -> &mut dyn Folder
<'i
, I
> {
37 /// We are eliminating one binder, but binders outside of that get preserved.
39 /// So e.g. consider this:
42 /// for<A, B> { for<C> { [A, C] } }
43 /// // ^ the binder we are substituing with `[u32]`
46 /// Here, `A` would be `^1.0` and `C` would be `^0.0`. We will replace `^0.0` with the
47 /// 0th index from the list (`u32`). We will convert `^1.0` (A) to `^0.0` -- i.e., shift
48 /// it **out** of one level of binder (the `for<C>` binder we are eliminating).
50 /// This gives us as a result:
53 /// for<A, B> { [A, u32] }
54 /// ^ represented as `^0.0`
59 outer_binder
: DebruijnIndex
,
60 ) -> Fallible
<Ty
<I
>> {
61 if let Some(index
) = bound_var
.index_if_innermost() {
62 match self.parameters
[index
].data(self.interner()) {
63 GenericArgData
::Ty(t
) => Ok(t
.shifted_in_from(self.interner(), outer_binder
)),
64 _
=> panic
!("mismatched kinds in substitution"),
69 .expect("cannot fail because this is not the innermost")
70 .shifted_in_from(outer_binder
)
71 .to_ty(self.interner()))
75 /// see `fold_free_var_ty`
76 fn fold_free_var_lifetime(
79 outer_binder
: DebruijnIndex
,
80 ) -> Fallible
<Lifetime
<I
>> {
81 if let Some(index
) = bound_var
.index_if_innermost() {
82 match self.parameters
[index
].data(self.interner()) {
83 GenericArgData
::Lifetime(l
) => Ok(l
.shifted_in_from(self.interner(), outer_binder
)),
84 _
=> panic
!("mismatched kinds in substitution"),
90 .shifted_in_from(outer_binder
)
91 .to_lifetime(self.interner()))
95 /// see `fold_free_var_ty`
96 fn fold_free_var_const(
100 outer_binder
: DebruijnIndex
,
101 ) -> Fallible
<Const
<I
>> {
102 if let Some(index
) = bound_var
.index_if_innermost() {
103 match self.parameters
[index
].data(self.interner()) {
104 GenericArgData
::Const(c
) => Ok(c
.shifted_in_from(self.interner(), outer_binder
)),
105 _
=> panic
!("mismatched kinds in substitution"),
111 .shifted_in_from(outer_binder
)
112 .to_const(self.interner(), ty
.clone()))
116 fn interner(&self) -> &'i I
{
120 fn target_interner(&self) -> &'i I
{