]> git.lizzy.rs Git - rust.git/commitdiff
Show case-insensitive exact matches instead of fuzzy flyimport for short paths
authorLukas Wirth <lukastw97@gmail.com>
Thu, 9 Dec 2021 18:18:11 +0000 (19:18 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Sat, 11 Dec 2021 13:47:11 +0000 (14:47 +0100)
crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
crates/ide_completion/src/completions/flyimport.rs
crates/ide_completion/src/lib.rs
crates/ide_completion/src/tests/flyimport.rs
crates/ide_db/src/helpers/import_assets.rs
crates/ide_db/src/items_locator.rs

index 3e33c62144ea727aa2f45bf3ce55508fa2ac7eaf..46bf4d7b46361a7b7bf78f0db2b45025ebbdc431 100644 (file)
@@ -65,7 +65,7 @@ pub(crate) fn replace_derive_with_manual_impl(
     let found_traits = items_locator::items_with_name(
         &ctx.sema,
         current_crate,
-        NameToImport::Exact(trait_path.segments().last()?.to_string()),
+        NameToImport::exact_case_sensitive(trait_path.segments().last()?.to_string()),
         items_locator::AssocItemSearch::Exclude,
         Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
     )
index 3a9c1b3beb738f7446c29f657350012686350d95..8994c25475b131cc4da5a994a3b1d31d3c9be7e6 100644 (file)
@@ -227,22 +227,18 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
         )
     } else {
         let fuzzy_name_length = fuzzy_name.len();
-        let assets_for_path = ImportAssets::for_fuzzy_path(
+        let mut assets_for_path = ImportAssets::for_fuzzy_path(
             current_module,
             ctx.path_qual().cloned(),
             fuzzy_name,
             &ctx.sema,
             ctx.token.parent()?,
         )?;
-
-        if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
-            && fuzzy_name_length < 2
-        {
-            cov_mark::hit!(ignore_short_input_for_path);
-            None
-        } else {
-            Some(assets_for_path)
+        if fuzzy_name_length < 3 {
+            cov_mark::hit!(flyimport_exact_on_short_path);
+            assets_for_path.path_fuzzy_name_to_exact(false);
         }
+        Some(assets_for_path)
     }
 }
 
index d9618642c456f867a5b8993aa5b8a0b71add83c8..6a087edc4f226bbd5c35cf8b0352640a72bc2c01 100644 (file)
@@ -195,7 +195,7 @@ pub fn resolve_completion_edits(
         let items_with_name = items_locator::items_with_name(
             &ctx.sema,
             current_crate,
-            NameToImport::Exact(imported_name),
+            NameToImport::exact_case_sensitive(imported_name),
             items_locator::AssocItemSearch::Include,
             Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
         );
index 23e5da463c7a9eac4b4d4972ceee65674e2c9d44..f40df62ece346a692b4522b9aa8ccb66dc8ab6f0 100644 (file)
@@ -96,25 +96,29 @@ fn main() {
 
 #[test]
 fn short_paths_are_ignored() {
-    cov_mark::check!(ignore_short_input_for_path);
+    cov_mark::check!(flyimport_exact_on_short_path);
 
     check(
         r#"
 //- /lib.rs crate:dep
-pub struct FirstStruct;
+pub struct Bar;
+pub struct Rcar;
+pub struct Rc;
 pub mod some_module {
-    pub struct SecondStruct;
-    pub struct ThirdStruct;
+    pub struct Bar;
+    pub struct Rcar;
+    pub struct Rc;
 }
 
 //- /main.rs crate:main deps:dep
-use dep::{FirstStruct, some_module::SecondStruct};
-
 fn main() {
-    t$0
+    rc$0
 }
 "#,
-        expect![[r#""#]],
+        expect![[r#"
+            st Rc (use dep::Rc)
+            st Rc (use dep::some_module::Rc)
+        "#]],
     );
 }
 
@@ -772,7 +776,7 @@ pub fn test_function() -> i32 {
 }
 
 fn main() {
-    TE$0
+    TES$0
 }"#,
         expect![[r#"
         ct TEST_CONST (use foo::TEST_CONST)
@@ -789,7 +793,7 @@ pub fn test_function() -> i32 {
 }
 
 fn main() {
-    te$0
+    tes$0
 }"#,
         expect![[r#"
         ct TEST_CONST (use foo::TEST_CONST)
@@ -846,7 +850,7 @@ struct Foo {
     some_field: i32,
 }
 fn main() {
-    let _ = Foo { some_field: so$0 };
+    let _ = Foo { some_field: som$0 };
 }
 "#,
         expect![[r#"
index 9a8adf167c8a05f0a9248291b695e872b892e5d7..024e0c9f81f497f7dd68a0dff1d52159315bad48 100644 (file)
@@ -68,17 +68,23 @@ pub struct FirstSegmentUnresolved {
 /// A name that will be used during item lookups.
 #[derive(Debug, Clone)]
 pub enum NameToImport {
-    /// Requires items with names that exactly match the given string, case-sensitive.
-    Exact(String),
+    /// Requires items with names that exactly match the given string, bool indicatse case-sensitivity.
+    Exact(String, bool),
     /// Requires items with names that case-insensitively contain all letters from the string,
     /// in the same order, but not necessary adjacent.
     Fuzzy(String),
 }
 
+impl NameToImport {
+    pub fn exact_case_sensitive(s: String) -> NameToImport {
+        NameToImport::Exact(s, true)
+    }
+}
+
 impl NameToImport {
     pub fn text(&self) -> &str {
         match self {
-            NameToImport::Exact(text) => text.as_str(),
+            NameToImport::Exact(text, _) => text.as_str(),
             NameToImport::Fuzzy(text) => text.as_str(),
         }
     }
@@ -140,7 +146,7 @@ pub fn for_derive_ident(sema: &Semantics<RootDatabase>, ident: &ast::Ident) -> O
         if let Some(_) = path.qualifier() {
             return None;
         }
-        let name = NameToImport::Exact(path.segment()?.name_ref()?.to_string());
+        let name = NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string());
         let candidate_node = attr.syntax().clone();
         Some(Self {
             import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
@@ -230,6 +236,18 @@ pub fn search_for_relative_paths(&self, sema: &Semantics<RootDatabase>) -> Vec<L
         self.search_for(sema, None)
     }
 
+    pub fn path_fuzzy_name_to_exact(&mut self, case_sensitive: bool) {
+        if let ImportCandidate::Path(PathImportCandidate { name: to_import, .. }) =
+            &mut self.import_candidate
+        {
+            let name = match to_import {
+                NameToImport::Fuzzy(name) => std::mem::take(name),
+                _ => return,
+            };
+            *to_import = NameToImport::Exact(name, case_sensitive);
+        }
+    }
+
     fn search_for(
         &self,
         sema: &Semantics<RootDatabase>,
@@ -561,7 +579,9 @@ fn for_method_call(
             Some(_) => None,
             None => Some(Self::TraitMethod(TraitImportCandidate {
                 receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(),
-                assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()),
+                assoc_item_name: NameToImport::exact_case_sensitive(
+                    method_call.name_ref()?.to_string(),
+                ),
             })),
         }
     }
@@ -573,7 +593,7 @@ fn for_regular_path(sema: &Semantics<RootDatabase>, path: &ast::Path) -> Option<
         path_import_candidate(
             sema,
             path.qualifier(),
-            NameToImport::Exact(path.segment()?.name_ref()?.to_string()),
+            NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string()),
         )
     }
 
@@ -587,7 +607,7 @@ fn for_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Self> {
         }
         Some(ImportCandidate::Path(PathImportCandidate {
             qualifier: None,
-            name: NameToImport::Exact(name.to_string()),
+            name: NameToImport::exact_case_sensitive(name.to_string()),
         }))
     }
 
index e0dbe6caf0af23383c62df50d6503415697fca97..ca8266b6d24fb1517906758a138954060a7e0ee9 100644 (file)
@@ -50,16 +50,18 @@ pub fn items_with_name<'a>(
     });
 
     let (mut local_query, mut external_query) = match name {
-        NameToImport::Exact(exact_name) => {
+        NameToImport::Exact(exact_name, case_sensitive) => {
             let mut local_query = symbol_index::Query::new(exact_name.clone());
             local_query.exact();
 
             let external_query = import_map::Query::new(exact_name)
                 .name_only()
-                .search_mode(import_map::SearchMode::Equals)
-                .case_sensitive();
+                .search_mode(import_map::SearchMode::Equals);
 
-            (local_query, external_query)
+            (
+                local_query,
+                if case_sensitive { external_query.case_sensitive() } else { external_query },
+            )
         }
         NameToImport::Fuzzy(fuzzy_search_string) => {
             let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());