Merge pull request #19613 from ChayimFriedman2/subst

fix: Fix a panic when a trait method in an impl declares a lifetime parameter not in the trait declaration
This commit is contained in:
Lukas Wirth 2025-04-18 18:51:14 +00:00 committed by GitHub
commit a09a5502c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 8 deletions

View File

@ -3773,17 +3773,23 @@ impl GenericSubstitution {
TypeOrConstParamData::ConstParamData(_) => None, TypeOrConstParamData::ConstParamData(_) => None,
}); });
// The `Substitution` is first self then container, we want the reverse order. // The `Substitution` is first self then container, we want the reverse order.
let self_params = self.subst.type_parameters(Interner).zip(type_params); let subst_type_params = self.subst.type_parameters(Interner).collect::<Vec<_>>();
let container_params = self.subst.as_slice(Interner)[generics.len()..] let mut self_params = subst_type_params
.iter() .iter()
.filter_map(|param| param.ty(Interner).cloned()) .zip(type_params)
.zip(container_type_params.into_iter().flatten());
container_params
.chain(self_params)
.filter_map(|(ty, name)| { .filter_map(|(ty, name)| {
Some((name?.symbol().clone(), Type { ty, env: self.env.clone() })) Some((name?.symbol().clone(), Type { ty: ty.clone(), env: self.env.clone() }))
}) })
.collect() .collect::<Vec<_>>();
let mut container_params = subst_type_params[self_params.len()..]
.iter()
.zip(container_type_params.into_iter().flatten())
.filter_map(|(ty, name)| {
Some((name?.symbol().clone(), Type { ty: ty.clone(), env: self.env.clone() }))
})
.collect::<Vec<_>>();
container_params.append(&mut self_params);
container_params
} }
} }

View File

@ -10762,3 +10762,35 @@ fn bar(v: &Foo<i32>) {
"#]], "#]],
); );
} }
#[test]
fn extra_lifetime_param_on_trait_method_subst() {
check(
r#"
struct AudioFormat;
trait ValueEnum {
fn to_possible_value(&self);
}
impl ValueEnum for AudioFormat {
fn to_possible_value<'a>(&'a self) {}
}
fn main() {
ValueEnum::to_possible_value$0(&AudioFormat);
}
"#,
expect![[r#"
*to_possible_value*
```rust
ra_test_fixture::AudioFormat
```
```rust
fn to_possible_value<'a>(&'a self)
```
"#]],
);
}