about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonas.schievink@ferrous-systems.com>2022-04-25 14:34:54 +0200
committerJonas Schievink <jonas.schievink@ferrous-systems.com>2022-04-25 14:34:54 +0200
commit3a83684a16b3e58b4dfedb23a745228350c8a78c (patch)
tree9e1b130e19713f36f3af976e0d035ca16d4cbd33
parentc1de78f54c295c2c9c7681b0506e38d5ee695d77 (diff)
downloadrust-3a83684a16b3e58b4dfedb23a745228350c8a78c.tar.gz
rust-3a83684a16b3e58b4dfedb23a745228350c8a78c.zip
Reduce priority of flyimport completions
-rw-r--r--crates/ide_completion/src/item.rs7
-rw-r--r--crates/ide_completion/src/render.rs41
2 files changed, 46 insertions, 2 deletions
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 41fae38da1e..29b073cfa52 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -141,6 +141,8 @@ pub struct CompletionRelevance {
     pub is_item_from_trait: bool,
     /// This is set when an import is suggested whose name is already imported.
     pub is_name_already_imported: bool,
+    /// This is set for completions that will insert a `use` item.
+    pub requires_import: bool,
     /// Set for method completions of the `core::ops` and `core::cmp` family.
     pub is_op_method: bool,
     /// Set for item completions that are private but in the workspace.
@@ -208,6 +210,7 @@ impl CompletionRelevance {
             is_local,
             is_item_from_trait,
             is_name_already_imported,
+            requires_import,
             is_op_method,
             is_private_editable,
             postfix_match,
@@ -226,6 +229,10 @@ impl CompletionRelevance {
         if !is_name_already_imported {
             score += 1;
         }
+        // lower rank for items that don't need an import
+        if !requires_import {
+            score += 1;
+        }
         if exact_name_match {
             score += 10;
         }
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 810ef63ec39..836b14bc2cd 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -58,7 +58,11 @@ impl<'a> RenderContext<'a> {
     }
 
     fn completion_relevance(&self) -> CompletionRelevance {
-        CompletionRelevance { is_private_editable: self.is_private_editable, ..Default::default() }
+        CompletionRelevance {
+            is_private_editable: self.is_private_editable,
+            requires_import: self.import_to_add.is_some(),
+            ..Default::default()
+        }
     }
 
     fn is_deprecated(&self, def: impl HasAttrs) -> bool {
@@ -247,6 +251,7 @@ fn render_resolution_simple_(
 
     let local_name = local_name.to_smol_str();
     let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone());
+    item.set_relevance(ctx.completion_relevance());
     if let ScopeDef::Local(local) = resolution {
         let ty = local.ty(db);
         if !ty.is_unknown() {
@@ -446,6 +451,7 @@ mod tests {
                     "snippet",
                 ),
                 (relevance.is_op_method, "op_method"),
+                (relevance.requires_import, "requires_import"),
             ]
             .into_iter()
             .filter_map(|(cond, desc)| if cond { Some(desc) } else { None })
@@ -626,6 +632,7 @@ fn main() { let _: m::Spam = S$0 }
                             is_local: false,
                             is_item_from_trait: false,
                             is_name_already_imported: false,
+                            requires_import: false,
                             is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
@@ -650,6 +657,7 @@ fn main() { let _: m::Spam = S$0 }
                             is_local: false,
                             is_item_from_trait: false,
                             is_name_already_imported: false,
+                            requires_import: false,
                             is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
@@ -740,6 +748,7 @@ fn foo() { A { the$0 } }
                             is_local: false,
                             is_item_from_trait: false,
                             is_name_already_imported: false,
+                            requires_import: false,
                             is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
@@ -1579,7 +1588,7 @@ fn main() {
             &[CompletionItemKind::Snippet, CompletionItemKind::Method],
             expect![[r#"
                 sn not [snippet]
-                me not() (use ops::Not) [type_could_unify]
+                me not() (use ops::Not) [type_could_unify+requires_import]
                 sn if []
                 sn while []
                 sn ref []
@@ -1621,4 +1630,32 @@ fn main() {
             "#]],
         );
     }
+
+    #[test]
+    fn flyimport_reduced_relevance() {
+        check_relevance(
+            r#"
+mod std {
+    pub mod io {
+        pub trait BufRead {}
+        pub struct BufReader;
+        pub struct BufWriter;
+    }
+}
+struct Buffer;
+
+fn f() {
+    Buf$0
+}
+"#,
+            expect![[r#"
+                md std []
+                st Buffer []
+                fn f() []
+                tt BufRead (use std::io::BufRead) [requires_import]
+                st BufReader (use std::io::BufReader) [requires_import]
+                st BufWriter (use std::io::BufWriter) [requires_import]
+            "#]],
+        );
+    }
 }