aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-09 16:05:23 +0000
committerGitHub <[email protected]>2021-03-09 16:05:23 +0000
commitc2359608c926d4828f2b112e7069978449851d58 (patch)
treeccb62a1da7516ce170e6ddf8481154465c7abba5 /crates/ide_completion
parent472641fc5beee1f998d46de70351bcb572d6226c (diff)
parent73b9937e4eea2633005e7d2814cb7990e5f20e8f (diff)
Merge #7944
7944: Selecting `&mut foo` completion now actually inserts `&mut` r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ide_completion')
-rw-r--r--crates/ide_completion/src/item.rs13
-rw-r--r--crates/ide_completion/src/render.rs90
2 files changed, 81 insertions, 22 deletions
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index b16f0775a..5e8ed75f1 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -68,7 +68,7 @@ pub struct CompletionItem {
68 68
69 /// Indicates that a reference or mutable reference to this variable is a 69 /// Indicates that a reference or mutable reference to this variable is a
70 /// possible match. 70 /// possible match.
71 ref_match: Option<(Mutability, CompletionScore)>, 71 ref_match: Option<Mutability>,
72 72
73 /// The import data to add to completion's edits. 73 /// The import data to add to completion's edits.
74 import_to_add: Option<ImportEdit>, 74 import_to_add: Option<ImportEdit>,
@@ -104,6 +104,9 @@ impl fmt::Debug for CompletionItem {
104 if let Some(score) = &self.score { 104 if let Some(score) = &self.score {
105 s.field("score", score); 105 s.field("score", score);
106 } 106 }
107 if let Some(mutability) = &self.ref_match {
108 s.field("ref_match", &format!("&{}", mutability.as_keyword_for_ref()));
109 }
107 if self.trigger_call_info { 110 if self.trigger_call_info {
108 s.field("trigger_call_info", &true); 111 s.field("trigger_call_info", &true);
109 } 112 }
@@ -261,7 +264,7 @@ impl CompletionItem {
261 self.trigger_call_info 264 self.trigger_call_info
262 } 265 }
263 266
264 pub fn ref_match(&self) -> Option<(Mutability, CompletionScore)> { 267 pub fn ref_match(&self) -> Option<Mutability> {
265 self.ref_match 268 self.ref_match
266 } 269 }
267 270
@@ -311,7 +314,7 @@ pub(crate) struct Builder {
311 deprecated: bool, 314 deprecated: bool,
312 trigger_call_info: Option<bool>, 315 trigger_call_info: Option<bool>,
313 score: Option<CompletionScore>, 316 score: Option<CompletionScore>,
314 ref_match: Option<(Mutability, CompletionScore)>, 317 ref_match: Option<Mutability>,
315} 318}
316 319
317impl Builder { 320impl Builder {
@@ -430,8 +433,8 @@ impl Builder {
430 self.import_to_add = import_to_add; 433 self.import_to_add = import_to_add;
431 self 434 self
432 } 435 }
433 pub(crate) fn ref_match(mut self, ref_match: (Mutability, CompletionScore)) -> Builder { 436 pub(crate) fn ref_match(mut self, mutability: Mutability) -> Builder {
434 self.ref_match = Some(ref_match); 437 self.ref_match = Some(mutability);
435 self 438 self
436 } 439 }
437} 440}
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 0a6ac8804..0a1b0f95d 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -254,10 +254,17 @@ impl<'a> Render<'a> {
254 { 254 {
255 item = item.set_score(score); 255 item = item.set_score(score);
256 } 256 }
257 if let Some(ref_match) = 257
258 refed_type_matches(&active_type, &active_name, &ty, &local_name) 258 if let Some(ty_without_ref) = active_type.remove_ref() {
259 { 259 if ty_without_ref == ty {
260 item = item.ref_match(ref_match); 260 cov_mark::hit!(suggest_ref);
261 let mutability = if active_type.is_mutable_reference() {
262 Mutability::Mut
263 } else {
264 Mutability::Shared
265 };
266 item = item.ref_match(mutability)
267 }
261 } 268 }
262 } 269 }
263 } 270 }
@@ -340,19 +347,6 @@ fn compute_score_from_active(
340 347
341 Some(res) 348 Some(res)
342} 349}
343fn refed_type_matches(
344 active_type: &Type,
345 active_name: &str,
346 ty: &Type,
347 name: &str,
348) -> Option<(Mutability, CompletionScore)> {
349 let derefed_active = active_type.remove_ref()?;
350 let score = compute_score_from_active(&derefed_active, &active_name, &ty, &name)?;
351 Some((
352 if active_type.is_mutable_reference() { Mutability::Mut } else { Mutability::Shared },
353 score,
354 ))
355}
356 350
357fn compute_score(ctx: &RenderContext, ty: &Type, name: &str) -> Option<CompletionScore> { 351fn compute_score(ctx: &RenderContext, ty: &Type, name: &str) -> Option<CompletionScore> {
358 let (active_name, active_type) = ctx.active_name_and_type()?; 352 let (active_name, active_type) = ctx.active_name_and_type()?;
@@ -947,4 +941,66 @@ fn f(foo: &Foo) { f(foo, w$0) }
947 "#]], 941 "#]],
948 ); 942 );
949 } 943 }
944
945 #[test]
946 fn suggest_ref_mut() {
947 cov_mark::check!(suggest_ref);
948 check(
949 r#"
950struct S;
951fn foo(s: &mut S) {}
952fn main() {
953 let mut s = S;
954 foo($0);
955}
956 "#,
957 expect![[r#"
958 [
959 CompletionItem {
960 label: "S",
961 source_range: 70..70,
962 delete: 70..70,
963 insert: "S",
964 kind: SymbolKind(
965 Struct,
966 ),
967 },
968 CompletionItem {
969 label: "foo(…)",
970 source_range: 70..70,
971 delete: 70..70,
972 insert: "foo(${1:&mut s})$0",
973 kind: SymbolKind(
974 Function,
975 ),
976 lookup: "foo",
977 detail: "-> ()",
978 trigger_call_info: true,
979 },
980 CompletionItem {
981 label: "main()",
982 source_range: 70..70,
983 delete: 70..70,
984 insert: "main()$0",
985 kind: SymbolKind(
986 Function,
987 ),
988 lookup: "main",
989 detail: "-> ()",
990 },
991 CompletionItem {
992 label: "s",
993 source_range: 70..70,
994 delete: 70..70,
995 insert: "s",
996 kind: SymbolKind(
997 Local,
998 ),
999 detail: "S",
1000 ref_match: "&mut ",
1001 },
1002 ]
1003 "#]],
1004 )
1005 }
950} 1006}