Skip to content

Commit 9b4fb79

Browse files
Fix a panic when a trait method in an impl declares a lifetime parameter not in the trait declaration
Shuffle the code a bit.
1 parent ea27351 commit 9b4fb79

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

crates/hir/src/lib.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -3773,17 +3773,22 @@ impl GenericSubstitution {
37733773
TypeOrConstParamData::ConstParamData(_) => None,
37743774
});
37753775
// The `Substitution` is first self then container, we want the reverse order.
3776-
let self_params = self.subst.type_parameters(Interner).zip(type_params);
3777-
let container_params = self.subst.as_slice(Interner)[generics.len()..]
3778-
.iter()
3779-
.filter_map(|param| param.ty(Interner).cloned())
3780-
.zip(container_type_params.into_iter().flatten());
3781-
container_params
3782-
.chain(self_params)
3776+
let mut subst_type_params = self.subst.type_parameters(Interner);
3777+
let mut self_params = subst_type_params
3778+
.by_ref()
3779+
.zip(type_params)
37833780
.filter_map(|(ty, name)| {
37843781
Some((name?.symbol().clone(), Type { ty, env: self.env.clone() }))
37853782
})
3786-
.collect()
3783+
.collect();
3784+
let mut container_params = subst_type_params
3785+
.zip(container_type_params.into_iter().flatten())
3786+
.filter_map(|(ty, name)| {
3787+
Some((name?.symbol().clone(), Type { ty, env: self.env.clone() }))
3788+
})
3789+
.collect::<Vec<_>>();
3790+
container_params.append(&mut self_params);
3791+
container_params
37873792
}
37883793
}
37893794

crates/ide/src/hover/tests.rs

+32
Original file line numberDiff line numberDiff line change
@@ -10762,3 +10762,35 @@ fn bar(v: &Foo<i32>) {
1076210762
"#]],
1076310763
);
1076410764
}
10765+
10766+
#[test]
10767+
fn extra_lifetime_param_on_trait_method_subst() {
10768+
check(
10769+
r#"
10770+
struct AudioFormat;
10771+
10772+
trait ValueEnum {
10773+
fn to_possible_value(&self);
10774+
}
10775+
10776+
impl ValueEnum for AudioFormat {
10777+
fn to_possible_value<'a>(&'a self) {}
10778+
}
10779+
10780+
fn main() {
10781+
ValueEnum::to_possible_value$0(&AudioFormat);
10782+
}
10783+
"#,
10784+
expect![[r#"
10785+
*to_possible_value*
10786+
10787+
```rust
10788+
ra_test_fixture::AudioFormat
10789+
```
10790+
10791+
```rust
10792+
fn to_possible_value<'a>(&'a self)
10793+
```
10794+
"#]],
10795+
);
10796+
}

0 commit comments

Comments
 (0)