diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index d6d3978385d9..d5a1d2113674 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -657,7 +657,7 @@ fn expected_type_and_name<'db>( cov_mark::hit!(expected_type_fn_param); ActiveParameter::at_token( sema, - token.clone(), + token.clone(), ).map(|ap| { let name = ap.ident().map(NameOrNameRef::Name); (Some(ap.ty), name) diff --git a/crates/ide-completion/src/context/tests.rs b/crates/ide-completion/src/context/tests.rs index 51d28bd4ff98..41f0db3c5282 100644 --- a/crates/ide-completion/src/context/tests.rs +++ b/crates/ide-completion/src/context/tests.rs @@ -90,6 +90,20 @@ fn bar(x: u32) {} "#, expect![[r#"ty: u32, name: x"#]], ); + check_expected_type_and_name( + r#" +fn foo() { bar(, $0); } +fn bar(x: u32, y: i32) {} +"#, + expect![[r#"ty: i32, name: y"#]], + ); + check_expected_type_and_name( + r#" +fn foo() { bar(, c$0); } +fn bar(x: u32, y: i32) {} +"#, + expect![[r#"ty: i32, name: y"#]], + ); } #[test] diff --git a/crates/ide-db/src/active_parameter.rs b/crates/ide-db/src/active_parameter.rs index 4fb7d142ed5f..f5a5b76c336a 100644 --- a/crates/ide-db/src/active_parameter.rs +++ b/crates/ide-db/src/active_parameter.rs @@ -5,7 +5,7 @@ use hir::{InFile, Semantics, Type}; use parser::T; use span::TextSize; use syntax::{ - AstNode, NodeOrToken, SyntaxToken, + AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, ast::{self, AstChildren, HasArgList, HasAttrs, HasName}, match_ast, }; @@ -102,8 +102,7 @@ pub fn callable_for_node<'db>( arg_list .syntax() .children_with_tokens() - .filter_map(NodeOrToken::into_token) - .filter(|t| t.kind() == T![,]) + .filter_map(into_comma) .take_while(|t| t.text_range().start() <= offset) .count() }); @@ -162,8 +161,7 @@ pub fn generic_def_for_node( let active_param = generic_arg_list .syntax() .children_with_tokens() - .filter_map(NodeOrToken::into_token) - .filter(|t| t.kind() == T![,]) + .filter_map(into_comma) .take_while(|t| t.text_range().start() <= token.text_range().start()) .count(); @@ -174,3 +172,12 @@ pub fn generic_def_for_node( Some((def, active_param, first_arg_is_non_lifetime, variant)) } + +fn into_comma(it: NodeOrToken) -> Option { + 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) +}