Skip to content

Commit 20896c4

Browse files
committed
fix: auto import trait if needed
1 parent d6afb4f commit 20896c4

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ authors = ["rust-analyzer team"]
1212
[profile.dev]
1313
# Disabling debug info speeds up builds a bunch,
1414
# and we don't rely on it for debugging that much.
15-
debug = 0
15+
debug = 2
1616

1717
[profile.dev.package]
1818
# These speed up local tests.

crates/ide-assists/src/handlers/unqualify_method_call.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ide_db::imports::insert_use::ImportScope;
12
use syntax::{
23
ast::{self, make, AstNode, HasArgList},
34
TextRange,
@@ -17,6 +18,8 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
1718
// ```
1819
// ->
1920
// ```
21+
// use std::ops::Add;
22+
//
2023
// fn main() {
2124
// 1.add(2);
2225
// }
@@ -76,10 +79,49 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>)
7679
edit.insert(close, ")");
7780
}
7881
edit.replace(replace_comma, format!(".{method_name}("));
82+
add_import(&path, ctx, edit);
7983
},
8084
)
8185
}
8286

87+
fn add_import(
88+
path: &ast::Path,
89+
ctx: &AssistContext<'_>,
90+
edit: &mut ide_db::source_change::SourceChangeBuilder,
91+
) {
92+
let qualifier = path.qualifier().unwrap();
93+
94+
// for `<i32 as std::ops::Add>`
95+
let path_type =
96+
qualifier.segment().unwrap().syntax().children().filter_map(ast::PathType::cast).last();
97+
let import = match path_type {
98+
Some(it) => it.path().unwrap(),
99+
None => qualifier,
100+
};
101+
102+
// in case for `<_>`
103+
match import.coloncolon_token() {
104+
Some(_) => (),
105+
None => {
106+
return;
107+
}
108+
}
109+
110+
let scope = ide_db::imports::insert_use::ImportScope::find_insert_use_container(
111+
path.syntax(),
112+
&ctx.sema,
113+
);
114+
115+
if let Some(scope) = scope {
116+
let scope = match scope {
117+
ImportScope::File(it) => ImportScope::File(edit.make_mut(it)),
118+
ImportScope::Module(it) => ImportScope::Module(edit.make_mut(it)),
119+
ImportScope::Block(it) => ImportScope::Block(edit.make_mut(it)),
120+
};
121+
ide_db::imports::insert_use::insert_use(&scope, import, &ctx.config.insert_use);
122+
}
123+
}
124+
83125
fn needs_parens_as_receiver(expr: &ast::Expr) -> bool {
84126
// Make `(expr).dummy()`
85127
let dummy_call = make::expr_method_call(
@@ -127,6 +169,8 @@ fn f() { S.f(S); }"#,
127169
//- minicore: add
128170
fn f() { <u32 as core::ops::Add>::$0add(2, 2); }"#,
129171
r#"
172+
use core::ops::Add;
173+
130174
fn f() { 2.add(2); }"#,
131175
);
132176

@@ -136,6 +180,8 @@ fn f() { 2.add(2); }"#,
136180
//- minicore: add
137181
fn f() { core::ops::Add::$0add(2, 2); }"#,
138182
r#"
183+
use core::ops::Add;
184+
139185
fn f() { 2.add(2); }"#,
140186
);
141187

@@ -179,6 +225,8 @@ impl core::ops::Deref for S {
179225
}
180226
fn f() { core::ops::Deref::$0deref(&S); }"#,
181227
r#"
228+
use core::ops::Deref;
229+
182230
struct S;
183231
impl core::ops::Deref for S {
184232
type Target = S;

crates/ide-assists/src/tests/generated.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,6 +2948,8 @@ fn main() {
29482948
mod std { pub mod ops { pub trait Add { fn add(self, _: Self) {} } impl Add for i32 {} } }
29492949
"#####,
29502950
r#####"
2951+
use std::ops::Add;
2952+
29512953
fn main() {
29522954
1.add(2);
29532955
}

0 commit comments

Comments
 (0)