about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-07 14:16:00 +0000
committerbors <bors@rust-lang.org>2022-05-07 14:16:00 +0000
commitbfb241afa3bd83b482aaddacd5d5cd2583603976 (patch)
tree1de04a4d2245cfa5b3cb57ab6a873b404c289b9a
parentf2216764c40527eecc846483da6b3ca0c030c0a7 (diff)
parent61e074f016ca6df88b6f88c822a413c4f5022784 (diff)
downloadrust-bfb241afa3bd83b482aaddacd5d5cd2583603976.tar.gz
rust-bfb241afa3bd83b482aaddacd5d5cd2583603976.zip
Auto merge of #12188 - Veykril:auto-import, r=Veykril
fix: Allow auto importing starting segments of use items
-rw-r--r--crates/ide-assists/src/handlers/auto_import.rs52
-rw-r--r--crates/ide-assists/src/handlers/qualify_path.rs52
-rw-r--r--crates/ide-db/src/imports/import_assets.rs9
3 files changed, 84 insertions, 29 deletions
diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs
index 874563c6f78..0a0dafb35ed 100644
--- a/crates/ide-assists/src/handlers/auto_import.rs
+++ b/crates/ide-assists/src/handlers/auto_import.rs
@@ -374,19 +374,6 @@ mod baz {
     }
 
     #[test]
-    fn not_applicable_in_import_statements() {
-        check_assist_not_applicable(
-            auto_import,
-            r"
-            use PubStruct$0;
-
-            pub mod PubMod {
-                pub struct PubStruct;
-            }",
-        );
-    }
-
-    #[test]
     fn function_import() {
         check_assist(
             auto_import,
@@ -1121,4 +1108,43 @@ struct Foo;
 "#,
         );
     }
+
+    #[test]
+    fn works_in_use_start() {
+        check_assist(
+            auto_import,
+            r#"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use foo$0::Foo;
+"#,
+            r#"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use bar::foo;
+use foo::Foo;
+"#,
+        );
+    }
+
+    #[test]
+    fn not_applicable_in_non_start_use() {
+        check_assist_not_applicable(
+            auto_import,
+            r"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use foo::Foo$0;
+",
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/qualify_path.rs b/crates/ide-assists/src/handlers/qualify_path.rs
index 5deb60f57b1..8d2293d2247 100644
--- a/crates/ide-assists/src/handlers/qualify_path.rs
+++ b/crates/ide-assists/src/handlers/qualify_path.rs
@@ -382,20 +382,6 @@ pub mod PubMod {
     }
 
     #[test]
-    fn not_applicable_in_import_statements() {
-        check_assist_not_applicable(
-            qualify_path,
-            r#"
-use PubStruct$0;
-
-pub mod PubMod {
-    pub struct PubStruct;
-}
-"#,
-        );
-    }
-
-    #[test]
     fn qualify_function() {
         check_assist(
             qualify_path,
@@ -1270,4 +1256,42 @@ struct Foo;
 "#,
         );
     }
+
+    #[test]
+    fn works_in_use_start() {
+        check_assist(
+            qualify_path,
+            r#"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use foo$0::Foo;
+"#,
+            r#"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use bar::foo::Foo;
+"#,
+        );
+    }
+
+    #[test]
+    fn not_applicable_in_non_start_use() {
+        check_assist_not_applicable(
+            qualify_path,
+            r"
+mod bar {
+    pub mod foo {
+        pub struct Foo;
+    }
+}
+use foo::Foo$0;
+",
+        );
+    }
 }
diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs
index f8cfe15c896..81467ab07a2 100644
--- a/crates/ide-db/src/imports/import_assets.rs
+++ b/crates/ide-db/src/imports/import_assets.rs
@@ -114,8 +114,13 @@ impl ImportAssets {
         sema: &Semantics<RootDatabase>,
     ) -> Option<Self> {
         let candidate_node = fully_qualified_path.syntax().clone();
-        if candidate_node.ancestors().find_map(ast::Use::cast).is_some() {
-            return None;
+        if let Some(use_tree) = candidate_node.ancestors().find_map(ast::UseTree::cast) {
+            // Path is inside a use tree, then only continue if it is the first segment of a use statement.
+            if use_tree.syntax().parent().and_then(ast::Use::cast).is_none()
+                || fully_qualified_path.qualifier().is_some()
+            {
+                return None;
+            }
         }
         Some(Self {
             import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?,