Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21414 from sshcrack/master
fix: Suggest traits other than ones in the environment crate
Shoyu Vanilla (Flint) 4 months ago
parent 58646b5 · parent 987433d · commit 870d845
-rw-r--r--crates/ide-completion/src/tests/flyimport.rs48
-rw-r--r--crates/ide-db/src/imports/import_assets.rs14
2 files changed, 61 insertions, 1 deletions
diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs
index 797df3f163..d7db896679 100644
--- a/crates/ide-completion/src/tests/flyimport.rs
+++ b/crates/ide-completion/src/tests/flyimport.rs
@@ -1976,3 +1976,51 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn trait_method_import_across_multiple_crates() {
+ let fixture = r#"
+ //- /lib.rs crate:test-trait
+ pub trait TestTrait {
+ fn test_function(&self) -> u32;
+ }
+
+ //- /lib.rs crate:test-implementation deps:test-trait
+ pub struct TestStruct(pub usize);
+
+ impl test_trait::TestTrait for TestStruct {
+ fn test_function(&self) -> u32 {
+ 1
+ }
+ }
+
+ //- /main.rs crate:main deps:test-implementation,test-trait
+ use test_implementation::TestStruct;
+
+ fn main() {
+ let test = TestStruct(42);
+ test.test_f$0
+ }
+ "#;
+
+ check(
+ fixture,
+ expect![[r#"
+ me test_function() (use test_trait::TestTrait) fn(&self) -> u32
+ "#]],
+ );
+
+ check_edit(
+ "test_function",
+ fixture,
+ r#"
+use test_implementation::TestStruct;
+use test_trait::TestTrait;
+
+fn main() {
+ let test = TestStruct(42);
+ test.test_function()$0
+}
+"#,
+ );
+}
diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs
index 90e3bb61f4..35579eb259 100644
--- a/crates/ide-db/src/imports/import_assets.rs
+++ b/crates/ide-db/src/imports/import_assets.rs
@@ -600,7 +600,19 @@ fn trait_applicable_items<'db>(
}
deref_chain
.into_iter()
- .filter_map(|ty| Some((ty.krate(db).into(), ty.fingerprint_for_trait_impl()?)))
+ .flat_map(|ty| {
+ let fingerprint = ty.fingerprint_for_trait_impl()?;
+ let mut crates = vec![];
+
+ if let Some(adt) = ty.as_adt() {
+ // Push crate where ADT was defined
+ crates.push((adt.krate(db).into(), fingerprint));
+ }
+ // Always include environment crate
+ crates.push((ty.krate(db).into(), fingerprint));
+ Some(crates)
+ })
+ .flatten()
.unique()
.collect::<Vec<_>>()
};