Skip to content

Commit 5f147cc

Browse files
Merge pull request #21926 from A4-Tacks/inlayhint-empty-arg
fix: Fix param inlayHints on empty expr and comma
2 parents 1fd88f5 + dff1339 commit 5f147cc

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

crates/ide/src/inlay_hints/param_name.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ pub(super) fn hints(
3737
let hints = callable
3838
.params()
3939
.into_iter()
40-
.zip(arg_list.args())
40+
.zip(arg_list.args_maybe_empty())
4141
.filter_map(|(p, arg)| {
42+
let arg = arg?;
4243
// Only annotate hints for expressions that exist in the original file
4344
let range = sema.original_range_opt(arg.syntax())?;
4445
if range.file_id != file_id {
@@ -561,6 +562,19 @@ fn main() {
561562
)
562563
}
563564

565+
#[test]
566+
fn param_name_hints_show_after_empty_arg() {
567+
check_params(
568+
r#"pub fn test(a: i32, b: i32, c: i32) {}
569+
fn main() {
570+
test(, 2,);
571+
//^ b
572+
test(, , 3);
573+
//^ c
574+
}"#,
575+
)
576+
}
577+
564578
#[test]
565579
fn function_call_parameter_hint() {
566580
check_params(

crates/syntax/src/ast/node_ext.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
7777
}
7878
}
7979

80+
fn into_comma(it: NodeOrToken<SyntaxNode, SyntaxToken>) -> Option<SyntaxToken> {
81+
let token = match it {
82+
NodeOrToken::Token(it) => it,
83+
NodeOrToken::Node(node) if node.kind() == SyntaxKind::ERROR => node.first_token()?,
84+
NodeOrToken::Node(_) => return None,
85+
};
86+
(token.kind() == T![,]).then_some(token)
87+
}
88+
8089
impl ast::Abi {
8190
pub fn abi_string(&self) -> Option<ast::String> {
8291
support::token(&self.syntax, SyntaxKind::STRING).and_then(ast::String::cast)
@@ -1037,6 +1046,21 @@ impl ast::GenericParamList {
10371046
}
10381047
}
10391048

1049+
impl ast::ArgList {
1050+
/// Comma separated args, argument may be empty
1051+
pub fn args_maybe_empty(&self) -> impl Iterator<Item = Option<ast::Expr>> {
1052+
// (Expr? ','?)*
1053+
let mut after_arg = false;
1054+
self.syntax().children_with_tokens().filter_map(move |it| {
1055+
if into_comma(it.clone()).is_some() {
1056+
if std::mem::take(&mut after_arg) { None } else { Some(None) }
1057+
} else {
1058+
Some(ast::Expr::cast(it.into_node()?).inspect(|_| after_arg = true))
1059+
}
1060+
})
1061+
}
1062+
}
1063+
10401064
impl ast::ForExpr {
10411065
pub fn iterable(&self) -> Option<ast::Expr> {
10421066
// If the iterable is a BlockExpr, check if the body is missing.

0 commit comments

Comments
 (0)