Skip to content

Commit 5d28dec

Browse files
committed
Fix importing unused traits in expand glob import
1 parent 585f5d4 commit 5d28dec

File tree

1 file changed

+73
-28
lines changed

1 file changed

+73
-28
lines changed

crates/assists/src/handlers/expand_glob_import.rs

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use either::Either;
2-
use hir::{MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope};
2+
use hir::{AssocItem, MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef};
33
use ide_db::{
44
defs::{classify_name_ref, Definition, NameRefClass},
55
search::SearchScope,
@@ -49,7 +49,7 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti
4949

5050
let refs_in_target = find_refs_in_mod(ctx, target_module, Some(current_module))?;
5151
let imported_defs = find_imported_defs(ctx, star)?;
52-
let names_to_import = find_names_to_import(ctx, current_scope, refs_in_target, imported_defs);
52+
let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
5353

5454
let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone());
5555
acc.add(
@@ -90,6 +90,18 @@ enum Def {
9090
MacroDef(MacroDef),
9191
}
9292

93+
impl Def {
94+
fn is_referenced_in(&self, ctx: &AssistContext) -> bool {
95+
let def = match self {
96+
Def::ModuleDef(def) => Definition::ModuleDef(*def),
97+
Def::MacroDef(def) => Definition::Macro(*def),
98+
};
99+
100+
let search_scope = SearchScope::single_file(ctx.frange.file_id);
101+
!def.find_usages(&ctx.sema, Some(search_scope)).is_empty()
102+
}
103+
}
104+
93105
#[derive(Debug, Clone)]
94106
struct Ref {
95107
// could be alias
@@ -105,35 +117,39 @@ impl Ref {
105117
_ => None,
106118
}
107119
}
108-
109-
fn is_referenced_in(&self, ctx: &AssistContext, scope: &SemanticsScope) -> bool {
110-
let def = match self.def {
111-
Def::ModuleDef(def) => Definition::ModuleDef(def),
112-
Def::MacroDef(def) => Definition::Macro(def),
113-
};
114-
115-
if let Definition::ModuleDef(ModuleDef::Trait(tr)) = def {
116-
if scope
117-
.traits_in_scope()
118-
.into_iter()
119-
.find(|other_tr_id| tr == other_tr_id.to_owned().into())
120-
.is_some()
121-
{
122-
return true;
123-
}
124-
}
125-
126-
let search_scope = SearchScope::single_file(ctx.frange.file_id);
127-
!def.find_usages(&ctx.sema, Some(search_scope)).is_empty()
128-
}
129120
}
130121

131122
#[derive(Debug, Clone)]
132123
struct Refs(Vec<Ref>);
133124

134125
impl Refs {
135-
fn used_refs(&self, ctx: &AssistContext, scope: &SemanticsScope) -> Refs {
136-
Refs(self.0.clone().into_iter().filter(|r| r.is_referenced_in(ctx, scope)).collect())
126+
fn used_refs(&self, ctx: &AssistContext) -> Refs {
127+
Refs(
128+
self.0
129+
.clone()
130+
.into_iter()
131+
.filter(|r| {
132+
if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def {
133+
if tr
134+
.items(ctx.db())
135+
.into_iter()
136+
.find(|ai| {
137+
if let AssocItem::Function(f) = *ai {
138+
Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx)
139+
} else {
140+
false
141+
}
142+
})
143+
.is_some()
144+
{
145+
return true;
146+
}
147+
}
148+
149+
r.def.is_referenced_in(ctx)
150+
})
151+
.collect(),
152+
)
137153
}
138154

139155
fn filter_out_by_defs(&self, defs: Vec<Def>) -> Refs {
@@ -191,11 +207,10 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>
191207

192208
fn find_names_to_import(
193209
ctx: &AssistContext,
194-
current_scope: SemanticsScope,
195210
refs_in_target: Refs,
196211
imported_defs: Vec<Def>,
197212
) -> Vec<Name> {
198-
let used_refs = refs_in_target.used_refs(ctx, &current_scope).filter_out_by_defs(imported_defs);
213+
let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs);
199214
used_refs.0.iter().map(|r| r.visible_name.clone()).collect()
200215
}
201216

@@ -767,7 +782,37 @@ fn main() {
767782
().method();
768783
}
769784
",
770-
)
785+
);
786+
787+
check_assist(
788+
expand_glob_import,
789+
r"
790+
//- /lib.rs crate:foo
791+
pub trait Tr {
792+
fn method(&self) {}
793+
}
794+
impl Tr for () {}
795+
796+
pub trait Tr2 {
797+
fn method2(&self) {}
798+
}
799+
impl Tr2 for () {}
800+
801+
//- /main.rs crate:main deps:foo
802+
use foo::*<|>;
803+
804+
fn main() {
805+
().method();
806+
}
807+
",
808+
r"
809+
use foo::Tr;
810+
811+
fn main() {
812+
().method();
813+
}
814+
",
815+
);
771816
}
772817

773818
#[test]

0 commit comments

Comments
 (0)