@@ -5,7 +5,7 @@ use ide_db::{
55 helpers:: mod_path_to_ast,
66 imports:: {
77 import_assets:: { ImportAssets , ImportCandidate , LocatedImport } ,
8- insert_use:: { insert_use, ImportScope } ,
8+ insert_use:: { insert_use, insert_use_as_alias , ImportScope } ,
99 } ,
1010} ;
1111use syntax:: { ast, AstNode , NodeOrToken , SyntaxElement } ;
@@ -129,10 +129,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
129129 for import in proposed_imports {
130130 let import_path = import. import_path ;
131131
132+ let ( assist_id, import_name) =
133+ ( AssistId ( "auto_import" , AssistKind :: QuickFix ) , import_path. display ( ctx. db ( ) ) ) ;
132134 acc. add_group (
133135 & group_label,
134- AssistId ( "auto_import" , AssistKind :: QuickFix ) ,
135- format ! ( "Import `{}`" , import_path . display ( ctx . db ( ) ) ) ,
136+ assist_id ,
137+ format ! ( "Import `{}`" , import_name ) ,
136138 range,
137139 |builder| {
138140 let scope = match scope. clone ( ) {
@@ -143,6 +145,38 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
143145 insert_use ( & scope, mod_path_to_ast ( & import_path) , & ctx. config . insert_use ) ;
144146 } ,
145147 ) ;
148+
149+ match import_assets. import_candidate ( ) {
150+ ImportCandidate :: TraitAssocItem ( name) | ImportCandidate :: TraitMethod ( name) => {
151+ let is_method =
152+ matches ! ( import_assets. import_candidate( ) , ImportCandidate :: TraitMethod ( _) ) ;
153+ let type_ = if is_method { "method" } else { "item" } ;
154+ let group_label = GroupLabel ( format ! (
155+ "Import a trait for {} {} by alias" ,
156+ type_,
157+ name. assoc_item_name. text( )
158+ ) ) ;
159+ acc. add_group (
160+ & group_label,
161+ assist_id,
162+ format ! ( "Import `{} as _`" , import_name) ,
163+ range,
164+ |builder| {
165+ let scope = match scope. clone ( ) {
166+ ImportScope :: File ( it) => ImportScope :: File ( builder. make_mut ( it) ) ,
167+ ImportScope :: Module ( it) => ImportScope :: Module ( builder. make_mut ( it) ) ,
168+ ImportScope :: Block ( it) => ImportScope :: Block ( builder. make_mut ( it) ) ,
169+ } ;
170+ insert_use_as_alias (
171+ & scope,
172+ mod_path_to_ast ( & import_path) ,
173+ & ctx. config . insert_use ,
174+ ) ;
175+ } ,
176+ ) ;
177+ }
178+ _ => { }
179+ }
146180 }
147181 Some ( ( ) )
148182}
@@ -253,7 +287,8 @@ mod tests {
253287 } ;
254288
255289 use crate :: tests:: {
256- check_assist, check_assist_not_applicable, check_assist_target, TEST_CONFIG ,
290+ check_assist, check_assist_by_label, check_assist_not_applicable, check_assist_target,
291+ TEST_CONFIG ,
257292 } ;
258293
259294 fn check_auto_import_order ( before : & str , order : & [ & str ] ) {
@@ -705,7 +740,7 @@ fn main() {
705740
706741 #[ test]
707742 fn associated_trait_function ( ) {
708- check_assist (
743+ check_assist_by_label (
709744 auto_import,
710745 r"
711746 mod test_mod {
@@ -739,6 +774,44 @@ fn main() {
739774 test_mod::TestStruct::test_function
740775 }
741776 " ,
777+ "Import `test_mod::TestTrait`" ,
778+ ) ;
779+
780+ check_assist_by_label (
781+ auto_import,
782+ r"
783+ mod test_mod {
784+ pub trait TestTrait {
785+ fn test_function();
786+ }
787+ pub struct TestStruct {}
788+ impl TestTrait for TestStruct {
789+ fn test_function() {}
790+ }
791+ }
792+
793+ fn main() {
794+ test_mod::TestStruct::test_function$0
795+ }
796+ " ,
797+ r"
798+ use test_mod::TestTrait as _;
799+
800+ mod test_mod {
801+ pub trait TestTrait {
802+ fn test_function();
803+ }
804+ pub struct TestStruct {}
805+ impl TestTrait for TestStruct {
806+ fn test_function() {}
807+ }
808+ }
809+
810+ fn main() {
811+ test_mod::TestStruct::test_function
812+ }
813+ " ,
814+ "Import `test_mod::TestTrait as _`" ,
742815 ) ;
743816 }
744817
@@ -776,7 +849,44 @@ fn main() {
776849
777850 #[ test]
778851 fn associated_trait_const ( ) {
779- check_assist (
852+ check_assist_by_label (
853+ auto_import,
854+ r"
855+ mod test_mod {
856+ pub trait TestTrait {
857+ const TEST_CONST: u8;
858+ }
859+ pub struct TestStruct {}
860+ impl TestTrait for TestStruct {
861+ const TEST_CONST: u8 = 42;
862+ }
863+ }
864+
865+ fn main() {
866+ test_mod::TestStruct::TEST_CONST$0
867+ }
868+ " ,
869+ r"
870+ use test_mod::TestTrait as _;
871+
872+ mod test_mod {
873+ pub trait TestTrait {
874+ const TEST_CONST: u8;
875+ }
876+ pub struct TestStruct {}
877+ impl TestTrait for TestStruct {
878+ const TEST_CONST: u8 = 42;
879+ }
880+ }
881+
882+ fn main() {
883+ test_mod::TestStruct::TEST_CONST
884+ }
885+ " ,
886+ "Import `test_mod::TestTrait as _`" ,
887+ ) ;
888+
889+ check_assist_by_label (
780890 auto_import,
781891 r"
782892 mod test_mod {
@@ -810,6 +920,7 @@ fn main() {
810920 test_mod::TestStruct::TEST_CONST
811921 }
812922 " ,
923+ "Import `test_mod::TestTrait`" ,
813924 ) ;
814925 }
815926
@@ -847,7 +958,46 @@ fn main() {
847958
848959 #[ test]
849960 fn trait_method ( ) {
850- check_assist (
961+ check_assist_by_label (
962+ auto_import,
963+ r"
964+ mod test_mod {
965+ pub trait TestTrait {
966+ fn test_method(&self);
967+ }
968+ pub struct TestStruct {}
969+ impl TestTrait for TestStruct {
970+ fn test_method(&self) {}
971+ }
972+ }
973+
974+ fn main() {
975+ let test_struct = test_mod::TestStruct {};
976+ test_struct.test_meth$0od()
977+ }
978+ " ,
979+ r"
980+ use test_mod::TestTrait as _;
981+
982+ mod test_mod {
983+ pub trait TestTrait {
984+ fn test_method(&self);
985+ }
986+ pub struct TestStruct {}
987+ impl TestTrait for TestStruct {
988+ fn test_method(&self) {}
989+ }
990+ }
991+
992+ fn main() {
993+ let test_struct = test_mod::TestStruct {};
994+ test_struct.test_method()
995+ }
996+ " ,
997+ "Import `test_mod::TestTrait as _`" ,
998+ ) ;
999+
1000+ check_assist_by_label (
8511001 auto_import,
8521002 r"
8531003 mod test_mod {
@@ -883,12 +1033,43 @@ fn main() {
8831033 test_struct.test_method()
8841034 }
8851035 " ,
1036+ "Import `test_mod::TestTrait`" ,
8861037 ) ;
8871038 }
8881039
8891040 #[ test]
8901041 fn trait_method_cross_crate ( ) {
891- check_assist (
1042+ check_assist_by_label (
1043+ auto_import,
1044+ r"
1045+ //- /main.rs crate:main deps:dep
1046+ fn main() {
1047+ let test_struct = dep::test_mod::TestStruct {};
1048+ test_struct.test_meth$0od()
1049+ }
1050+ //- /dep.rs crate:dep
1051+ pub mod test_mod {
1052+ pub trait TestTrait {
1053+ fn test_method(&self);
1054+ }
1055+ pub struct TestStruct {}
1056+ impl TestTrait for TestStruct {
1057+ fn test_method(&self) {}
1058+ }
1059+ }
1060+ " ,
1061+ r"
1062+ use dep::test_mod::TestTrait as _;
1063+
1064+ fn main() {
1065+ let test_struct = dep::test_mod::TestStruct {};
1066+ test_struct.test_method()
1067+ }
1068+ " ,
1069+ "Import `dep::test_mod::TestTrait as _`" ,
1070+ ) ;
1071+
1072+ check_assist_by_label (
8921073 auto_import,
8931074 r"
8941075 //- /main.rs crate:main deps:dep
@@ -915,12 +1096,41 @@ fn main() {
9151096 test_struct.test_method()
9161097 }
9171098 " ,
1099+ "Import `dep::test_mod::TestTrait`" ,
9181100 ) ;
9191101 }
9201102
9211103 #[ test]
9221104 fn assoc_fn_cross_crate ( ) {
923- check_assist (
1105+ check_assist_by_label (
1106+ auto_import,
1107+ r"
1108+ //- /main.rs crate:main deps:dep
1109+ fn main() {
1110+ dep::test_mod::TestStruct::test_func$0tion
1111+ }
1112+ //- /dep.rs crate:dep
1113+ pub mod test_mod {
1114+ pub trait TestTrait {
1115+ fn test_function();
1116+ }
1117+ pub struct TestStruct {}
1118+ impl TestTrait for TestStruct {
1119+ fn test_function() {}
1120+ }
1121+ }
1122+ " ,
1123+ r"
1124+ use dep::test_mod::TestTrait as _;
1125+
1126+ fn main() {
1127+ dep::test_mod::TestStruct::test_function
1128+ }
1129+ " ,
1130+ "Import `dep::test_mod::TestTrait as _`" ,
1131+ ) ;
1132+
1133+ check_assist_by_label (
9241134 auto_import,
9251135 r"
9261136 //- /main.rs crate:main deps:dep
@@ -945,12 +1155,41 @@ fn main() {
9451155 dep::test_mod::TestStruct::test_function
9461156 }
9471157 " ,
1158+ "Import `dep::test_mod::TestTrait`" ,
9481159 ) ;
9491160 }
9501161
9511162 #[ test]
9521163 fn assoc_const_cross_crate ( ) {
953- check_assist (
1164+ check_assist_by_label (
1165+ auto_import,
1166+ r"
1167+ //- /main.rs crate:main deps:dep
1168+ fn main() {
1169+ dep::test_mod::TestStruct::CONST$0
1170+ }
1171+ //- /dep.rs crate:dep
1172+ pub mod test_mod {
1173+ pub trait TestTrait {
1174+ const CONST: bool;
1175+ }
1176+ pub struct TestStruct {}
1177+ impl TestTrait for TestStruct {
1178+ const CONST: bool = true;
1179+ }
1180+ }
1181+ " ,
1182+ r"
1183+ use dep::test_mod::TestTrait as _;
1184+
1185+ fn main() {
1186+ dep::test_mod::TestStruct::CONST
1187+ }
1188+ " ,
1189+ "Import `dep::test_mod::TestTrait as _`" ,
1190+ ) ;
1191+
1192+ check_assist_by_label (
9541193 auto_import,
9551194 r"
9561195 //- /main.rs crate:main deps:dep
@@ -975,6 +1214,7 @@ fn main() {
9751214 dep::test_mod::TestStruct::CONST
9761215 }
9771216 " ,
1217+ "Import `dep::test_mod::TestTrait`" ,
9781218 ) ;
9791219 }
9801220
0 commit comments