]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-ir-0.55.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
>>(interner
: &I
, parameters
: &[GenericArg
<I
>], value
: T
) -> T
::Result
{
22 DebruijnIndex
::INNERMOST
,
28 impl<'i
, I
: Interner
> Folder
<'i
, I
> for Subst
<'_
, 'i
, I
> {
29 fn as_dyn(&mut self) -> &mut dyn Folder
<'i
, I
> {
33 /// We are eliminating one binder, but binders outside of that get preserved.
35 /// So e.g. consider this:
38 /// for<A, B> { for<C> { [A, C] } }
39 /// // ^ the binder we are substituing with `[u32]`
42 /// Here, `A` would be `^1.0` and `C` would be `^0.0`. We will replace `^0.0` with the
43 /// 0th index from the list (`u32`). We will convert `^1.0` (A) to `^0.0` -- i.e., shift
44 /// it **out** of one level of binder (the `for<C>` binder we are eliminating).
46 /// This gives us as a result:
49 /// for<A, B> { [A, u32] }
50 /// ^ represented as `^0.0`
55 outer_binder
: DebruijnIndex
,
56 ) -> Fallible
<Ty
<I
>> {
57 if let Some(index
) = bound_var
.index_if_innermost() {
58 match self.parameters
[index
].data(self.interner()) {
59 GenericArgData
::Ty(t
) => {
60 Ok(t
.clone().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
) => {
82 Ok(l
.clone().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
) => {
105 Ok(c
.clone().shifted_in_from(self.interner(), outer_binder
))
107 _
=> panic
!("mismatched kinds in substitution"),
113 .shifted_in_from(outer_binder
)
114 .to_const(self.interner(), ty
))
118 fn interner(&self) -> &'i I
{