Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21926 from A4-Tacks/inlayhint-empty-arg
fix: Fix param inlayHints on empty expr and comma
Chayim Refael Friedman 7 weeks ago
parent 1fd88f5 · parent dff1339 · commit 5f147cc
-rw-r--r--crates/ide/src/inlay_hints/param_name.rs16
-rw-r--r--crates/syntax/src/ast/node_ext.rs24
2 files changed, 39 insertions, 1 deletions
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index 08588bbed0..8dddf9d37e 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -37,8 +37,9 @@ pub(super) fn hints(
let hints = callable
.params()
.into_iter()
- .zip(arg_list.args())
+ .zip(arg_list.args_maybe_empty())
.filter_map(|(p, arg)| {
+ let arg = arg?;
// Only annotate hints for expressions that exist in the original file
let range = sema.original_range_opt(arg.syntax())?;
if range.file_id != file_id {
@@ -562,6 +563,19 @@ fn main() {
}
#[test]
+ fn param_name_hints_show_after_empty_arg() {
+ check_params(
+ r#"pub fn test(a: i32, b: i32, c: i32) {}
+fn main() {
+ test(, 2,);
+ //^ b
+ test(, , 3);
+ //^ c
+}"#,
+ )
+ }
+
+ #[test]
fn function_call_parameter_hint() {
check_params(
r#"
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 63e4608d0f..3fc3b39fee 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -77,6 +77,15 @@ fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
}
}
+fn into_comma(it: NodeOrToken<SyntaxNode, SyntaxToken>) -> Option<SyntaxToken> {
+ let token = match it {
+ NodeOrToken::Token(it) => it,
+ NodeOrToken::Node(node) if node.kind() == SyntaxKind::ERROR => node.first_token()?,
+ NodeOrToken::Node(_) => return None,
+ };
+ (token.kind() == T![,]).then_some(token)
+}
+
impl ast::Abi {
pub fn abi_string(&self) -> Option<ast::String> {
support::token(&self.syntax, SyntaxKind::STRING).and_then(ast::String::cast)
@@ -1037,6 +1046,21 @@ impl ast::GenericParamList {
}
}
+impl ast::ArgList {
+ /// Comma separated args, argument may be empty
+ pub fn args_maybe_empty(&self) -> impl Iterator<Item = Option<ast::Expr>> {
+ // (Expr? ','?)*
+ let mut after_arg = false;
+ self.syntax().children_with_tokens().filter_map(move |it| {
+ if into_comma(it.clone()).is_some() {
+ if std::mem::take(&mut after_arg) { None } else { Some(None) }
+ } else {
+ Some(ast::Expr::cast(it.into_node()?).inspect(|_| after_arg = true))
+ }
+ })
+ }
+}
+
impl ast::ForExpr {
pub fn iterable(&self) -> Option<ast::Expr> {
// If the iterable is a BlockExpr, check if the body is missing.