@@ -5,7 +5,7 @@ use ide_db::{
5
5
helpers:: mod_path_to_ast,
6
6
imports:: {
7
7
import_assets:: { ImportAssets , ImportCandidate , LocatedImport } ,
8
- insert_use:: { insert_use, ImportScope } ,
8
+ insert_use:: { insert_use, insert_use_as_alias , ImportScope } ,
9
9
} ,
10
10
} ;
11
11
use syntax:: { ast, AstNode , NodeOrToken , SyntaxElement } ;
@@ -129,10 +129,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
129
129
for import in proposed_imports {
130
130
let import_path = import. import_path ;
131
131
132
+ let ( assist_id, import_name) =
133
+ ( AssistId ( "auto_import" , AssistKind :: QuickFix ) , import_path. display ( ctx. db ( ) ) ) ;
132
134
acc. add_group (
133
135
& group_label,
134
- AssistId ( "auto_import" , AssistKind :: QuickFix ) ,
135
- format ! ( "Import `{}`" , import_path . display ( ctx . db ( ) ) ) ,
136
+ assist_id ,
137
+ format ! ( "Import `{}`" , import_name ) ,
136
138
range,
137
139
|builder| {
138
140
let scope = match scope. clone ( ) {
@@ -143,6 +145,38 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
143
145
insert_use ( & scope, mod_path_to_ast ( & import_path) , & ctx. config . insert_use ) ;
144
146
} ,
145
147
) ;
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
+ }
146
180
}
147
181
Some ( ( ) )
148
182
}
@@ -253,7 +287,8 @@ mod tests {
253
287
} ;
254
288
255
289
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 ,
257
292
} ;
258
293
259
294
fn check_auto_import_order ( before : & str , order : & [ & str ] ) {
@@ -705,7 +740,7 @@ fn main() {
705
740
706
741
#[ test]
707
742
fn associated_trait_function ( ) {
708
- check_assist (
743
+ check_assist_by_label (
709
744
auto_import,
710
745
r"
711
746
mod test_mod {
@@ -739,6 +774,44 @@ fn main() {
739
774
test_mod::TestStruct::test_function
740
775
}
741
776
" ,
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 _`" ,
742
815
) ;
743
816
}
744
817
@@ -776,7 +849,44 @@ fn main() {
776
849
777
850
#[ test]
778
851
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 (
780
890
auto_import,
781
891
r"
782
892
mod test_mod {
@@ -810,6 +920,7 @@ fn main() {
810
920
test_mod::TestStruct::TEST_CONST
811
921
}
812
922
" ,
923
+ "Import `test_mod::TestTrait`" ,
813
924
) ;
814
925
}
815
926
@@ -847,7 +958,46 @@ fn main() {
847
958
848
959
#[ test]
849
960
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 (
851
1001
auto_import,
852
1002
r"
853
1003
mod test_mod {
@@ -883,12 +1033,43 @@ fn main() {
883
1033
test_struct.test_method()
884
1034
}
885
1035
" ,
1036
+ "Import `test_mod::TestTrait`" ,
886
1037
) ;
887
1038
}
888
1039
889
1040
#[ test]
890
1041
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 (
892
1073
auto_import,
893
1074
r"
894
1075
//- /main.rs crate:main deps:dep
@@ -915,12 +1096,41 @@ fn main() {
915
1096
test_struct.test_method()
916
1097
}
917
1098
" ,
1099
+ "Import `dep::test_mod::TestTrait`" ,
918
1100
) ;
919
1101
}
920
1102
921
1103
#[ test]
922
1104
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 (
924
1134
auto_import,
925
1135
r"
926
1136
//- /main.rs crate:main deps:dep
@@ -945,12 +1155,41 @@ fn main() {
945
1155
dep::test_mod::TestStruct::test_function
946
1156
}
947
1157
" ,
1158
+ "Import `dep::test_mod::TestTrait`" ,
948
1159
) ;
949
1160
}
950
1161
951
1162
#[ test]
952
1163
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 (
954
1193
auto_import,
955
1194
r"
956
1195
//- /main.rs crate:main deps:dep
@@ -975,6 +1214,7 @@ fn main() {
975
1214
dep::test_mod::TestStruct::CONST
976
1215
}
977
1216
" ,
1217
+ "Import `dep::test_mod::TestTrait`" ,
978
1218
) ;
979
1219
}
980
1220
0 commit comments