1+ use ide_db:: imports:: insert_use:: ImportScope ;
12use 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// }
@@ -38,7 +41,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>)
3841 let first_arg = args_iter. next ( ) ?;
3942 let second_arg = args_iter. next ( ) ;
4043
41- _ = path. qualifier ( ) ?;
44+ let qualifier = path. qualifier ( ) ?;
4245 let method_name = path. segment ( ) ?. name_ref ( ) ?;
4346
4447 let res = ctx. sema . resolve_path ( & path) ?;
@@ -76,10 +79,44 @@ 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 ( qualifier, ctx, edit) ;
7983 } ,
8084 )
8185}
8286
87+ fn add_import (
88+ qualifier : ast:: Path ,
89+ ctx : & AssistContext < ' _ > ,
90+ edit : & mut ide_db:: source_change:: SourceChangeBuilder ,
91+ ) {
92+ // for `<i32 as std::ops::Add>`
93+ let path_type =
94+ qualifier. segment ( ) . unwrap ( ) . syntax ( ) . children ( ) . filter_map ( ast:: PathType :: cast) . last ( ) ;
95+ let import = match path_type {
96+ Some ( it) => it. path ( ) . unwrap ( ) ,
97+ None => qualifier,
98+ } ;
99+
100+ // in case for `<_>`
101+ if import. coloncolon_token ( ) . is_none ( ) {
102+ return ;
103+ }
104+
105+ let scope = ide_db:: imports:: insert_use:: ImportScope :: find_insert_use_container (
106+ import. syntax ( ) ,
107+ & ctx. sema ,
108+ ) ;
109+
110+ if let Some ( scope) = scope {
111+ let scope = match scope {
112+ ImportScope :: File ( it) => ImportScope :: File ( edit. make_mut ( it) ) ,
113+ ImportScope :: Module ( it) => ImportScope :: Module ( edit. make_mut ( it) ) ,
114+ ImportScope :: Block ( it) => ImportScope :: Block ( edit. make_mut ( it) ) ,
115+ } ;
116+ ide_db:: imports:: insert_use:: insert_use ( & scope, import, & ctx. config . insert_use ) ;
117+ }
118+ }
119+
83120fn needs_parens_as_receiver ( expr : & ast:: Expr ) -> bool {
84121 // Make `(expr).dummy()`
85122 let dummy_call = make:: expr_method_call (
@@ -127,6 +164,8 @@ fn f() { S.f(S); }"#,
127164//- minicore: add
128165fn f() { <u32 as core::ops::Add>::$0add(2, 2); }"# ,
129166 r#"
167+ use core::ops::Add;
168+
130169fn f() { 2.add(2); }"# ,
131170 ) ;
132171
@@ -136,6 +175,8 @@ fn f() { 2.add(2); }"#,
136175//- minicore: add
137176fn f() { core::ops::Add::$0add(2, 2); }"# ,
138177 r#"
178+ use core::ops::Add;
179+
139180fn f() { 2.add(2); }"# ,
140181 ) ;
141182
@@ -179,6 +220,8 @@ impl core::ops::Deref for S {
179220}
180221fn f() { core::ops::Deref::$0deref(&S); }"# ,
181222 r#"
223+ use core::ops::Deref;
224+
182225struct S;
183226impl core::ops::Deref for S {
184227 type Target = S;
0 commit comments