Skip to content

Commit 99e94d2

Browse files
committed
Auto merge of rust-lang#15788 - Young-Flash:import_anonymously, r=lnicola
feat: import trait with alias ![import_trait_with_alias](https://github.com/rust-lang/rust-analyzer/assets/71162630/81601160-fe55-46e3-ab8d-b2705e1aa696) cc `@Veykril` close rust-lang/rust-analyzer#15684
2 parents a2e2881 + 929544e commit 99e94d2

File tree

2 files changed

+276
-12
lines changed

2 files changed

+276
-12
lines changed

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

Lines changed: 250 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
};
1111
use 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

Comments
 (0)