Skip to content

Commit a02a1af

Browse files
ChayimFriedman2Veykril
authored andcommitted
Allow flyimporting excluded trait items if there is an exact match in the name
I.e. with `fn foo()`, don't complete at `x.fo|`, but complete (with imports) for `x.foo|`, since this is less likely to have false positives. I opted to only do that for flyimport, even though for basic imports there can also be snippet completion (completing the params list for a method), since this is less universally applicable and seems not so useful.
1 parent 7e6ade1 commit a02a1af

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

crates/ide-completion/src/completions/flyimport.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ fn import_on_the_fly(
258258

259259
let import_cfg = ctx.config.import_path_config();
260260

261+
let completed_name = ctx.token.to_string();
262+
261263
import_assets
262264
.search_for_imports(&ctx.sema, import_cfg, ctx.config.insert_use.prefix_kind)
263265
.filter(ns_filter)
@@ -271,7 +273,13 @@ fn import_on_the_fly(
271273
if let ModuleDef::Trait(trait_) = import.item_to_import.into_module_def() {
272274
let excluded = ctx.exclude_flyimport_traits.contains(&trait_);
273275
let trait_itself_imported = import.item_to_import == import.original_item;
274-
!excluded || trait_itself_imported
276+
if !excluded || trait_itself_imported {
277+
return true;
278+
}
279+
280+
let item = import.original_item.into_module_def();
281+
// Filter that item out, unless its name matches the name the user wrote exactly - in which case preserve it.
282+
item.name(ctx.db).is_some_and(|name| name.eq_ident(&completed_name))
275283
} else {
276284
true
277285
}
@@ -355,6 +363,8 @@ fn import_on_the_fly_method(
355363

356364
let cfg = ctx.config.import_path_config();
357365

366+
let completed_name = ctx.token.to_string();
367+
358368
import_assets
359369
.search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind)
360370
.filter(|import| {
@@ -363,7 +373,13 @@ fn import_on_the_fly_method(
363373
})
364374
.filter(|import| {
365375
if let ModuleDef::Trait(trait_) = import.item_to_import.into_module_def() {
366-
!ctx.exclude_flyimport_traits.contains(&trait_)
376+
if !ctx.exclude_flyimport_traits.contains(&trait_) {
377+
return true;
378+
}
379+
380+
let item = import.original_item.into_module_def();
381+
// Filter that method out, unless its name matches the name the user wrote exactly - in which case preserve it.
382+
item.name(ctx.db).is_some_and(|name| name.eq_ident(&completed_name))
367383
} else {
368384
true
369385
}

crates/ide-completion/src/tests/flyimport.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ use expect_test::{expect, Expect};
33
use crate::{
44
context::{CompletionAnalysis, NameContext, NameKind, NameRefKind},
55
tests::{check_edit, check_edit_with_config, TEST_CONFIG},
6+
CompletionConfig,
67
};
78

89
fn check(ra_fixture: &str, expect: Expect) {
9-
let config = TEST_CONFIG;
10+
check_with_config(TEST_CONFIG, ra_fixture, expect);
11+
}
12+
13+
fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Expect) {
1014
let (db, position) = crate::tests::position(ra_fixture);
1115
let (ctx, analysis) = crate::context::CompletionContext::new(&db, position, &config).unwrap();
1216

@@ -1762,3 +1766,31 @@ fn function() {
17621766
expect![""],
17631767
);
17641768
}
1769+
1770+
#[test]
1771+
fn excluded_trait_item_included_when_exact_match() {
1772+
check_with_config(
1773+
CompletionConfig {
1774+
exclude_traits: &["test::module2::ExcludedTrait".to_owned()],
1775+
..TEST_CONFIG
1776+
},
1777+
r#"
1778+
mod module2 {
1779+
pub trait ExcludedTrait {
1780+
fn foo(&self) {}
1781+
fn bar(&self) {}
1782+
fn baz(&self) {}
1783+
}
1784+
1785+
impl<T> ExcludedTrait for T {}
1786+
}
1787+
1788+
fn foo() {
1789+
true.foo$0
1790+
}
1791+
"#,
1792+
expect![[r#"
1793+
me foo() (use module2::ExcludedTrait) fn(&self)
1794+
"#]],
1795+
);
1796+
}

0 commit comments

Comments
 (0)