feat: Improve hover too long parameter list

Example
---
```rust
fn fn_$0(
    attrs: impl IntoIterator<Item = ast::Attr>,
    visibility: Option<ast::Visibility>,
    fn_name: ast::Name,
    type_params: Option<ast::GenericParamList>,
    where_clause: Option<ast::WhereClause>,
    params: ast::ParamList,
    body: ast::BlockExpr,
    ret_type: Option<ast::RetType>,
    is_async: bool,
    is_const: bool,
    is_unsafe: bool,
    is_gen: bool,
) -> ast::Fn {}
```

**Before this PR**

```rust
fn fn_(attrs: impl IntoIterator<Item = ast::Attr>, visibility: Option<ast::Visibility>, fn_name: ast::Name, type_params: Option<ast::GenericParamList>, where_clause: Option<ast::WhereClause>, params: ast::ParamList, body: ast::BlockExpr, ret_type: Option<ast::RetType>, is_async: bool, is_const: bool, is_unsafe: bool, is_gen: bool) -> ast::Fn
```

**After this PR**

```rust
fn fn_(
    attrs: impl IntoIterator<Item = ast::Attr>,
    visibility: Option<ast::Visibility>,
    fn_name: ast::Name,
    type_params: Option<ast::GenericParamList>,
    where_clause: Option<ast::WhereClause>,
    params: ast::ParamList,
    body: ast::BlockExpr,
    ret_type: Option<ast::RetType>,
    is_async: bool,
    is_const: bool,
    is_unsafe: bool,
    is_gen: bool
) -> ast::Fn
```
This commit is contained in:
A4-Tacks 2026-02-05 14:01:35 +08:00
parent ec6d039cec
commit 4b68f80a4e
No known key found for this signature in database
GPG key ID: 9E63F956E66DD9C7
2 changed files with 104 additions and 2 deletions

View file

@ -172,8 +172,13 @@ fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Re
write_generic_params(GenericDefId::FunctionId(func_id), f)?;
let too_long_param = data.params.len() > 4;
f.write_char('(')?;
if too_long_param {
f.write_str("\n ")?;
}
let mut first = true;
let mut skip_self = 0;
if let Some(self_param) = func.self_param(db) {
@ -182,11 +187,12 @@ fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Re
skip_self = 1;
}
let comma = if too_long_param { ",\n " } else { ", " };
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
let body = db.body(func_id.into());
for (type_ref, param) in data.params.iter().zip(func.assoc_fn_params(db)).skip(skip_self) {
if !first {
f.write_str(", ")?;
f.write_str(comma)?;
} else {
first = false;
}
@ -201,11 +207,14 @@ fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Re
if data.is_varargs() {
if !first {
f.write_str(", ")?;
f.write_str(comma)?;
}
f.write_str("...")?;
}
if too_long_param {
f.write_char('\n')?;
}
f.write_char(')')?;
// `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.

View file

@ -9719,6 +9719,99 @@ fn test_hover_function_with_pat_param() {
);
}
#[test]
fn test_hover_function_with_too_long_param() {
check(
r#"
fn fn_$0(
attrs: impl IntoIterator<Item = ast::Attr>,
visibility: Option<ast::Visibility>,
fn_name: ast::Name,
type_params: Option<ast::GenericParamList>,
where_clause: Option<ast::WhereClause>,
params: ast::ParamList,
body: ast::BlockExpr,
ret_type: Option<ast::RetType>,
is_async: bool,
is_const: bool,
is_unsafe: bool,
is_gen: bool,
) -> ast::Fn {}
"#,
expect![[r#"
*fn_*
```rust
ra_test_fixture
```
```rust
fn fn_(
attrs: impl IntoIterator<Item = ast::Attr>,
visibility: Option<ast::Visibility>,
fn_name: ast::Name,
type_params: Option<ast::GenericParamList>,
where_clause: Option<ast::WhereClause>,
params: ast::ParamList,
body: ast::BlockExpr,
ret_type: Option<ast::RetType>,
is_async: bool,
is_const: bool,
is_unsafe: bool,
is_gen: bool
) -> ast::Fn
```
"#]],
);
check(
r#"
fn fn_$0(
&self,
attrs: impl IntoIterator<Item = ast::Attr>,
visibility: Option<ast::Visibility>,
fn_name: ast::Name,
type_params: Option<ast::GenericParamList>,
where_clause: Option<ast::WhereClause>,
params: ast::ParamList,
body: ast::BlockExpr,
ret_type: Option<ast::RetType>,
is_async: bool,
is_const: bool,
is_unsafe: bool,
is_gen: bool,
...
) -> ast::Fn {}
"#,
expect![[r#"
*fn_*
```rust
ra_test_fixture
```
```rust
fn fn_(
&self,
attrs: impl IntoIterator<Item = ast::Attr>,
visibility: Option<ast::Visibility>,
fn_name: ast::Name,
type_params: Option<ast::GenericParamList>,
where_clause: Option<ast::WhereClause>,
params: ast::ParamList,
body: ast::BlockExpr,
ret_type: Option<ast::RetType>,
is_async: bool,
is_const: bool,
is_unsafe: bool,
is_gen: bool,
...
) -> ast::Fn
```
"#]],
);
}
#[test]
fn hover_path_inside_block_scope() {
check(