Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/fn_param.rs')
-rw-r--r--crates/ide-completion/src/completions/fn_param.rs40
1 files changed, 33 insertions, 7 deletions
diff --git a/crates/ide-completion/src/completions/fn_param.rs b/crates/ide-completion/src/completions/fn_param.rs
index 96dac66b8a..bd0b69215c 100644
--- a/crates/ide-completion/src/completions/fn_param.rs
+++ b/crates/ide-completion/src/completions/fn_param.rs
@@ -30,14 +30,27 @@ pub(crate) fn complete_fn_param(
_ => return None,
};
+ let qualifier = param_qualifier(param);
let comma_wrapper = comma_wrapper(ctx);
let mut add_new_item_to_acc = |label: &str| {
- let mk_item = |label: &str, range: TextRange| {
- CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition)
+ let label = label.strip_prefix(qualifier.as_str()).unwrap_or(label);
+ let insert = if label.starts_with('#') {
+ // FIXME: `#[attr] it: i32` -> `#[attr] mut it: i32`
+ label.to_smolstr()
+ } else {
+ format_smolstr!("{qualifier}{label}")
+ };
+ let mk_item = |insert_text: &str, range: TextRange| {
+ let mut item =
+ CompletionItem::new(CompletionItemKind::Binding, range, label, ctx.edition);
+ if insert_text != label {
+ item.insert_text(insert_text);
+ }
+ item
};
let item = match &comma_wrapper {
- Some((fmt, range)) => mk_item(&fmt(label), *range),
- None => mk_item(label, ctx.source_range()),
+ Some((fmt, range)) => mk_item(&fmt(&insert), *range),
+ None => mk_item(&insert, ctx.source_range()),
};
// Completion lookup is omitted intentionally here.
// See the full discussion: https://github.com/rust-lang/rust-analyzer/issues/12073
@@ -75,9 +88,6 @@ fn fill_fn_params(
let mut file_params = FxHashMap::default();
let mut extract_params = |f: ast::Fn| {
- if !is_simple_param(current_param) {
- return;
- }
f.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| {
if let Some(pat) = param.pat() {
let whole_param = param.to_smolstr();
@@ -88,6 +98,9 @@ fn fill_fn_params(
};
for node in ctx.token.parent_ancestors() {
+ if !is_simple_param(current_param) {
+ break;
+ }
match_ast! {
match node {
ast::SourceFile(it) => it.items().filter_map(|item| match item {
@@ -214,3 +227,16 @@ fn is_simple_param(param: &ast::Param) -> bool {
.pat()
.is_none_or(|pat| matches!(pat, ast::Pat::IdentPat(ident_pat) if ident_pat.pat().is_none()))
}
+
+fn param_qualifier(param: &ast::Param) -> SmolStr {
+ let mut b = syntax::SmolStrBuilder::new();
+ if let Some(ast::Pat::IdentPat(pat)) = param.pat() {
+ if pat.ref_token().is_some() {
+ b.push_str("ref ");
+ }
+ if pat.mut_token().is_some() {
+ b.push_str("mut ");
+ }
+ }
+ b.finish()
+}