Skip to content

Commit 9a3eae8

Browse files
committed
fix: don't add duplicate & during completion
1 parent f1097c2 commit 9a3eae8

File tree

2 files changed

+72
-68
lines changed

2 files changed

+72
-68
lines changed

crates/ide_completion/src/context.rs

+49-16
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,19 @@ impl<'a> CompletionContext<'a> {
385385
(ty, name)
386386
},
387387
ast::ArgList(_it) => {
388-
cov_mark::hit!(expected_type_fn_param_with_leading_char);
389-
cov_mark::hit!(expected_type_fn_param_without_leading_char);
388+
cov_mark::hit!(expected_type_fn_param);
390389
ActiveParameter::at_token(
391390
&self.sema,
392391
self.token.clone(),
393392
).map(|ap| {
394393
let name = ap.ident().map(NameOrNameRef::Name);
395-
(Some(ap.ty), name)
394+
let ty = if has_ref(&self.token) {
395+
cov_mark::hit!(expected_type_fn_param_ref);
396+
ap.ty.remove_ref()
397+
} else {
398+
Some(ap.ty)
399+
};
400+
(ty, name)
396401
})
397402
.unwrap_or((None, None))
398403
},
@@ -697,6 +702,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
697702
use_tree.path().zip(Some(true))
698703
}
699704

705+
fn has_ref(token: &SyntaxToken) -> bool {
706+
let mut token = token.clone();
707+
for skip in [WHITESPACE, IDENT, T![mut]] {
708+
if token.kind() == skip {
709+
token = match token.prev_token() {
710+
Some(it) => it,
711+
None => return false,
712+
}
713+
}
714+
}
715+
token.kind() == T![&]
716+
}
717+
700718
#[cfg(test)]
701719
mod tests {
702720
use expect_test::{expect, Expect};
@@ -769,33 +787,48 @@ fn foo() {
769787
}
770788

771789
#[test]
772-
fn expected_type_fn_param_without_leading_char() {
773-
cov_mark::check!(expected_type_fn_param_without_leading_char);
790+
fn expected_type_fn_param() {
791+
cov_mark::check!(expected_type_fn_param);
774792
check_expected_type_and_name(
775793
r#"
776-
fn foo() {
777-
bar($0);
778-
}
779-
794+
fn foo() { bar($0); }
795+
fn bar(x: u32) {}
796+
"#,
797+
expect![[r#"ty: u32, name: x"#]],
798+
);
799+
check_expected_type_and_name(
800+
r#"
801+
fn foo() { bar(c$0); }
780802
fn bar(x: u32) {}
781803
"#,
782804
expect![[r#"ty: u32, name: x"#]],
783805
);
784806
}
785807

786808
#[test]
787-
fn expected_type_fn_param_with_leading_char() {
788-
cov_mark::check!(expected_type_fn_param_with_leading_char);
809+
fn expected_type_fn_param_ref() {
810+
cov_mark::check!(expected_type_fn_param_ref);
789811
check_expected_type_and_name(
790812
r#"
791-
fn foo() {
792-
bar(c$0);
793-
}
794-
795-
fn bar(x: u32) {}
813+
fn foo() { bar(&$0); }
814+
fn bar(x: &u32) {}
796815
"#,
797816
expect![[r#"ty: u32, name: x"#]],
798817
);
818+
check_expected_type_and_name(
819+
r#"
820+
fn foo() { bar(&mut $0); }
821+
fn bar(x: &mut u32) {}
822+
"#,
823+
expect![[r#"ty: u32, name: x"#]],
824+
);
825+
check_expected_type_and_name(
826+
r#"
827+
fn foo() { bar(&c$0); }
828+
fn bar(x: &u32) {}
829+
"#,
830+
expect![[r#"ty: u32, name: x"#]],
831+
);
799832
}
800833

801834
#[test]

crates/ide_completion/src/render.rs

+23-52
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ fn f() {
10571057
#[test]
10581058
fn suggest_ref_mut() {
10591059
cov_mark::check!(suggest_ref);
1060-
check(
1060+
check_relevance(
10611061
r#"
10621062
struct S;
10631063
fn foo(s: &mut S) {}
@@ -1067,58 +1067,29 @@ fn main() {
10671067
}
10681068
"#,
10691069
expect![[r#"
1070-
[
1071-
CompletionItem {
1072-
label: "S",
1073-
source_range: 70..70,
1074-
delete: 70..70,
1075-
insert: "S",
1076-
kind: SymbolKind(
1077-
Struct,
1078-
),
1079-
},
1080-
CompletionItem {
1081-
label: "foo(…)",
1082-
source_range: 70..70,
1083-
delete: 70..70,
1084-
insert: "foo(${1:&mut s})$0",
1085-
kind: SymbolKind(
1086-
Function,
1087-
),
1088-
lookup: "foo",
1089-
detail: "fn(&mut S)",
1090-
trigger_call_info: true,
1091-
},
1092-
CompletionItem {
1093-
label: "main()",
1094-
source_range: 70..70,
1095-
delete: 70..70,
1096-
insert: "main()$0",
1097-
kind: SymbolKind(
1098-
Function,
1099-
),
1100-
lookup: "main",
1101-
detail: "fn()",
1102-
},
1103-
CompletionItem {
1104-
label: "s",
1105-
source_range: 70..70,
1106-
delete: 70..70,
1107-
insert: "s",
1108-
kind: SymbolKind(
1109-
Local,
1110-
),
1111-
detail: "S",
1112-
relevance: CompletionRelevance {
1113-
exact_name_match: true,
1114-
type_match: None,
1115-
is_local: true,
1116-
},
1117-
ref_match: "&mut ",
1118-
},
1119-
]
1070+
lc s [name+local]
1071+
lc &mut s [type+name+local]
1072+
st S []
1073+
fn main() []
1074+
fn foo(…) []
11201075
"#]],
1121-
)
1076+
);
1077+
check_relevance(
1078+
r#"
1079+
struct S;
1080+
fn foo(s: &mut S) {}
1081+
fn main() {
1082+
let mut s = S;
1083+
foo(&mut $0);
1084+
}
1085+
"#,
1086+
expect![[r#"
1087+
lc s [type+name+local]
1088+
st S []
1089+
fn main() []
1090+
fn foo(…) []
1091+
"#]],
1092+
);
11221093
}
11231094

11241095
#[test]

0 commit comments

Comments
 (0)