mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
Auto merge of #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 #17871 We call `generic_args_sans_defaults` here;64a140527b/crates/hir-ty/src/display.rs (L1021-L1034)
but the following substitution inside that function panic in #17871;64a140527b/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`
This commit is contained in:
commit
2b86639018
2 changed files with 35 additions and 8 deletions
|
@ -1019,26 +1019,25 @@ impl HirDisplay for Ty {
|
||||||
let (parent_len, self_param, type_, const_, impl_, lifetime) =
|
let (parent_len, self_param, type_, const_, impl_, lifetime) =
|
||||||
generics.provenance_split();
|
generics.provenance_split();
|
||||||
let parameters = parameters.as_slice(Interner);
|
let parameters = parameters.as_slice(Interner);
|
||||||
|
debug_assert_eq!(
|
||||||
|
parameters.len(),
|
||||||
|
parent_len + self_param as usize + type_ + const_ + impl_ + lifetime
|
||||||
|
);
|
||||||
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
|
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
|
||||||
if parameters.len() - impl_ > 0 {
|
if parameters.len() - impl_ > 0 {
|
||||||
// `parameters` are in the order of fn's params (including impl traits), fn's lifetimes
|
// `parameters` are in the order of fn's params (including impl traits), fn's lifetimes
|
||||||
|
let parameters =
|
||||||
|
generic_args_sans_defaults(f, Some(generic_def_id), parameters);
|
||||||
let without_impl = self_param as usize + type_ + const_ + lifetime;
|
let without_impl = self_param as usize + type_ + const_ + lifetime;
|
||||||
// parent's params (those from enclosing impl or trait, if any).
|
// parent's params (those from enclosing impl or trait, if any).
|
||||||
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
|
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
|
||||||
debug_assert_eq!(parent_params.len(), parent_len);
|
|
||||||
|
|
||||||
let parent_params =
|
|
||||||
generic_args_sans_defaults(f, Some(generic_def_id), parent_params);
|
|
||||||
let fn_params =
|
|
||||||
&generic_args_sans_defaults(f, Some(generic_def_id), fn_params)
|
|
||||||
[0..without_impl];
|
|
||||||
|
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
hir_fmt_generic_arguments(f, parent_params, None)?;
|
hir_fmt_generic_arguments(f, parent_params, None)?;
|
||||||
if !parent_params.is_empty() && !fn_params.is_empty() {
|
if !parent_params.is_empty() && !fn_params.is_empty() {
|
||||||
write!(f, ", ")?;
|
write!(f, ", ")?;
|
||||||
}
|
}
|
||||||
hir_fmt_generic_arguments(f, fn_params, None)?;
|
hir_fmt_generic_arguments(f, &fn_params[0..without_impl], None)?;
|
||||||
write!(f, ">")?;
|
write!(f, ">")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8602,3 +8602,31 @@ fn test() {
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_17871() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
trait T {
|
||||||
|
fn f<A>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {}
|
||||||
|
impl T for S {
|
||||||
|
fn f<A>() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x$0 = S::f::<i32>;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*x*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// size = 0, align = 1
|
||||||
|
let x: fn f<S, i32>()
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue