Skip to content

Commit e20180d

Browse files
committed
Auto merge of rust-lang#17893 - ShoyuVanilla:issue-17871, r=flodiebold
fix: Panic while hovering associated function with type annotation on generic param that not inherited from its container type Fixes rust-lang#17871 We call `generic_args_sans_defaults` here; https://github.com/rust-lang/rust-analyzer/blob/64a140527b383e3a2fe95908881624fc5374c60c/crates/hir-ty/src/display.rs#L1021-L1034 but the following substitution inside that function panic in rust-lang#17871; https://github.com/rust-lang/rust-analyzer/blob/64a140527b383e3a2fe95908881624fc5374c60c/crates/hir-ty/src/display.rs#L1468 it's because the `Binders.binder` inside `default_parameters` has a same length with the generics of the function we are hovering on, but the generics of it is split into two, `fn_params` and `parent_params`. Because of this, it may panic if the function has one or more default parameters and both `fn_params` and `parent_params` are non-empty, like the case in the title of this PR. So, we must call `generic_args_sans_default` first and then split it into `fn_params` and `parent_params`
2 parents 89cd585 + b0183f8 commit e20180d

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/display.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1019,26 +1019,25 @@ impl HirDisplay for Ty {
10191019
let (parent_len, self_param, type_, const_, impl_, lifetime) =
10201020
generics.provenance_split();
10211021
let parameters = parameters.as_slice(Interner);
1022+
debug_assert_eq!(
1023+
parameters.len(),
1024+
parent_len + self_param as usize + type_ + const_ + impl_ + lifetime
1025+
);
10221026
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
10231027
if parameters.len() - impl_ > 0 {
10241028
// `parameters` are in the order of fn's params (including impl traits), fn's lifetimes
1029+
let parameters =
1030+
generic_args_sans_defaults(f, Some(generic_def_id), parameters);
10251031
let without_impl = self_param as usize + type_ + const_ + lifetime;
10261032
// parent's params (those from enclosing impl or trait, if any).
10271033
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
1028-
debug_assert_eq!(parent_params.len(), parent_len);
1029-
1030-
let parent_params =
1031-
generic_args_sans_defaults(f, Some(generic_def_id), parent_params);
1032-
let fn_params =
1033-
&generic_args_sans_defaults(f, Some(generic_def_id), fn_params)
1034-
[0..without_impl];
10351034

10361035
write!(f, "<")?;
10371036
hir_fmt_generic_arguments(f, parent_params, None)?;
10381037
if !parent_params.is_empty() && !fn_params.is_empty() {
10391038
write!(f, ", ")?;
10401039
}
1041-
hir_fmt_generic_arguments(f, fn_params, None)?;
1040+
hir_fmt_generic_arguments(f, &fn_params[0..without_impl], None)?;
10421041
write!(f, ">")?;
10431042
}
10441043
}

src/tools/rust-analyzer/crates/ide/src/hover/tests.rs

+28
Original file line numberDiff line numberDiff line change
@@ -8602,3 +8602,31 @@ fn test() {
86028602
"#]],
86038603
);
86048604
}
8605+
8606+
#[test]
8607+
fn issue_17871() {
8608+
check(
8609+
r#"
8610+
trait T {
8611+
fn f<A>();
8612+
}
8613+
8614+
struct S {}
8615+
impl T for S {
8616+
fn f<A>() {}
8617+
}
8618+
8619+
fn main() {
8620+
let x$0 = S::f::<i32>;
8621+
}
8622+
"#,
8623+
expect![[r#"
8624+
*x*
8625+
8626+
```rust
8627+
// size = 0, align = 1
8628+
let x: fn f<S, i32>()
8629+
```
8630+
"#]],
8631+
);
8632+
}

0 commit comments

Comments
 (0)